enum_map_internals/
iter.rs

1use {Enum, EnumMap};
2
3use core::iter::{Enumerate, FusedIterator};
4use core::marker::PhantomData;
5use core::mem::ManuallyDrop;
6use core::ptr;
7use core::slice;
8
9/// Immutable enum map iterator
10///
11/// This struct is created by `iter` method or `into_iter` on a reference
12/// to `EnumMap`.
13///
14/// # Examples
15///
16/// ```
17/// # extern crate enum_map;
18/// use enum_map::{enum_map, Enum};
19///
20/// #[derive(Enum)]
21/// enum Example {
22///     A,
23///     B,
24///     C,
25/// }
26///
27/// fn main() {
28///     let mut map = enum_map! { Example::A => 3, _ => 0 };
29///     assert_eq!(map[Example::A], 3);
30///     for (key, &value) in &map {
31///         assert_eq!(value, match key {
32///             Example::A => 3,
33///             _ => 0,
34///         });
35///     }
36/// }
37/// ```
38#[derive(Debug)]
39pub struct Iter<'a, K, V: 'a> {
40    _phantom: PhantomData<fn() -> K>,
41    iterator: Enumerate<slice::Iter<'a, V>>,
42}
43
44impl<'a, K: Enum<V>, V> Iterator for Iter<'a, K, V> {
45    type Item = (K, &'a V);
46    #[inline]
47    fn next(&mut self) -> Option<Self::Item> {
48        self.iterator
49            .next()
50            .map(|(index, item)| (K::from_usize(index), item))
51    }
52
53    #[inline]
54    fn size_hint(&self) -> (usize, Option<usize>) {
55        self.iterator.size_hint()
56    }
57
58    fn fold<B, F>(self, init: B, f: F) -> B
59    where
60        F: FnMut(B, Self::Item) -> B,
61    {
62        self.iterator
63            .map(|(index, item)| (K::from_usize(index), item))
64            .fold(init, f)
65    }
66}
67
68impl<'a, K: Enum<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
69    #[inline]
70    fn next_back(&mut self) -> Option<Self::Item> {
71        self.iterator
72            .next_back()
73            .map(|(index, item)| (K::from_usize(index), item))
74    }
75}
76
77impl<'a, K: Enum<V>, V> ExactSizeIterator for Iter<'a, K, V> {}
78
79impl<'a, K: Enum<V>, V> FusedIterator for Iter<'a, K, V> {}
80
81impl<'a, K: Enum<V>, V> IntoIterator for &'a EnumMap<K, V> {
82    type Item = (K, &'a V);
83    type IntoIter = Iter<'a, K, V>;
84    #[inline]
85    fn into_iter(self) -> Self::IntoIter {
86        Iter {
87            _phantom: PhantomData,
88            iterator: self.as_slice().iter().enumerate(),
89        }
90    }
91}
92
93/// Mutable map iterator
94///
95/// This struct is created by `iter_mut` method or `into_iter` on a mutable
96/// reference to `EnumMap`.
97///
98/// # Examples
99///
100/// ```
101/// # extern crate enum_map;
102/// use enum_map::{enum_map, Enum};
103///
104/// #[derive(Debug, Enum)]
105/// enum Example {
106///     A,
107///     B,
108///     C,
109/// }
110///
111/// fn main() {
112///     let mut map = enum_map! { Example::A => 3, _ => 0 };
113///     for (_, value) in &mut map {
114///         *value += 1;
115///     }
116///     assert_eq!(map, enum_map! { Example::A => 4, _ => 1 });
117/// }
118/// ```
119#[derive(Debug)]
120pub struct IterMut<'a, K, V: 'a> {
121    _phantom: PhantomData<fn() -> K>,
122    iterator: Enumerate<slice::IterMut<'a, V>>,
123}
124
125impl<'a, K: Enum<V>, V> Iterator for IterMut<'a, K, V> {
126    type Item = (K, &'a mut V);
127    #[inline]
128    fn next(&mut self) -> Option<Self::Item> {
129        self.iterator
130            .next()
131            .map(|(index, item)| (K::from_usize(index), item))
132    }
133
134    #[inline]
135    fn size_hint(&self) -> (usize, Option<usize>) {
136        self.iterator.size_hint()
137    }
138
139    fn fold<B, F>(self, init: B, f: F) -> B
140    where
141        F: FnMut(B, Self::Item) -> B,
142    {
143        self.iterator
144            .map(|(index, item)| (K::from_usize(index), item))
145            .fold(init, f)
146    }
147}
148
149impl<'a, K: Enum<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
150    #[inline]
151    fn next_back(&mut self) -> Option<Self::Item> {
152        self.iterator
153            .next_back()
154            .map(|(index, item)| (K::from_usize(index), item))
155    }
156}
157
158impl<'a, K: Enum<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}
159
160impl<'a, K: Enum<V>, V> FusedIterator for IterMut<'a, K, V> {}
161
162impl<'a, K: Enum<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
163    type Item = (K, &'a mut V);
164    type IntoIter = IterMut<'a, K, V>;
165    #[inline]
166    fn into_iter(self) -> Self::IntoIter {
167        IterMut {
168            _phantom: PhantomData,
169            iterator: self.as_mut_slice().iter_mut().enumerate(),
170        }
171    }
172}
173
174/// A map iterator that moves out of map.
175///
176/// This struct is created by `into_iter` on `EnumMap`.
177///
178/// # Examples
179///
180/// ```
181/// # extern crate enum_map;
182/// use enum_map::{enum_map, Enum};
183///
184/// #[derive(Debug, Enum)]
185/// enum Example {
186///     A,
187///     B,
188/// }
189///
190/// fn main() {
191///     let map = enum_map! { Example::A | Example::B => String::from("123") };
192///     for (_, value) in map {
193///         assert_eq!(value + "4", "1234");
194///     }
195/// }
196/// ```
197pub struct IntoIter<K: Enum<V>, V> {
198    map: ManuallyDrop<EnumMap<K, V>>,
199    position: usize,
200}
201
202impl<K: Enum<V>, V> Iterator for IntoIter<K, V> {
203    type Item = (K, V);
204    fn next(&mut self) -> Option<(K, V)> {
205        let slice = self.map.as_slice();
206        if self.position < slice.len() {
207            let key = K::from_usize(self.position);
208            let result = Some((key, unsafe { ptr::read(&slice[self.position]) }));
209            self.position += 1;
210            result
211        } else {
212            None
213        }
214    }
215
216    #[inline]
217    fn size_hint(&self) -> (usize, Option<usize>) {
218        let slice = self.map.as_slice();
219        let diff = slice.len() - self.position;
220        (diff, Some(diff))
221    }
222}
223
224impl<K: Enum<V>, V> ExactSizeIterator for IntoIter<K, V> {}
225
226impl<K: Enum<V>, V> FusedIterator for IntoIter<K, V> {}
227
228impl<K: Enum<V>, V> Drop for IntoIter<K, V> {
229    #[inline]
230    fn drop(&mut self) {
231        for _item in self {}
232    }
233}
234
235impl<K: Enum<V>, V> IntoIterator for EnumMap<K, V> {
236    type Item = (K, V);
237    type IntoIter = IntoIter<K, V>;
238    #[inline]
239    fn into_iter(self) -> Self::IntoIter {
240        IntoIter {
241            map: ManuallyDrop::new(self),
242            position: 0,
243        }
244    }
245}
246
247impl<K: Enum<V>, V> EnumMap<K, V> {
248    /// An iterator visiting all values. The iterator type is `&V`.
249    ///
250    /// # Examples
251    ///
252    /// ```
253    /// # extern crate enum_map;
254    /// use enum_map::enum_map;
255    ///
256    /// fn main() {
257    ///     let map = enum_map! { false => 3, true => 4 };
258    ///     let mut values = map.values();
259    ///     assert_eq!(values.next(), Some(&3));
260    ///     assert_eq!(values.next(), Some(&4));
261    ///     assert_eq!(values.next(), None);
262    /// }
263    /// ```
264    #[inline]
265    pub fn values(&self) -> Values<V> {
266        Values(self.as_slice().iter())
267    }
268
269    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
270    ///
271    /// # Examples
272    ///
273    /// ```
274    /// # extern crate enum_map;
275    /// use enum_map::enum_map;
276    ///
277    /// fn main() {
278    ///     let mut map = enum_map! { _ => 2 };
279    ///     for value in map.values_mut() {
280    ///         *value += 2;
281    ///     }
282    ///     assert_eq!(map[false], 4);
283    ///     assert_eq!(map[true], 4);
284    /// }
285    /// ```
286    #[inline]
287    pub fn values_mut(&mut self) -> ValuesMut<V> {
288        ValuesMut(self.as_mut_slice().iter_mut())
289    }
290}
291
292/// An iterator over the values of `EnumMap`.
293///
294/// This `struct` is created by the `values` method of `EnumMap`.
295/// See its documentation for more.
296pub struct Values<'a, V: 'a>(slice::Iter<'a, V>);
297
298impl<'a, V: 'a> Iterator for Values<'a, V> {
299    type Item = &'a V;
300    #[inline]
301    fn next(&mut self) -> Option<&'a V> {
302        self.0.next()
303    }
304
305    #[inline]
306    fn size_hint(&self) -> (usize, Option<usize>) {
307        self.0.size_hint()
308    }
309}
310
311impl<'a, V: 'a> DoubleEndedIterator for Values<'a, V> {
312    #[inline]
313    fn next_back(&mut self) -> Option<&'a V> {
314        self.0.next_back()
315    }
316}
317
318impl<'a, V: 'a> ExactSizeIterator for Values<'a, V> {}
319
320impl<'a, V: 'a> FusedIterator for Values<'a, V> {}
321
322/// A mutable iterator over the values of `EnumMap`.
323///
324/// This `struct` is created by the `values_mut` method of `EnumMap`.
325/// See its documentation for more.
326pub struct ValuesMut<'a, V: 'a>(slice::IterMut<'a, V>);
327
328impl<'a, V: 'a> Iterator for ValuesMut<'a, V> {
329    type Item = &'a mut V;
330    #[inline]
331    fn next(&mut self) -> Option<&'a mut V> {
332        self.0.next()
333    }
334
335    #[inline]
336    fn size_hint(&self) -> (usize, Option<usize>) {
337        self.0.size_hint()
338    }
339}
340
341impl<'a, V: 'a> DoubleEndedIterator for ValuesMut<'a, V> {
342    #[inline]
343    fn next_back(&mut self) -> Option<&'a mut V> {
344        self.0.next_back()
345    }
346}
347
348impl<'a, V: 'a> ExactSizeIterator for ValuesMut<'a, V> {}
349
350impl<'a, V: 'a> FusedIterator for ValuesMut<'a, V> {}