@@ -68,23 +68,6 @@ impl Tree {
6868 handle_tsk_return_value ! ( rv, tree)
6969 }
7070
71- fn advance_details ( & mut self ) {
72- let rv = if self . current_tree == 0 {
73- unsafe { ll_bindings:: tsk_tree_first ( self . as_mut_ptr ( ) ) }
74- } else {
75- unsafe { ll_bindings:: tsk_tree_next ( self . as_mut_ptr ( ) ) }
76- } ;
77- if rv == 0 {
78- self . advanced = false ;
79- self . current_tree += 1 ;
80- } else if rv == 1 {
81- self . advanced = true ;
82- self . current_tree += 1 ;
83- } else if rv < 0 {
84- panic_on_tskit_error ! ( rv) ;
85- }
86- }
87-
8871 pub fn parent_array ( & self ) -> crate :: ffi:: TskIdArray {
8972 crate :: ffi:: TskIdArray :: new ( self . inner . parent , self . inner . num_nodes )
9073 }
@@ -361,7 +344,20 @@ impl Tree {
361344impl streaming_iterator:: StreamingIterator for Tree {
362345 type Item = Tree ;
363346 fn advance ( & mut self ) {
364- self . advance_details ( ) ;
347+ let rv = if self . current_tree == 0 {
348+ unsafe { ll_bindings:: tsk_tree_first ( self . as_mut_ptr ( ) ) }
349+ } else {
350+ unsafe { ll_bindings:: tsk_tree_next ( self . as_mut_ptr ( ) ) }
351+ } ;
352+ if rv == 0 {
353+ self . advanced = false ;
354+ self . current_tree += 1 ;
355+ } else if rv == 1 {
356+ self . advanced = true ;
357+ self . current_tree += 1 ;
358+ } else if rv < 0 {
359+ panic_on_tskit_error ! ( rv) ;
360+ }
365361 }
366362
367363 fn get ( & self ) -> Option < & Tree > {
@@ -372,6 +368,25 @@ impl streaming_iterator::StreamingIterator for Tree {
372368 }
373369}
374370
371+ impl streaming_iterator:: DoubleEndedStreamingIterator for Tree {
372+ fn advance_back ( & mut self ) {
373+ let rv = if self . current_tree == 0 {
374+ unsafe { ll_bindings:: tsk_tree_last ( self . as_mut_ptr ( ) ) }
375+ } else {
376+ unsafe { ll_bindings:: tsk_tree_prev ( self . as_mut_ptr ( ) ) }
377+ } ;
378+ if rv == 0 {
379+ self . advanced = false ;
380+ self . current_tree -= 1 ;
381+ } else if rv == 1 {
382+ self . advanced = true ;
383+ self . current_tree -= 1 ;
384+ } else if rv < 0 {
385+ panic_on_tskit_error ! ( rv) ;
386+ }
387+ }
388+ }
389+
375390/// Specify the traversal order used by
376391/// [`Tree::nodes`].
377392pub enum NodeTraversalOrder {
@@ -718,6 +733,9 @@ impl TreeSequence {
718733 /// // You must include streaming_iterator as a dependency
719734 /// // and import this type.
720735 /// use streaming_iterator::StreamingIterator;
736+ /// // Import this to allow .next_back() for reverse
737+ /// // iteration over trees.
738+ /// use streaming_iterator::DoubleEndedStreamingIterator;
721739 ///
722740 /// let mut tables = tskit::TableCollection::new(1000.).unwrap();
723741 /// tables.build_index();
@@ -880,6 +898,7 @@ pub(crate) mod test_trees {
880898 make_small_table_collection, make_small_table_collection_two_trees,
881899 treeseq_from_small_table_collection, treeseq_from_small_table_collection_two_trees,
882900 } ;
901+ use streaming_iterator:: DoubleEndedStreamingIterator ;
883902 use streaming_iterator:: StreamingIterator ;
884903
885904 #[ test]
@@ -1053,4 +1072,35 @@ pub(crate) mod test_trees {
10531072 let dumped = ts. dump_tables ( ) . unwrap ( ) ;
10541073 assert ! ( tables_copy. equals( & dumped, crate :: TableEqualityOptions :: default ( ) ) ) ;
10551074 }
1075+
1076+ #[ test]
1077+ fn test_reverse_tree_iteration ( ) {
1078+ let treeseq = treeseq_from_small_table_collection_two_trees ( ) ;
1079+ let mut tree_iter = treeseq. tree_iterator ( TreeFlags :: default ( ) ) . unwrap ( ) ;
1080+ let mut starts_fwd = vec ! [ ] ;
1081+ let mut stops_fwd = vec ! [ ] ;
1082+ let mut starts_rev = vec ! [ ] ;
1083+ let mut stops_rev = vec ! [ ] ;
1084+ while let Some ( tree) = tree_iter. next ( ) {
1085+ let interval = tree. interval ( ) ;
1086+ starts_fwd. push ( interval. 0 ) ;
1087+ stops_fwd. push ( interval. 1 ) ;
1088+ }
1089+ assert_eq ! ( stops_fwd. len( ) , 2 ) ;
1090+ assert_eq ! ( stops_fwd. len( ) , 2 ) ;
1091+
1092+ // NOTE: we do NOT need to create a new iterator.
1093+ while let Some ( tree) = tree_iter. next_back ( ) {
1094+ let interval = tree. interval ( ) ;
1095+ starts_rev. push ( interval. 0 ) ;
1096+ stops_rev. push ( interval. 1 ) ;
1097+ }
1098+ assert_eq ! ( starts_fwd. len( ) , starts_rev. len( ) ) ;
1099+ assert_eq ! ( stops_fwd. len( ) , stops_rev. len( ) ) ;
1100+
1101+ starts_rev. reverse ( ) ;
1102+ assert ! ( starts_fwd == starts_rev) ;
1103+ stops_rev. reverse ( ) ;
1104+ assert ! ( stops_fwd == stops_rev) ;
1105+ }
10561106}
0 commit comments