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