Skip to content

Commit 066023e

Browse files
committed
feat: implement hash_map! macro
1 parent 4b55fe1 commit 066023e

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

library/std/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@
294294
#![feature(f128)]
295295
#![feature(ffi_const)]
296296
#![feature(formatting_options)]
297+
#![feature(hash_map_internals)]
298+
#![feature(hash_map_macro)]
297299
#![feature(if_let_guard)]
298300
#![feature(intra_doc_pointers)]
299301
#![feature(iter_advance_by)]

library/std/src/macros.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,77 @@ macro_rules! dbg {
379379
($($crate::dbg!($val)),+,)
380380
};
381381
}
382+
383+
#[doc(hidden)]
384+
#[macro_export]
385+
#[allow_internal_unstable(hash_map_internals)]
386+
#[unstable(feature = "hash_map_internals", issue = "none")]
387+
macro_rules! repetition_utils {
388+
(@count $($tokens:tt),*) => {{
389+
[$($crate::repetition_utils!(@replace $tokens => ())),*].len()
390+
}};
391+
392+
(@replace $x:tt => $y:tt) => { $y }
393+
}
394+
395+
/// Creates a [`HashMap`] containing the arguments.
396+
///
397+
/// `hash_map!` allows specifying the entries that make
398+
/// up the [`HashMap`] where the key and value are separated by a `=>`.
399+
///
400+
/// The entries are separated by commas with a trailing comma being allowed.
401+
///
402+
/// It is semantically equivalent to using repeated [`HashMap::insert`]
403+
/// on a newly created hashmap.
404+
///
405+
/// `hash_map!` will attempt to avoid repeated reallocations by
406+
/// using [`HashMap::with_capacity`].
407+
///
408+
/// # Examples
409+
///
410+
/// ```rust
411+
/// #![feature(hash_map_macro)]
412+
///
413+
/// let map = hash_map! {
414+
/// "key" => "value",
415+
/// "key1" => "value1"
416+
/// };
417+
///
418+
/// assert_eq!(map.get("key"), Some(&"value"));
419+
/// assert_eq!(map.get("key1"), Some(&"value1"));
420+
/// assert!(map.get("brrrrrrooooommm").is_none());
421+
/// ```
422+
///
423+
/// And with a trailing comma
424+
///
425+
///```rust
426+
/// #![feature(hash_map_macro)]
427+
///
428+
/// let map = hash_map! {
429+
/// "key" => "value", // notice the ,
430+
/// };
431+
///
432+
/// assert_eq!(map.get("key"), Some(&"value"));
433+
/// ```
434+
///
435+
/// The key and value are moved into the HashMap.
436+
///
437+
/// [`HashMap`]: crate::collections::HashMap
438+
/// [`HashMap::insert`]: crate::collections::HashMap::insert
439+
/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity
440+
#[macro_export]
441+
#[allow_internal_unstable(hash_map_internals)]
442+
#[unstable(feature = "hash_map_macro", issue = "144032")]
443+
macro_rules! hash_map {
444+
() => {{
445+
$crate::collections::HashMap::new()
446+
}};
447+
448+
( $( $key:expr => $value:expr ),* $(,)? ) => {{
449+
let mut map = $crate::collections::HashMap::with_capacity(
450+
const { $crate::repetition_utils!(@count $($key),*) }
451+
);
452+
$( map.insert($key, $value); )*
453+
map
454+
}}
455+
}

0 commit comments

Comments
 (0)