Skip to content

Commit 96c6519

Browse files
committed
implement NodeMut::leaves_mut_with
1 parent 71eb07c commit 96c6519

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

src/node_mut.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,146 @@ where
26152615
})
26162616
}
26172617

2618+
/// Creates an iterator of mutable references to leaves of the subtree rooted at this node.
2619+
///
2620+
/// The order of the leaves is determined by the type of the `traverser` which implements [`Traverser`].
2621+
/// Available implementations are:
2622+
/// * [`Bfs`] for breadth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search))
2623+
/// * [`Dfs`] for (pre-order) depth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Depth-first_search))
2624+
/// * [`PostOrder`] for post-order ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Post-order,_LRN))
2625+
///
2626+
/// As opposed to [`leaves_mut`], this method does require internal allocation.
2627+
/// Furthermore, it allows to attach node depths or sibling indices to the yield values.
2628+
/// Please see the examples below.
2629+
///
2630+
/// [`leaves_mut`]: crate::NodeMut::leaves_mut
2631+
/// [`Bfs`]: crate::Bfs
2632+
/// [`Dfs`]: crate::Dfs
2633+
/// [`PostOrder`]: crate::PostOrder
2634+
///
2635+
/// # Examples
2636+
///
2637+
/// ## Examples - Repeated Iterations without Allocation
2638+
///
2639+
/// ```
2640+
/// use orx_tree::*;
2641+
///
2642+
/// // 1
2643+
/// // ╱ ╲
2644+
/// // ╱ ╲
2645+
/// // 2 3
2646+
/// // ╱ ╲ ╱ ╲
2647+
/// // 4 5 6 7
2648+
/// // | | ╱ ╲
2649+
/// // 8 9 10 11
2650+
///
2651+
/// let mut tree = DynTree::new(1);
2652+
///
2653+
/// let mut root = tree.root_mut();
2654+
/// let [id2, id3] = root.push_children([2, 3]);
2655+
///
2656+
/// let mut n2 = tree.node_mut(id2);
2657+
/// let [id4, _] = n2.push_children([4, 5]);
2658+
///
2659+
/// tree.node_mut(id4).push_child(8);
2660+
///
2661+
/// let mut n3 = tree.node_mut(id3);
2662+
/// let [id6, id7] = n3.push_children([6, 7]);
2663+
///
2664+
/// tree.node_mut(id6).push_child(9);
2665+
/// tree.node_mut(id7).push_children([10, 11]);
2666+
///
2667+
/// // create the traverser 'bfs' (or others) only once, use it many times
2668+
/// // to walk over references, mutable references or removed values
2669+
/// // without additional allocation
2670+
///
2671+
/// let mut t = Bfs::default();
2672+
///
2673+
/// for (l, leaf) in tree.root_mut().leaves_mut_with(&mut t).enumerate() {
2674+
/// *leaf += 100 * l;
2675+
/// }
2676+
///
2677+
/// let bfs_leaves: Vec<_> = tree.root().leaves_with(&mut t).copied().collect();
2678+
/// assert_eq!(bfs_leaves, [5, 108, 209, 310, 411]);
2679+
///
2680+
/// // get the leaves from any node
2681+
///
2682+
/// let mut n3 = tree.node_mut(id3);
2683+
/// for (l, leaf) in n3.leaves_mut_with(&mut t).enumerate() {
2684+
/// *leaf -= 100 * l;
2685+
/// }
2686+
///
2687+
/// let n3 = tree.node(id3);
2688+
/// let leaves: Vec<_> = n3.leaves_with(&mut t).copied().collect();
2689+
/// assert_eq!(leaves, [209, 210, 211]);
2690+
/// ```
2691+
///
2692+
/// ## Examples - Yielding Different Items
2693+
///
2694+
/// ```
2695+
/// use orx_tree::*;
2696+
///
2697+
/// // 1
2698+
/// // ╱ ╲
2699+
/// // ╱ ╲
2700+
/// // 2 3
2701+
/// // ╱ ╲ ╱ ╲
2702+
/// // 4 5 6 7
2703+
/// // | | ╱ ╲
2704+
/// // 8 9 10 11
2705+
/// let mut tree = DynTree::new(1);
2706+
///
2707+
/// let mut root = tree.root_mut();
2708+
/// let [id2, id3] = root.push_children([2, 3]);
2709+
///
2710+
/// let mut n2 = tree.node_mut(id2);
2711+
/// let [id4, _] = n2.push_children([4, 5]);
2712+
///
2713+
/// tree.node_mut(id4).push_child(8);
2714+
///
2715+
/// let mut n3 = tree.node_mut(id3);
2716+
/// let [id6, id7] = n3.push_children([6, 7]);
2717+
///
2718+
/// tree.node_mut(id6).push_child(9);
2719+
/// tree.node_mut(id7).push_children([10, 11]);
2720+
///
2721+
/// // create the traverser 'bfs' iterator which additionally
2722+
/// // yields depths (or sibling_idx)
2723+
///
2724+
/// let mut bfs = Traversal.bfs().with_depth();
2725+
///
2726+
/// for (depth, x) in tree.root_mut().leaves_mut_with(&mut bfs) {
2727+
/// *x += 100 * depth;
2728+
/// }
2729+
///
2730+
/// let root = tree.root();
2731+
/// let leaves: Vec<_> = root.leaves_with(&mut bfs).collect();
2732+
/// assert_eq!(
2733+
/// leaves,
2734+
/// [(2, &205), (3, &308), (3, &309), (3, &310), (3, &311)]
2735+
/// );
2736+
/// ```
2737+
pub fn leaves_mut_with<T, O>(
2738+
&'a mut self,
2739+
traverser: &'a mut T,
2740+
) -> impl Iterator<Item = OverItemMut<'a, V, O, M, P>>
2741+
where
2742+
O: OverMut,
2743+
T: Traverser<O>,
2744+
{
2745+
T::iter_ptr_with_storage(self.node_ptr(), traverser.storage_mut())
2746+
.filter(|x| {
2747+
let ptr: &NodePtr<V> = O::Enumeration::node_data(x);
2748+
unsafe { &*ptr.ptr() }.next().is_empty()
2749+
})
2750+
.map(|x| {
2751+
O::Enumeration::from_element_ptr_mut::<'a, V, M, P, O::NodeItemMut<'a, V, M, P>>(
2752+
self.col(),
2753+
x,
2754+
)
2755+
})
2756+
}
2757+
26182758
// recursive
26192759

26202760
/// Recursively sets the data of all nodes belonging to the subtree rooted at this node using the `compute_data`

0 commit comments

Comments
 (0)