@@ -155,6 +155,20 @@ impl<'treeseq> LLTree<'treeseq> {
155155 pub fn flags ( & self ) -> TreeFlags {
156156 self . flags
157157 }
158+
159+ pub fn traverse_nodes (
160+ & self ,
161+ order : NodeTraversalOrder ,
162+ ) -> Box < dyn Iterator < Item = NodeId > + ' _ > {
163+ match order {
164+ NodeTraversalOrder :: Preorder => {
165+ Box :: new ( NodeIteratorAdapter ( PreorderNodeIterator :: new ( self ) ) )
166+ }
167+ NodeTraversalOrder :: Postorder => {
168+ Box :: new ( NodeIteratorAdapter ( PostorderNodeIterator :: new ( self ) ) )
169+ }
170+ }
171+ }
158172}
159173
160174// Trait defining iteration over nodes.
@@ -227,6 +241,64 @@ impl NodeIterator for PreorderNodeIterator<'_> {
227241 }
228242}
229243
244+ struct PostorderNodeIterator < ' a > {
245+ nodes : Vec < NodeId > ,
246+ current_node_index : usize ,
247+ current_node : Option < NodeId > ,
248+ num_nodes_current_tree : usize ,
249+ tree : & ' a LLTree < ' a > ,
250+ }
251+
252+ impl < ' a > PostorderNodeIterator < ' a > {
253+ fn new ( tree : & ' a LLTree < ' a > ) -> Self {
254+ let mut num_nodes_current_tree: tsk_size_t = 0 ;
255+ let ptr = std:: ptr:: addr_of_mut!( num_nodes_current_tree) ;
256+ let mut nodes = vec ! [
257+ NodeId :: NULL ;
258+ // NOTE: this fn does not return error codes
259+ usize :: try_from( unsafe {
260+ bindings:: tsk_tree_get_size_bound( tree. as_ptr( ) )
261+ } ) . unwrap_or( usize :: MAX )
262+ ] ;
263+
264+ let rv = unsafe {
265+ bindings:: tsk_tree_postorder ( tree. as_ptr ( ) , nodes. as_mut_ptr ( ) . cast :: < tsk_id_t > ( ) , ptr)
266+ } ;
267+
268+ // This is either out of memory
269+ // or node out of range.
270+ // The former is fatal, and the latter
271+ // not relevant (for now), as we start at roots.
272+ if rv < 0 {
273+ panic ! ( "fatal error calculating postoder node list" ) ;
274+ }
275+
276+ Self {
277+ nodes,
278+ current_node_index : 0 ,
279+ current_node : None ,
280+ num_nodes_current_tree : usize:: try_from ( num_nodes_current_tree) . unwrap_or ( 0 ) ,
281+ tree,
282+ }
283+ }
284+ }
285+
286+ impl NodeIterator for PostorderNodeIterator < ' _ > {
287+ fn next_node ( & mut self ) {
288+ match self . current_node_index < self . num_nodes_current_tree {
289+ true => {
290+ self . current_node = Some ( self . nodes [ self . current_node_index ] ) ;
291+ self . current_node_index += 1 ;
292+ }
293+ false => self . current_node = None ,
294+ }
295+ }
296+
297+ fn current_node ( & mut self ) -> Option < NodeId > {
298+ todo ! ( )
299+ }
300+ }
301+
230302struct SamplesIterator < ' a > {
231303 current_node : Option < NodeId > ,
232304 next_sample_index : NodeId ,
0 commit comments