use std::iter::FusedIterator;
use num_traits::AsPrimitive;
use crate::{NodePoint, Octant, Octree, Proxy, ProxyData, TreeIndex};
pub struct LeafIter<'tree, T, Idx: TreeIndex> {
pub(crate) tree: &'tree Octree<T, Idx>,
pub(crate) node_stack: Vec<(&'tree Proxy<Idx>, Octant, NodePoint<Idx>)>,
pub(crate) curr_node: Option<(&'tree Proxy<Idx>, Octant, NodePoint<Idx>)>,
}
impl<'tree, T, Idx: TreeIndex> FusedIterator for LeafIter<'tree, T, Idx> where u8: AsPrimitive<Idx> {}
impl<'tree, T, Idx: TreeIndex> Iterator for LeafIter<'tree, T, Idx>
where
u8: AsPrimitive<Idx>,
{
type Item = (&'tree T, NodePoint<Idx>);
fn next(&mut self) -> Option<Self::Item> {
while let Some((prox, oct, np)) = self.curr_node {
match prox.data {
ProxyData::Void => self.curr_node = self.node_stack.pop(), ProxyData::Leaf(leaf_idx) => {
self.curr_node = self.node_stack.pop();
return Some((&self.tree.leaf_data[leaf_idx.as_()], np));
}
ProxyData::Branch(ch_idx) => {
let children: &[Idx; 8] = &self.tree.branch_data[ch_idx.as_()];
self.curr_node = Some((
&self.tree.proxies[children[oct.0 as usize].as_()],
Octant(0),
np + oct,
));
if oct.0 < 8 {
self.node_stack.push((prox, Octant(oct.0 + 1), np));
}
}
}
}
None
}
}