summaryrefslogtreecommitdiffstats
path: root/third_party/rust/enum-map/src/iter.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/enum-map/src/iter.rs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/enum-map/src/iter.rs')
-rw-r--r--third_party/rust/enum-map/src/iter.rs415
1 files changed, 415 insertions, 0 deletions
diff --git a/third_party/rust/enum-map/src/iter.rs b/third_party/rust/enum-map/src/iter.rs
new file mode 100644
index 0000000000..393d8d1027
--- /dev/null
+++ b/third_party/rust/enum-map/src/iter.rs
@@ -0,0 +1,415 @@
+#![allow(clippy::module_name_repetitions)]
+
+// SPDX-FileCopyrightText: 2017 - 2022 Kamila Borowska <kamila@borowska.pw>
+// SPDX-FileCopyrightText: 2020 Amanieu d'Antras <amanieu@gmail.com>
+// SPDX-FileCopyrightText: 2021 Bruno CorrĂȘa Zimmermann <brunoczim@gmail.com>
+//
+// SPDX-License-Identifier: MIT OR Apache-2.0
+
+use crate::{EnumArray, EnumMap};
+use core::iter::{Enumerate, FusedIterator};
+use core::marker::PhantomData;
+use core::mem::ManuallyDrop;
+use core::ops::Range;
+use core::ptr;
+use core::slice;
+
+/// Immutable enum map iterator
+///
+/// This struct is created by `iter` method or `into_iter` on a reference
+/// to `EnumMap`.
+///
+/// # Examples
+///
+/// ```
+/// use enum_map::{enum_map, Enum};
+///
+/// #[derive(Enum)]
+/// enum Example {
+/// A,
+/// B,
+/// C,
+/// }
+///
+/// let mut map = enum_map! { Example::A => 3, _ => 0 };
+/// assert_eq!(map[Example::A], 3);
+/// for (key, &value) in &map {
+/// assert_eq!(value, match key {
+/// Example::A => 3,
+/// _ => 0,
+/// });
+/// }
+/// ```
+#[derive(Debug)]
+pub struct Iter<'a, K, V: 'a> {
+ _phantom: PhantomData<fn() -> K>,
+ iterator: Enumerate<slice::Iter<'a, V>>,
+}
+
+impl<'a, K: EnumArray<V>, V> Clone for Iter<'a, K, V> {
+ fn clone(&self) -> Self {
+ Iter {
+ _phantom: PhantomData,
+ iterator: self.iterator.clone(),
+ }
+ }
+}
+
+impl<'a, K: EnumArray<V>, V> Iterator for Iter<'a, K, V> {
+ type Item = (K, &'a V);
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iterator
+ .next()
+ .map(|(index, item)| (K::from_usize(index), item))
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iterator.size_hint()
+ }
+
+ fn fold<B, F>(self, init: B, f: F) -> B
+ where
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.iterator
+ .map(|(index, item)| (K::from_usize(index), item))
+ .fold(init, f)
+ }
+}
+
+impl<'a, K: EnumArray<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iterator
+ .next_back()
+ .map(|(index, item)| (K::from_usize(index), item))
+ }
+}
+
+impl<'a, K: EnumArray<V>, V> ExactSizeIterator for Iter<'a, K, V> {}
+
+impl<'a, K: EnumArray<V>, V> FusedIterator for Iter<'a, K, V> {}
+
+impl<'a, K: EnumArray<V>, V> IntoIterator for &'a EnumMap<K, V> {
+ type Item = (K, &'a V);
+ type IntoIter = Iter<'a, K, V>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ Iter {
+ _phantom: PhantomData,
+ iterator: self.as_slice().iter().enumerate(),
+ }
+ }
+}
+
+/// Mutable map iterator
+///
+/// This struct is created by `iter_mut` method or `into_iter` on a mutable
+/// reference to `EnumMap`.
+///
+/// # Examples
+///
+/// ```
+/// use enum_map::{enum_map, Enum};
+///
+/// #[derive(Debug, Enum)]
+/// enum Example {
+/// A,
+/// B,
+/// C,
+/// }
+///
+/// let mut map = enum_map! { Example::A => 3, _ => 0 };
+/// for (_, value) in &mut map {
+/// *value += 1;
+/// }
+/// assert_eq!(map, enum_map! { Example::A => 4, _ => 1 });
+/// ```
+#[derive(Debug)]
+pub struct IterMut<'a, K, V: 'a> {
+ _phantom: PhantomData<fn() -> K>,
+ iterator: Enumerate<slice::IterMut<'a, V>>,
+}
+
+impl<'a, K: EnumArray<V>, V> Iterator for IterMut<'a, K, V> {
+ type Item = (K, &'a mut V);
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iterator
+ .next()
+ .map(|(index, item)| (K::from_usize(index), item))
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iterator.size_hint()
+ }
+
+ fn fold<B, F>(self, init: B, f: F) -> B
+ where
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.iterator
+ .map(|(index, item)| (K::from_usize(index), item))
+ .fold(init, f)
+ }
+}
+
+impl<'a, K: EnumArray<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iterator
+ .next_back()
+ .map(|(index, item)| (K::from_usize(index), item))
+ }
+}
+
+impl<'a, K: EnumArray<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}
+
+impl<'a, K: EnumArray<V>, V> FusedIterator for IterMut<'a, K, V> {}
+
+impl<'a, K: EnumArray<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
+ type Item = (K, &'a mut V);
+ type IntoIter = IterMut<'a, K, V>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ IterMut {
+ _phantom: PhantomData,
+ iterator: self.as_mut_slice().iter_mut().enumerate(),
+ }
+ }
+}
+
+/// A map iterator that moves out of map.
+///
+/// This struct is created by `into_iter` on `EnumMap`.
+///
+/// # Examples
+///
+/// ```
+/// use enum_map::{enum_map, Enum};
+///
+/// #[derive(Debug, Enum)]
+/// enum Example {
+/// A,
+/// B,
+/// }
+///
+/// let map = enum_map! { Example::A | Example::B => String::from("123") };
+/// for (_, value) in map {
+/// assert_eq!(value + "4", "1234");
+/// }
+/// ```
+pub struct IntoIter<K: EnumArray<V>, V> {
+ map: ManuallyDrop<EnumMap<K, V>>,
+ alive: Range<usize>,
+}
+
+impl<K: EnumArray<V>, V> Iterator for IntoIter<K, V> {
+ type Item = (K, V);
+ fn next(&mut self) -> Option<(K, V)> {
+ let position = self.alive.next()?;
+ Some((K::from_usize(position), unsafe {
+ ptr::read(&self.map.as_slice()[position])
+ }))
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.alive.size_hint()
+ }
+}
+
+impl<K: EnumArray<V>, V> DoubleEndedIterator for IntoIter<K, V> {
+ fn next_back(&mut self) -> Option<(K, V)> {
+ let position = self.alive.next_back()?;
+ Some((K::from_usize(position), unsafe {
+ ptr::read(&self.map.as_slice()[position])
+ }))
+ }
+}
+
+impl<K: EnumArray<V>, V> ExactSizeIterator for IntoIter<K, V> {}
+
+impl<K: EnumArray<V>, V> FusedIterator for IntoIter<K, V> {}
+
+impl<K: EnumArray<V>, V> Drop for IntoIter<K, V> {
+ #[inline]
+ fn drop(&mut self) {
+ unsafe {
+ ptr::drop_in_place(&mut self.map.as_mut_slice()[self.alive.clone()]);
+ }
+ }
+}
+
+impl<K: EnumArray<V>, V> IntoIterator for EnumMap<K, V> {
+ type Item = (K, V);
+ type IntoIter = IntoIter<K, V>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ let len = self.len();
+ IntoIter {
+ map: ManuallyDrop::new(self),
+ alive: 0..len,
+ }
+ }
+}
+
+impl<K: EnumArray<V>, V> EnumMap<K, V> {
+ /// An iterator visiting all values. The iterator type is `&V`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use enum_map::enum_map;
+ ///
+ /// let map = enum_map! { false => 3, true => 4 };
+ /// let mut values = map.values();
+ /// assert_eq!(values.next(), Some(&3));
+ /// assert_eq!(values.next(), Some(&4));
+ /// assert_eq!(values.next(), None);
+ /// ```
+ #[inline]
+ pub fn values(&self) -> Values<V> {
+ Values(self.as_slice().iter())
+ }
+
+ /// An iterator visiting all values mutably. The iterator type is `&mut V`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use enum_map::enum_map;
+ ///
+ /// let mut map = enum_map! { _ => 2 };
+ /// for value in map.values_mut() {
+ /// *value += 2;
+ /// }
+ /// assert_eq!(map[false], 4);
+ /// assert_eq!(map[true], 4);
+ /// ```
+ #[inline]
+ pub fn values_mut(&mut self) -> ValuesMut<V> {
+ ValuesMut(self.as_mut_slice().iter_mut())
+ }
+
+ /// Creates a consuming iterator visiting all the values. The map
+ /// cannot be used after calling this. The iterator element type
+ /// is `V`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use enum_map::enum_map;
+ ///
+ /// let mut map = enum_map! { false => "hello", true => "goodbye" };
+ /// assert_eq!(map.into_values().collect::<Vec<_>>(), ["hello", "goodbye"]);
+ /// ```
+ #[inline]
+ pub fn into_values(self) -> IntoValues<K, V> {
+ IntoValues {
+ inner: self.into_iter(),
+ }
+ }
+}
+
+/// An iterator over the values of `EnumMap`.
+///
+/// This `struct` is created by the `values` method of `EnumMap`.
+/// See its documentation for more.
+pub struct Values<'a, V: 'a>(slice::Iter<'a, V>);
+
+impl<'a, V> Clone for Values<'a, V> {
+ fn clone(&self) -> Self {
+ Values(self.0.clone())
+ }
+}
+
+impl<'a, V: 'a> Iterator for Values<'a, V> {
+ type Item = &'a V;
+ #[inline]
+ fn next(&mut self) -> Option<&'a V> {
+ self.0.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
+}
+
+impl<'a, V: 'a> DoubleEndedIterator for Values<'a, V> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a V> {
+ self.0.next_back()
+ }
+}
+
+impl<'a, V: 'a> ExactSizeIterator for Values<'a, V> {}
+
+impl<'a, V: 'a> FusedIterator for Values<'a, V> {}
+
+/// A mutable iterator over the values of `EnumMap`.
+///
+/// This `struct` is created by the `values_mut` method of `EnumMap`.
+/// See its documentation for more.
+pub struct ValuesMut<'a, V: 'a>(slice::IterMut<'a, V>);
+
+impl<'a, V: 'a> Iterator for ValuesMut<'a, V> {
+ type Item = &'a mut V;
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut V> {
+ self.0.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
+}
+
+impl<'a, V: 'a> DoubleEndedIterator for ValuesMut<'a, V> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut V> {
+ self.0.next_back()
+ }
+}
+
+impl<'a, V: 'a> ExactSizeIterator for ValuesMut<'a, V> {}
+
+impl<'a, V: 'a> FusedIterator for ValuesMut<'a, V> {}
+
+/// An owning iterator over the values of an `EnumMap`.
+///
+/// This `struct` is created by the `into_values` method of `EnumMap`.
+/// See its documentation for more.
+pub struct IntoValues<K: EnumArray<V>, V> {
+ inner: IntoIter<K, V>,
+}
+
+impl<K, V> Iterator for IntoValues<K, V>
+where
+ K: EnumArray<V>,
+{
+ type Item = V;
+
+ fn next(&mut self) -> Option<V> {
+ Some(self.inner.next()?.1)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<K: EnumArray<V>, V> DoubleEndedIterator for IntoValues<K, V> {
+ fn next_back(&mut self) -> Option<V> {
+ Some(self.inner.next_back()?.1)
+ }
+}
+
+impl<K, V> ExactSizeIterator for IntoValues<K, V> where K: EnumArray<V> {}
+
+impl<K, V> FusedIterator for IntoValues<K, V> where K: EnumArray<V> {}