Skip to content

Commit 2cb3c7b

Browse files
iajoinercuviper
andcommitted
feat: add ringmap_with_default and ringset_with_default macros
(cherry picked from commit 5fd897196333c830798ade91e655a3c07f131926) Ported from indexmap to ringmap. Co-authored-by: Josh Stone <[email protected]>
1 parent cb92ff5 commit 2cb3c7b

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
@@ -95,7 +95,8 @@
9595
//! [`with_capacity_and_hasher`][RingMap::with_capacity_and_hasher] instead.
9696
//! A no-std compatible hasher will be needed as well, for example
9797
//! from the crate `twox-hash`.
98-
//! - Macros [`ringmap!`] and [`ringset!`] are unavailable without `std`.
98+
//! - Macros [`ringmap!`] and [`ringset!`] are unavailable without `std`. Use
99+
//! the macros [`ringmap_with_default!`] and [`ringset_with_default!`] instead.
99100
100101
#![cfg_attr(docsrs, feature(doc_cfg))]
101102

src/macros.rs

+74
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,40 @@
1+
/// Create an [`RingMap`][crate::RingMap] from a list of key-value pairs
2+
/// and a `BuildHasherDefault`-wrapped custom hasher.
3+
///
4+
/// ## Example
5+
///
6+
/// ```
7+
/// use ringmap::ringmap_with_default;
8+
/// use fnv::FnvHasher;
9+
///
10+
/// let map = ringmap_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! ringmap_with_default {
24+
($H:ty; $($key:expr => $value:expr,)+) => { $crate::ringmap_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::RingMap::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! ringmap {
3572
};
3673
}
3774

75+
/// Create an [`RingSet`][crate::RingSet] from a list of values
76+
/// and a `BuildHasherDefault`-wrapped custom hasher.
77+
///
78+
/// ## Example
79+
///
80+
/// ```
81+
/// use ringmap::ringset_with_default;
82+
/// use fnv::FnvHasher;
83+
///
84+
/// let set = ringset_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! ringset_with_default {
98+
($H:ty; $($value:expr,)+) => { $crate::ringset_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::RingSet::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)