orx_tree/traversal/post_order/
iter_ptr.rs1use super::{post_enumeration::PostOrderEnumeration, states::State};
2use crate::{TreeVariant, traversal::enumeration::Enumeration, tree_variant::RefsChildren};
3use alloc::vec::Vec;
4use core::marker::PhantomData;
5use orx_self_or::SoM;
6use orx_selfref_col::NodePtr;
7
8pub type Item<V, E> = <E as Enumeration>::Item<NodePtr<V>>;
9
10pub struct PostOrderIterPtr<V, E, S = Vec<State<V>>>
11where
12 E: PostOrderEnumeration,
13 V: TreeVariant,
14 S: SoM<Vec<State<V>>>,
15{
16 states: S,
17 depth: usize,
18 phantom: PhantomData<(V, E)>,
19}
20
21impl<V, E, S> From<(S, NodePtr<V>)> for PostOrderIterPtr<V, E, S>
22where
23 E: PostOrderEnumeration,
24 V: TreeVariant,
25 S: SoM<Vec<State<V>>>,
26{
27 fn from((mut states, root): (S, NodePtr<V>)) -> Self {
28 states.get_mut().clear();
29 states.get_mut().push((root, 0));
30 Self {
31 states,
32 depth: 0,
33 phantom: PhantomData,
34 }
35 }
36}
37
38impl<V, E> Default for PostOrderIterPtr<V, E, Vec<State<V>>>
39where
40 E: PostOrderEnumeration,
41 V: TreeVariant,
42{
43 fn default() -> Self {
44 Self {
45 states: Vec::default(),
46 depth: 0,
47 phantom: PhantomData,
48 }
49 }
50}
51
52impl<V, E> Clone for PostOrderIterPtr<V, E, Vec<State<V>>>
53where
54 E: PostOrderEnumeration,
55 V: TreeVariant,
56{
57 fn clone(&self) -> Self {
58 Self {
59 states: self.states.clone(),
60 depth: self.depth,
61 phantom: PhantomData,
62 }
63 }
64}
65
66impl<V, E, S> PostOrderIterPtr<V, E, S>
69where
70 E: PostOrderEnumeration,
71 V: TreeVariant,
72 S: SoM<Vec<State<V>>>,
73{
74 fn current(&self) -> Option<&State<V>> {
75 match self.depth < usize::MAX {
76 true => self.states.get_ref().get(self.depth),
77 false => None,
78 }
79 }
80
81 fn move_deeper(&mut self, child: NodePtr<V>) {
82 self.depth += 1;
83 super::states::set(self.states.get_mut(), self.depth, child);
84 }
85
86 fn move_shallower(&mut self) {
87 match self.depth {
88 0 => self.depth = usize::MAX,
89 _ => {
90 self.depth -= 1;
91 super::states::increment_child_idx(self.states.get_mut(), self.depth);
92 }
93 }
94 }
95}
96
97impl<V, E, S> Iterator for PostOrderIterPtr<V, E, S>
98where
99 E: PostOrderEnumeration,
100 V: TreeVariant,
101 S: SoM<Vec<State<V>>>,
102{
103 type Item = Item<V, E>;
104
105 fn next(&mut self) -> Option<Self::Item> {
106 loop {
107 match self.current() {
108 None => return None,
109 Some((ptr, child_idx)) => {
110 let node = unsafe { &*ptr.ptr() };
111 let child_ptr = node.next().get_ptr(*child_idx).cloned();
112 match child_ptr {
113 Some(child_ptr) => self.move_deeper(child_ptr),
114 None => {
115 let output = Some(E::create_post_item(
116 ptr.clone(),
117 self.depth,
118 self.states.get_ref(),
119 ));
120 self.move_shallower();
121 return output;
122 }
123 }
124 }
125 }
126 }
127 }
128}