use EnumMap;
use Internal;
use core::iter::Enumerate;
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
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: Internal<V>, V> Iterator for Iter<'a, K, V> {
type Item = (K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.iterator
.next()
.map(|(index, item)| (K::from_usize(index), item))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iterator.size_hint()
}
}
impl<'a, K: Internal<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.iterator
.next_back()
.map(|(index, item)| (K::from_usize(index), item))
}
}
impl<'a, K: Internal<V>, V> ExactSizeIterator for Iter<'a, K, V> {}
impl<'a, K: Internal<V>, V> IntoIterator for &'a EnumMap<K, V> {
type Item = (K, &'a V);
type IntoIter = Iter<'a, K, V>;
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: Internal<V>, V> Iterator for IterMut<'a, K, V> {
type Item = (K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.iterator
.next()
.map(|(index, item)| (K::from_usize(index), item))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iterator.size_hint()
}
}
impl<'a, K: Internal<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.iterator
.next_back()
.map(|(index, item)| (K::from_usize(index), item))
}
}
impl<'a, K: Internal<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}
impl<'a, K: Internal<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
type Item = (K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
IterMut {
_phantom: PhantomData,
iterator: self.as_mut_slice().iter_mut().enumerate(),
}
}
}
pub struct IntoIter<K: Internal<V>, V> {
map: ManuallyDrop<EnumMap<K, V>>,
position: usize,
}
impl<K: Internal<V>, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
let slice = self.map.as_slice();
if self.position < slice.len() {
let key = K::from_usize(self.position);
let result = Some((key, unsafe { ptr::read(&slice[self.position]) }));
self.position += 1;
result
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let slice = self.map.as_slice();
let diff = slice.len() - self.position;
(diff, Some(diff))
}
}
impl<K: Internal<V>, V> ExactSizeIterator for IntoIter<K, V> {}
impl<K: Internal<V>, V> Drop for IntoIter<K, V> {
fn drop(&mut self) {
for _item in self {}
}
}
impl<K: Internal<V>, V> IntoIterator for EnumMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
map: ManuallyDrop::new(self),
position: 0,
}
}
}