1 #[cfg(has_std)] 2 #[macro_export] 3 /// Create an `IndexMap` from a list of key-value pairs 4 /// 5 /// ## Example 6 /// 7 /// ``` 8 /// use indexmap::indexmap; 9 /// 10 /// let map = indexmap!{ 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_rules! indexmap { 22 (@single $($x:tt)*) => (()); 23 (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::indexmap!(@single $rest)),*])); 24 25 ($($key:expr => $value:expr,)+) => { $crate::indexmap!($($key => $value),+) }; 26 ($($key:expr => $value:expr),*) => { 27 { 28 let _cap = $crate::indexmap!(@count $($key),*); 29 let mut _map = $crate::IndexMap::with_capacity(_cap); 30 $( 31 _map.insert($key, $value); 32 )* 33 _map 34 } 35 }; 36 } 37 38 #[cfg(has_std)] 39 #[macro_export] 40 /// Create an `IndexSet` from a list of values 41 /// 42 /// ## Example 43 /// 44 /// ``` 45 /// use indexmap::indexset; 46 /// 47 /// let set = indexset!{ 48 /// "a", 49 /// "b", 50 /// }; 51 /// assert!(set.contains("a")); 52 /// assert!(set.contains("b")); 53 /// assert!(!set.contains("c")); 54 /// 55 /// // "a" is the first value 56 /// assert_eq!(set.iter().next(), Some(&"a")); 57 /// ``` 58 macro_rules! indexset { 59 (@single $($x:tt)*) => (()); 60 (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::indexset!(@single $rest)),*])); 61 62 ($($value:expr,)+) => { $crate::indexset!($($value),+) }; 63 ($($value:expr),*) => { 64 { 65 let _cap = $crate::indexset!(@count $($value),*); 66 let mut _set = $crate::IndexSet::with_capacity(_cap); 67 $( 68 _set.insert($value); 69 )* 70 _set 71 } 72 }; 73 } 74 75 // generate all the Iterator methods by just forwarding to the underlying 76 // self.iter and mapping its element. 77 macro_rules! iterator_methods { 78 // $map_elt is the mapping function from the underlying iterator's element 79 // same mapping function for both options and iterators 80 ($map_elt:expr) => { 81 fn next(&mut self) -> Option<Self::Item> { 82 self.iter.next().map($map_elt) 83 } 84 85 fn size_hint(&self) -> (usize, Option<usize>) { 86 self.iter.size_hint() 87 } 88 89 fn count(self) -> usize { 90 self.iter.len() 91 } 92 93 fn nth(&mut self, n: usize) -> Option<Self::Item> { 94 self.iter.nth(n).map($map_elt) 95 } 96 97 fn last(mut self) -> Option<Self::Item> { 98 self.next_back() 99 } 100 101 fn collect<C>(self) -> C 102 where 103 C: FromIterator<Self::Item>, 104 { 105 // NB: forwarding this directly to standard iterators will 106 // allow it to leverage unstable traits like `TrustedLen`. 107 self.iter.map($map_elt).collect() 108 } 109 }; 110 } 111 112 macro_rules! double_ended_iterator_methods { 113 // $map_elt is the mapping function from the underlying iterator's element 114 // same mapping function for both options and iterators 115 ($map_elt:expr) => { 116 fn next_back(&mut self) -> Option<Self::Item> { 117 self.iter.next_back().map($map_elt) 118 } 119 120 fn nth_back(&mut self, n: usize) -> Option<Self::Item> { 121 self.iter.nth_back(n).map($map_elt) 122 } 123 }; 124 } 125 126 // generate `ParallelIterator` methods by just forwarding to the underlying 127 // self.entries and mapping its elements. 128 #[cfg(any(feature = "rayon", feature = "rustc-rayon"))] 129 macro_rules! parallel_iterator_methods { 130 // $map_elt is the mapping function from the underlying iterator's element 131 ($map_elt:expr) => { 132 fn drive_unindexed<C>(self, consumer: C) -> C::Result 133 where 134 C: UnindexedConsumer<Self::Item>, 135 { 136 self.entries 137 .into_par_iter() 138 .map($map_elt) 139 .drive_unindexed(consumer) 140 } 141 142 // NB: This allows indexed collection, e.g. directly into a `Vec`, but the 143 // underlying iterator must really be indexed. We should remove this if we 144 // start having tombstones that must be filtered out. 145 fn opt_len(&self) -> Option<usize> { 146 Some(self.entries.len()) 147 } 148 }; 149 } 150 151 // generate `IndexedParallelIterator` methods by just forwarding to the underlying 152 // self.entries and mapping its elements. 153 #[cfg(any(feature = "rayon", feature = "rustc-rayon"))] 154 macro_rules! indexed_parallel_iterator_methods { 155 // $map_elt is the mapping function from the underlying iterator's element 156 ($map_elt:expr) => { 157 fn drive<C>(self, consumer: C) -> C::Result 158 where 159 C: Consumer<Self::Item>, 160 { 161 self.entries.into_par_iter().map($map_elt).drive(consumer) 162 } 163 164 fn len(&self) -> usize { 165 self.entries.len() 166 } 167 168 fn with_producer<CB>(self, callback: CB) -> CB::Output 169 where 170 CB: ProducerCallback<Self::Item>, 171 { 172 self.entries 173 .into_par_iter() 174 .map($map_elt) 175 .with_producer(callback) 176 } 177 }; 178 } 179