use crate::array::*;
use crate::finite_function::*;
use crate::indexed_coproduct::*;
use core::iter::IntoIterator;
use num_traits::{One, Zero};
pub struct IndexedCoproductFiniteFunctionIterator<K: ArrayKind> {
pointers: K::Type<K::I>,
values: FiniteFunction<K>,
index: K::I,
}
impl<K: ArrayKind> Iterator for IndexedCoproductFiniteFunctionIterator<K>
where
K::Type<K::I>: NaturalArray<K>,
K::I: Into<usize>,
{
type Item = FiniteFunction<K>;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.pointers.len() - K::I::one() {
return None;
}
let start = self.pointers.get(self.index.clone());
let end = self.pointers.get(self.index.clone() + K::I::one());
let values = self.values.table.get_range(start.clone()..end.clone());
let ff = FiniteFunction {
table: K::Index::from_slice(values),
target: self.values.target.clone(),
};
self.index = self.index.clone() + K::I::one();
Some(ff)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let n = (self.pointers.len() - K::I::one()).into();
(n, Some(n)) }
}
impl<K: ArrayKind> ExactSizeIterator for IndexedCoproductFiniteFunctionIterator<K>
where
K::Type<K::I>: NaturalArray<K>,
K::I: Into<usize>,
{
fn len(&self) -> usize {
(self.pointers.len() - K::I::one()).into()
}
}
impl<K: ArrayKind> IntoIterator for IndexedCoproduct<K, FiniteFunction<K>>
where
K::Type<K::I>: NaturalArray<K>,
K::I: Into<usize>,
{
type Item = FiniteFunction<K>;
type IntoIter = IndexedCoproductFiniteFunctionIterator<K>;
fn into_iter(self) -> Self::IntoIter {
IndexedCoproductFiniteFunctionIterator {
pointers: self.sources.table.into().cumulative_sum(),
values: self.values,
index: K::I::zero(),
}
}
}