Skip to content

Commit b10b273

Browse files
authored
Merge pull request #380 from iajoiner/feat/macros-no-std
feat: add no_std macros `indexmap_with_default` and `indexset_with_default`
2 parents 5b133ae + 5fd8971 commit b10b273

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-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

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

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

0 commit comments

Comments
 (0)