open_hypergraphs/indexed_coproduct/
iterator.rs

1//! [`IndexedCoproduct`] as collections of [`FiniteFunction`]s.
2//! NOTE: the implementations here are not optimized.
3use crate::array::*;
4use crate::finite_function::*;
5use crate::indexed_coproduct::*;
6use core::iter::IntoIterator;
7use num_traits::{One, Zero};
8
9/// Iterator for IndexedCoproduct that yields each element
10pub struct IndexedCoproductFiniteFunctionIterator<K: ArrayKind> {
11    /// Cumulative sum of sources of an indexed coproduct
12    pointers: K::Type<K::I>,
13
14    /// Unchanged values array
15    values: FiniteFunction<K>,
16
17    /// index of next slice.
18    index: K::I,
19}
20
21impl<K: ArrayKind> Iterator for IndexedCoproductFiniteFunctionIterator<K>
22where
23    K::Type<K::I>: NaturalArray<K>,
24    K::I: Into<usize>,
25{
26    type Item = FiniteFunction<K>;
27
28    fn next(&mut self) -> Option<Self::Item> {
29        // Check if we've reached the end of the iterator
30        if self.index >= self.pointers.len() - K::I::one() {
31            return None;
32        }
33
34        // Get the start and end indices for this slice
35        let start = self.pointers.get(self.index.clone());
36        let end = self.pointers.get(self.index.clone() + K::I::one());
37
38        // Create a FiniteFunction from the slice of values between start and end
39        let values = self.values.table.get_range(start.clone()..end.clone());
40
41        // Create a new FiniteFunction with the extracted values
42        let ff = FiniteFunction {
43            table: K::Index::from_slice(values),
44            target: self.values.target.clone(),
45        };
46
47        // Increment the index for the next call
48        self.index = self.index.clone() + K::I::one();
49
50        Some(ff)
51    }
52
53    fn size_hint(&self) -> (usize, Option<usize>) {
54        let n = (self.pointers.len() - K::I::one()).into();
55        (n, Some(n)) // exact size is known
56    }
57}
58
59impl<K: ArrayKind> ExactSizeIterator for IndexedCoproductFiniteFunctionIterator<K>
60where
61    K::Type<K::I>: NaturalArray<K>,
62    K::I: Into<usize>,
63{
64    fn len(&self) -> usize {
65        (self.pointers.len() - K::I::one()).into()
66    }
67}
68
69impl<K: ArrayKind> IntoIterator for IndexedCoproduct<K, FiniteFunction<K>>
70where
71    K::Type<K::I>: NaturalArray<K>,
72    K::I: Into<usize>,
73{
74    type Item = FiniteFunction<K>;
75    type IntoIter = IndexedCoproductFiniteFunctionIterator<K>;
76
77    fn into_iter(self) -> Self::IntoIter {
78        IndexedCoproductFiniteFunctionIterator {
79            pointers: self.sources.table.into().cumulative_sum(),
80            values: self.values,
81            index: K::I::zero(),
82        }
83    }
84}