enum_map/
iter.rs

1#![allow(clippy::module_name_repetitions)]
2
3// SPDX-FileCopyrightText: 2017 - 2022 Kamila Borowska <kamila@borowska.pw>
4// SPDX-FileCopyrightText: 2020 Amanieu d'Antras <amanieu@gmail.com>
5// SPDX-FileCopyrightText: 2021 Bruno Corrêa Zimmermann <brunoczim@gmail.com>
6//
7// SPDX-License-Identifier: MIT OR Apache-2.0
8
9use crate::{EnumArray, EnumMap};
10use core::iter::{Enumerate, FusedIterator};
11use core::marker::PhantomData;
12use core::mem::ManuallyDrop;
13use core::ops::Range;
14use core::ptr;
15use core::slice;
16
17/// Immutable enum map iterator
18///
19/// This struct is created by `iter` method or `into_iter` on a reference
20/// to `EnumMap`.
21///
22/// # Examples
23///
24/// ```
25/// use enum_map::{enum_map, Enum};
26///
27/// #[derive(Enum)]
28/// enum Example {
29///     A,
30///     B,
31///     C,
32/// }
33///
34/// let mut map = enum_map! { Example::A => 3, _ => 0 };
35/// assert_eq!(map[Example::A], 3);
36/// for (key, &value) in &map {
37///     assert_eq!(value, match key {
38///         Example::A => 3,
39///         _ => 0,
40///     });
41/// }
42/// ```
43#[derive(Debug)]
44pub struct Iter<'a, K, V: 'a> {
45    _phantom: PhantomData<fn() -> K>,
46    iterator: Enumerate<slice::Iter<'a, V>>,
47}
48
49impl<'a, K: EnumArray<V>, V> Clone for Iter<'a, K, V> {
50    fn clone(&self) -> Self {
51        Iter {
52            _phantom: PhantomData,
53            iterator: self.iterator.clone(),
54        }
55    }
56}
57
58impl<'a, K: EnumArray<V>, V> Iterator for Iter<'a, K, V> {
59    type Item = (K, &'a V);
60    #[inline]
61    fn next(&mut self) -> Option<Self::Item> {
62        self.iterator
63            .next()
64            .map(|(index, item)| (K::from_usize(index), item))
65    }
66
67    #[inline]
68    fn size_hint(&self) -> (usize, Option<usize>) {
69        self.iterator.size_hint()
70    }
71
72    fn fold<B, F>(self, init: B, f: F) -> B
73    where
74        F: FnMut(B, Self::Item) -> B,
75    {
76        self.iterator
77            .map(|(index, item)| (K::from_usize(index), item))
78            .fold(init, f)
79    }
80}
81
82impl<'a, K: EnumArray<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
83    #[inline]
84    fn next_back(&mut self) -> Option<Self::Item> {
85        self.iterator
86            .next_back()
87            .map(|(index, item)| (K::from_usize(index), item))
88    }
89}
90
91impl<'a, K: EnumArray<V>, V> ExactSizeIterator for Iter<'a, K, V> {}
92
93impl<'a, K: EnumArray<V>, V> FusedIterator for Iter<'a, K, V> {}
94
95impl<'a, K: EnumArray<V>, V> IntoIterator for &'a EnumMap<K, V> {
96    type Item = (K, &'a V);
97    type IntoIter = Iter<'a, K, V>;
98    #[inline]
99    fn into_iter(self) -> Self::IntoIter {
100        Iter {
101            _phantom: PhantomData,
102            iterator: self.as_slice().iter().enumerate(),
103        }
104    }
105}
106
107/// Mutable map iterator
108///
109/// This struct is created by `iter_mut` method or `into_iter` on a mutable
110/// reference to `EnumMap`.
111///
112/// # Examples
113///
114/// ```
115/// use enum_map::{enum_map, Enum};
116///
117/// #[derive(Debug, Enum)]
118/// enum Example {
119///     A,
120///     B,
121///     C,
122/// }
123///
124/// let mut map = enum_map! { Example::A => 3, _ => 0 };
125/// for (_, value) in &mut map {
126///     *value += 1;
127/// }
128/// assert_eq!(map, enum_map! { Example::A => 4, _ => 1 });
129/// ```
130#[derive(Debug)]
131pub struct IterMut<'a, K, V: 'a> {
132    _phantom: PhantomData<fn() -> K>,
133    iterator: Enumerate<slice::IterMut<'a, V>>,
134}
135
136impl<'a, K: EnumArray<V>, V> Iterator for IterMut<'a, K, V> {
137    type Item = (K, &'a mut V);
138    #[inline]
139    fn next(&mut self) -> Option<Self::Item> {
140        self.iterator
141            .next()
142            .map(|(index, item)| (K::from_usize(index), item))
143    }
144
145    #[inline]
146    fn size_hint(&self) -> (usize, Option<usize>) {
147        self.iterator.size_hint()
148    }
149
150    fn fold<B, F>(self, init: B, f: F) -> B
151    where
152        F: FnMut(B, Self::Item) -> B,
153    {
154        self.iterator
155            .map(|(index, item)| (K::from_usize(index), item))
156            .fold(init, f)
157    }
158}
159
160impl<'a, K: EnumArray<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
161    #[inline]
162    fn next_back(&mut self) -> Option<Self::Item> {
163        self.iterator
164            .next_back()
165            .map(|(index, item)| (K::from_usize(index), item))
166    }
167}
168
169impl<'a, K: EnumArray<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}
170
171impl<'a, K: EnumArray<V>, V> FusedIterator for IterMut<'a, K, V> {}
172
173impl<'a, K: EnumArray<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
174    type Item = (K, &'a mut V);
175    type IntoIter = IterMut<'a, K, V>;
176    #[inline]
177    fn into_iter(self) -> Self::IntoIter {
178        IterMut {
179            _phantom: PhantomData,
180            iterator: self.as_mut_slice().iter_mut().enumerate(),
181        }
182    }
183}
184
185/// A map iterator that moves out of map.
186///
187/// This struct is created by `into_iter` on `EnumMap`.
188///
189/// # Examples
190///
191/// ```
192/// use enum_map::{enum_map, Enum};
193///
194/// #[derive(Debug, Enum)]
195/// enum Example {
196///     A,
197///     B,
198/// }
199///
200/// let map = enum_map! { Example::A | Example::B => String::from("123") };
201/// for (_, value) in map {
202///     assert_eq!(value + "4", "1234");
203/// }
204/// ```
205pub struct IntoIter<K: EnumArray<V>, V> {
206    map: ManuallyDrop<EnumMap<K, V>>,
207    alive: Range<usize>,
208}
209
210impl<K: EnumArray<V>, V> Iterator for IntoIter<K, V> {
211    type Item = (K, V);
212    fn next(&mut self) -> Option<(K, V)> {
213        let position = self.alive.next()?;
214        Some((K::from_usize(position), unsafe {
215            ptr::read(&self.map.as_slice()[position])
216        }))
217    }
218
219    #[inline]
220    fn size_hint(&self) -> (usize, Option<usize>) {
221        self.alive.size_hint()
222    }
223}
224
225impl<K: EnumArray<V>, V> DoubleEndedIterator for IntoIter<K, V> {
226    fn next_back(&mut self) -> Option<(K, V)> {
227        let position = self.alive.next_back()?;
228        Some((K::from_usize(position), unsafe {
229            ptr::read(&self.map.as_slice()[position])
230        }))
231    }
232}
233
234impl<K: EnumArray<V>, V> ExactSizeIterator for IntoIter<K, V> {}
235
236impl<K: EnumArray<V>, V> FusedIterator for IntoIter<K, V> {}
237
238impl<K: EnumArray<V>, V> Drop for IntoIter<K, V> {
239    #[inline]
240    fn drop(&mut self) {
241        unsafe {
242            ptr::drop_in_place(&mut self.map.as_mut_slice()[self.alive.clone()]);
243        }
244    }
245}
246
247impl<K: EnumArray<V>, V> IntoIterator for EnumMap<K, V> {
248    type Item = (K, V);
249    type IntoIter = IntoIter<K, V>;
250    #[inline]
251    fn into_iter(self) -> Self::IntoIter {
252        let len = self.len();
253        IntoIter {
254            map: ManuallyDrop::new(self),
255            alive: 0..len,
256        }
257    }
258}
259
260impl<K: EnumArray<V>, V> EnumMap<K, V> {
261    /// An iterator visiting all values. The iterator type is `&V`.
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// use enum_map::enum_map;
267    ///
268    /// let map = enum_map! { false => 3, true => 4 };
269    /// let mut values = map.values();
270    /// assert_eq!(values.next(), Some(&3));
271    /// assert_eq!(values.next(), Some(&4));
272    /// assert_eq!(values.next(), None);
273    /// ```
274    #[inline]
275    pub fn values(&self) -> Values<V> {
276        Values(self.as_slice().iter())
277    }
278
279    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
280    ///
281    /// # Examples
282    ///
283    /// ```
284    /// use enum_map::enum_map;
285    ///
286    /// let mut map = enum_map! { _ => 2 };
287    /// for value in map.values_mut() {
288    ///     *value += 2;
289    /// }
290    /// assert_eq!(map[false], 4);
291    /// assert_eq!(map[true], 4);
292    /// ```
293    #[inline]
294    pub fn values_mut(&mut self) -> ValuesMut<V> {
295        ValuesMut(self.as_mut_slice().iter_mut())
296    }
297
298    /// Creates a consuming iterator visiting all the values. The map
299    /// cannot be used after calling this. The iterator element type
300    /// is `V`.
301    ///
302    /// # Examples
303    ///
304    /// ```
305    /// use enum_map::enum_map;
306    ///
307    /// let mut map = enum_map! { false => "hello", true => "goodbye" };
308    /// assert_eq!(map.into_values().collect::<Vec<_>>(), ["hello", "goodbye"]);
309    /// ```
310    #[inline]
311    pub fn into_values(self) -> IntoValues<K, V> {
312        IntoValues {
313            inner: self.into_iter(),
314        }
315    }
316}
317
318/// An iterator over the values of `EnumMap`.
319///
320/// This `struct` is created by the `values` method of `EnumMap`.
321/// See its documentation for more.
322pub struct Values<'a, V: 'a>(slice::Iter<'a, V>);
323
324impl<'a, V> Clone for Values<'a, V> {
325    fn clone(&self) -> Self {
326        Values(self.0.clone())
327    }
328}
329
330impl<'a, V: 'a> Iterator for Values<'a, V> {
331    type Item = &'a V;
332    #[inline]
333    fn next(&mut self) -> Option<&'a V> {
334        self.0.next()
335    }
336
337    #[inline]
338    fn size_hint(&self) -> (usize, Option<usize>) {
339        self.0.size_hint()
340    }
341}
342
343impl<'a, V: 'a> DoubleEndedIterator for Values<'a, V> {
344    #[inline]
345    fn next_back(&mut self) -> Option<&'a V> {
346        self.0.next_back()
347    }
348}
349
350impl<'a, V: 'a> ExactSizeIterator for Values<'a, V> {}
351
352impl<'a, V: 'a> FusedIterator for Values<'a, V> {}
353
354/// A mutable iterator over the values of `EnumMap`.
355///
356/// This `struct` is created by the `values_mut` method of `EnumMap`.
357/// See its documentation for more.
358pub struct ValuesMut<'a, V: 'a>(slice::IterMut<'a, V>);
359
360impl<'a, V: 'a> Iterator for ValuesMut<'a, V> {
361    type Item = &'a mut V;
362    #[inline]
363    fn next(&mut self) -> Option<&'a mut V> {
364        self.0.next()
365    }
366
367    #[inline]
368    fn size_hint(&self) -> (usize, Option<usize>) {
369        self.0.size_hint()
370    }
371}
372
373impl<'a, V: 'a> DoubleEndedIterator for ValuesMut<'a, V> {
374    #[inline]
375    fn next_back(&mut self) -> Option<&'a mut V> {
376        self.0.next_back()
377    }
378}
379
380impl<'a, V: 'a> ExactSizeIterator for ValuesMut<'a, V> {}
381
382impl<'a, V: 'a> FusedIterator for ValuesMut<'a, V> {}
383
384/// An owning iterator over the values of an `EnumMap`.
385///
386/// This `struct` is created by the `into_values` method of `EnumMap`.
387/// See its documentation for more.
388pub struct IntoValues<K: EnumArray<V>, V> {
389    inner: IntoIter<K, V>,
390}
391
392impl<K, V> Iterator for IntoValues<K, V>
393where
394    K: EnumArray<V>,
395{
396    type Item = V;
397
398    fn next(&mut self) -> Option<V> {
399        Some(self.inner.next()?.1)
400    }
401
402    fn size_hint(&self) -> (usize, Option<usize>) {
403        self.inner.size_hint()
404    }
405}
406
407impl<K: EnumArray<V>, V> DoubleEndedIterator for IntoValues<K, V> {
408    fn next_back(&mut self) -> Option<V> {
409        Some(self.inner.next_back()?.1)
410    }
411}
412
413impl<K, V> ExactSizeIterator for IntoValues<K, V> where K: EnumArray<V> {}
414
415impl<K, V> FusedIterator for IntoValues<K, V> where K: EnumArray<V> {}