Skip to content

Commit 6301a2a

Browse files
committed
feat: add indexmap_with_default and indexset_with_default macros
1 parent b56f035 commit 6301a2a

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@
9898
//! [`with_capacity_and_hasher`][IndexMap::with_capacity_and_hasher] instead.
9999
//! A no-std compatible hasher will be needed as well, for example
100100
//! from the crate `twox-hash`.
101-
//! - Macros [`indexmap!`] and [`indexset!`] are unavailable without `std`.
101+
//! - Macros [`indexmap!`] and [`indexset!`] are unavailable without `std`. Use
102+
//! the macros [`indexmap_with_default!`] and [`indexset_with_default!`] instead.
102103
103104
#![cfg_attr(docsrs, feature(doc_cfg))]
104105

src/macros.rs

+72
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
/// Create an [`IndexMap`][crate::IndexMap] from a list of key-value pairs and a custom hasher
2+
///
3+
/// ## Example
4+
///
5+
/// ```
6+
/// use indexmap::indexmap_with_default;
7+
/// use std::hash::DefaultHasher;
8+
///
9+
/// let map = indexmap_with_default!{
10+
/// DefaultHasher;
11+
/// "a" => 1,
12+
/// "b" => 2,
13+
/// };
14+
/// assert_eq!(map["a"], 1);
15+
/// assert_eq!(map["b"], 2);
16+
/// assert_eq!(map.get("c"), None);
17+
///
18+
/// // "a" is the first key
19+
/// assert_eq!(map.keys().next(), Some(&"a"));
20+
/// ```
21+
#[macro_export]
22+
macro_rules! indexmap_with_default {
23+
($H:ty; $($key:expr => $value:expr,)+) => { $crate::indexmap_with_default!($H; $($key => $value),+) };
24+
($H:ty; $($key:expr => $value:expr),*) => {{
25+
let builder = ::core::hash::BuildHasherDefault::<$H>::new();
26+
const CAP: usize = <[()]>::len(&[$({ stringify!($key); }),*]);
27+
#[allow(unused_mut)]
28+
// Specify your custom `H` (must implement Default + Hasher) as the hasher:
29+
let mut map = $crate::IndexMap::with_capacity_and_hasher(CAP, builder);
30+
$(
31+
map.insert($key, $value);
32+
)*
33+
map
34+
}};
35+
}
36+
137
#[cfg(feature = "std")]
238
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
339
#[macro_export]
@@ -35,6 +71,42 @@ macro_rules! indexmap {
3571
};
3672
}
3773

74+
/// Create an [`IndexSet`][crate::IndexSet] from a list of key-value pairs and a custom hasher
75+
///
76+
/// ## Example
77+
///
78+
/// ```
79+
/// use indexmap::indexset_with_default;
80+
/// use std::hash::DefaultHasher;
81+
///
82+
/// let set = indexset_with_default!{
83+
/// DefaultHasher;
84+
/// "a",
85+
/// "b",
86+
/// };
87+
/// assert!(set.contains("a"));
88+
/// assert!(set.contains("b"));
89+
/// assert!(!set.contains("c"));
90+
///
91+
/// // "a" is the first value
92+
/// assert_eq!(set.iter().next(), Some(&"a"));
93+
/// ```
94+
#[macro_export]
95+
macro_rules! indexset_with_default {
96+
($H:ty; $($value:expr,)+) => { $crate::indexset_with_default!($H; $($value),+) };
97+
($H:ty; $($value:expr),*) => {{
98+
let builder = ::core::hash::BuildHasherDefault::<$H>::new();
99+
const CAP: usize = <[()]>::len(&[$({ stringify!($value); }),*]);
100+
#[allow(unused_mut)]
101+
// Specify your custom `H` (must implement Default + Hash) as the hasher:
102+
let mut set = $crate::IndexSet::with_capacity_and_hasher(CAP, builder);
103+
$(
104+
set.insert($value);
105+
)*
106+
set
107+
}};
108+
}
109+
38110
#[cfg(feature = "std")]
39111
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
40112
#[macro_export]

0 commit comments

Comments
 (0)