use super::*;
pub trait IterIndex<T, const N: usize>
{
type IterIndex: Iterator<Item = Vector<T, N>>;
fn iter_index(&self) -> Self::IterIndex;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VectorIter<Idx, const N: usize>
where
Idx: Integer,
{
cur: Vector<Idx, N>,
end: Vector<Idx, N>,
}
impl<Idx, const N: usize> VectorIter<Idx, N>
where
Idx: Integer,
{
pub fn from_cur_to_end(cur: Vector<Idx, N>, end: Vector<Idx, N>) -> Self
{
Self {
cur,
end: if end.have_area_usize()
{
end
}
else
{
Vector::ZERO
},
}
}
pub fn new(end: Vector<Idx, N>) -> Self { Self::from_cur_to_end(Vector::ZERO, end) }
}
impl<Idx, const N: usize> Iterator for VectorIter<Idx, N>
where
Idx: Integer,
{
type Item = Vector<Idx, N>;
fn next(&mut self) -> Option<Self::Item>
{
let v = self.cur;
let mut i = 0;
while i < N
{
self.cur[i].increment();
if self.cur[i] < self.end[i]
{
return Some(v);
}
self.cur[i] = Idx::ZERO;
i += 1;
}
self.cur = self.end;
if self.end.all_zero()
{
None
}
else
{
self.end = zero();
Some(v)
}
}
fn size_hint(&self) -> (usize, Option<usize>)
{
let len = self.len();
(len, Some(len))
}
}
impl<Idx, const N: usize> std::iter::FusedIterator for VectorIter<Idx, N> where Idx: Integer {}
impl<Idx, const N: usize> std::iter::ExactSizeIterator for VectorIter<Idx, N>
where
Idx: Integer,
{
fn len(&self) -> usize
{
self.end.area_usize() - unsafe { Vector::<Idx, N>::to_index_unchecked(self.cur, self.end) }
}
}
impl<Idx, const N: usize> IterIndex<Idx, N> for Vector<Idx, N>
where
Idx: Integer,
{
type IterIndex = VectorIter<Idx, N>;
fn iter_index(&self) -> Self::IterIndex { Self::IterIndex::new(*self) }
}