diff --git a/Cargo.toml b/Cargo.toml index a0ef93f..2c561e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ orx-self-or = "1.2.0" serde = { version = "1.0.228", optional = true, default-features = false } orx-pinned-vec = { version = "3.21.0", default-features = false } orx-split-vec = { version = "3.22.0", default-features = false } -orx-selfref-col = { version = "3.0.0", default-features = false } +orx-selfref-col = { version = "3.1.0", default-features = false } orx-concurrent-iter = { version = "3.3.0", default-features = false } orx-parallel = { version = "3.4.0", default-features = false, optional = true } diff --git a/src/dary/variant.rs b/src/dary/variant.rs index 2d61f5e..4a42049 100644 --- a/src/dary/variant.rs +++ b/src/dary/variant.rs @@ -8,6 +8,16 @@ pub struct Dary { p: PhantomData, } +/// # SAFETY +/// +/// Tree variants do not hold any data; and hence, safe to sync. +unsafe impl Sync for Dary {} + +/// # SAFETY +/// +/// Tree variants do not hold any data; and hence, safe to sync. +unsafe impl Send for Dary {} + impl Variant for Dary { type Item = T; diff --git a/src/dyn/variant.rs b/src/dyn/variant.rs index e4deb92..2e0b6a9 100644 --- a/src/dyn/variant.rs +++ b/src/dyn/variant.rs @@ -8,6 +8,16 @@ pub struct Dyn { p: PhantomData, } +/// # SAFETY +/// +/// Tree variants do not hold any data, safe to send or sync. +unsafe impl Sync for Dyn {} + +/// # SAFETY +/// +/// Tree variants do not hold any data, safe to send or sync. +unsafe impl Send for Dyn {} + impl Variant for Dyn { type Item = T; diff --git a/src/iter/children_mut.rs b/src/iter/children_mut.rs index 5e71bd1..298d5ca 100644 --- a/src/iter/children_mut.rs +++ b/src/iter/children_mut.rs @@ -51,7 +51,7 @@ where type Item = NodeMut<'b, V, M, P, NodeMutDown>; fn next(&mut self) -> Option { - self.children_ptr.next().map(|p| self.next_child(*p)) + self.children_ptr.next().map(|p| self.next_child(p)) } fn size_hint(&self) -> (usize, Option) { @@ -79,6 +79,6 @@ where 'a: 'b, { fn next_back(&mut self) -> Option { - self.children_ptr.next_back().map(|p| self.next_child(*p)) + self.children_ptr.next_back().map(|p| self.next_child(p)) } } diff --git a/src/node_mut.rs b/src/node_mut.rs index b900672..89e9cc5 100644 --- a/src/node_mut.rs +++ b/src/node_mut.rs @@ -1645,13 +1645,13 @@ where match parent_ptr { None => { - let first_child = self.node().next().children_ptr().next().cloned(); + let first_child = self.node().next().children_ptr().next(); self.col.ends_mut().set(first_child); } Some(parent_ptr) => { let parent = unsafe { &mut *parent_ptr.ptr_mut() }; parent.next_mut().remove_at(sibling_idx); - for child_ptr in self.node().next().children_ptr().rev().cloned() { + for child_ptr in self.node().next().children_ptr().rev() { parent.next_mut().insert(sibling_idx, child_ptr); } } @@ -1697,7 +1697,7 @@ where /// let bfs: Vec<_> = tree.root().walk::().copied().collect(); /// assert_eq!(bfs, [1, 2, 3, 4, 5, 8]); /// ``` - pub fn remove_children(&mut self) { + pub fn remove_children(&'a mut self) { for c in self.children_mut() { _ = c.prune(); } @@ -1769,9 +1769,13 @@ where /// assert_eq!(all_values, [101, 202, 303, 4, 5, 406, 507]); /// ``` #[allow(clippy::missing_panics_doc)] - pub fn custom_walk_mut(&mut self, next_node: F) -> impl Iterator + pub fn custom_walk_mut<'t, F>( + &mut self, + next_node: F, + ) -> impl Iterator + 't where - F: Fn(Node<'a, V, M, P>) -> Option>, + F: Fn(Node<'a, V, M, P>) -> Option> + 't, + 'a: 't, { let iter_ptr = CustomWalkIterPtr::new(self.col(), Some(self.node_ptr()), next_node); iter_ptr.map(|ptr| { @@ -2047,10 +2051,9 @@ where /// assert_eq!(dfs, [1, 2, 4, 8, 5, 9, 3, 6, 10, 7, 11, 12]); /// ``` pub fn children_mut( - &mut self, - ) -> impl ExactSizeIterator> - + DoubleEndedIterator - + use<'_, 'a, V, M, P, MO> { + &'a mut self, + ) -> impl ExactSizeIterator> + DoubleEndedIterator + { ChildrenMutIter::new(self.col, unsafe { self.node_ptr.ptr() }) } @@ -2127,9 +2130,11 @@ where /// assert_eq!(post_order.next(), Some(&mut 4)); // ... /// } /// ``` - pub fn walk_mut(&'a mut self) -> impl Iterator + pub fn walk_mut<'t, T>(&mut self) -> impl Iterator + 't where T: Traverser, + T::Storage: 't, + 'a: 't, { T::iter_mut_with_owned_storage::(self) } @@ -2272,13 +2277,14 @@ where /// ] /// ); /// ``` - pub fn walk_mut_with( - &'a mut self, - traverser: &'a mut T, - ) -> impl Iterator> + pub fn walk_mut_with<'t, T, O>( + &mut self, + traverser: &'t mut T, + ) -> impl Iterator> + 't where O: OverMut, T: Traverser, + 'a: 't, { traverser.iter_mut(self) } @@ -2522,13 +2528,14 @@ where /// ] /// ); /// ``` - pub fn into_walk_with( + pub fn into_walk_with<'t, T, O>( self, - traverser: &'a mut T, - ) -> impl Iterator> + traverser: &'t mut T, + ) -> impl Iterator> + 't where O: OverMut, T: Traverser, + 'a: 't, { traverser.into_iter(self) } @@ -2598,10 +2605,12 @@ where /// let leaves: Vec<_> = n3.leaves::().copied().collect(); /// assert_eq!(leaves, [209, 210, 211]); /// ``` - pub fn leaves_mut(&'a mut self) -> impl Iterator + pub fn leaves_mut<'t, T>(&mut self) -> impl Iterator + 't where - T: Traverser, + T: Traverser + 't, + 'a: 't, { + let col = self.col(); T::iter_ptr_with_owned_storage(self.node_ptr()) .filter(|x: &NodePtr| unsafe { &*x.ptr() }.next().is_empty()) .map(|x: NodePtr| { @@ -2611,7 +2620,7 @@ where M, P, &'a mut V::Item, - >(self.col(), x) + >(col, x) }) } @@ -2734,14 +2743,16 @@ where /// [(2, &205), (3, &308), (3, &309), (3, &310), (3, &311)] /// ); /// ``` - pub fn leaves_mut_with( - &'a mut self, - traverser: &'a mut T, - ) -> impl Iterator> + pub fn leaves_mut_with<'t, T, O>( + &mut self, + traverser: &'t mut T, + ) -> impl Iterator> + 't where O: OverMut, T: Traverser, + 'a: 't, { + let col = self.col(); T::iter_ptr_with_storage(self.node_ptr(), traverser.storage_mut()) .filter(|x| { let ptr: &NodePtr = O::Enumeration::node_data(x); @@ -2749,8 +2760,7 @@ where }) .map(|x| { O::Enumeration::from_element_ptr_mut::<'a, V, M, P, O::NodeItemMut<'a, V, M, P>>( - self.col(), - x, + col, x, ) }) } @@ -2932,13 +2942,14 @@ where /// /// assert!(tree.is_empty()); /// ``` - pub fn into_leaves_with( + pub fn into_leaves_with<'t, T, O>( self, - traverser: &'a mut T, - ) -> impl Iterator> + traverser: &'t mut T, + ) -> impl Iterator> + 't where O: OverMut, T: Traverser, + 'a: 't, { T::into_iter_with_storage_filtered(self, traverser.storage_mut(), |x| { let ptr = ::node_data(x); diff --git a/src/node_ref.rs b/src/node_ref.rs index f0d733b..dc26f87 100644 --- a/src/node_ref.rs +++ b/src/node_ref.rs @@ -295,11 +295,15 @@ where /// /// assert_eq!(data, ['a', 'c', 'd', 'e', 'b']); /// ``` - fn children(&'a self) -> impl ExactSizeIterator> { + fn children<'t>(&self) -> impl ExactSizeIterator> + 't + where + 'a: 't, + { + let col = self.col(); self.node() .next() .children_ptr() - .map(|ptr| Node::new(self.col(), *ptr)) + .map(move |ptr| Node::new(col, ptr)) } /// Creates a **[parallel iterator]** of children nodes of this node. @@ -373,15 +377,17 @@ where /// assert_eq!(seq_value, par_value_4t); /// ``` #[cfg(feature = "parallel")] - fn children_par(&'a self) -> impl ParIter> + fn children_par<'t>(&self) -> impl ParIter> + 't where V::Item: Send + Sync, - Self: Sync, +

::PinnedVec: Sync, + 'a: 't, { + let col = self.col(); self.node() .next() .children_ptr_par() - .map(|ptr| Node::new(self.col(), *ptr)) + .map(move |ptr| Node::new(col, ptr)) } /// Returns the `child-index`-th child of the node; returns None if out of bounds. @@ -548,7 +554,7 @@ where .map(|parent| { let ptr = self.node_ptr(); let mut children = parent.next().children_ptr(); - children.position(|x| *x == ptr).expect("this node exists") + children.position(|x| x == ptr).expect("this node exists") }) .unwrap_or(0) } @@ -663,11 +669,15 @@ where /// let ancestors_data: Vec<_> = n4.ancestors().map(|x| *x.data()).collect(); /// assert_eq!(ancestors_data, [2, 1]); /// ``` - fn ancestors(&'a self) -> impl Iterator> { + fn ancestors<'t>(&self) -> impl Iterator> + 't + where + 'a: 't, + { let root_ptr = self.col().ends().get().expect("Tree is non-empty"); + let col = self.col(); AncestorsIterPtr::new(root_ptr, self.node_ptr()) .skip(1) - .map(|ptr| Node::new(self.col(), ptr)) + .map(|ptr| Node::new(col, ptr)) } /// Creates a **[parallel iterator]** starting from this node moving upwards until the root: @@ -686,9 +696,10 @@ where /// [`num_threads`]: orx_parallel::ParIter::num_threads /// [`chunk_size`]: orx_parallel::ParIter::chunk_size #[cfg(feature = "parallel")] - fn ancestors_par(&'a self) -> impl ParIter> + fn ancestors_par<'t>(&self) -> impl ParIter> + 't where V::Item: Send + Sync, + 'a: 't, { self.ancestors().collect::>().into_par() } @@ -856,12 +867,13 @@ where /// let values: Vec<_> = tree.node(id3).custom_walk(next_node).copied().collect(); /// assert_eq!(values, [3, 6, 7, 10, 11]); /// ``` - fn custom_walk(&self, next_node: F) -> impl Iterator + fn custom_walk<'t, F>(&self, next_node: F) -> impl Iterator + 't where - F: Fn(Node<'a, V, M, P>) -> Option>, + F: Fn(Node<'a, V, M, P>) -> Option> + 't, + 'a: 't, { let iter_ptr = CustomWalkIterPtr::new(self.col(), Some(self.node_ptr()), next_node); - iter_ptr.map(|ptr| { + iter_ptr.map(move |ptr| { let node = unsafe { &*ptr.ptr() }; node.data() .expect("node is returned by next_node and is active") @@ -880,10 +892,11 @@ where /// [`num_threads`]: orx_parallel::ParIter::num_threads /// [`chunk_size`]: orx_parallel::ParIter::chunk_size #[cfg(feature = "parallel")] - fn custom_walk_par(&self, next_node: F) -> impl ParIter + fn custom_walk_par<'t, F>(&self, next_node: F) -> impl ParIter + 't where - F: Fn(Node<'a, V, M, P>) -> Option>, + F: Fn(Node<'a, V, M, P>) -> Option> + 't, V::Item: Send + Sync, + 'a: 't, { self.custom_walk(next_node) .collect::>() @@ -962,10 +975,12 @@ where /// let post_order: Vec<_> = n2.walk::().copied().collect(); /// assert_eq!(post_order, [8, 4, 5, 2]); /// ``` - fn walk(&'a self) -> impl Iterator + fn walk<'t, T>(&self) -> impl Iterator + 't where T: Traverser, + T::Storage: 't, Self: Sized, + 'a: 't, { T::iter_with_owned_storage::(self) } @@ -985,11 +1000,13 @@ where /// [`num_threads`]: orx_parallel::ParIter::num_threads /// [`chunk_size`]: orx_parallel::ParIter::chunk_size #[cfg(feature = "parallel")] - fn walk_par(&'a self) -> impl ParIter + fn walk_par<'t, T>(&self) -> impl ParIter + 't where T: Traverser, + T::Storage: 't, Self: Sized, V::Item: Send + Sync, + 'a: 't, { self.walk::().collect::>().into_par() } @@ -1137,14 +1154,15 @@ where /// ); /// ``` fn walk_with<'t, T, O>( - &'a self, + &self, traverser: &'t mut T, - ) -> impl Iterator> + ) -> impl Iterator> + 't where O: Over, T: Traverser, + T::Storage: 't, Self: Sized, - 't: 'a, + 'a: 't, { traverser.iter(self) } @@ -1162,15 +1180,15 @@ where /// [`chunk_size`]: orx_parallel::ParIter::chunk_size #[cfg(feature = "parallel")] fn walk_with_par<'t, T, O>( - &'a self, + &self, traverser: &'t mut T, - ) -> impl ParIter> + ) -> impl ParIter> + 't where O: Over, T: Traverser, Self: Sized, - 't: 'a, OverItem<'a, V, O, M, P>: Send + Sync, + 'a: 't, { self.walk_with(traverser) .collect::>() @@ -1278,9 +1296,10 @@ where /// .unwrap(); /// assert_eq!(max_label_path, vec![9, 6, 3, 1]); /// ``` - fn paths(&'a self) -> impl Iterator + Clone> + fn paths<'t, T>(&self) -> impl Iterator + Clone> + 't where - T: Traverser, + T: Traverser + 't, + 'a: 't, { let node_ptr = self.node_ptr(); T::iter_ptr_with_owned_storage(node_ptr) @@ -1379,10 +1398,13 @@ where /// assert_eq!(best_path, expected.iter().collect::>()); /// ``` #[cfg(feature = "parallel")] - fn paths_par(&'a self) -> impl ParIter + Clone> + fn paths_par<'t, T>( + &self, + ) -> impl ParIter + Clone> + 't where T: Traverser, V::Item: Send + Sync, + 'a: 't, { let node_ptr = self.node_ptr(); let node_ptrs: alloc::vec::Vec<_> = T::iter_ptr_with_owned_storage(node_ptr) @@ -1486,15 +1508,17 @@ where /// ] /// ); /// ``` - fn paths_with( - &'a self, - traverser: &'a mut T, - ) -> impl Iterator::NodeItem<'a, V, M, P>> + Clone> + fn paths_with<'t, T, O>( + &self, + traverser: &'t mut T, + ) -> impl Iterator::NodeItem<'a, V, M, P>> + Clone> + 't where O: Over, T: Traverser, + 'a: 't, { let node_ptr = self.node_ptr(); + let col = self.col(); T::iter_ptr_with_storage(node_ptr, TraverserCore::storage_mut(traverser)) .filter(|x| { let ptr: &NodePtr = O::Enumeration::node_data(x); @@ -1505,8 +1529,7 @@ where let iter = AncestorsIterPtr::new(node_ptr, *ptr); iter.map(|ptr: NodePtr| { O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>( - self.col(), - ptr, + col, ptr, ) }) }) @@ -1598,17 +1621,20 @@ where /// assert_eq!(best_path, expected.iter().collect::>()); /// ``` #[cfg(feature = "parallel")] - fn paths_with_par( - &'a self, - traverser: &'a mut T, - ) -> impl ParIter::NodeItem<'a, V, M, P>> + Clone> + fn paths_with_par<'t, T, O>( + &self, + traverser: &'t mut T, + ) -> impl ParIter::NodeItem<'a, V, M, P>> + Clone> + 't where O: Over, T: Traverser, V::Item: Send + Sync, Self: Sync, +

::PinnedVec: Sync, + 'a: 't, { let node_ptr = self.node_ptr(); + let col = self.col(); let node_ptrs: alloc::vec::Vec<_> = T::iter_ptr_with_storage(node_ptr, TraverserCore::storage_mut(traverser)) @@ -1617,10 +1643,7 @@ where node_ptrs.into_par().map(move |x| { let iter = AncestorsIterPtr::new(node_ptr, x); iter.map(|ptr: NodePtr| { - O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>( - self.col(), - ptr, - ) + O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>(col, ptr) }) }) } @@ -1668,7 +1691,7 @@ where /// let bfs: Vec<_> = clone.root().walk::().copied().collect(); /// assert_eq!(bfs, [2, 5, 6, 8, 9, 10]); /// ``` - fn clone_as_tree(&'a self) -> Tree + fn clone_as_tree(&self) -> Tree where V2: TreeVariant + 'a, P::PinnedVec: Default, @@ -1758,16 +1781,17 @@ where /// .collect(); /// assert_eq!(bfs_leaves, [5, 8, 9, 10, 11]); /// ``` - fn leaves(&'a self) -> impl Iterator + fn leaves<'t, T>(&self) -> impl Iterator + 't where - T: Traverser, + T: Traverser + 't, + 'a: 't, { + let col = self.col(); T::iter_ptr_with_owned_storage(self.node_ptr()) .filter(|x: &NodePtr| unsafe { &*x.ptr() }.next().is_empty()) .map(|x: NodePtr| { ::Enumeration::from_element_ptr::<'a, V, M, P, &'a V::Item>( - self.col(), - x, + col, x, ) }) } @@ -1784,10 +1808,11 @@ where /// [`num_threads`]: orx_parallel::ParIter::num_threads /// [`chunk_size`]: orx_parallel::ParIter::chunk_size #[cfg(feature = "parallel")] - fn leaves_par(&'a self) -> impl ParIter + fn leaves_par<'t, T>(&self) -> impl ParIter + 't where T: Traverser, V::Item: Send + Sync, + 'a: 't, { self.leaves::() .collect::>() @@ -1873,24 +1898,23 @@ where /// assert_eq!(sibling_idx, 0); /// assert_eq!(leaf.data(), &8); /// ``` - fn leaves_with( - &'a self, - traverser: &'a mut T, - ) -> impl Iterator> + fn leaves_with<'t, T, O>( + &self, + traverser: &'t mut T, + ) -> impl Iterator> + 't where O: Over, T: Traverser, + 'a: 't, { + let col = self.col(); T::iter_ptr_with_storage(self.node_ptr(), traverser.storage_mut()) .filter(|x| { let ptr: &NodePtr = O::Enumeration::node_data(x); unsafe { &*ptr.ptr() }.next().is_empty() }) .map(|x| { - O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>( - self.col(), - x, - ) + O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>(col, x) }) } @@ -1906,14 +1930,15 @@ where /// [`num_threads`]: orx_parallel::ParIter::num_threads /// [`chunk_size`]: orx_parallel::ParIter::chunk_size #[cfg(feature = "parallel")] - fn leaves_with_par( - &'a self, - traverser: &'a mut T, + fn leaves_with_par<'t, T, O>( + &self, + traverser: &'t mut T, ) -> impl ParIter> where O: Over, T: Traverser, OverItem<'a, V, O, M, P>: Send + Sync, + 'a: 't, { self.leaves_with(traverser) .collect::>() @@ -1979,10 +2004,10 @@ where /// assert_eq!(a.node(dfs_indices[2]).data(), &3); /// assert_eq!(a.node(dfs_indices[3]).data(), &7); /// ``` - fn indices(&self) -> impl Iterator> + fn indices<'t, T>(&self) -> impl Iterator> + 't where - T: Traverser, - V: 'static, + T: Traverser + 't, + 'a: 't, { let node_ptr = self.node_ptr(); let state = self.col().memory_state(); @@ -2010,15 +2035,15 @@ where /// This method additionally allow for yielding node depths and sibling indices in addition to node indices. /// /// [`indices_with`]: crate::NodeRef::indices_with - fn indices_with( + fn indices_with<'t, T, O>( &self, - traverser: &mut T, - ) -> impl Iterator::Item>> + traverser: &'t mut T, + ) -> impl Iterator::Item>> + 't where O: Over, T: Traverser, - V: 'static, Self: Sized, + 'a: 't, { let node_ptr = self.node_ptr(); let state = self.col().memory_state(); diff --git a/src/pinned_storage.rs b/src/pinned_storage.rs index f5e90e6..7278889 100644 --- a/src/pinned_storage.rs +++ b/src/pinned_storage.rs @@ -2,7 +2,7 @@ use crate::{TreeVariant, aliases::N}; use orx_split_vec::{PinnedVec, Recursive, SplitVec}; /// Trait defining the underlying pinned vector storage of the tree. -pub trait PinnedStorage: 'static { +pub trait PinnedStorage: 'static + Sync { /// The pinned vector for the given variant `V`. type PinnedVec: PinnedVec> where diff --git a/src/traversal/breadth_first/iter_ptr.rs b/src/traversal/breadth_first/iter_ptr.rs index 38e9b0c..64c588e 100644 --- a/src/traversal/breadth_first/iter_ptr.rs +++ b/src/traversal/breadth_first/iter_ptr.rs @@ -72,7 +72,7 @@ where self.stack.get_mut().pop_front().inspect(|element| { let node_ptr = E::node_value(element); let parent = unsafe { &*node_ptr.ptr() }; - let children_ptr = parent.next().children_ptr().cloned(); + let children_ptr = parent.next().children_ptr(); let children = E::children(element, children_ptr); self.stack.get_mut().extend(children); }) diff --git a/src/traversal/breadth_first/traverser_core.rs b/src/traversal/breadth_first/traverser_core.rs index 1b68856..588f087 100644 --- a/src/traversal/breadth_first/traverser_core.rs +++ b/src/traversal/breadth_first/traverser_core.rs @@ -39,46 +39,50 @@ impl TraverserCore for Bfs { BfsIterPtr::<_, O::Enumeration, _>::from((storage, node_ptr)) } - fn iter_with_storage<'a, V, M, P>( - node: &'a impl NodeRef<'a, V, M, P>, - storage: impl SoM>, - ) -> impl Iterator> + fn iter_with_storage<'t, 'a, V, M, P>( + node: &impl NodeRef<'a, V, M, P>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + Self::Storage: 't, + 'a: 't, { let root = node.node_ptr(); let iter = BfsIterPtr::<_, O::Enumeration, _>::from((storage, root)); BfsIterRef::<'_, _, M, P, _, _, _>::from((node.col(), iter)) } - fn iter<'a, V, M, P>( - &'a mut self, - node: &'a impl NodeRef<'a, V, M, P>, - ) -> impl Iterator> + fn iter<'t, 'a, V, M, P>( + &'t mut self, + node: &impl NodeRef<'a, V, M, P>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + 'a: 't, { let queue = self.queue.for_variant::(); Self::iter_with_storage(node, queue) } - fn iter_mut<'a, V, M, P, MO>( - &'a mut self, - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - ) -> impl Iterator> + fn iter_mut<'t, 'a, V, M, P, MO>( + &'t mut self, + node: &mut NodeMut<'a, V, M, P, MO>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, O: OverMut, + 'a: 't, { let queue = self.queue.for_variant::(); - Self::iter_mut_with_storage(node_mut, queue) + Self::iter_mut_with_storage(node, queue) } fn into_iter<'a, V, M, P, MO>( @@ -96,16 +100,18 @@ impl TraverserCore for Bfs { Self::into_iter_with_storage(node_mut, queue) } - fn iter_mut_with_storage<'a, V, M, P, MO>( - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - storage: impl SoM>, - ) -> impl Iterator> + fn iter_mut_with_storage<'t, 'a, V, M, P, MO>( + node_mut: &mut NodeMut<'a, V, M, P, MO>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, O: OverMut, + Self::Storage: 't, + 'a: 't, { let root = node_mut.node_ptr(); let iter_ptr = BfsIterPtr::::from((storage, root)); diff --git a/src/traversal/depth_first/iter_ptr.rs b/src/traversal/depth_first/iter_ptr.rs index 1cf2d6f..50095f1 100644 --- a/src/traversal/depth_first/iter_ptr.rs +++ b/src/traversal/depth_first/iter_ptr.rs @@ -72,7 +72,7 @@ where 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().cloned(); + let children_ptr = parent.next().children_ptr(); let children = E::children(element, children_ptr).rev(); self.stack.get_mut().extend(children); }) diff --git a/src/traversal/depth_first/traverser_core.rs b/src/traversal/depth_first/traverser_core.rs index af74c62..46a6be5 100644 --- a/src/traversal/depth_first/traverser_core.rs +++ b/src/traversal/depth_first/traverser_core.rs @@ -39,46 +39,50 @@ impl TraverserCore for Dfs { DfsIterPtr::<_, O::Enumeration, _>::from((storage, node_ptr)) } - fn iter_with_storage<'a, V, M, P>( - node: &'a impl NodeRef<'a, V, M, P>, - storage: impl SoM>, - ) -> impl Iterator> + fn iter_with_storage<'t, 'a, V, M, P>( + node: &impl NodeRef<'a, V, M, P>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + Self::Storage: 't, + 'a: 't, { let root = node.node_ptr(); let iter = DfsIterPtr::<_, O::Enumeration, _>::from((storage, root)); DfsIterRef::<'_, _, M, P, _, _, _>::from((node.col(), iter)) } - fn iter<'a, V, M, P>( - &'a mut self, - node: &'a impl NodeRef<'a, V, M, P>, - ) -> impl Iterator> + fn iter<'t, 'a, V, M, P>( + &'t mut self, + node: &impl NodeRef<'a, V, M, P>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + 'a: 't, { let stack = self.stack.for_variant::(); Self::iter_with_storage(node, stack) } - fn iter_mut<'a, V, M, P, MO>( - &'a mut self, - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - ) -> impl Iterator> + fn iter_mut<'t, 'a, V, M, P, MO>( + &'t mut self, + node: &mut NodeMut<'a, V, M, P, MO>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, O: OverMut, + 'a: 't, { let stack = self.stack.for_variant::(); - Self::iter_mut_with_storage(node_mut, stack) + Self::iter_mut_with_storage(node, stack) } fn into_iter<'a, V, M, P, MO>( @@ -96,16 +100,18 @@ impl TraverserCore for Dfs { Self::into_iter_with_storage(node_mut, stack) } - fn iter_mut_with_storage<'a, V, M, P, MO>( - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - storage: impl SoM>, - ) -> impl Iterator> + fn iter_mut_with_storage<'t, 'a, V, M, P, MO>( + node_mut: &mut NodeMut<'a, V, M, P, MO>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, O: OverMut, + Self::Storage: 't, + 'a: 't, { let root = node_mut.node_ptr(); let iter_ptr = DfsIterPtr::::from((storage, root)); diff --git a/src/traversal/post_order/traverser_core.rs b/src/traversal/post_order/traverser_core.rs index ad64a69..fde3d49 100644 --- a/src/traversal/post_order/traverser_core.rs +++ b/src/traversal/post_order/traverser_core.rs @@ -39,46 +39,50 @@ impl TraverserCore for PostOrder { PostOrderIterPtr::<_, O::Enumeration, _>::from((storage, node_ptr)) } - fn iter_with_storage<'a, V, M, P>( - node: &'a impl NodeRef<'a, V, M, P>, - storage: impl SoM>, - ) -> impl Iterator> + fn iter_with_storage<'t, 'a, V, M, P>( + node: &impl NodeRef<'a, V, M, P>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + Self::Storage: 't, + 'a: 't, { let root = node.node_ptr(); let iter_ptr = PostOrderIterPtr::::from((storage, root)); PostOrderIterRef::from((node.col(), iter_ptr)) } - fn iter<'a, V, M, P>( - &'a mut self, - node: &'a impl NodeRef<'a, V, M, P>, - ) -> impl Iterator> + fn iter<'t, 'a, V, M, P>( + &'t mut self, + node: &impl NodeRef<'a, V, M, P>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + 'a: 't, { let states = self.states.for_variant::(); Self::iter_with_storage(node, states) } - fn iter_mut<'a, V, M, P, MO>( - &'a mut self, - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - ) -> impl Iterator> + fn iter_mut<'t, 'a, V, M, P, MO>( + &'t mut self, + node: &mut NodeMut<'a, V, M, P, MO>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, O: OverMut, + 'a: 't, { let states = self.states.for_variant::(); - Self::iter_mut_with_storage(node_mut, states) + Self::iter_mut_with_storage(node, states) } fn into_iter<'a, V, M, P, MO>( @@ -96,16 +100,18 @@ impl TraverserCore for PostOrder { Self::into_iter_with_storage(node_mut, states) } - fn iter_mut_with_storage<'a, V, M, P, MO>( - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - storage: impl SoM>, - ) -> impl Iterator> + fn iter_mut_with_storage<'t, 'a, V, M, P, MO>( + node_mut: &mut NodeMut<'a, V, M, P, MO>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, O: OverMut, + Self::Storage: 't, + 'a: 't, { let root = node_mut.node_ptr(); let iter_ptr = PostOrderIterPtr::::from((storage, root)); diff --git a/src/traversal/traverser_core.rs b/src/traversal/traverser_core.rs index 0ce4b82..e4edfc6 100644 --- a/src/traversal/traverser_core.rs +++ b/src/traversal/traverser_core.rs @@ -21,21 +21,23 @@ where fn storage_mut(&mut self) -> &mut Self::Storage; - fn iter_ptr_with_storage<'a, V>( + fn iter_ptr_with_storage<'t, V>( node_ptr: NodePtr, - storage: impl SoM>, + storage: impl SoM> + 't, ) -> impl Iterator::Item>> where - V: TreeVariant + 'a; + V: TreeVariant + 't; - fn iter_with_storage<'a, V, M, P>( - node: &'a impl NodeRef<'a, V, M, P>, - storage: impl SoM>, - ) -> impl Iterator> + fn iter_with_storage<'t, 'a, V, M, P>( + node: &impl NodeRef<'a, V, M, P>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, - P: PinnedStorage; + P: PinnedStorage, + Self::Storage: 't, + 'a: 't; /// Returns an iterator which yields all nodes including the `node` and all its descendants; i.e., /// all nodes of the subtree rooted at the given `node`. @@ -74,24 +76,28 @@ where /// [`OverDepthNode`]: crate::traversal::OverDepthNode /// [`OverSiblingIdxNode`]: crate::traversal::OverSiblingIdxNode /// [`OverDepthSiblingIdxNode`]: crate::traversal::OverDepthSiblingIdxNode - fn iter<'a, V, M, P>( - &'a mut self, - node: &'a impl NodeRef<'a, V, M, P>, - ) -> impl Iterator> + fn iter<'t, 'a, V, M, P>( + &'t mut self, + node: &impl NodeRef<'a, V, M, P>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, - P: PinnedStorage; - fn iter_mut_with_storage<'a, V, M, P, MO>( - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - storage: impl SoM>, - ) -> impl Iterator> + P: PinnedStorage, + 'a: 't; + + fn iter_mut_with_storage<'t, 'a, V, M, P, MO>( + node: &mut NodeMut<'a, V, M, P, MO>, + storage: impl SoM> + 't, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, - O: OverMut; + O: OverMut, + Self::Storage: 't, + 'a: 't; /// Returns a mutable iterator which yields all nodes including the `node` and all its descendants; i.e., /// all nodes of the subtree rooted at the given `node`. @@ -123,19 +129,20 @@ where /// [`OverDepthData`]: crate::traversal::OverDepthData /// [`OverSiblingIdxData`]: crate::traversal::OverSiblingIdxData /// [`OverDepthSiblingIdxData`]: crate::traversal::OverDepthSiblingIdxData - fn iter_mut<'a, V, M, P, MO>( - &'a mut self, - node: &'a mut NodeMut<'a, V, M, P, MO>, - ) -> impl Iterator> + fn iter_mut<'t, 'a, V, M, P, MO>( + &'t mut self, + node: &mut NodeMut<'a, V, M, P, MO>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, MO: NodeMutOrientation, - O: OverMut; + O: OverMut, + 'a: 't; fn into_iter_with_storage<'a, V, M, P, MO>( - node_mut: NodeMut<'a, V, M, P, MO>, + node: NodeMut<'a, V, M, P, MO>, storage: impl SoM>, ) -> impl Iterator> where @@ -146,7 +153,7 @@ where O: Over; fn into_iter_with_storage_filtered<'a, V, M, P, MO, F>( - node_mut: NodeMut<'a, V, M, P, MO>, + node: NodeMut<'a, V, M, P, MO>, storage: impl SoM>, filter: F, ) -> impl Iterator> @@ -212,41 +219,46 @@ where // provided - fn iter_ptr_with_owned_storage<'a, V>( + fn iter_ptr_with_owned_storage<'t, V>( node_ptr: NodePtr, ) -> impl Iterator::Item>> where - V: TreeVariant + 'a, + V: TreeVariant + 't, + >::Storage: 't, { Self::iter_ptr_with_storage(node_ptr, Self::Storage::default()) } - fn iter_with_owned_storage<'a, V, M, P>( - node: &'a impl NodeRef<'a, V, M, P>, - ) -> impl Iterator> + fn iter_with_owned_storage<'t, 'a, V, M, P>( + node: &impl NodeRef<'a, V, M, P>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + Self::Storage: 't, + 'a: 't, { Self::iter_with_storage(node, Self::Storage::default()) } - fn iter_mut_with_owned_storage<'a, V, M, P, MO>( - node_mut: &'a mut NodeMut<'a, V, M, P, MO>, - ) -> impl Iterator> + fn iter_mut_with_owned_storage<'t, 'a, V, M, P, MO>( + node: &mut NodeMut<'a, V, M, P, MO>, + ) -> impl Iterator> + 't where V: TreeVariant + 'a, M: MemoryPolicy, P: PinnedStorage, + Self::Storage: 't, MO: NodeMutOrientation, O: OverMut, + 'a: 't, { - Self::iter_mut_with_storage(node_mut, Self::Storage::default()) + Self::iter_mut_with_storage(node, Self::Storage::default()) } fn into_iter_with_owned_storage<'a, V, M, P, MO>( - node_mut: NodeMut<'a, V, M, P, MO>, + node: NodeMut<'a, V, M, P, MO>, ) -> impl Iterator> where V: TreeVariant + 'a, @@ -255,6 +267,6 @@ where MO: NodeMutOrientation, O: Over, { - Self::into_iter_with_storage(node_mut, Self::Storage::default()) + Self::into_iter_with_storage(node, Self::Storage::default()) } } diff --git a/src/tree.rs b/src/tree.rs index 14a36ff..b840ada 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -213,7 +213,7 @@ where /// tree.push_root('a'); /// assert_eq!(tree.root().data(), &'a'); /// ``` - pub fn root(&self) -> Node<'_, V, M, P> { + pub fn root<'a>(&'a self) -> Node<'a, V, M, P> { self.root_ptr() .map(|p| Node::new(&self.0, p)) .expect("Tree is empty and has no root. You may use `push_root` to add a root and/or `get_root` to safely access the root if it exists.") @@ -257,7 +257,7 @@ where /// tree.node_mut(b).push_child('d'); /// tree.node_mut(c).push_children(['e', 'f']); /// ``` - pub fn root_mut(&mut self) -> NodeMut<'_, V, M, P> { + pub fn root_mut<'a>(&'a mut self) -> NodeMut<'a, V, M, P> { self.root_ptr() .map(|p| NodeMut::new(&mut self.0, p)) .expect("Tree is empty and has no root. You may use `push_root` to add a root and/or `get_root` to safely access the root if it exists.") @@ -284,7 +284,7 @@ where /// tree.push_root('a'); /// assert_eq!(tree.root().data(), &'a'); /// ``` - pub fn get_root(&self) -> Option> { + pub fn get_root<'a>(&'a self) -> Option> { self.root_ptr().map(|p| Node::new(&self.0, p)) } @@ -309,7 +309,7 @@ where /// tree.clear(); /// assert_eq!(tree.get_root_mut(), None); /// ``` - pub fn get_root_mut(&mut self) -> Option> { + pub fn get_root_mut<'a>(&'a mut self) -> Option> { self.root_ptr().map(|p| NodeMut::new(&mut self.0, p)) } @@ -404,8 +404,8 @@ where /// assert_eq!(bfs_values, [1, 2, 3, 4, 5]); /// ``` #[inline(always)] - pub fn node(&self, node_idx: NodeIdx) -> Node<'_, V, M, P> { - assert!(self.is_node_idx_valid(node_idx), "{}", INVALID_IDX_ERROR); + pub fn node<'a>(&'a self, node_idx: NodeIdx) -> Node<'a, V, M, P> { + assert!(self.is_node_idx_valid(node_idx), "{INVALID_IDX_ERROR}"); Node::new(&self.0, node_idx.0.node_ptr()) } @@ -458,8 +458,8 @@ where /// assert_eq!(bfs_values, [1, 2, 3, 4, 5]); /// ``` #[inline(always)] - pub fn node_mut(&mut self, node_idx: NodeIdx) -> NodeMut<'_, V, M, P> { - assert!(self.is_node_idx_valid(node_idx), "{}", INVALID_IDX_ERROR); + pub fn node_mut<'a>(&'a mut self, node_idx: NodeIdx) -> NodeMut<'a, V, M, P> { + assert!(self.is_node_idx_valid(node_idx), "{INVALID_IDX_ERROR}"); NodeMut::new(&mut self.0, node_idx.0.node_ptr()) } @@ -481,7 +481,7 @@ where /// [`NodeIdxError::RemovedNode`]: crate::NodeIdxError::RemovedNode /// [`NodeIdxError::ReorganizedCollection`]: crate::NodeIdxError::ReorganizedCollection #[inline(always)] - pub fn get_node(&self, node_idx: NodeIdx) -> Option> { + pub fn get_node<'a>(&'a self, node_idx: NodeIdx) -> Option> { self.is_node_idx_valid(node_idx) .then(|| Node::new(&self.0, node_idx.0.node_ptr())) } @@ -504,7 +504,7 @@ where /// [`NodeIdxError::RemovedNode`]: crate::NodeIdxError::RemovedNode /// [`NodeIdxError::ReorganizedCollection`]: crate::NodeIdxError::ReorganizedCollection #[inline(always)] - pub fn get_node_mut(&mut self, node_idx: NodeIdx) -> Option> { + pub fn get_node_mut<'a>(&'a mut self, node_idx: NodeIdx) -> Option> { self.is_node_idx_valid(node_idx) .then(|| NodeMut::new(&mut self.0, node_idx.0.node_ptr())) } @@ -525,7 +525,7 @@ where /// [`NodeIdxError::RemovedNode`]: crate::NodeIdxError::RemovedNode /// [`NodeIdxError::ReorganizedCollection`]: crate::NodeIdxError::ReorganizedCollection #[inline(always)] - pub fn try_node(&self, node_idx: NodeIdx) -> Result, NodeIdxError> { + pub fn try_node<'a>(&'a self, node_idx: NodeIdx) -> Result, NodeIdxError> { self.0 .try_get_ptr(node_idx.0) .map(|ptr| Node::new(&self.0, ptr)) @@ -547,10 +547,10 @@ where /// [`NodeIdxError::RemovedNode`]: crate::NodeIdxError::RemovedNode /// [`NodeIdxError::ReorganizedCollection`]: crate::NodeIdxError::ReorganizedCollection #[inline(always)] - pub fn try_node_mut( - &mut self, + pub fn try_node_mut<'a>( + &'a mut self, node_idx: NodeIdx, - ) -> Result, NodeIdxError> { + ) -> Result, NodeIdxError> { self.0 .try_get_ptr(node_idx.0) .map(|ptr| NodeMut::new(&mut self.0, ptr)) @@ -566,7 +566,7 @@ where /// [`node`]: Self::node /// [`is_node_idx_valid`]: Self::is_node_idx_valid #[inline(always)] - pub unsafe fn node_unchecked(&self, node_idx: NodeIdx) -> Node<'_, V, M, P> { + pub unsafe fn node_unchecked<'a>(&'a self, node_idx: NodeIdx) -> Node<'a, V, M, P> { Node::new(&self.0, node_idx.0.node_ptr()) } @@ -580,7 +580,10 @@ where /// [`node_mut`]: Self::node_mut /// [`is_node_idx_valid`]: Self::is_node_idx_valid #[inline(always)] - pub unsafe fn node_mut_unchecked(&mut self, node_idx: NodeIdx) -> NodeMut<'_, V, M, P> { + pub unsafe fn node_mut_unchecked<'a>( + &'a mut self, + node_idx: NodeIdx, + ) -> NodeMut<'a, V, M, P> { NodeMut::new(&mut self.0, node_idx.0.node_ptr()) } diff --git a/src/tree_variant.rs b/src/tree_variant.rs index 5ed9e54..570cc00 100644 --- a/src/tree_variant.rs +++ b/src/tree_variant.rs @@ -7,10 +7,10 @@ use orx_selfref_col::{ /// Variant of a tree. pub trait TreeVariant: - Variant, Prev = RefsSingle, Next = Self::Children> + Variant, Prev = RefsSingle, Next = Self::Children> + Sync { /// Memory reclaimer of the tree. - type Reclaimer: MemoryReclaimer; + type Reclaimer: MemoryReclaimer + Sync; /// Children references of the tree nodes. type Children: RefsChildren + Refs; @@ -19,21 +19,18 @@ pub trait TreeVariant: // children pub trait RefsChildren { - type ChildrenPtrIter<'a>: ExactSizeIterator> - + DoubleEndedIterator - + Default + type ChildrenPtrIter<'a>: ExactSizeIterator> + DoubleEndedIterator + Default where V: 'a, Self: 'a; fn num_children(&self) -> usize; - fn children_ptr(&self) -> Self::ChildrenPtrIter<'_>; + fn children_ptr<'a>(&'a self) -> Self::ChildrenPtrIter<'a>; #[cfg(feature = "parallel")] - fn children_ptr_par<'a>(&'a self) -> impl ParIter> + fn children_ptr_par(&self) -> impl ParIter> where - V: 'a, V::Item: Send + Sync; fn get_ptr(&self, i: usize) -> Option>; @@ -50,7 +47,7 @@ pub trait RefsChildren { impl RefsChildren for RefsVec { type ChildrenPtrIter<'a> - = core::slice::Iter<'a, NodePtr> + = core::iter::Copied>> where V: 'a, Self: 'a; @@ -61,17 +58,16 @@ impl RefsChildren for RefsVec { } #[inline(always)] - fn children_ptr(&self) -> Self::ChildrenPtrIter<'_> { - self.iter() + fn children_ptr<'a>(&'a self) -> Self::ChildrenPtrIter<'a> { + self.iter().copied() } #[cfg(feature = "parallel")] - fn children_ptr_par<'a>(&'a self) -> impl ParIter> + fn children_ptr_par(&self) -> impl ParIter> where - V: 'a, V::Item: Send + Sync, { - self.as_slice().par() + self.as_slice().par().copied() } #[inline(always)] @@ -101,7 +97,7 @@ impl RefsChildren for RefsVec { impl RefsChildren for RefsArrayLeftMost { type ChildrenPtrIter<'a> - = ArrayLeftMostPtrIter<'a, V> + = core::iter::Copied> where V: 'a, Self: 'a; @@ -112,20 +108,22 @@ impl RefsChildren for RefsArrayLeftMost { } #[inline(always)] - fn children_ptr(&self) -> Self::ChildrenPtrIter<'_> { - self.iter() + fn children_ptr<'a>(&'a self) -> Self::ChildrenPtrIter<'a> { + self.iter().copied() } #[cfg(feature = "parallel")] - fn children_ptr_par<'a>(&'a self) -> impl ParIter> + fn children_ptr_par(&self) -> impl ParIter> where - V: 'a, V::Item: Send + Sync, { - self.as_slice().par().map(|x| { - x.as_ref() - .expect("all elements of RefsArrayLeftMost::as_slice are of Some variant") - }) + self.as_slice() + .par() + .map(|x| { + x.as_ref() + .expect("all elements of RefsArrayLeftMost::as_slice are of Some variant") + }) + .copied() } #[inline(always)] diff --git a/tests/iterator_lifetimes.rs b/tests/iterator_lifetimes.rs new file mode 100644 index 0000000..4c04e0f --- /dev/null +++ b/tests/iterator_lifetimes.rs @@ -0,0 +1,332 @@ +use orx_tree::traversal::*; +use orx_tree::*; + +/* +These tests are created with respect to the issue: https://github.com/orxfun/orx-tree/issues/188. + +They are expected to compile. + +The `find` methods below return a node referencing the `tree`, which must be independent +of the root node or traverser if provided externally. + +The methods must NOT fail to compile due to the following errors: +* referencing local variable `traverser`, or +* referencing local variable `root`. + +These are temporary references, instead the output's lifetime must depend on the tree. +*/ + +fn find_ancestors<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.ancestors().find(|x| x.data() == predicate) +} + +#[cfg(feature = "parallel")] +fn find_ancestors_par<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.ancestors_par().find(|x| x.data() == predicate) +} + +fn find_children<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.children().find(|x| x.data() == predicate) +} + +#[cfg(feature = "parallel")] +fn find_children_par<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.children_par().find(|x| x.data() == predicate) +} + +fn find_custom_walk<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let custom_walk = |node: Node<'a, V>| node.get_child(0); + let root = tree.get_root()?; + let mut walker = root.custom_walk(custom_walk); + walker.find(|v| v == &predicate) +} + +#[cfg(feature = "parallel")] +fn find_custom_walk_par<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let custom_walk = |node: Node<'a, V>| node.get_child(0); + let root = tree.get_root()?; + let walker = root.custom_walk_par(custom_walk); + walker.find(|v| v == &predicate) +} + +fn find_walk<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + let mut walker = root.walk::(); + walker.find(|v| v == &predicate) +} + +#[cfg(feature = "parallel")] +fn find_walk_par<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + let walker = root.walk_par::(); + walker.find(|v| v == &predicate) +} + +fn find_walk_with<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let root = tree.get_root()?; + let mut walker = root.walk_with(&mut traverser); + walker.find(|v| v.data() == predicate) +} + +#[cfg(feature = "parallel")] +fn find_walk_with_par<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let root = tree.get_root()?; + let walker = root.walk_with_par(&mut traverser); + walker.find(|v| v.data() == predicate) +} + +fn find_paths<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.paths::() + .find(|x| x.clone().any(|x| x == predicate)) + .and_then(|mut x| x.next()) +} + +fn find_paths_with<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let root = tree.get_root()?; + root.paths_with(&mut traverser) + .find(|x| { + x.clone().map(|x| x.data()).any(|x| x == predicate) + }) + .and_then(|mut x| x.next()) +} + +#[cfg(feature = "parallel")] +fn find_paths_with_par<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let root = tree.get_root()?; + root.paths_with_par(&mut traverser) + .find(|x| { + x.clone().map(|x| x.data()).any(|x| x == predicate) + }) + .and_then(|mut x| x.next()) +} + +#[cfg(feature = "parallel")] +fn find_paths_par<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.paths_par::() + .find(|x| x.clone().any(|x| x == predicate)) + .and_then(|mut x| x.next()) +} + +fn find_leaves<'a, V: TreeVariant>(tree: &'a Tree, predicate: &V::Item) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.leaves::().find(|v| v == &predicate) +} + +#[cfg(feature = "parallel")] +fn find_leaves_par<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option<&'a V::Item> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.leaves_par::().find(|v| v == &predicate) +} + +fn find_leaves_with<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let root = tree.get_root()?; + root.leaves_with(&mut traverser) + .find(|v| v.data() == predicate) +} + +#[cfg(feature = "parallel")] +fn find_leaves_with_par<'a, V: TreeVariant>( + tree: &'a Tree, + predicate: &V::Item, +) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let root = tree.get_root()?; + root.leaves_with_par(&mut traverser) + .find(|v| v.data() == predicate) +} + +fn find_indices(tree: &Tree, predicate: &V::Item) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let root = tree.get_root()?; + root.indices::() + .find(|v| tree.node(*v).data() == predicate) +} + +fn find_indices_with(tree: &Tree, predicate: &V::Item) -> Option> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let root = tree.get_root()?; + root.indices_with(&mut traverser) + .find(|v| tree.node(*v).data() == predicate) +} + +// mut + +fn find_custom_walk_mut<'a, V: TreeVariant>( + tree: &'a mut Tree, + predicate: &V::Item, +) -> Option<&'a mut V::Item> +where + V::Item: Eq + Sync + Send, +{ + let custom_walk = |node: Node<'a, V>| node.get_child(0); + let mut root = tree.get_root_mut()?; + let mut walker = root.custom_walk_mut(custom_walk); + walker.find(|v| v == &predicate) +} + +fn find_walk_mut<'a, V: TreeVariant>( + tree: &'a mut Tree, + predicate: &V::Item, +) -> Option<&'a mut V::Item> +where + V::Item: Eq + Sync + Send, +{ + let mut root = tree.get_root_mut()?; + let mut walker = root.walk_mut::(); + walker.find(|v| v == &predicate) +} + +fn find_leaves_mut<'a, V: TreeVariant>( + tree: &'a mut Tree, + predicate: &V::Item, +) -> Option<&'a mut V::Item> +where + V::Item: Eq + Sync + Send, +{ + let mut root = tree.get_root_mut()?; + root.leaves_mut::().find(|v| v == &predicate) +} + +fn find_leaves_mut_with<'a, V: TreeVariant>( + tree: &'a mut Tree, + predicate: &V::Item, +) -> Option<&'a mut V::Item> +where + V::Item: Eq + Sync + Send, +{ + let mut traverser = Dfs::::new(); + let mut root = tree.get_root_mut()?; + root.leaves_mut_with(&mut traverser) + .find(|v| v == &predicate) +} + +#[test] +fn node_ref_lifetime_tests() { + let mut tree = DynTree::new(42); + + assert_eq!(find_ancestors(&tree, &7), None); + assert_eq!(find_children(&tree, &7), None); + assert_eq!(find_custom_walk(&tree, &7), None); + assert_eq!(find_walk(&tree, &7), None); + assert_eq!(find_walk_with(&tree, &7), None); + assert_eq!(find_paths(&tree, &7), None); + assert_eq!(find_paths_with(&tree, &7), None); + assert_eq!(find_leaves(&tree, &7), None); + assert_eq!(find_leaves_with(&tree, &7), None); + assert_eq!(find_indices(&tree, &7), None); + assert_eq!(find_indices_with(&tree, &7), None); + #[cfg(feature = "parallel")] + { + assert_eq!(find_ancestors_par(&tree, &7), None); + assert_eq!(find_children_par(&tree, &7), None); + assert_eq!(find_custom_walk_par(&tree, &7), None); + assert_eq!(find_walk_par(&tree, &7), None); + assert_eq!(find_walk_with_par(&tree, &7), None); + assert_eq!(find_paths_par(&tree, &7), None); + assert_eq!(find_paths_with_par(&tree, &7), None); + assert_eq!(find_leaves_par(&tree, &7), None); + assert_eq!(find_leaves_with_par(&tree, &7), None); + } + + assert_eq!(find_custom_walk_mut(&mut tree, &7), None); + assert_eq!(find_walk_mut(&mut tree, &7), None); + assert_eq!(find_leaves_mut(&mut tree, &7), None); + assert_eq!(find_leaves_mut_with(&mut tree, &7), None); +}