use super::dfs_enumeration::DepthFirstEnumeration;
use super::stack::Item;
use crate::TreeVariant;
use crate::tree_variant::RefsChildren;
use alloc::vec::Vec;
use core::marker::PhantomData;
use orx_self_or::SoM;
use orx_selfref_col::NodePtr;
pub struct DfsIterPtr<V, E, S = Vec<Item<V, E>>>
where
E: DepthFirstEnumeration,
V: TreeVariant,
S: SoM<Vec<Item<V, E>>>,
{
stack: S,
phantom: PhantomData<(V, E)>,
}
impl<V, E, S> From<(S, NodePtr<V>)> for DfsIterPtr<V, E, S>
where
E: DepthFirstEnumeration,
V: TreeVariant,
S: SoM<Vec<Item<V, E>>>,
{
fn from((mut stack, root): (S, NodePtr<V>)) -> Self {
stack.get_mut().clear();
stack.get_mut().push(E::from_root(root));
Self {
stack,
phantom: PhantomData,
}
}
}
impl<V, E> Default for DfsIterPtr<V, E, Vec<Item<V, E>>>
where
E: DepthFirstEnumeration,
V: TreeVariant,
{
fn default() -> Self {
Self {
stack: Vec::default(),
phantom: PhantomData,
}
}
}
impl<V, E> Clone for DfsIterPtr<V, E, Vec<Item<V, E>>>
where
E: DepthFirstEnumeration,
V: TreeVariant,
Item<V, E>: Clone,
{
fn clone(&self) -> Self {
Self {
stack: self.stack.clone(),
phantom: PhantomData,
}
}
}
impl<V, E, S> Iterator for DfsIterPtr<V, E, S>
where
E: DepthFirstEnumeration,
V: TreeVariant,
S: SoM<Vec<Item<V, E>>>,
{
type Item = Item<V, E>;
fn next(&mut self) -> Option<Self::Item> {
self.stack.get_mut().pop().inspect(|element| {
let node_ptr = E::node_value(element);
let parent = unsafe { &*node_ptr.ptr() };
let children_ptr = parent.next().children_ptr();
let children = E::children(element, children_ptr).rev();
self.stack.get_mut().extend(children);
})
}
}