1919/// // "a" is the first key
2020/// assert_eq!(map.keys().next(), Some(&"a"));
2121/// ```
22+ ///
23+ /// This can also be initialized in `const` contexts:
24+ ///
25+ /// ```
26+ /// use indexmap::{IndexMap, indexmap_with_default};
27+ /// use fnv::FnvBuildHasher; // = BuildHasherDefault<FnvHasher>
28+ /// use std::sync::Mutex;
29+ ///
30+ /// static GLOBAL: Mutex<IndexMap<String, i32, FnvBuildHasher>> =
31+ /// Mutex::new(indexmap_with_default!());
32+ ///
33+ /// if let Ok(mut map) = GLOBAL.lock() {
34+ /// map.insert("a".into(), 1);
35+ /// map.insert("b".into(), 2);
36+ /// }
37+ ///
38+ /// assert_eq!(GLOBAL.lock().unwrap()["a"], 1);
39+ /// assert_eq!(GLOBAL.lock().unwrap()["b"], 2);
40+ /// ```
2241#[ macro_export]
2342macro_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>:: new( ) ;
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) ;
43+ ( ) => { const {
44+ $crate:: IndexMap :: with_hasher(
45+ // Let type inference figure out the hasher:
46+ :: core:: hash:: BuildHasherDefault :: new( ) ,
47+ )
48+ } } ;
49+ ( $H: ty $( ; ) ?) => { const {
50+ $crate:: IndexMap :: with_hasher(
51+ // Specify your custom `H` (must implement Default + Hasher) as the hasher:
52+ :: core:: hash:: BuildHasherDefault :: <$H>:: new( ) ,
53+ )
54+ } } ;
55+ ( $H: ty; $( $key: expr => $value: expr) ,+ $( , ) ?) => { {
56+ let mut map = $crate:: IndexMap :: with_capacity_and_hasher(
57+ // Note: `stringify!($key)` is just here to consume the repetition,
58+ // but we throw away that string literal during constant evaluation.
59+ const { <[ ( ) ] >:: len( & [ $( { stringify!( $key) ; } ) ,* ] ) } ,
60+ // Specify your custom `H` (must implement Default + Hasher) as the hasher:
61+ :: core:: hash:: BuildHasherDefault :: <$H>:: new( ) ,
62+ ) ;
3163 $(
3264 map. insert( $key, $value) ;
33- ) *
65+ ) +
3466 map
3567 } } ;
3668}
@@ -57,19 +89,18 @@ macro_rules! indexmap_with_default {
5789/// assert_eq!(map.keys().next(), Some(&"a"));
5890/// ```
5991macro_rules! indexmap {
60- ( $ ( $key : expr => $value : expr , ) + ) => { $crate:: indexmap! ( $ ( $key => $value ) ,+ ) } ;
61- ( $( $key: expr => $value: expr) ,* ) => {
62- {
92+ ( ) => { $crate:: IndexMap :: new ( ) } ;
93+ ( $( $key: expr => $value: expr) ,+ $ ( , ) ? ) => { {
94+ let mut map = $crate :: IndexMap :: with_capacity (
6395 // Note: `stringify!($key)` is just here to consume the repetition,
6496 // but we throw away that string literal during constant evaluation.
65- const CAP : usize = <[ ( ) ] >:: len( & [ $( { stringify!( $key) ; } ) ,* ] ) ;
66- let mut map = $crate:: IndexMap :: with_capacity( CAP ) ;
67- $(
68- map. insert( $key, $value) ;
69- ) *
70- map
71- }
72- } ;
97+ const { <[ ( ) ] >:: len( & [ $( { stringify!( $key) ; } ) ,* ] ) } ,
98+ ) ;
99+ $(
100+ map. insert( $key, $value) ;
101+ ) +
102+ map
103+ } } ;
73104}
74105
75106/// Create an [`IndexSet`][crate::IndexSet] from a list of values
@@ -93,18 +124,52 @@ macro_rules! indexmap {
93124/// // "a" is the first value
94125/// assert_eq!(set.iter().next(), Some(&"a"));
95126/// ```
127+ ///
128+ /// This can also be initialized in `const` contexts:
129+ ///
130+ /// ```
131+ /// use indexmap::{IndexSet, indexset_with_default};
132+ /// use fnv::FnvBuildHasher; // = BuildHasherDefault<FnvHasher>
133+ /// use std::sync::Mutex;
134+ ///
135+ /// static INTERN: Mutex<IndexSet<String, FnvBuildHasher>> =
136+ /// Mutex::new(indexset_with_default!());
137+ ///
138+ /// if let Ok(mut set) = INTERN.lock() {
139+ /// set.insert("a".into());
140+ /// set.insert("b".into());
141+ /// set.insert("c".into());
142+ /// }
143+ ///
144+ /// assert!(INTERN.lock().unwrap().contains("a"));
145+ /// assert!(INTERN.lock().unwrap().contains("b"));
146+ /// assert!(INTERN.lock().unwrap().contains("c"));
147+ /// ```
96148#[ macro_export]
97149macro_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>:: new( ) ;
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) ;
150+ ( ) => { const {
151+ $crate:: IndexSet :: with_hasher(
152+ // Let type inference figure out the hasher:
153+ :: core:: hash:: BuildHasherDefault :: new( ) ,
154+ )
155+ } } ;
156+ ( $H: ty $( ; ) ?) => { const {
157+ $crate:: IndexSet :: with_hasher(
158+ // Specify your custom `H` (must implement Default + Hasher) as the hasher:
159+ :: core:: hash:: BuildHasherDefault :: <$H>:: new( ) ,
160+ )
161+ } } ;
162+ ( $H: ty; $( $value: expr) ,+ $( , ) ?) => { {
163+ let mut set = $crate:: IndexSet :: with_capacity_and_hasher(
164+ // Note: `stringify!($value)` is just here to consume the repetition,
165+ // but we throw away that string literal during constant evaluation.
166+ const { <[ ( ) ] >:: len( & [ $( { stringify!( $value) ; } ) ,* ] ) } ,
167+ // Specify your custom `H` (must implement Default + Hasher) as the hasher:
168+ :: core:: hash:: BuildHasherDefault :: <$H>:: new( ) ,
169+ ) ;
105170 $(
106171 set. insert( $value) ;
107- ) *
172+ ) +
108173 set
109174 } } ;
110175}
@@ -131,19 +196,18 @@ macro_rules! indexset_with_default {
131196/// assert_eq!(set.iter().next(), Some(&"a"));
132197/// ```
133198macro_rules! indexset {
134- ( $ ( $value : expr , ) + ) => { $crate:: indexset! ( $ ( $value ) ,+ ) } ;
135- ( $( $value: expr) ,* ) => {
136- {
199+ ( ) => { $crate:: IndexSet :: new ( ) } ;
200+ ( $( $value: expr) ,+ $ ( , ) ? ) => { {
201+ let mut set = $crate :: IndexSet :: with_capacity (
137202 // Note: `stringify!($value)` is just here to consume the repetition,
138203 // but we throw away that string literal during constant evaluation.
139- const CAP : usize = <[ ( ) ] >:: len( & [ $( { stringify!( $value) ; } ) ,* ] ) ;
140- let mut set = $crate:: IndexSet :: with_capacity( CAP ) ;
141- $(
142- set. insert( $value) ;
143- ) *
144- set
145- }
146- } ;
204+ const { <[ ( ) ] >:: len( & [ $( { stringify!( $value) ; } ) ,* ] ) } ,
205+ ) ;
206+ $(
207+ set. insert( $value) ;
208+ ) +
209+ set
210+ } } ;
147211}
148212
149213// generate all the Iterator methods by just forwarding to the underlying
0 commit comments