| 1 | /// Create an [`IndexMap`][crate::IndexMap] from a list of key-value pairs |
| 2 | /// and a [`BuildHasherDefault`][core::hash::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 | |
| 38 | #[cfg (feature = "std" )] |
| 39 | #[cfg_attr (docsrs, doc(cfg(feature = "std" )))] |
| 40 | #[macro_export ] |
| 41 | /// Create an [`IndexMap`][crate::IndexMap] from a list of key-value pairs |
| 42 | /// |
| 43 | /// ## Example |
| 44 | /// |
| 45 | /// ``` |
| 46 | /// use indexmap::indexmap; |
| 47 | /// |
| 48 | /// let map = indexmap!{ |
| 49 | /// "a" => 1, |
| 50 | /// "b" => 2, |
| 51 | /// }; |
| 52 | /// assert_eq!(map["a" ], 1); |
| 53 | /// assert_eq!(map["b" ], 2); |
| 54 | /// assert_eq!(map.get("c" ), None); |
| 55 | /// |
| 56 | /// // "a" is the first key |
| 57 | /// assert_eq!(map.keys().next(), Some(&"a" )); |
| 58 | /// ``` |
| 59 | macro_rules! indexmap { |
| 60 | ($($key:expr => $value:expr,)+) => { $crate::indexmap!($($key => $value),+) }; |
| 61 | ($($key:expr => $value:expr),*) => { |
| 62 | { |
| 63 | // Note: `stringify!($key)` is just here to consume the repetition, |
| 64 | // 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 | }; |
| 73 | } |
| 74 | |
| 75 | /// Create an [`IndexSet`][crate::IndexSet] from a list of values |
| 76 | /// and a [`BuildHasherDefault`][core::hash::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 | |
| 112 | #[cfg (feature = "std" )] |
| 113 | #[cfg_attr (docsrs, doc(cfg(feature = "std" )))] |
| 114 | #[macro_export ] |
| 115 | /// Create an [`IndexSet`][crate::IndexSet] from a list of values |
| 116 | /// |
| 117 | /// ## Example |
| 118 | /// |
| 119 | /// ``` |
| 120 | /// use indexmap::indexset; |
| 121 | /// |
| 122 | /// let set = indexset!{ |
| 123 | /// "a" , |
| 124 | /// "b" , |
| 125 | /// }; |
| 126 | /// assert!(set.contains("a" )); |
| 127 | /// assert!(set.contains("b" )); |
| 128 | /// assert!(!set.contains("c" )); |
| 129 | /// |
| 130 | /// // "a" is the first value |
| 131 | /// assert_eq!(set.iter().next(), Some(&"a" )); |
| 132 | /// ``` |
| 133 | macro_rules! indexset { |
| 134 | ($($value:expr,)+) => { $crate::indexset!($($value),+) }; |
| 135 | ($($value:expr),*) => { |
| 136 | { |
| 137 | // Note: `stringify!($value)` is just here to consume the repetition, |
| 138 | // 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 | }; |
| 147 | } |
| 148 | |
| 149 | // generate all the Iterator methods by just forwarding to the underlying |
| 150 | // self.iter and mapping its element. |
| 151 | macro_rules! iterator_methods { |
| 152 | // $map_elt is the mapping function from the underlying iterator's element |
| 153 | // same mapping function for both options and iterators |
| 154 | ($map_elt:expr) => { |
| 155 | fn next(&mut self) -> Option<Self::Item> { |
| 156 | self.iter.next().map($map_elt) |
| 157 | } |
| 158 | |
| 159 | fn size_hint(&self) -> (usize, Option<usize>) { |
| 160 | self.iter.size_hint() |
| 161 | } |
| 162 | |
| 163 | fn count(self) -> usize { |
| 164 | self.iter.len() |
| 165 | } |
| 166 | |
| 167 | fn nth(&mut self, n: usize) -> Option<Self::Item> { |
| 168 | self.iter.nth(n).map($map_elt) |
| 169 | } |
| 170 | |
| 171 | fn last(mut self) -> Option<Self::Item> { |
| 172 | self.next_back() |
| 173 | } |
| 174 | |
| 175 | fn collect<C>(self) -> C |
| 176 | where |
| 177 | C: FromIterator<Self::Item>, |
| 178 | { |
| 179 | // NB: forwarding this directly to standard iterators will |
| 180 | // allow it to leverage unstable traits like `TrustedLen`. |
| 181 | self.iter.map($map_elt).collect() |
| 182 | } |
| 183 | }; |
| 184 | } |
| 185 | |
| 186 | macro_rules! double_ended_iterator_methods { |
| 187 | // $map_elt is the mapping function from the underlying iterator's element |
| 188 | // same mapping function for both options and iterators |
| 189 | ($map_elt:expr) => { |
| 190 | fn next_back(&mut self) -> Option<Self::Item> { |
| 191 | self.iter.next_back().map($map_elt) |
| 192 | } |
| 193 | |
| 194 | fn nth_back(&mut self, n: usize) -> Option<Self::Item> { |
| 195 | self.iter.nth_back(n).map($map_elt) |
| 196 | } |
| 197 | }; |
| 198 | } |
| 199 | |
| 200 | // generate `ParallelIterator` methods by just forwarding to the underlying |
| 201 | // self.entries and mapping its elements. |
| 202 | #[cfg (feature = "rayon" )] |
| 203 | macro_rules! parallel_iterator_methods { |
| 204 | // $map_elt is the mapping function from the underlying iterator's element |
| 205 | ($map_elt:expr) => { |
| 206 | fn drive_unindexed<C>(self, consumer: C) -> C::Result |
| 207 | where |
| 208 | C: UnindexedConsumer<Self::Item>, |
| 209 | { |
| 210 | self.entries |
| 211 | .into_par_iter() |
| 212 | .map($map_elt) |
| 213 | .drive_unindexed(consumer) |
| 214 | } |
| 215 | |
| 216 | // NB: This allows indexed collection, e.g. directly into a `Vec`, but the |
| 217 | // underlying iterator must really be indexed. We should remove this if we |
| 218 | // start having tombstones that must be filtered out. |
| 219 | fn opt_len(&self) -> Option<usize> { |
| 220 | Some(self.entries.len()) |
| 221 | } |
| 222 | }; |
| 223 | } |
| 224 | |
| 225 | // generate `IndexedParallelIterator` methods by just forwarding to the underlying |
| 226 | // self.entries and mapping its elements. |
| 227 | #[cfg (feature = "rayon" )] |
| 228 | macro_rules! indexed_parallel_iterator_methods { |
| 229 | // $map_elt is the mapping function from the underlying iterator's element |
| 230 | ($map_elt:expr) => { |
| 231 | fn drive<C>(self, consumer: C) -> C::Result |
| 232 | where |
| 233 | C: Consumer<Self::Item>, |
| 234 | { |
| 235 | self.entries.into_par_iter().map($map_elt).drive(consumer) |
| 236 | } |
| 237 | |
| 238 | fn len(&self) -> usize { |
| 239 | self.entries.len() |
| 240 | } |
| 241 | |
| 242 | fn with_producer<CB>(self, callback: CB) -> CB::Output |
| 243 | where |
| 244 | CB: ProducerCallback<Self::Item>, |
| 245 | { |
| 246 | self.entries |
| 247 | .into_par_iter() |
| 248 | .map($map_elt) |
| 249 | .with_producer(callback) |
| 250 | } |
| 251 | }; |
| 252 | } |
| 253 | |