Skip to main content

enum_map/
iter.rs

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