#![allow(clippy::module_name_repetitions)]
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;
#[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(),
}
}
}
#[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(),
}
}
}
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> {
#[inline]
pub fn values(&self) -> Values<V> {
Values(self.as_slice().iter())
}
#[inline]
pub fn values_mut(&mut self) -> ValuesMut<V> {
ValuesMut(self.as_mut_slice().iter_mut())
}
#[inline]
pub fn into_values(self) -> IntoValues<K, V> {
IntoValues {
inner: self.into_iter(),
}
}
}
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> {}
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> {}
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> {}