use core::iter::{DoubleEndedIterator, FusedIterator};
use crate::{listindex::ListIndex, IndexList};
pub struct ListIter<'a, T> {
pub(crate) list: &'a IndexList<T>,
pub(crate) start: ListIndex,
pub(crate) end: ListIndex,
pub(crate) len: usize,
}
impl<T> ListIter<'_, T> {
#[inline]
fn set_empty(&mut self) {
self.start = ListIndex::new();
self.end = ListIndex::new();
self.len = 0;
}
}
impl<'a, T> Iterator for ListIter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let item = self.list.get(self.start)?;
if self.start == self.end {
self.set_empty()
} else {
self.start = self.list.next_index(self.start);
self.len -= 1;
}
Some(item)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<T> FusedIterator for ListIter<'_, T> {}
impl<T> ExactSizeIterator for ListIter<'_, T> {}
impl<T> DoubleEndedIterator for ListIter<'_, T> {
fn next_back(&mut self) -> Option<Self::Item> {
let item = self.list.get(self.end)?;
if self.start == self.end {
self.set_empty()
} else {
self.end = self.list.prev_index(self.end);
self.len -= 1;
}
Some(item)
}
}