use crate::base::Enumoid;
use num_traits::FromPrimitive;
use std::marker;
use std::slice;
pub struct EnumSliceIter<'a, T: Enumoid, V: 'a> {
pub(crate) _phantom: marker::PhantomData<T>,
pub(crate) word: T::Word,
pub(crate) iter: slice::Iter<'a, V>,
}
impl<'a, T: Enumoid, V> Iterator for EnumSliceIter<'a, T, V> {
type Item = (T, &'a V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let value = self.iter.next()?;
let key = unsafe { T::from_word_unchecked(self.word) };
self.word = self.word + T::ONE_WORD;
Some((key, value))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, T: Enumoid, V> ExactSizeIterator for EnumSliceIter<'a, T, V> {}
impl<'a, T: Enumoid, V> DoubleEndedIterator for EnumSliceIter<'a, T, V> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let value = self.iter.next_back()?;
let idx = self.word + T::Word::from_usize(self.iter.len()).unwrap();
let key = unsafe { T::from_word_unchecked(idx) };
Some((key, value))
}
}
pub struct EnumSliceIterMut<'a, T: Enumoid, V: 'a> {
pub(crate) _phantom: marker::PhantomData<T>,
pub(crate) word: T::Word,
pub(crate) iter: slice::IterMut<'a, V>,
}
impl<'a, T: Enumoid, V> Iterator for EnumSliceIterMut<'a, T, V> {
type Item = (T, &'a mut V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let value = self.iter.next()?;
let key = unsafe { T::from_word_unchecked(self.word) };
self.word = self.word + T::ONE_WORD;
Some((key, value))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, T: Enumoid, V> ExactSizeIterator for EnumSliceIterMut<'a, T, V> {}
impl<'a, T: Enumoid, V> DoubleEndedIterator for EnumSliceIterMut<'a, T, V> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let value = self.iter.next_back()?;
let idx = self.word + T::Word::from_usize(self.iter.len()).unwrap();
let key = unsafe { T::from_word_unchecked(idx) };
Some((key, value))
}
}