From b67457854ffae8ed2db8e73db7481382985024f3 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 19:59:15 +0100 Subject: [PATCH 01/16] revise new NodePtr unsafe api --- Cargo.toml | 2 +- src/iter/doubly_iter_mut.rs | 5 +++-- src/iter/doubly_iter_owned.rs | 5 +++-- src/iter/singly_iter_mut.rs | 3 ++- src/iter/singly_iter_owned.rs | 3 ++- src/memory/doubly_reclaimer.rs | 8 ++++++-- src/memory/singly_reclaimer.rs | 8 ++++++-- src/pointers/doubly_ptr.rs | 6 +++--- src/pointers/singly_ptr.rs | 6 +++--- 9 files changed, 29 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 409dbaa..3e8528d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ orx-pinned-vec = { version = "3.21.0", default-features = false } orx-fixed-vec = { version = "3.22.0", default-features = false } orx-split-vec = { version = "3.22.0", default-features = false } orx-concurrent-iter = { version = "3.1.0", default-features = false } -orx-selfref-col = { version = "2.14.0", default-features = false } +orx-selfref-col = { path = "../orx-selfref-col", default-features = false } orx-parallel = { version = "3.3.0", default-features = false, optional = true } [dev-dependencies] diff --git a/src/iter/doubly_iter_mut.rs b/src/iter/doubly_iter_mut.rs index 244e3ea..a7a2300 100644 --- a/src/iter/doubly_iter_mut.rs +++ b/src/iter/doubly_iter_mut.rs @@ -55,7 +55,7 @@ where fn next(&mut self) -> Option { match &self.current { Some(p) => { - let ptr = p.ptr_mut(); + let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { false => self.current = self.col.node(p).next().get().cloned(), true => self.end(), @@ -75,7 +75,8 @@ where fn next_back(&mut self) -> Option { match &self.current_back { Some(p) => { - let ptr = p.ptr_mut(); + // SAFETY: collection as alive as guaranteed by the `col` field. + let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { false => self.current_back = self.col.node(p).prev().get().cloned(), true => self.end(), diff --git a/src/iter/doubly_iter_owned.rs b/src/iter/doubly_iter_owned.rs index c3e899e..dba5900 100644 --- a/src/iter/doubly_iter_owned.rs +++ b/src/iter/doubly_iter_owned.rs @@ -44,7 +44,7 @@ where fn next(&mut self) -> Option { match &self.current { Some(p) => { - let ptr = p.ptr_mut(); + let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { false => self.current = self.col.node(p).next().get().cloned(), true => self.end(), @@ -64,7 +64,8 @@ where fn next_back(&mut self) -> Option { match &self.current_back { Some(p) => { - let ptr = p.ptr_mut(); + // SAFETY: collection as alive as guaranteed by the `col` field. + let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { false => self.current_back = self.col.node(p).prev().get().cloned(), true => self.end(), diff --git a/src/iter/singly_iter_mut.rs b/src/iter/singly_iter_mut.rs index ae7aa97..6c6356f 100644 --- a/src/iter/singly_iter_mut.rs +++ b/src/iter/singly_iter_mut.rs @@ -40,7 +40,8 @@ where fn next(&mut self) -> Option { match &self.current { Some(p) => { - let ptr = p.ptr_mut(); + // SAFETY: collection as alive as guaranteed by the `col` field. + let ptr = unsafe { p.ptr_mut() }; self.current = self.col.node(p).next().get().cloned(); unsafe { &mut *ptr }.data_mut() } diff --git a/src/iter/singly_iter_owned.rs b/src/iter/singly_iter_owned.rs index d8dcd37..691dbf0 100644 --- a/src/iter/singly_iter_owned.rs +++ b/src/iter/singly_iter_owned.rs @@ -33,7 +33,8 @@ where fn next(&mut self) -> Option { match &self.current { Some(p) => { - let ptr = p.ptr_mut(); + // SAFETY: collection as alive as guaranteed by the `col` field. + let ptr = unsafe { p.ptr_mut() }; self.current = self.col.node(p).next().get().cloned(); unsafe { &mut *ptr }.take_data() } diff --git a/src/memory/doubly_reclaimer.rs b/src/memory/doubly_reclaimer.rs index e404222..f32c31f 100644 --- a/src/memory/doubly_reclaimer.rs +++ b/src/memory/doubly_reclaimer.rs @@ -77,11 +77,15 @@ fn swap( &mut *(occupied as *mut Node>) }); - if occupied == col.ends().get(FRONT_IDX).expect("nonempty list").ptr() { + // SAFETY: we have a mutual &mut reference to the underlying collection + // which is guaranteed to be in the same memory state as occupied + if occupied == unsafe { col.ends().get(FRONT_IDX).expect("nonempty list").ptr() } { col.ends_mut().set(FRONT_IDX, node_ptr(vacant)); } - if occupied == col.ends().get(BACK_IDX).expect("nonempty list").ptr() { + // SAFETY: we have a mutual &mut reference to the underlying collection + // which is guaranteed to be in the same memory state as occupied + if occupied == unsafe { col.ends().get(BACK_IDX).expect("nonempty list").ptr() } { col.ends_mut().set(BACK_IDX, node_ptr(vacant)); } } diff --git a/src/memory/singly_reclaimer.rs b/src/memory/singly_reclaimer.rs index 1fb0eec..8eeb283 100644 --- a/src/memory/singly_reclaimer.rs +++ b/src/memory/singly_reclaimer.rs @@ -30,10 +30,14 @@ impl MemoryReclaimer> for SinglyReclaimer { match swapped { true => { nodes_moved = true; - swap(col, vacant_ptr, occupied_ptr.ptr(), prev); + // SAFETY: we have a mutual &mut reference to the underlying collection + // which is guaranteed to be in the same memory state as occupied + swap(col, vacant_ptr, unsafe { occupied_ptr.ptr() }, prev); prev = vacant_ptr; } - false => prev = occupied_ptr.ptr(), + // SAFETY: we have a mutual &mut reference to the underlying collection + // which is guaranteed to be in the same memory state as occupied + false => prev = unsafe { occupied_ptr.ptr() }, } match next { diff --git a/src/pointers/doubly_ptr.rs b/src/pointers/doubly_ptr.rs index f2579fc..b71d643 100644 --- a/src/pointers/doubly_ptr.rs +++ b/src/pointers/doubly_ptr.rs @@ -6,15 +6,15 @@ pub type DoublyPtr = NodePtr>; impl DoublyPointer for DoublyPtr { #[inline(always)] - fn raw_ptr(&self) -> *mut Node> { - self.ptr() as *mut Node> + unsafe fn raw_ptr(&self) -> *mut Node> { + unsafe { self.ptr() as *mut Node> } } } /// A node pointer in a doubly linked list. pub trait DoublyPointer { /// Returns the raw pointer to the node. - fn raw_ptr(&self) -> *mut Node>; + unsafe fn raw_ptr(&self) -> *mut Node>; /// Returns a reference to the node. /// diff --git a/src/pointers/singly_ptr.rs b/src/pointers/singly_ptr.rs index f2be2cf..a7bc474 100644 --- a/src/pointers/singly_ptr.rs +++ b/src/pointers/singly_ptr.rs @@ -6,15 +6,15 @@ pub type SinglyPtr = NodePtr>; impl SinglyPointer for SinglyPtr { #[inline(always)] - fn raw_ptr(&self) -> *mut Node> { - self.ptr() as *mut Node> + unsafe fn raw_ptr(&self) -> *mut Node> { + unsafe { self.ptr() as *mut Node> } } } /// A node pointer in a Singly linked list. pub trait SinglyPointer { /// Returns the raw pointer to the node. - fn raw_ptr(&self) -> *mut Node>; + unsafe fn raw_ptr(&self) -> *mut Node>; /// Returns a reference to the node. /// From 099a2b92d5b72da12df613ed6a35eda9679fbe34 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 20:29:31 +0100 Subject: [PATCH 02/16] revise code for copy implementation of NodeIdx --- src/list/common_traits/index.rs | 40 ++++++++++----------- src/list/ends_traits/doubly_ends.rs | 20 +++++------ src/list/ends_traits/doubly_ends_mut.rs | 34 +++++++++--------- src/list/ends_traits/singly_ends.rs | 14 ++++---- src/list/ends_traits/singly_ends_mut.rs | 8 ++--- src/list/get_doubly.rs | 5 ++- src/list/helper_traits/doubly_ends.rs | 39 ++++++++------------ src/list/idx_doubly.rs | 12 +++---- src/list/iter_traits/doubly_iterable.rs | 8 ++--- src/list/iter_traits/doubly_iterable_mut.rs | 6 ++-- src/list/iter_traits/singly_iterable.rs | 2 +- src/list/iter_traits/singly_iterable_mut.rs | 2 +- src/list/mut_doubly.rs | 5 ++- 13 files changed, 92 insertions(+), 103 deletions(-) diff --git a/src/list/common_traits/index.rs b/src/list/common_traits/index.rs index 4bd246e..0288e9b 100644 --- a/src/list/common_traits/index.rs +++ b/src/list/common_traits/index.rs @@ -8,7 +8,7 @@ use orx_selfref_col::{MemoryPolicy, Node}; // doubly -impl<'i, T, M, P> Index<&'i DoublyIdx> for List, M, P> +impl Index> for List, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -22,12 +22,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index(&self, index: &'i DoublyIdx) -> &Self::Output { + fn index(&self, index: DoublyIdx) -> &Self::Output { self.get(index).expect(OOB) } } -impl<'i, T, M, P> Index<&'i DoublyIdx> for ListSlice<'_, Doubly, M, P> +impl Index> for ListSlice<'_, Doubly, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -41,12 +41,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index(&self, index: &'i DoublyIdx) -> &Self::Output { + fn index(&self, index: DoublyIdx) -> &Self::Output { self.get(index).expect(OOB) } } -impl<'i, T, M, P> Index<&'i DoublyIdx> for ListSliceMut<'_, Doubly, M, P> +impl Index> for ListSliceMut<'_, Doubly, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -60,12 +60,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index(&self, index: &'i DoublyIdx) -> &Self::Output { + fn index(&self, index: DoublyIdx) -> &Self::Output { self.get(index).expect(OOB) } } -impl<'i, T, M, P> IndexMut<&'i DoublyIdx> for List, M, P> +impl<'i, T, M, P> IndexMut> for List, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -77,12 +77,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index_mut(&mut self, index: &'i DoublyIdx) -> &mut Self::Output { + fn index_mut(&mut self, index: DoublyIdx) -> &mut Self::Output { self.get_mut(index).expect(OOB) } } -impl<'i, T, M, P> IndexMut<&'i DoublyIdx> for ListSliceMut<'_, Doubly, M, P> +impl IndexMut> for ListSliceMut<'_, Doubly, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -94,14 +94,14 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index_mut(&mut self, index: &'i DoublyIdx) -> &mut Self::Output { + fn index_mut(&mut self, index: DoublyIdx) -> &mut Self::Output { self.get_mut(index).expect(OOB) } } // singly -impl<'i, T, M, P> Index<&'i SinglyIdx> for List, M, P> +impl Index> for List, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -115,12 +115,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index(&self, index: &'i SinglyIdx) -> &Self::Output { + fn index(&self, index: SinglyIdx) -> &Self::Output { self.get(index).expect(OOB) } } -impl<'i, T, M, P> Index<&'i SinglyIdx> for ListSlice<'_, Singly, M, P> +impl Index> for ListSlice<'_, Singly, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -134,12 +134,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index(&self, index: &'i SinglyIdx) -> &Self::Output { + fn index(&self, index: SinglyIdx) -> &Self::Output { self.get(index).expect(OOB) } } -impl<'i, T, M, P> Index<&'i SinglyIdx> for ListSliceMut<'_, Singly, M, P> +impl Index> for ListSliceMut<'_, Singly, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -153,12 +153,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index(&self, index: &'i SinglyIdx) -> &Self::Output { + fn index(&self, index: SinglyIdx) -> &Self::Output { self.get(index).expect(OOB) } } -impl<'i, T, M, P> IndexMut<&'i SinglyIdx> for List, M, P> +impl IndexMut> for List, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -170,12 +170,12 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index_mut(&mut self, index: &'i SinglyIdx) -> &mut Self::Output { + fn index_mut(&mut self, index: SinglyIdx) -> &mut Self::Output { self.get_mut(index).expect(OOB) } } -impl<'i, T, M, P> IndexMut<&'i SinglyIdx> for ListSliceMut<'_, Singly, M, P> +impl IndexMut> for ListSliceMut<'_, Singly, M, P> where M: MemoryPolicy>, P: PinnedVec>>, @@ -187,7 +187,7 @@ where /// Panics if the `index` is invalid; i.e., /// * `list.is_valid(index)` returns false, equivalently, /// * `list.idx_err(index)` returns the detail of the error. - fn index_mut(&mut self, index: &'i SinglyIdx) -> &mut Self::Output { + fn index_mut(&mut self, index: SinglyIdx) -> &mut Self::Output { self.get_mut(index).expect(OOB) } } diff --git a/src/list/ends_traits/doubly_ends.rs b/src/list/ends_traits/doubly_ends.rs index cb0ba4e..0363da8 100644 --- a/src/list/ends_traits/doubly_ends.rs +++ b/src/list/ends_traits/doubly_ends.rs @@ -177,7 +177,7 @@ where /// assert_eq!(list.idx_err(&idx), None); /// // assert_eq!(list.idx_err(&other_idx), Some(NodeIdxError::OutOfBounds)); /// ``` - fn idx_err(&self, idx: &DoublyIdx) -> Option { + fn idx_err(&self, idx: DoublyIdx) -> Option { self.col().try_get_ptr(idx).err() } @@ -268,7 +268,7 @@ where /// assert_eq!(list.is_valid(&idx), true); /// // assert_eq!(list.is_valid(&other_idx), false); /// ``` - fn is_valid(&self, idx: &DoublyIdx) -> bool { + fn is_valid(&self, idx: DoublyIdx) -> bool { self.col().try_get_ptr(idx).is_ok() } @@ -373,7 +373,7 @@ where /// assert_eq!(list.get(&idx), Some(&'a')); /// // assert_eq!(list.get(&other_idx), None); /// ``` - fn get<'a>(&'a self, idx: &DoublyIdx) -> Option<&'a T> + fn get<'a>(&'a self, idx: DoublyIdx) -> Option<&'a T> where M: 'a, P: 'a, @@ -484,7 +484,7 @@ where /// assert_eq!(list.try_get(&idx), Ok(&'a')); /// // assert_eq!(list.try_get(&other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` - fn try_get<'a>(&'a self, idx: &DoublyIdx) -> Result<&'a T, NodeIdxError> + fn try_get<'a>(&'a self, idx: DoublyIdx) -> Result<&'a T, NodeIdxError> where M: 'a, P: 'a, @@ -526,7 +526,7 @@ where /// /// assert!(list.next_idx_of(&d).is_none()); /// ``` - fn next_idx_of(&self, idx: &DoublyIdx) -> Option> { + fn next_idx_of(&self, idx: DoublyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); let next_ptr = self.col().node(&ptr).next().get(); next_ptr.map(|p| DoublyIdx::new(self.col().memory_state(), p)) @@ -556,12 +556,12 @@ where /// let c = list.next_idx_of(&a).and_then(|b| list.next_of(&b)); /// assert_eq!(c, Some(&'c')); /// ``` - fn next_of<'a>(&'a self, idx: &DoublyIdx) -> Option<&'a T> + fn next_of<'a>(&'a self, idx: DoublyIdx) -> Option<&'a T> where M: 'a, P: 'a, { - self.next_idx_of(idx).and_then(|i| self.get(&i)) + self.next_idx_of(idx).and_then(|i| self.get(i)) } /// ***O(1)*** Returns the index of the element preceding the one with the given `idx`. @@ -593,7 +593,7 @@ where /// /// assert!(list.prev_idx_of(&a).is_none()); /// ``` - fn prev_idx_of(&self, idx: &DoublyIdx) -> Option> { + fn prev_idx_of(&self, idx: DoublyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); let prev_ptr = self.col().node(&ptr).prev().get(); prev_ptr.map(|p| DoublyIdx::new(self.col().memory_state(), p)) @@ -623,12 +623,12 @@ where /// let a = list.prev_idx_of(&c).and_then(|b| list.prev_of(&b)); /// assert_eq!(a, Some(&'a')); /// ``` - fn prev_of<'a>(&'a self, idx: &DoublyIdx) -> Option<&'a T> + fn prev_of<'a>(&'a self, idx: DoublyIdx) -> Option<&'a T> where M: 'a, P: 'a, { - self.prev_idx_of(idx).and_then(|i| self.get(&i)) + self.prev_idx_of(idx).and_then(|i| self.get(i)) } } diff --git a/src/list/ends_traits/doubly_ends_mut.rs b/src/list/ends_traits/doubly_ends_mut.rs index 6046181..3a2c226 100644 --- a/src/list/ends_traits/doubly_ends_mut.rs +++ b/src/list/ends_traits/doubly_ends_mut.rs @@ -179,7 +179,7 @@ where /// assert!(list.get_mut(&idx).is_some()); /// // assert_eq!(list.get_mut(&other_idx), None); /// ``` - fn get_mut<'a>(&'a mut self, idx: &DoublyIdx) -> Option<&'a mut T> + fn get_mut<'a>(&'a mut self, idx: DoublyIdx) -> Option<&'a mut T> where M: 'a, P: 'a, @@ -296,7 +296,7 @@ where /// assert!(list.try_get_mut(&idx).is_ok()); /// // assert_eq!(list.try_get_mut(&other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` - fn try_get_mut<'a>(&'a mut self, idx: &DoublyIdx) -> Result<&'a mut T, NodeIdxError> + fn try_get_mut<'a>(&'a mut self, idx: DoublyIdx) -> Result<&'a mut T, NodeIdxError> where M: 'a, P: 'a, @@ -335,12 +335,12 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'd'])); /// ``` - fn next_mut_of<'a>(&'a mut self, idx: &DoublyIdx) -> Option<&'a mut T> + fn next_mut_of<'a>(&'a mut self, idx: DoublyIdx) -> Option<&'a mut T> where M: 'a, P: 'a, { - self.next_idx_of(idx).and_then(|i| self.get_mut(&i)) + self.next_idx_of(idx).and_then(|i| self.get_mut(i)) } /// ***O(1)*** Returns a mutable reference to the element preceding the one with the given `idx`. @@ -369,12 +369,12 @@ where /// /// assert!(list.eq_to_iter_vals(['x', 'b', 'c', 'd'])); /// ``` - fn prev_mut_of<'a>(&'a mut self, idx: &DoublyIdx) -> Option<&'a mut T> + fn prev_mut_of<'a>(&'a mut self, idx: DoublyIdx) -> Option<&'a mut T> where M: 'a, P: 'a, { - self.prev_idx_of(idx).and_then(|i| self.get_mut(&i)) + self.prev_idx_of(idx).and_then(|i| self.get_mut(i)) } /// ***O(n)*** Reverses the list (in-place). @@ -486,7 +486,7 @@ where /// list.move_next_to(&idx[3], &idx[0]); /// assert!(list.eq_to_iter_vals([0, 3, 1, 4, 5, 2])); /// ``` - fn move_next_to(&mut self, idx: &DoublyIdx, idx_target: &DoublyIdx) { + fn move_next_to(&mut self, idx: DoublyIdx, idx_target: DoublyIdx) { let mid = self.col().try_get_ptr(idx).expect(IDX_ERR); let prev = self.col().try_get_ptr(idx_target).expect(IDX_ERR); @@ -591,7 +591,7 @@ where /// list.move_prev_to(&idx[3], &idx[0]); /// assert!(list.eq_to_iter_vals([3, 0, 4, 1, 2, 5])); /// ``` - fn move_prev_to(&mut self, idx: &DoublyIdx, idx_target: &DoublyIdx) { + fn move_prev_to(&mut self, idx: DoublyIdx, idx_target: DoublyIdx) { let mid = self.col().try_get_ptr(idx).expect(IDX_ERR); let next = self.col().try_get_ptr(idx_target).expect(IDX_ERR); @@ -696,10 +696,10 @@ where /// list.move_to_front(&idx[3]); /// assert!(list.eq_to_iter_vals([3, 2, 5, 0, 1, 4])); /// ``` - fn move_to_front(&mut self, idx: &DoublyIdx) { + fn move_to_front(&mut self, idx: DoublyIdx) { let ptr = self.ends().get(FRONT_IDX).expect(OOB); let idx_target = NodeIdx::new(self.col().memory_state(), ptr); - self.move_prev_to(idx, &idx_target); + self.move_prev_to(idx, idx_target); } /// ***O(1)*** Moves the element with the given `idx` @@ -728,10 +728,10 @@ where /// list.move_to_back(&idx[2]); /// assert!(list.eq_to_iter_vals([0, 3, 5, 1, 4, 2])); /// ``` - fn move_to_back(&mut self, idx: &DoublyIdx) { + fn move_to_back(&mut self, idx: DoublyIdx) { let ptr = self.ends().get(BACK_IDX).expect(OOB); let idx_target = NodeIdx::new(self.col().memory_state(), ptr); - self.move_next_to(idx, &idx_target); + self.move_next_to(idx, idx_target); } /// ***O(1)*** Swaps the elements with indices `a` and `b`. @@ -759,7 +759,7 @@ where /// list.swap(&idx[3], &idx[5]); /// assert!(list.eq_to_iter_vals([4, 3, 2, 5, 0, 1])); /// ``` - fn swap(&mut self, idx_a: &DoublyIdx, idx_b: &DoublyIdx) { + fn swap(&mut self, idx_a: DoublyIdx, idx_b: DoublyIdx) { let a = self.col().try_get_ptr(idx_a).expect(IDX_ERR); let b = self.col().try_get_ptr(idx_b).expect(IDX_ERR); @@ -874,7 +874,7 @@ where /// This example also makes it clear that the unsafe api is very useful; /// however, it must only be used through a safe method that defines a /// proved to be legal move as a combination of unsafe moves. - unsafe fn add_link(&mut self, a: &DoublyIdx, b: &DoublyIdx) { + unsafe fn add_link(&mut self, a: DoublyIdx, b: DoublyIdx) { let a = self.col().try_get_ptr(a).expect(OOB); let b = self.col().try_get_ptr(b).expect(OOB); self.link(&a, &b); @@ -919,7 +919,7 @@ where /// This example also makes it clear that the unsafe api is very useful; /// however, it must only be used through a safe method that defines a /// proved to be legal move as a combination of unsafe moves. - unsafe fn remove_link(&mut self, a: &DoublyIdx, b: &DoublyIdx) { + unsafe fn remove_link(&mut self, a: DoublyIdx, b: DoublyIdx) { let a = self.col().try_get_ptr(a).expect(OOB); let b = self.col().try_get_ptr(b).expect(OOB); self.unlink(&a, &b); @@ -961,7 +961,7 @@ where /// This example also makes it clear that the unsafe api is very useful; /// however, it must only be used through a safe method that defines a /// proved to be legal move as a combination of unsafe moves. - unsafe fn set_front(&mut self, new_front: &DoublyIdx) { + unsafe fn set_front(&mut self, new_front: DoublyIdx) { let new_front = self.col().try_get_ptr(new_front).expect(OOB); self.col_mut().ends_mut().set_some(FRONT_IDX, new_front); } @@ -1002,7 +1002,7 @@ where /// This example also makes it clear that the unsafe api is very useful; /// however, it must only be used through a safe method that defines a /// proved to be legal move as a combination of unsafe moves. - unsafe fn set_back(&mut self, new_back: &DoublyIdx) { + unsafe fn set_back(&mut self, new_back: DoublyIdx) { let new_back = self.col().try_get_ptr(new_back).expect(OOB); self.col_mut().ends_mut().set_some(BACK_IDX, new_back); } diff --git a/src/list/ends_traits/singly_ends.rs b/src/list/ends_traits/singly_ends.rs index de82607..275bafc 100644 --- a/src/list/ends_traits/singly_ends.rs +++ b/src/list/ends_traits/singly_ends.rs @@ -140,7 +140,7 @@ where /// assert_eq!(list.idx_err(&idx), None); /// // assert_eq!(list.idx_err(&other_idx), Some(NodeIdxError::OutOfBounds)); /// ``` - fn idx_err(&self, idx: &SinglyIdx) -> Option { + fn idx_err(&self, idx: SinglyIdx) -> Option { self.col().try_get_ptr(idx).err() } @@ -231,7 +231,7 @@ where /// assert_eq!(list.is_valid(&idx), true); /// // assert_eq!(list.is_valid(&other_idx), false); /// ``` - fn is_valid(&self, idx: &SinglyIdx) -> bool { + fn is_valid(&self, idx: SinglyIdx) -> bool { self.col().try_get_ptr(idx).is_ok() } @@ -336,7 +336,7 @@ where /// assert_eq!(list.get(&idx), Some(&'a')); /// // assert_eq!(list.get(&other_idx), None); /// ``` - fn get<'a>(&'a self, idx: &SinglyIdx) -> Option<&'a T> + fn get<'a>(&'a self, idx: SinglyIdx) -> Option<&'a T> where M: 'a, P: 'a, @@ -447,7 +447,7 @@ where /// assert_eq!(list.try_get(&idx), Ok(&'a')); /// // assert_eq!(list.try_get(&other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` - fn try_get<'a>(&'a self, idx: &SinglyIdx) -> Result<&'a T, NodeIdxError> + fn try_get<'a>(&'a self, idx: SinglyIdx) -> Result<&'a T, NodeIdxError> where M: 'a, P: 'a, @@ -489,7 +489,7 @@ where /// /// assert!(list.next_idx_of(&d).is_none()); /// ``` - fn next_idx_of(&self, idx: &SinglyIdx) -> Option> { + fn next_idx_of(&self, idx: SinglyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); let next_ptr = self.col().node(&ptr).next().get(); next_ptr.map(|p| SinglyIdx::new(self.col().memory_state(), p)) @@ -519,12 +519,12 @@ where /// let c = list.next_idx_of(&a).and_then(|b| list.next_of(&b)); /// assert_eq!(c, Some(&'c')); /// ``` - fn next_of<'a>(&'a self, idx: &SinglyIdx) -> Option<&'a T> + fn next_of<'a>(&'a self, idx: SinglyIdx) -> Option<&'a T> where M: 'a, P: 'a, { - self.next_idx_of(idx).and_then(|i| self.get(&i)) + self.next_idx_of(idx).and_then(|i| self.get(i)) } } diff --git a/src/list/ends_traits/singly_ends_mut.rs b/src/list/ends_traits/singly_ends_mut.rs index c51713c..9fff43d 100644 --- a/src/list/ends_traits/singly_ends_mut.rs +++ b/src/list/ends_traits/singly_ends_mut.rs @@ -146,7 +146,7 @@ where /// assert!(list.get_mut(&idx).is_some()); /// // assert_eq!(list.get_mut(&other_idx), None); /// ``` - fn get_mut<'a>(&'a mut self, idx: &SinglyIdx) -> Option<&'a mut T> + fn get_mut<'a>(&'a mut self, idx: SinglyIdx) -> Option<&'a mut T> where M: 'a, P: 'a, @@ -263,7 +263,7 @@ where /// assert!(list.try_get_mut(&idx).is_ok()); /// // assert_eq!(list.try_get_mut(&other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` - fn try_get_mut<'a>(&'a mut self, idx: &SinglyIdx) -> Result<&'a mut T, NodeIdxError> + fn try_get_mut<'a>(&'a mut self, idx: SinglyIdx) -> Result<&'a mut T, NodeIdxError> where M: 'a, P: 'a, @@ -302,12 +302,12 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'd'])); /// ``` - fn next_mut_of<'a>(&'a mut self, idx: &SinglyIdx) -> Option<&'a mut T> + fn next_mut_of<'a>(&'a mut self, idx: SinglyIdx) -> Option<&'a mut T> where M: 'a, P: 'a, { - self.next_idx_of(idx).and_then(|i| self.get_mut(&i)) + self.next_idx_of(idx).and_then(|i| self.get_mut(i)) } } diff --git a/src/list/get_doubly.rs b/src/list/get_doubly.rs index e956bf6..902f15f 100644 --- a/src/list/get_doubly.rs +++ b/src/list/get_doubly.rs @@ -77,10 +77,9 @@ where /// let slice = list.slice(&idx[4]..&idx[1]); /// assert!(slice.eq_to_iter_vals([4, 5, 6, 7, 8, 9])); /// ``` - pub fn slice<'a, R>(&self, range: R) -> ListSlice<'_, Doubly, M> + pub fn slice(&self, range: R) -> ListSlice<'_, Doubly, M> where - R: RangeBounds<&'a DoublyIdx>, - T: 'a, + R: RangeBounds>, { let ends = self.slice_ends(range).expect("invalid indices in range"); ListSlice { col: &self.0, ends } diff --git a/src/list/helper_traits/doubly_ends.rs b/src/list/helper_traits/doubly_ends.rs index e3003e2..ffdb7d1 100644 --- a/src/list/helper_traits/doubly_ends.rs +++ b/src/list/helper_traits/doubly_ends.rs @@ -1,8 +1,6 @@ use super::{HasCol, HasColMut}; -use crate::{ - Doubly, DoublyIdx, - type_aliases::{BACK_IDX, FRONT_IDX}, -}; +use crate::type_aliases::{BACK_IDX, FRONT_IDX}; +use crate::{Doubly, DoublyIdx}; use core::ops::RangeBounds; use orx_pinned_vec::PinnedVec; use orx_selfref_col::{MemoryPolicy, Node, NodeIdxError, NodePtr, Refs, Variant}; @@ -16,60 +14,53 @@ where /// Returns a reference to the ends of the linked list. fn ends(&self) -> & as Variant>::Ends; - fn range_start<'a, R: RangeBounds<&'a DoublyIdx>>( + fn range_start>>( &self, range: &R, - ) -> Result>>, NodeIdxError> - where - T: 'a, - { + ) -> Result>>, NodeIdxError> { use core::ops::Bound::*; let begin = match range.start_bound() { Excluded(x) => { - let ptr = self.col().try_get_ptr(x)?; + let ptr = self.col().try_get_ptr(*x)?; self.col().node(&ptr).next().get().cloned() } - Included(x) => Some(self.col().try_get_ptr(x)?), + Included(x) => Some(self.col().try_get_ptr(*x)?), Unbounded => self.col().ends().get(FRONT_IDX).cloned(), }; Ok(begin) } - fn range_end<'a, R: RangeBounds<&'a DoublyIdx>>( + fn range_end>>( &self, range: &R, - front: &NodePtr>, - ) -> Result>>, NodeIdxError> - where - T: 'a, - { + front: NodePtr>, + ) -> Result>>, NodeIdxError> { use core::ops::Bound::*; let end = match range.end_bound() { Excluded(x) => { - let ptr = self.col().try_get_ptr(x)?; - match ptr == *front { + let ptr = self.col().try_get_ptr(*x)?; + match ptr == front { false => self.col().node(&ptr).prev().get().cloned(), true => None, } } - Included(x) => Some(self.col().try_get_ptr(x)?), + Included(x) => Some(self.col().try_get_ptr(*x)?), Unbounded => self.ends().get(BACK_IDX).cloned(), }; Ok(end) } - fn slice_ends<'a, R>(&self, range: R) -> Result< as Variant>::Ends, NodeIdxError> + fn slice_ends(&self, range: R) -> Result< as Variant>::Ends, NodeIdxError> where - R: RangeBounds<&'a DoublyIdx>, - T: 'a, + R: RangeBounds>, { Ok(match self.range_start(&range)? { Some(front) => { - let back = self.range_end(&range, &front)?; + let back = self.range_end(&range, front)?; match back { Some(back) => { let mut ends = as Variant>::Ends::empty(); diff --git a/src/list/idx_doubly.rs b/src/list/idx_doubly.rs index b8c94c8..71b47f8 100644 --- a/src/list/idx_doubly.rs +++ b/src/list/idx_doubly.rs @@ -38,7 +38,7 @@ where /// assert_eq!(value, 'b'); /// assert!(list.eq_to_iter_vals(['a', 'c', 'd', 'e'])); /// ``` - pub fn remove(&mut self, idx: &DoublyIdx) -> T { + pub fn remove(&mut self, idx: DoublyIdx) -> T { let idx = self.0.try_get_ptr(idx).expect(IDX_ERR); let [prev, next] = { let node = self.0.node(&idx); @@ -85,7 +85,7 @@ where /// assert_eq!(list.get(&x), Some(&'x')); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'c', 'd'])); ///``` - pub fn insert_next_to(&mut self, idx: &DoublyIdx, value: T) -> DoublyIdx { + pub fn insert_next_to(&mut self, idx: DoublyIdx, value: T) -> DoublyIdx { let prev = self.0.try_get_ptr(idx).expect(IDX_ERR); let next = self.0.node(&prev).next().get().cloned(); let idx = self.0.push(value); @@ -132,7 +132,7 @@ where /// assert_eq!(list.get(&x), Some(&'x')); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'c', 'd'])); ///``` - pub fn insert_prev_to(&mut self, idx: &DoublyIdx, value: T) -> DoublyIdx { + pub fn insert_prev_to(&mut self, idx: DoublyIdx, value: T) -> DoublyIdx { let next = self.0.try_get_ptr(idx).expect(IDX_ERR); let prev = self.0.node(&next).prev().get().cloned(); let idx = self.0.push(value); @@ -180,7 +180,7 @@ where /// let value = list.try_remove(&idx); /// assert_eq!(value, None); /// ``` - pub fn try_remove(&mut self, idx: &DoublyIdx) -> Option { + pub fn try_remove(&mut self, idx: DoublyIdx) -> Option { let can_remove = self.0.node_mut_from_idx(idx).is_some_and(|n| n.is_active()); match can_remove { true => { @@ -241,7 +241,7 @@ where ///``` pub fn try_insert_next_to( &mut self, - idx: &DoublyIdx, + idx: DoublyIdx, value: T, ) -> Result, NodeIdxError> { let prev = self.0.try_get_ptr(idx)?; @@ -297,7 +297,7 @@ where ///``` pub fn try_insert_prev_to( &mut self, - idx: &DoublyIdx, + idx: DoublyIdx, value: T, ) -> Result, NodeIdxError> { let next = self.0.try_get_ptr(idx)?; diff --git a/src/list/iter_traits/doubly_iterable.rs b/src/list/iter_traits/doubly_iterable.rs index 89d021f..c388c54 100644 --- a/src/list/iter_traits/doubly_iterable.rs +++ b/src/list/iter_traits/doubly_iterable.rs @@ -197,7 +197,7 @@ where /// ``` fn ring_iter<'a>( &'a self, - pivot_idx: &DoublyIdx, + pivot_idx: DoublyIdx, ) -> Chain, DoublyIter<'a, T, P>> where M: 'a, @@ -243,7 +243,7 @@ where /// assert_eq!(iter.next(), Some(&3)); /// assert_eq!(iter.next(), None); /// ``` - fn iter_from<'a>(&'a self, idx: &DoublyIdx) -> DoublyIter<'a, T, P> + fn iter_from<'a>(&'a self, idx: DoublyIdx) -> DoublyIter<'a, T, P> where M: 'a, { @@ -278,7 +278,7 @@ where /// assert_eq!(iter.next(), Some(&0)); /// assert_eq!(iter.next(), None); /// ``` - fn iter_backward_from<'a>(&'a self, idx: &DoublyIdx) -> Rev> + fn iter_backward_from<'a>(&'a self, idx: DoublyIdx) -> Rev> where M: 'a, { @@ -311,7 +311,7 @@ where /// /// assert_eq!(iter.next(), None); /// ``` - fn iter_links_from<'a>(&'a self, idx: &DoublyIdx) -> DoublyLinkIter<'a, T, P> + fn iter_links_from<'a>(&'a self, idx: DoublyIdx) -> DoublyLinkIter<'a, T, P> where M: 'a, { diff --git a/src/list/iter_traits/doubly_iterable_mut.rs b/src/list/iter_traits/doubly_iterable_mut.rs index f03695a..24e76bd 100644 --- a/src/list/iter_traits/doubly_iterable_mut.rs +++ b/src/list/iter_traits/doubly_iterable_mut.rs @@ -74,7 +74,7 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 12, 13])); /// ``` - fn iter_mut_from<'a>(&'a mut self, idx: &DoublyIdx) -> DoublyIterMut<'a, T, P> + fn iter_mut_from<'a>(&'a mut self, idx: DoublyIdx) -> DoublyIterMut<'a, T, P> where M: 'a, { @@ -111,7 +111,7 @@ where /// /// assert!(list.eq_to_iter_vals([10, 11, 12, 3])); /// ``` - fn iter_mut_backward_from<'a>(&'a mut self, idx: &DoublyIdx) -> Rev> + fn iter_mut_backward_from<'a>(&'a mut self, idx: DoublyIdx) -> Rev> where M: 'a, { @@ -156,7 +156,7 @@ where /// scan(list.ring_iter_mut(&idx[3])); /// assert!(list.eq_to_iter_vals([7, 8, 10, 3, 7])); /// ``` - fn ring_iter_mut<'a>(&'a mut self, pivot_idx: &DoublyIdx) -> DoublyIterMutChain<'a, T, P> + fn ring_iter_mut<'a>(&'a mut self, pivot_idx: DoublyIdx) -> DoublyIterMutChain<'a, T, P> where M: 'a, { diff --git a/src/list/iter_traits/singly_iterable.rs b/src/list/iter_traits/singly_iterable.rs index 671ba95..fadf788 100644 --- a/src/list/iter_traits/singly_iterable.rs +++ b/src/list/iter_traits/singly_iterable.rs @@ -127,7 +127,7 @@ where /// assert_eq!(iter.next(), Some(&3)); /// assert_eq!(iter.next(), None); /// ``` - fn iter_from<'a>(&'a self, idx: &SinglyIdx) -> SinglyIter<'a, T, P> + fn iter_from<'a>(&'a self, idx: SinglyIdx) -> SinglyIter<'a, T, P> where M: 'a, { diff --git a/src/list/iter_traits/singly_iterable_mut.rs b/src/list/iter_traits/singly_iterable_mut.rs index 7f02c7a..a140e02 100644 --- a/src/list/iter_traits/singly_iterable_mut.rs +++ b/src/list/iter_traits/singly_iterable_mut.rs @@ -70,7 +70,7 @@ where /// /// assert!(list.eq_to_iter_vals([0, 11, 12, 13])); /// ``` - fn iter_mut_from<'a>(&'a mut self, idx: &SinglyIdx) -> SinglyIterMut<'a, T, P> + fn iter_mut_from<'a>(&'a mut self, idx: SinglyIdx) -> SinglyIterMut<'a, T, P> where M: 'a, { diff --git a/src/list/mut_doubly.rs b/src/list/mut_doubly.rs index e597dc8..b3284dc 100644 --- a/src/list/mut_doubly.rs +++ b/src/list/mut_doubly.rs @@ -281,10 +281,9 @@ where /// let slice = list.slice_mut(&idx[4]..&idx[1]); /// assert!(slice.eq_to_iter_vals([4, 5, 6, 7, 8, 9])); /// ``` - pub fn slice_mut<'a, R>(&mut self, range: R) -> ListSliceMut<'_, Doubly, M, P> + pub fn slice_mut(&mut self, range: R) -> ListSliceMut<'_, Doubly, M, P> where - R: RangeBounds<&'a DoublyIdx>, - T: 'a, + R: RangeBounds>, { let ends = self.slice_ends(range).expect("invalid indices in range"); ListSliceMut { list: self, ends } From 1eab079f3a31aa65f38a26c8dd6fb2a804ad0a4e Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 20:34:30 +0100 Subject: [PATCH 03/16] fix tests for copy usage of node index --- tests/append.rs | 8 +++--- tests/idx_doubly.rs | 49 +++++++++++++++---------------------- tests/insert.rs | 12 ++++----- tests/iter_from.rs | 6 ++--- tests/list_move_next_to.rs | 22 ++++++++--------- tests/list_move_prev_to.rs | 20 +++++++-------- tests/list_swap.rs | 6 ++--- tests/remove.rs | 8 +++--- tests/ring_iter.rs | 22 ++++++++--------- tests/ring_iter_mut.rs | 8 +++--- tests/slice_move_next_to.rs | 48 ++++++++++++++++++------------------ tests/slice_move_prev_to.rs | 40 +++++++++++++++--------------- tests/slice_mut_doubly.rs | 2 +- tests/slice_swap.rs | 28 ++++++++++----------- 14 files changed, 135 insertions(+), 144 deletions(-) diff --git a/tests/append.rs b/tests/append.rs index d30e86c..f7e6ff5 100644 --- a/tests/append.rs +++ b/tests/append.rs @@ -23,8 +23,8 @@ fn append_front_doubly>>(mut list: List>>(mut list: List list.validate(); assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])); - assert_eq!(list.get(&a), Some(&'a')); - assert_eq!(list.get(&g), Some(&'g')); + assert_eq!(list.get(a), Some(&'a')); + assert_eq!(list.get(g), Some(&'g')); } diff --git a/tests/idx_doubly.rs b/tests/idx_doubly.rs index 67b58f2..af7e92d 100644 --- a/tests/idx_doubly.rs +++ b/tests/idx_doubly.rs @@ -11,31 +11,28 @@ fn idx_get_lazy() { let _ = list.push_back(2); assert!(list.eq_to_iter_refs(&[0, 1, 2])); - assert_eq!(list.try_get(&idx0), Ok(&0)); + assert_eq!(list.try_get(idx0), Ok(&0)); - *list.try_get_mut(&idx0).unwrap() = 42; - assert_eq!(list.try_get(&idx0), Ok(&42)); + *list.try_get_mut(idx0).unwrap() = 42; + assert_eq!(list.try_get(idx0), Ok(&42)); _ = list.pop_front(); assert!(list.eq_to_iter_refs(&[1, 2])); - assert_eq!(list.try_get(&idx0), Err(NodeIdxError::RemovedNode)); - assert_eq!(list.try_get_mut(&idx0), Err(NodeIdxError::RemovedNode)); + assert_eq!(list.try_get(idx0), Err(NodeIdxError::RemovedNode)); + assert_eq!(list.try_get_mut(idx0), Err(NodeIdxError::RemovedNode)); let idx3 = list.push_back(3); assert!(list.eq_to_iter_refs(&[1, 2, 3])); - assert_eq!(list.try_get(&idx0), Err(NodeIdxError::RemovedNode)); - assert_eq!(list.try_get(&idx3), Ok(&3)); + assert_eq!(list.try_get(idx0), Err(NodeIdxError::RemovedNode)); + assert_eq!(list.try_get(idx3), Ok(&3)); // since we use DoublyList with 'lazy-reclaim' variant, unless we call 'reclaim_closed_nodes' // * state will never change // * indices will always be valid (Active or RemovedNode) list.reclaim_closed_nodes(); - assert_eq!( - list.try_get(&idx0), - Err(NodeIdxError::ReorganizedCollection) - ); - assert_eq!(list.try_get(&idx3), Err(NodeIdxError::OutOfBounds)); + assert_eq!(list.try_get(idx0), Err(NodeIdxError::ReorganizedCollection)); + assert_eq!(list.try_get(idx3), Err(NodeIdxError::OutOfBounds)); } #[test] @@ -47,19 +44,16 @@ fn idx_get() { let _ = list.push_back(2); assert!(list.eq_to_iter_refs(&[0, 1, 2])); - assert_eq!(list.try_get(&idx0), Ok(&0)); + assert_eq!(list.try_get(idx0), Ok(&0)); - *list.try_get_mut(&idx0).unwrap() = 42; - assert_eq!(list.try_get(&idx0), Ok(&42)); + *list.try_get_mut(idx0).unwrap() = 42; + assert_eq!(list.try_get(idx0), Ok(&42)); _ = list.pop_front(); assert!(list.eq_to_iter_refs(&[1, 2])); + assert_eq!(list.try_get(idx0), Err(NodeIdxError::ReorganizedCollection)); assert_eq!( - list.try_get(&idx0), - Err(NodeIdxError::ReorganizedCollection) - ); - assert_eq!( - list.try_get_mut(&idx0), + list.try_get_mut(idx0), Err(NodeIdxError::ReorganizedCollection) ); @@ -74,20 +68,17 @@ fn idx_get() { _ = list.pop_front(); assert!(list.eq_to_iter_refs(&[1, 2, 3, 4])); - assert_eq!(list.try_get(&idx1), Ok(&1)); - assert_eq!(list.try_get(&idx4), Ok(&4)); + assert_eq!(list.try_get(idx1), Ok(&1)); + assert_eq!(list.try_get(idx4), Ok(&4)); - *list.try_get_mut(&idx1).unwrap() = 42; - assert_eq!(list.try_get(&idx1), Ok(&42)); + *list.try_get_mut(idx1).unwrap() = 42; + assert_eq!(list.try_get(idx1), Ok(&42)); assert_eq!(list.node_utilization().num_active_nodes, 4); assert_eq!(list.node_utilization().num_closed_nodes, 1); list.reclaim_closed_nodes(); - assert_eq!( - list.try_get(&idx1), - Err(NodeIdxError::ReorganizedCollection) - ); - assert_eq!(list.try_get(&idx4), Err(NodeIdxError::OutOfBounds)); + assert_eq!(list.try_get(idx1), Err(NodeIdxError::ReorganizedCollection)); + assert_eq!(list.try_get(idx4), Err(NodeIdxError::OutOfBounds)); } diff --git a/tests/insert.rs b/tests/insert.rs index 15cd35d..bced3f7 100644 --- a/tests/insert.rs +++ b/tests/insert.rs @@ -37,15 +37,15 @@ fn insert_doubly>>( _ => 4, }; let idx = match next_to { - true => list.try_insert_next_to(&indices[idx], 'f'), - false => list.try_insert_prev_to(&indices[idx], 'f'), + true => list.try_insert_next_to(indices[idx], 'f'), + false => list.try_insert_prev_to(indices[idx], 'f'), } .unwrap(); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals(vec.iter().copied())); - assert_eq!(list.get(&idx), Some(&'f')); + assert_eq!(list.get(idx), Some(&'f')); } #[test_matrix([0, 1, 2, 3, 4], [true, false])] @@ -71,14 +71,14 @@ fn insert_doubly_oob(idx: usize, next_to: bool) { 3 => 1, _ => 4, }; - let _ = list.try_remove(&indices[idx]); + let _ = list.try_remove(indices[idx]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals(vec.iter().copied())); let idx = match next_to { - true => list.try_insert_next_to(&indices[idx], 'f'), - false => list.try_insert_prev_to(&indices[idx], 'f'), + true => list.try_insert_next_to(indices[idx], 'f'), + false => list.try_insert_prev_to(indices[idx], 'f'), }; assert!(idx.is_err()); diff --git a/tests/iter_from.rs b/tests/iter_from.rs index f06d820..634ed77 100644 --- a/tests/iter_from.rs +++ b/tests/iter_from.rs @@ -14,7 +14,7 @@ fn test_singly_iter_from( .0; let vec_slice = &vec[position..]; - let mut list_slice = list.iter_from(&idx); + let mut list_slice = list.iter_from(idx); #[cfg(feature = "validation")] list.validate(); @@ -40,7 +40,7 @@ fn test_doubly_iter_from( .0; let vec_slice = &vec[position..]; - let mut list_slice = list.iter_from(&idx); + let mut list_slice = list.iter_from(idx); #[cfg(feature = "validation")] list.validate(); @@ -66,7 +66,7 @@ fn test_doubly_iter_backward_from( .0; let vec_slice = &vec[0..=position]; - let mut list_slice = list.iter_backward_from(&idx); + let mut list_slice = list.iter_backward_from(idx); #[cfg(feature = "validation")] list.validate(); diff --git a/tests/list_move_next_to.rs b/tests/list_move_next_to.rs index fac255d..159bfbb 100644 --- a/tests/list_move_next_to.rs +++ b/tests/list_move_next_to.rs @@ -11,7 +11,7 @@ fn list_move_next_to_front() { let n = 10; for i in 1..n { let (mut list, idx) = list_and_indices(n); - list.move_next_to(&idx[i], &idx[0]); + list.move_next_to(idx[i], idx[0]); let mut vec: Vec<_> = (0..n).into_iter().filter(|x| x != &i).collect(); vec.insert(1, i); @@ -27,7 +27,7 @@ fn list_move_next_to_back() { let n = 10; for i in 0..n { let (mut list, idx) = list_and_indices(n); - list.move_next_to(&idx[i], &idx[n - 1]); + list.move_next_to(idx[i], idx[n - 1]); let mut vec: Vec<_> = (0..n).into_iter().filter(|x| x != &i).collect(); vec.insert(n - 1, i); @@ -41,19 +41,19 @@ fn list_move_next_to_back() { #[test] fn list_move_next_front_prev_to_arbitrary() { let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[0], &idx[2]); + list.move_next_to(idx[0], idx[2]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([1, 2, 0, 3, 4])); let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[0], &idx[3]); + list.move_next_to(idx[0], idx[3]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([1, 2, 3, 0, 4])); let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[0], &idx[4]); + list.move_next_to(idx[0], idx[4]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([1, 2, 3, 4, 0])); @@ -62,19 +62,19 @@ fn list_move_next_front_prev_to_arbitrary() { #[test] fn list_move_next_back_prev_to_arbitrary() { let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[4], &idx[2]); + list.move_next_to(idx[4], idx[2]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 1, 2, 4, 3])); let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[4], &idx[0]); + list.move_next_to(idx[4], idx[0]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 4, 1, 2, 3])); let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[4], &idx[1]); + list.move_next_to(idx[4], idx[1]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 1, 4, 2, 3])); @@ -83,19 +83,19 @@ fn list_move_next_back_prev_to_arbitrary() { #[test] fn list_move_next_to_arbitrary() { let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[3], &idx[2]); + list.move_next_to(idx[3], idx[2]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4])); let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[3], &idx[0]); + list.move_next_to(idx[3], idx[0]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 3, 1, 2, 4])); let (mut list, idx) = list_and_indices(5); - list.move_next_to(&idx[1], &idx[3]); + list.move_next_to(idx[1], idx[3]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 2, 3, 1, 4])); diff --git a/tests/list_move_prev_to.rs b/tests/list_move_prev_to.rs index de02409..de96e07 100644 --- a/tests/list_move_prev_to.rs +++ b/tests/list_move_prev_to.rs @@ -11,7 +11,7 @@ fn list_move_prev_to_front() { let n = 10; for i in 0..n { let (mut list, idx) = list_and_indices(n); - list.move_prev_to(&idx[i], &idx[0]); + list.move_prev_to(idx[i], idx[0]); let mut vec: Vec<_> = (0..n).into_iter().filter(|x| x != &i).collect(); vec.insert(0, i); @@ -27,7 +27,7 @@ fn list_move_prev_to_back() { let n = 10; for i in 0..n { let (mut list, idx) = list_and_indices(n); - list.move_prev_to(&idx[i], &idx[n - 1]); + list.move_prev_to(idx[i], idx[n - 1]); let mut vec: Vec<_> = (0..n).into_iter().filter(|x| x != &i).collect(); match i != n - 1 { @@ -44,19 +44,19 @@ fn list_move_prev_to_back() { #[test] fn list_move_front_prev_to_arbitrary() { let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[0], &idx[2]); + list.move_prev_to(idx[0], idx[2]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([1, 0, 2, 3, 4])); let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[0], &idx[3]); + list.move_prev_to(idx[0], idx[3]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([1, 2, 0, 3, 4])); let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[0], &idx[4]); + list.move_prev_to(idx[0], idx[4]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([1, 2, 3, 0, 4])); @@ -65,19 +65,19 @@ fn list_move_front_prev_to_arbitrary() { #[test] fn list_move_back_prev_to_arbitrary() { let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[4], &idx[2]); + list.move_prev_to(idx[4], idx[2]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 1, 4, 2, 3])); let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[4], &idx[0]); + list.move_prev_to(idx[4], idx[0]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([4, 0, 1, 2, 3])); let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[4], &idx[1]); + list.move_prev_to(idx[4], idx[1]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 4, 1, 2, 3])); @@ -86,13 +86,13 @@ fn list_move_back_prev_to_arbitrary() { #[test] fn list_move_prev_to_arbitrary() { let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[3], &idx[2]); + list.move_prev_to(idx[3], idx[2]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 1, 3, 2, 4])); let (mut list, idx) = list_and_indices(5); - list.move_prev_to(&idx[1], &idx[3]); + list.move_prev_to(idx[1], idx[3]); #[cfg(feature = "validation")] list.validate(); assert!(list.eq_to_iter_vals([0, 2, 1, 3, 4])); diff --git a/tests/list_swap.rs b/tests/list_swap.rs index a83fa21..4739564 100644 --- a/tests/list_swap.rs +++ b/tests/list_swap.rs @@ -22,14 +22,14 @@ fn list_swap() { let a = r.random_range(0..list.len()); let b = r.random_range(0..list.len()); - list.swap(&idx[a], &idx[b]); + list.swap(idx[a], idx[b]); // validate #[cfg(feature = "validation")] list.validate(); - let val_a = list.get(&idx[a]).unwrap(); - let val_b = list.get(&idx[b]).unwrap(); + let val_a = list.get(idx[a]).unwrap(); + let val_b = list.get(idx[b]).unwrap(); let idx_a = control.iter().position(|x| x == val_a).unwrap(); let idx_b = control.iter().position(|x| x == val_b).unwrap(); diff --git a/tests/remove.rs b/tests/remove.rs index daf40c0..cb48bf8 100644 --- a/tests/remove.rs +++ b/tests/remove.rs @@ -17,7 +17,7 @@ fn remove_doubly>>(mut list: List, M>, let c = chars[idx]; - let idx = &indices[idx]; + let idx = indices[idx]; let removed = list.try_remove(idx); #[cfg(feature = "validation")] list.validate(); @@ -37,7 +37,7 @@ fn remove_doubly_oob>>(mut list: List, let _ = list.pop_back(); - let removed = list.try_remove(&indices[4]); + let removed = list.try_remove(indices[4]); #[cfg(feature = "validation")] list.validate(); @@ -63,10 +63,10 @@ fn remove_doubly_other_list>>(mut other: List = list.iter().collect(); for i in 0..list.len() { - let cyclic: Vec<_> = list.ring_iter(&idx[i]).collect(); + let cyclic: Vec<_> = list.ring_iter(idx[i]).collect(); assert_eq!(cyclic.len(), list.len()); for j in i..list.len() { @@ -19,7 +19,7 @@ fn ring_iter_on_list() { assert_eq!(cyclic[j + list.len() - i], values[j]); } - let mut cyclic_rev: Vec<_> = list.ring_iter(&idx[i]).rev().collect(); + let mut cyclic_rev: Vec<_> = list.ring_iter(idx[i]).rev().collect(); cyclic_rev.reverse(); assert_eq!(cyclic, cyclic_rev); } @@ -35,13 +35,13 @@ fn ring_iter_on_slice() { let idx: Vec<_> = list.indices().collect(); let n = b - a; - let slice = list.slice(&idx[a]..&idx[b]); + let slice = list.slice(idx[a]..idx[b]); let idx: Vec<_> = slice.indices().collect(); let values: Vec<_> = slice.iter().collect(); for i in 0..n { - let cyclic: Vec<_> = slice.ring_iter(&idx[i]).collect(); + let cyclic: Vec<_> = slice.ring_iter(idx[i]).collect(); assert_eq!(cyclic.len(), n); for j in i..n { @@ -51,7 +51,7 @@ fn ring_iter_on_slice() { assert_eq!(cyclic[j + n - i], values[j]); } - let mut cyclic_rev: Vec<_> = slice.ring_iter(&idx[i]).rev().collect(); + let mut cyclic_rev: Vec<_> = slice.ring_iter(idx[i]).rev().collect(); cyclic_rev.reverse(); assert_eq!(cyclic, cyclic_rev); @@ -63,23 +63,23 @@ fn ring_iter_demo() { let list: DoublyList<_> = (0..8).collect(); let idx: Vec<_> = list.indices().collect(); - let iter = list.ring_iter(&idx[2]); + let iter = list.ring_iter(idx[2]); assert_eq!(iter.copied().collect::>(), [2, 3, 4, 5, 6, 7, 0, 1]); - let iter = list.ring_iter(&idx[4]); + let iter = list.ring_iter(idx[4]); assert_eq!(iter.copied().collect::>(), [4, 5, 6, 7, 0, 1, 2, 3]); // ring iterator is also double-ended - let iter = list.ring_iter(&idx[4]).rev(); + let iter = list.ring_iter(idx[4]).rev(); assert_eq!(iter.copied().collect::>(), [3, 2, 1, 0, 7, 6, 5, 4]); // ring iterators are also available for slices - let slice = list.slice(&idx[3]..&idx[7]); + let slice = list.slice(idx[3]..idx[7]); assert!(slice.eq_to_iter_vals([3, 4, 5, 6])); - let iter = slice.ring_iter(&idx[4]); + let iter = slice.ring_iter(idx[4]); assert_eq!(iter.copied().collect::>(), [4, 5, 6, 3,]); - let iter = slice.ring_iter(&idx[6]); + let iter = slice.ring_iter(idx[6]); assert_eq!(iter.copied().collect::>(), [6, 3, 4, 5]); } diff --git a/tests/ring_iter_mut.rs b/tests/ring_iter_mut.rs index 91d4f39..f17b266 100644 --- a/tests/ring_iter_mut.rs +++ b/tests/ring_iter_mut.rs @@ -11,7 +11,7 @@ fn ring_iter_mut_on_list() { let values: Vec<_> = list.iter().cloned().collect(); for i in 0..n { - let cyclic: Vec<_> = list.ring_iter_mut(&idx[i]).map(|x| x.clone()).collect(); + let cyclic: Vec<_> = list.ring_iter_mut(idx[i]).map(|x| x.clone()).collect(); assert_eq!(cyclic.len(), n); for j in i..n { @@ -33,13 +33,13 @@ fn ring_iter_mut_on_slice() { let idx: Vec<_> = list.indices().collect(); let n = b - a; - let mut slice = list.slice_mut(&idx[a]..&idx[b]); + let mut slice = list.slice_mut(idx[a]..idx[b]); let idx: Vec<_> = slice.indices().collect(); let values: Vec<_> = slice.iter().cloned().collect(); for i in 0..n { - let cyclic: Vec<_> = slice.ring_iter_mut(&idx[i]).map(|x| x.clone()).collect(); + let cyclic: Vec<_> = slice.ring_iter_mut(idx[i]).map(|x| x.clone()).collect(); assert_eq!(cyclic.len(), n); for j in i..n { @@ -73,6 +73,6 @@ fn ring_iter_mut_demo() { // circular scan starting from a pivot point in the middle let mut list: DoublyList<_> = (0..5).collect(); let idx: Vec<_> = list.indices().collect(); - scan(list.ring_iter_mut(&idx[3])); + scan(list.ring_iter_mut(idx[3])); assert!(list.eq_to_iter_vals([7, 8, 10, 3, 7])); } diff --git a/tests/slice_move_next_to.rs b/tests/slice_move_next_to.rs index c337fbb..22acd48 100644 --- a/tests/slice_move_next_to.rs +++ b/tests/slice_move_next_to.rs @@ -13,10 +13,10 @@ fn slice_move_next_to_front() { let b = 5; for i in (a + 1)..=b { let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[i - a], &idx[0]); + slice.move_next_to(idx[i - a], idx[0]); let slice: Vec<_> = slice.iter().copied().collect(); @@ -38,10 +38,10 @@ fn slice_move_next_to_back() { let b = 5; for i in a..=b { let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[i - a], &idx[b - 1]); + slice.move_next_to(idx[i - a], idx[b - 1]); let slice: Vec<_> = slice.iter().copied().collect(); @@ -63,9 +63,9 @@ fn slice_move_next_to_front_arbitrary() { let b = 5; let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[0], &idx[2]); + slice.move_next_to(idx[0], idx[2]); assert_eq!( slice.iter().copied().collect::>(), vec![2, 3, 1, 4, 5] @@ -75,9 +75,9 @@ fn slice_move_next_to_front_arbitrary() { assert!(list.eq_to_iter_vals([0, 2, 3, 1, 4, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[0], &idx[3]); + slice.move_next_to(idx[0], idx[3]); assert_eq!( slice.iter().copied().collect::>(), vec![2, 3, 4, 1, 5] @@ -87,9 +87,9 @@ fn slice_move_next_to_front_arbitrary() { assert!(list.eq_to_iter_vals([0, 2, 3, 4, 1, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[0], &idx[4]); + slice.move_next_to(idx[0], idx[4]); assert_eq!( slice.iter().copied().collect::>(), vec![2, 3, 4, 5, 1] @@ -106,9 +106,9 @@ fn slice_move_next_to_back_arbitrary() { let b = 5; let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[4], &idx[2]); + slice.move_next_to(idx[4], idx[2]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 3, 5, 4] @@ -118,9 +118,9 @@ fn slice_move_next_to_back_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 2, 3, 5, 4, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[4], &idx[3]); + slice.move_next_to(idx[4], idx[3]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 3, 4, 5] @@ -130,9 +130,9 @@ fn slice_move_next_to_back_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[4], &idx[4]); + slice.move_next_to(idx[4], idx[4]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 3, 4, 5] @@ -142,9 +142,9 @@ fn slice_move_next_to_back_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[4], &idx[0]); + slice.move_next_to(idx[4], idx[0]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 5, 2, 3, 4] @@ -161,9 +161,9 @@ fn slice_move_next_to_arbitrary() { let b = 5; let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[3], &idx[2]); + slice.move_next_to(idx[3], idx[2]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 3, 4, 5] @@ -173,9 +173,9 @@ fn slice_move_next_to_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[3], &idx[0]); + slice.move_next_to(idx[3], idx[0]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 4, 2, 3, 5] @@ -185,9 +185,9 @@ fn slice_move_next_to_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 4, 2, 3, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_next_to(&idx[1], &idx[3]); + slice.move_next_to(idx[1], idx[3]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 3, 4, 2, 5] diff --git a/tests/slice_move_prev_to.rs b/tests/slice_move_prev_to.rs index 49ff763..72470d0 100644 --- a/tests/slice_move_prev_to.rs +++ b/tests/slice_move_prev_to.rs @@ -13,10 +13,10 @@ fn slice_move_prev_to_front() { let b = 5; for i in a..=b { let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[i - a], &idx[0]); + slice.move_prev_to(idx[i - a], idx[0]); let slice: Vec<_> = slice.iter().copied().collect(); @@ -38,10 +38,10 @@ fn slice_move_prev_to_back() { let b = 5; for i in a..=b { let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[i - a], &idx[b - 1]); + slice.move_prev_to(idx[i - a], idx[b - 1]); let slice: Vec<_> = slice.iter().copied().collect(); @@ -66,9 +66,9 @@ fn slice_move_front_prev_to_arbitrary() { let b = 5; let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[0], &idx[2]); + slice.move_prev_to(idx[0], idx[2]); assert_eq!( slice.iter().copied().collect::>(), vec![2, 1, 3, 4, 5] @@ -78,9 +78,9 @@ fn slice_move_front_prev_to_arbitrary() { assert!(list.eq_to_iter_vals([0, 2, 1, 3, 4, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[0], &idx[3]); + slice.move_prev_to(idx[0], idx[3]); assert_eq!( slice.iter().copied().collect::>(), vec![2, 3, 1, 4, 5] @@ -90,9 +90,9 @@ fn slice_move_front_prev_to_arbitrary() { assert!(list.eq_to_iter_vals([0, 2, 3, 1, 4, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[0], &idx[4]); + slice.move_prev_to(idx[0], idx[4]); assert_eq!( slice.iter().copied().collect::>(), vec![2, 3, 4, 1, 5] @@ -109,9 +109,9 @@ fn slice_move_back_prev_to_arbitrary() { let b = 5; let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[4], &idx[2]); + slice.move_prev_to(idx[4], idx[2]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 5, 3, 4] @@ -121,9 +121,9 @@ fn slice_move_back_prev_to_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 2, 5, 3, 4, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[4], &idx[3]); + slice.move_prev_to(idx[4], idx[3]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 3, 5, 4] @@ -133,9 +133,9 @@ fn slice_move_back_prev_to_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 2, 3, 5, 4, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[4], &idx[4]); + slice.move_prev_to(idx[4], idx[4]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 3, 4, 5] @@ -152,9 +152,9 @@ fn slice_move_prev_to_arbitrary() { let b = 5; let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[3], &idx[2]); + slice.move_prev_to(idx[3], idx[2]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 2, 4, 3, 5] @@ -164,9 +164,9 @@ fn slice_move_prev_to_arbitrary() { assert!(list.eq_to_iter_vals([0, 1, 2, 4, 3, 5, 6, 7, 8, 9])); let (mut list, idx) = list_and_indices(n); - let mut slice = list.slice_mut(&idx[a]..=&idx[b]); + let mut slice = list.slice_mut(idx[a]..=idx[b]); let idx: Vec<_> = slice.indices().collect(); - slice.move_prev_to(&idx[1], &idx[3]); + slice.move_prev_to(idx[1], idx[3]); assert_eq!( slice.iter().copied().collect::>(), vec![1, 3, 2, 4, 5] diff --git a/tests/slice_mut_doubly.rs b/tests/slice_mut_doubly.rs index ec58dfe..c64b72e 100644 --- a/tests/slice_mut_doubly.rs +++ b/tests/slice_mut_doubly.rs @@ -41,7 +41,7 @@ fn singleton_slice() { let indices = [a.clone(), b.clone(), c.clone()]; - for (i, x) in indices.iter().enumerate() { + for (i, x) in indices.iter().copied().enumerate() { let mut slice = list.slice_mut(x..=x); *slice.get_mut(x).unwrap() = expected[i]; } diff --git a/tests/slice_swap.rs b/tests/slice_swap.rs index 72c6176..4c9a0b4 100644 --- a/tests/slice_swap.rs +++ b/tests/slice_swap.rs @@ -5,16 +5,16 @@ fn slice_swap_with_all_idx() { let mut list: DoublyList<_> = (0..7).collect(); let all_idx: Vec<_> = list.indices().collect(); - let mut slice = list.slice_mut(&all_idx[1]..&all_idx[5]); + let mut slice = list.slice_mut(all_idx[1]..all_idx[5]); assert_eq!(slice.iter().copied().collect::>(), [1, 2, 3, 4]); - slice.swap(&all_idx[1], &all_idx[4]); + slice.swap(all_idx[1], all_idx[4]); assert_eq!(slice.iter().copied().collect::>(), [4, 2, 3, 1]); - slice.swap(&all_idx[2], &all_idx[1]); + slice.swap(all_idx[2], all_idx[1]); assert_eq!(slice.iter().copied().collect::>(), [4, 1, 3, 2]); - slice.swap(&all_idx[2], &all_idx[3]); + slice.swap(all_idx[2], all_idx[3]); assert_eq!(slice.iter().copied().collect::>(), [4, 1, 2, 3]); #[cfg(feature = "validation")] @@ -31,18 +31,18 @@ fn slice_swap_with_slice_idx() { let mut list: DoublyList<_> = (0..7).collect(); let all_idx: Vec<_> = list.indices().collect(); - let mut slice = list.slice_mut(&all_idx[1]..&all_idx[5]); + let mut slice = list.slice_mut(all_idx[1]..all_idx[5]); let idx: Vec<_> = slice.indices().collect(); assert_eq!(slice.iter().copied().collect::>(), [1, 2, 3, 4]); - slice.swap(&idx[1], &idx[3]); + slice.swap(idx[1], idx[3]); assert_eq!(slice.iter().copied().collect::>(), [1, 4, 3, 2]); - slice.swap(&idx[0], &idx[2]); + slice.swap(idx[0], idx[2]); assert_eq!(slice.iter().copied().collect::>(), [3, 4, 1, 2]); - slice.swap(&idx[3], &idx[1]); + slice.swap(idx[3], idx[1]); assert_eq!(slice.iter().copied().collect::>(), [3, 2, 1, 4]); #[cfg(feature = "validation")] @@ -64,37 +64,37 @@ fn slice_swap_with_entire_list() { [0, 1, 2, 3, 4, 5, 6] ); - slice.swap(&all_idx[1], &all_idx[4]); + slice.swap(all_idx[1], all_idx[4]); assert_eq!( slice.iter().copied().collect::>(), [0, 4, 2, 3, 1, 5, 6] ); - slice.swap(&all_idx[2], &all_idx[1]); + slice.swap(all_idx[2], all_idx[1]); assert_eq!( slice.iter().copied().collect::>(), [0, 4, 1, 3, 2, 5, 6] ); - slice.swap(&all_idx[2], &all_idx[3]); + slice.swap(all_idx[2], all_idx[3]); assert_eq!( slice.iter().copied().collect::>(), [0, 4, 1, 2, 3, 5, 6] ); - slice.swap(&all_idx[0], &all_idx[6]); + slice.swap(all_idx[0], all_idx[6]); assert_eq!( slice.iter().copied().collect::>(), [6, 4, 1, 2, 3, 5, 0] ); - slice.swap(&all_idx[4], &all_idx[6]); + slice.swap(all_idx[4], all_idx[6]); assert_eq!( slice.iter().copied().collect::>(), [4, 6, 1, 2, 3, 5, 0] ); - slice.swap(&all_idx[0], &all_idx[2]); + slice.swap(all_idx[0], all_idx[2]); assert_eq!( slice.iter().copied().collect::>(), [4, 6, 1, 0, 3, 5, 2] From eb94952a0c5dd469625ed382552b1119e9c1d31f Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 20:35:29 +0100 Subject: [PATCH 04/16] fix examples and benchmarks for copy node index --- benches/doubly_shuffling_around.rs | 6 +++--- examples/tour_mutations.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/benches/doubly_shuffling_around.rs b/benches/doubly_shuffling_around.rs index 23d066e..a0e86b5 100644 --- a/benches/doubly_shuffling_around.rs +++ b/benches/doubly_shuffling_around.rs @@ -89,9 +89,9 @@ struct TourLinkedList { impl TourLinkedList { fn insert_after(&mut self, city: usize, city_to_succeed: usize) { - let a = &self.idx[city]; - let b = &self.idx[city_to_succeed]; - self.cities.move_next_to(&a, &b); + let a = self.idx[city]; + let b = self.idx[city_to_succeed]; + self.cities.move_next_to(a, b); } fn create_tour(num_cities: usize, moves: &[(usize, usize)]) -> Self { diff --git a/examples/tour_mutations.rs b/examples/tour_mutations.rs index 0c31d6a..1161cd2 100644 --- a/examples/tour_mutations.rs +++ b/examples/tour_mutations.rs @@ -117,9 +117,9 @@ impl Debug for TourLinkedList { impl TourLinkedList { fn insert_after(&mut self, city: usize, city_to_succeed: usize) { - let a = &self.idx[city]; - let b = &self.idx[city_to_succeed]; - self.cities.move_next_to(&a, &b); + let a = self.idx[city]; + let b = self.idx[city_to_succeed]; + self.cities.move_next_to(a, b); } fn create_tour(num_cities: usize, num_moves: usize) -> Self { From b8d9b166f5927274d46ecb93a41dba13fd46e2a6 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 20:55:26 +0100 Subject: [PATCH 05/16] fixes for Copy NodeIdx --- README.md | 188 ++++++++++--------- src/list/common_traits/into.rs | 190 ++++++++++---------- src/list/ends_traits/doubly_ends.rs | 152 ++++++++-------- src/list/ends_traits/doubly_ends_mut.rs | 146 +++++++-------- src/list/ends_traits/singly_ends.rs | 140 +++++++-------- src/list/ends_traits/singly_ends_mut.rs | 74 ++++---- src/list/get_doubly.rs | 6 +- src/list/idx_doubly.rs | 32 ++-- src/list/iter_traits/doubly_iterable.rs | 26 +-- src/list/iter_traits/doubly_iterable_mut.rs | 6 +- src/list/iter_traits/singly_iterable.rs | 4 +- src/list/iter_traits/singly_iterable_mut.rs | 2 +- src/list/linear_eq.rs | 48 ++--- src/list/mut_doubly.rs | 6 +- tests/reverse.rs | 10 +- tests/slice_doubly.rs | 18 +- tests/slice_iter_rev.rs | 12 +- tests/slice_wrong_direction.rs | 10 +- 18 files changed, 543 insertions(+), 527 deletions(-) diff --git a/README.md b/README.md index 260c5c4..169dc08 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,11 @@ A linked list implementation with unique features and an extended list of constant time methods providing high performance traversals and mutations. Both doubly and singly lists are provided as generic variants of the core struct `List`. It is sufficient to know the four variants: -* [`DoublyList`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html) and [`SinglyList`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.SinglyList.html) -* [`DoublyListLazy`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyListLazy.html) and [`SinglyListLazy`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.SinglyListLazy.html) (*Lazy* suffix corresponds to lazy memory reclaim and will be explained in the indices section) -> **no-std**: This crate supports **no-std**; however, *std* is added due to the default [**orx-parallel**](https://crates.io/crates/orx-parallel) feature. Please include with **no-default-features** for no-std use cases: `cargo add orx-linked-list --no-default-features`. +- [`DoublyList`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html) and [`SinglyList`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.SinglyList.html) +- [`DoublyListLazy`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyListLazy.html) and [`SinglyListLazy`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.SinglyListLazy.html) (_Lazy_ suffix corresponds to lazy memory reclaim and will be explained in the indices section) + +> **no-std**: This crate supports **no-std**; however, _std_ is added due to the default [**orx-parallel**](https://crates.io/crates/orx-parallel) feature. Please include with **no-default-features** for no-std use cases: `cargo add orx-linked-list --no-default-features`. ## Efficiency @@ -22,6 +23,7 @@ We observe in benchmarks that `DoublyList` is significantly faster than the stan A. Benchmark & Example: Mutation At Ends In [doubly_mutation_ends.rs](https://github.com/orxfun/orx-linked-list/blob/main/benches/doubly_mutation_ends.rs) benchmark, we first push elements to a linked list until it reaches a particular length. Then, we call + - `push_back` - `push_front` - `pop_back` @@ -79,24 +81,24 @@ Sequential computation over DoublyList : 11.78s Parallelized over DoublyList using orx_parallel : 2.93s ``` -*The suffix "_x" indicates that the iterators yield elements in arbitrary order, rather than from front to back. Parallelization of all iterations defined in the next section is in progress.* +_The suffix "\_x" indicates that the iterators yield elements in arbitrary order, rather than from front to back. Parallelization of all iterations defined in the next section is in progress._ ## Iterations Linked lists are all about traversal. Therefore, the linked lists defined in this crate, especially the **DoublyList**, provide various useful ways to iterate over the data: -| | | -|------------|------------| -| [`iter()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter) | from front to back of the list | -| `iter().rev()` | from back to front | -| [`iter_from(idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_from) | forward starting from the node with the given index to the back | -| [`iter_backward_from(idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_backward_from) | backward starting from the node with the given index to the front | -| [`ring_iter(pivot_idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.ring_iter) | forward starting from the pivot node with the given index until the node before the pivot node, linking back to the front and giving the list the **circular behavior** | -| [`iter_links()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_links) | forward over the links, rather than nodes, from front to back | -| [`iter_x()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.iter_x) | over elements in an arbitrary order, which is often faster when the order is not required | -||| +| | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`iter()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter) | from front to back of the list | +| `iter().rev()` | from back to front | +| [`iter_from(idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_from) | forward starting from the node with the given index to the back | +| [`iter_backward_from(idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_backward_from) | backward starting from the node with the given index to the front | +| [`ring_iter(pivot_idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.ring_iter) | forward starting from the pivot node with the given index until the node before the pivot node, linking back to the front and giving the list the **circular behavior** | +| [`iter_links()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_links) | forward over the links, rather than nodes, from front to back | +| [`iter_x()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.iter_x) | over elements in an arbitrary order, which is often faster when the order is not required | +| | | -As typical, above-mentioned methods have the "_mut" suffixed versions for iterating over mutable references. +As typical, above-mentioned methods have the "\_mut" suffixed versions for iterating over mutable references.
Example: Iterations or Traversals @@ -121,19 +123,20 @@ assert_eq!(res, [0, 1, 2, 3, 4, 5]); // deterministic but arbitrary order // using indices (see the indices section for details) let idx: Vec<_> = list.indices().collect(); -let res = list.iter_from(&idx[3]).copied().collect::>(); +let res = list.iter_from(idx[3]).copied().collect::>(); assert_eq!(res, [3, 4, 5]); let res = list - .iter_backward_from(&idx[3]) + .iter_backward_from(idx[3]) .copied() .collect::>(); assert_eq!(res, [3, 2, 1, 0]); -let res = list.ring_iter(&idx[3]).copied().collect::>(); +let res = list.ring_iter(idx[3]).copied().collect::>(); assert_eq!(res, [3, 4, 5, 0, 1, 2]); ``` +
## Zero-Cost Append or Merge @@ -158,19 +161,21 @@ let other = DoublyList::from_iter(['d', 'e'].into_iter()); list.append_front(other); assert!(list.eq_to_iter_vals(['d', 'e', 'a', 'b', 'c'])); ``` - + ## Node Indices [`DoublyIdx`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyIdx.html) and [`SinglyIdx`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.SinglyIdx.html) are the node indices for doubly and singly linked lists, respectively. A node index is analogous to **usize for a slice** (`&[T]`) in the following: -* It provides constant time access to any element in the list. + +- It provides constant time access to any element in the list. It differs from **usize for a slice** due to the following: -* `usize` represents a position of the slice. Say we have the slice `['a', 'b', 'c']`. Currently, index **0** points to element `a`. However, if we swap the first and third elements, index **0** will now be pointing to `c` because the `usize` represents a position on the slice. -* A node index represents the element it is created for. Say we now have a list `['a', 'b', 'c']` instead and `idx_a` is the index of the first element. It will always be pointing to this element no matter how many times we change its position, its value, etc. + +- `usize` represents a position of the slice. Say we have the slice `['a', 'b', 'c']`. Currently, index **0** points to element `a`. However, if we swap the first and third elements, index **0** will now be pointing to `c` because the `usize` represents a position on the slice. +- A node index represents the element it is created for. Say we now have a list `['a', 'b', 'c']` instead and `idx_a` is the index of the first element. It will always be pointing to this element no matter how many times we change its position, its value, etc. Knowing the index of an element enables a large number of constant time operations. Below is a toy example to demonstrate how the index represents an element rather than a position, and illustrates some of the possible O(1) methods using it. @@ -189,48 +194,49 @@ let idx_d = list.push_back('d'); assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); // O(1) access / mutate its value -assert_eq!(list.get(&idx), Some(&'a')); -*list.get_mut(&idx).unwrap() = 'o'; -list[&idx] = 'X'; -assert_eq!(list[&idx], 'X'); +assert_eq!(list.get(idx), Some(&'a')); +*list.get_mut(idx).unwrap() = 'o'; +list[idx] = 'X'; +assert_eq!(list[idx], 'X'); assert!(list.eq_to_iter_vals(['X', 'b', 'c', 'd'])); // O(1) move it around -list.move_to_back(&idx); +list.move_to_back(idx); assert!(list.eq_to_iter_vals(['b', 'c', 'd', 'X'])); -list.move_prev_to(&idx, &idx_d); +list.move_prev_to(idx, idx_d); assert!(list.eq_to_iter_vals(['b', 'c', 'X', 'd'])); // O(1) start iterators from it -let res = list.iter_from(&idx).copied().collect::>(); +let res = list.iter_from(idx).copied().collect::>(); assert_eq!(res, ['X', 'd']); -let res = list.iter_backward_from(&idx).copied().collect::>(); +let res = list.iter_backward_from(idx).copied().collect::>(); assert_eq!(res, ['X', 'c', 'b']); -let res = list.ring_iter(&idx).copied().collect::>(); +let res = list.ring_iter(idx).copied().collect::>(); assert_eq!(res, ['X', 'd', 'b', 'c']); // O(1) insert elements relative to it -list.insert_prev_to(&idx, '>'); -list.insert_next_to(&idx, '<'); +list.insert_prev_to(idx, '>'); +list.insert_next_to(idx, '<'); assert!(list.eq_to_iter_vals(['b', 'c', '>', 'X', '<', 'd'])); // O(1) remove it -let x = list.remove(&idx); +let x = list.remove(idx); assert_eq!(x, 'X'); assert!(list.eq_to_iter_vals(['b', 'c', '>', '<', 'd'])); // what happens to the index if the element is removed? -assert_eq!(list.get(&idx), None); // `get` safely returns None +assert_eq!(list.get(idx), None); // `get` safely returns None // O(1) we can query its state -assert_eq!(list.is_valid(&idx), false); -assert_eq!(list.idx_err(&idx), Some(NodeIdxError::RemovedNode)); +assert_eq!(list.is_valid(idx), false); +assert_eq!(list.idx_err(idx), Some(NodeIdxError::RemovedNode)); -// list[&idx] = 'Y'; // panics! +// list[idx] = 'Y'; // panics! ``` + ### How to get Node Indices @@ -247,11 +253,11 @@ let mut list = DoublyList::new(); let c = list.push_back('c'); let b = list.push_front('b'); -let a = list.insert_prev_to(&b, 'a'); -let d = list.insert_next_to(&c, 'd'); +let a = list.insert_prev_to(b, 'a'); +let d = list.insert_next_to(c, 'd'); assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); -let values = [list[&a], list[&b], list[&c], list[&d]]; +let values = [list[a], list[b], list[c], list[d]]; assert_eq!(values, ['a', 'b', 'c', 'd']); ``` @@ -275,9 +281,9 @@ assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); let idx: Vec<_> = list.indices().collect(); -assert_eq!(list[&idx[2]], 'c'); -assert_eq!(list.remove(&idx[1]), 'b'); -assert_eq!(list.remove(&idx[3]), 'd'); +assert_eq!(list[idx[2]], 'c'); +assert_eq!(list.remove(idx[1]), 'b'); +assert_eq!(list.remove(idx[3]), 'd'); assert!(list.eq_to_iter_vals(['a', 'c'])); ``` @@ -287,13 +293,14 @@ assert!(list.eq_to_iter_vals(['a', 'c'])); ### Constant Time Methods Traditionally, linked lists provide constant time access to the ends of the list, and allows mutations pushing to and popping from the front and the back (when doubly). Using the node indices, the following methods can also be performed in **O(1)** time: -* accessing (reading or writing) a particular element ([`get`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEnds.html#method.get), [`get_mut`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.get_mut)) -* accessing (reading or writing) a the previous or next of a particular element ([`next_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEnds.html#method.next_of), [`prev_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEnds.html#method.prev_of), [`next_mut_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.next_mut_of), [`prev_mut_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.prev_mut_of)) -* starting iterators from a particular element ([`iter_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_from), [`iter_backward_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_backward_from), [`ring_iter`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.ring_iter), [`iter_mut_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterableMut.html#method.iter_mut_from), [`iter_mut_backward_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterableMut.html#method.iter_mut_backward_from), [`ring_iter_mut`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterableMut.html#method.ring_iter_mut)) -* moving an element to the ends ([`move_to_front`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_to_front), [`move_to_back`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_to_back)) -* moving an element to previous or next to another element ([`move_next_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_next_to), [`move_prev_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_prev_to)) -* inserting new elements relative to a particular element ([`insert_next_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.insert_next_to), [`insert_prev_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.insert_prev_to)) -* removing a particular element ([`remove`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.remove)) + +- accessing (reading or writing) a particular element ([`get`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEnds.html#method.get), [`get_mut`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.get_mut)) +- accessing (reading or writing) a the previous or next of a particular element ([`next_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEnds.html#method.next_of), [`prev_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEnds.html#method.prev_of), [`next_mut_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.next_mut_of), [`prev_mut_of`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.prev_mut_of)) +- starting iterators from a particular element ([`iter_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_from), [`iter_backward_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_backward_from), [`ring_iter`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.ring_iter), [`iter_mut_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterableMut.html#method.iter_mut_from), [`iter_mut_backward_from`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterableMut.html#method.iter_mut_backward_from), [`ring_iter_mut`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterableMut.html#method.ring_iter_mut)) +- moving an element to the ends ([`move_to_front`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_to_front), [`move_to_back`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_to_back)) +- moving an element to previous or next to another element ([`move_next_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_next_to), [`move_prev_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyEndsMut.html#method.move_prev_to)) +- inserting new elements relative to a particular element ([`insert_next_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.insert_next_to), [`insert_prev_to`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.insert_prev_to)) +- removing a particular element ([`remove`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.remove)) ### Slices @@ -311,7 +318,7 @@ let idx: Vec<_> = list.indices().collect(); assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5])); // slice -let slice = list.slice(&idx[1]..&idx[4]); +let slice = list.slice(idx[1]..idx[4]); assert!(slice.eq_to_iter_vals([1, 2, 3])); assert_eq!(slice.front(), Some(&1)); @@ -320,30 +327,33 @@ assert_eq!(slice.iter().copied().collect::>(), [1, 2, 3]); assert_eq!(slice.iter().rev().copied().collect::>(), [3, 2, 1]); // slice-mut -let mut slice = list.slice_mut(&idx[1]..&idx[4]); +let mut slice = list.slice_mut(idx[1]..idx[4]); for x in slice.iter_mut() { *x += 10; } assert!(slice.eq_to_iter_vals([11, 12, 13])); -slice.move_to_front(&idx[2]); +slice.move_to_front(idx[2]); assert!(slice.eq_to_iter_vals([12, 11, 13])); *slice.back_mut().unwrap() = 42; assert!(list.eq_to_iter_vals([0, 12, 11, 42, 4, 5])); ``` + ### Efficiency of Constant Time Mutations (Example) How important are the additional O(1) methods? -* In this talk [here](https://www.youtube.com/watch?v=YQs6IC-vgmo), Bjarne Stroustrup explains why we should avoid linked lists. The talk nicely summarizes the trouble of achieving the appealing constant time mutation promise of linked list. Further, additional memory requirement due to the storage of links or pointers is mentioned. -* Likewise, there exists the following note in the documentation of the `std::collections::LinkedList`: "It is almost always better to use Vec or VecDeque because array-based containers are generally faster, more memory efficient, and make better use of CPU cache." + +- In this talk [here](https://www.youtube.com/watch?v=YQs6IC-vgmo), Bjarne Stroustrup explains why we should avoid linked lists. The talk nicely summarizes the trouble of achieving the appealing constant time mutation promise of linked list. Further, additional memory requirement due to the storage of links or pointers is mentioned. +- Likewise, there exists the following note in the documentation of the `std::collections::LinkedList`: "It is almost always better to use Vec or VecDeque because array-based containers are generally faster, more memory efficient, and make better use of CPU cache." This crate aims to overcome the concerns with the following approach: -* Underlying nodes of the list are stored in fragments of contagious storages. Further, the list is self organizing to keep the nodes dense, rather than scattered in memory. Therefore, it aims to benefit from cache locality. -* Provides a safe node index support which allows us to jump to any element in constant time, and hence, be able to take benefit from mutating links, and hence the sequence, in constant time. + +- Underlying nodes of the list are stored in fragments of contagious storages. Further, the list is self organizing to keep the nodes dense, rather than scattered in memory. Therefore, it aims to benefit from cache locality. +- Provides a safe node index support which allows us to jump to any element in constant time, and hence, be able to take benefit from mutating links, and hence the sequence, in constant time. â–¶ Actually, there is no choice between a `Vec` and a linked list. They are rarely interchangeable, and when they are, Vec must be the right structure. @@ -356,9 +366,10 @@ See the example in [tour_mutations.rs](https://github.com/orxfun/orx-linked-list `cargo run --release --example tour_mutations -- --num-cities 10000 --num-moves 10000` The challenge is as follows: -* We have a tour of n cities with ids 0..n. -* We have an algorithm that searches for and yields improving moves (not included in the benchmark). -* In the data structure representing the tour, we are required to implement `fn insert_after(&mut self, city: usize, city_to_succeed: usize)` method which is required to move the *city* after the *city_to_succeed*. + +- We have a tour of n cities with ids 0..n. +- We have an algorithm that searches for and yields improving moves (not included in the benchmark). +- In the data structure representing the tour, we are required to implement `fn insert_after(&mut self, city: usize, city_to_succeed: usize)` method which is required to move the _city_ after the _city_to_succeed_. Although this seems like a primitive operation, it is challenging to implement with a standard vector. Details of an attempt can be found in the example. In brief, one way or the other, it is not clear how to avoid the O(n) time complexity of the update. @@ -380,9 +391,9 @@ struct TourLinkedList { impl TourLinkedList { fn insert_after(&mut self, city: usize, city_to_succeed: usize) { - let a = &self.idx[city]; - let b = &self.idx[city_to_succeed]; - self.cities.move_next_to(&a, &b); + let a = self.idx[city]; + let b = self.idx[city_to_succeed]; + self.cities.move_next_to(a, b); } } ``` @@ -394,27 +405,31 @@ Although clear from the worst time complexity of the implementations, [doubly_sh ### Memory & Safety As mentioned, node indices are associated with elements rather than positions. -* The linked list can provide safe access through node indices due to the fact that the underlying storage is a [`SplitVec`](https://crates.io/crates/orx-split-vec) which implements [`PinnedVec`](https://crates.io/crates/orx-pinned-vec), keeping the memory positions of its elements unchanged, unless they are explicitly changed. -* Therefore, the list is able to know if a node index is pointing to a valid memory position belonging to itself, and prevents to use a node index created from one list on another list: - * `get`, `is_valid`, `idx_err` returns None, false and `NodeIdxErr::OutOfBounds`, respectively. -* Further, when an element is removed from the list, its position is not immediately filled by other elements. Therefore, the index still points to the correct memory position and the list is able to know that the element is removed. - * `get`, `is_valid`, `idx_err` returns None, false and `NodeIdxErr::RemovedNode`, respectively. + +- The linked list can provide safe access through node indices due to the fact that the underlying storage is a [`SplitVec`](https://crates.io/crates/orx-split-vec) which implements [`PinnedVec`](https://crates.io/crates/orx-pinned-vec), keeping the memory positions of its elements unchanged, unless they are explicitly changed. +- Therefore, the list is able to know if a node index is pointing to a valid memory position belonging to itself, and prevents to use a node index created from one list on another list: + - `get`, `is_valid`, `idx_err` returns None, false and `NodeIdxErr::OutOfBounds`, respectively. +- Further, when an element is removed from the list, its position is not immediately filled by other elements. Therefore, the index still points to the correct memory position and the list is able to know that the element is removed. + - `get`, `is_valid`, `idx_err` returns None, false and `NodeIdxErr::RemovedNode`, respectively. Clearly, such a memory policy leaves gaps in the storage and utilization of memory becomes important. Therefore, the linked lists are self-organizing as follows: -* Whenever an element is removed, the utilization of nodes is checked. Node utilization is the ratio of active nodes to occupied nodes. -* Whenever the utilization falls below a certain threshold (75% by default), positions of closed nodes are reclaimed and utilization is brought back to 100%. + +- Whenever an element is removed, the utilization of nodes is checked. Node utilization is the ratio of active nodes to occupied nodes. +- Whenever the utilization falls below a certain threshold (75% by default), positions of closed nodes are reclaimed and utilization is brought back to 100%. When, a node reorganization is triggered, node indices collected beforehand become invalid. The linked lists, however, have a means to know that the node index is now invalid by comparing the so called memory states of the index and list. If we attempt to use a node index after the list is reorganized and the index is invalidated, we safely get an error: - * `get`, `is_valid`, `idx_err` returns None, false and `NodeIdxErr::ReorganizedCollection`, respectively. -*In summary, we can make sure whether or not using a node index is safe. Further, we cannot have an unchecked / unsafe access to elements that we are not supposed to.* +- `get`, `is_valid`, `idx_err` returns None, false and `NodeIdxErr::ReorganizedCollection`, respectively. + +_In summary, we can make sure whether or not using a node index is safe. Further, we cannot have an unchecked / unsafe access to elements that we are not supposed to._ It sounds inconvenient that the indices can implicitly be invalidated. The situation, however, is not complicated or unpredictable. -* First, we know that growth can never cause reorganization; only removals can trigger it. -* Second, we have the lazy versions of the lists which will never automatically reorganize nodes. Collected indices will always be valid unless we explicitly call `reclaim_closed_nodes`. -* Third, it is free to transform between auto-reclaim and lazy-reclaim modes. -*Therefore, we can have full control on the valid lifetime of our indices.* +- First, we know that growth can never cause reorganization; only removals can trigger it. +- Second, we have the lazy versions of the lists which will never automatically reorganize nodes. Collected indices will always be valid unless we explicitly call `reclaim_closed_nodes`. +- Third, it is free to transform between auto-reclaim and lazy-reclaim modes. + +_Therefore, we can have full control on the valid lifetime of our indices._
Controlling Validity of Node Indices @@ -450,12 +465,12 @@ let mut list: DoublyListLazy<_> = list.into_lazy_reclaim(); // mutate & move things around for i in 0..list.len() { match i % 3 { - 0 => list.move_to_front(&idx[i]), + 0 => list.move_to_front(idx[i]), 1 => { let j = (i + 1) % list.len(); - list.move_next_to(&idx[i], &idx[j]); + list.move_next_to(idx[i], idx[j]); } - _ => list[&idx[i]] *= 2, + _ => list[idx[i]] *= 2, } } @@ -469,10 +484,10 @@ for i in 0..(list.len() / 2) { // remove 10 more by indices -> no reorganization let mut num_removed = 0; -for idx in &idx { +for idx in idx.iter().copied() { // if not yet removed - if list.is_valid(&idx) { - list.remove(&idx); + if list.is_valid(idx) { + list.remove(idx); num_removed += 1; if num_removed == 10 { break; @@ -489,10 +504,10 @@ assert_eq!(idx.len(), 40); // * 10 of them are pointing to remaining elements // * 30 of them are pointing to gaps -let num_active = idx.iter().filter(|x| list.is_valid(x)).count(); +let num_active = idx.iter().filter(|x| list.is_valid(**x)).count(); let num_removed = idx .iter() - .filter(|x| list.idx_err(x) == Some(NodeIdxError::RemovedNode)) + .filter(|x| list.idx_err(**x) == Some(NodeIdxError::RemovedNode)) .count(); assert_eq!(num_active, 10); assert_eq!(num_removed, 30); @@ -501,7 +516,7 @@ assert_eq!(num_removed, 30); list.reclaim_closed_nodes(); // this explicitly invalidates all indices -let num_valid_indices = idx.iter().filter(|x| list.is_valid(x)).count(); +let num_valid_indices = idx.iter().filter(|x| list.is_valid(**x)).count(); assert_eq!(num_valid_indices, 0); // and brings utilization to 100% @@ -512,6 +527,7 @@ assert_eq!(utilization.num_closed_nodes, 0); // now we can switch back to the auto-reclaim mode let list = list.into_auto_reclaim(); ``` +
## Contributing diff --git a/src/list/common_traits/into.rs b/src/list/common_traits/into.rs index 9cfe844..6261216 100644 --- a/src/list/common_traits/into.rs +++ b/src/list/common_traits/into.rs @@ -81,22 +81,22 @@ where /// /// // we can still use the indices to have constant time access to nodes /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); - /// assert_eq!(list.idx_err(&c), None); - /// assert_eq!(list.idx_err(&d), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(c), None); + /// assert_eq!(list.idx_err(d), None); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), Some(&'c')); - /// assert_eq!(list.get(&d), Some(&'d')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), Some(&'c')); + /// assert_eq!(list.get(d), Some(&'d')); /// /// // make auto again /// let mut list: DoublyList<_> = list.into_auto_reclaim(); /// /// // now removals might lead to reorganization if node utilization /// // falls below a certain threshold (75% when D=2). - /// let pop = list.remove(&d); + /// let pop = list.remove(d); /// assert_eq!(pop, 'd'); /// /// // 2 removed nodes reclaimed (b, d); 2 active nodes remains (c, a) @@ -104,22 +104,22 @@ where /// assert_eq!(list.node_utilization().num_closed_nodes, 0); /// /// // node positions might have change during reorganization - /// assert_eq!(list.idx_err(&a), Some(NodeIdxError::ReorganizedCollection)); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(a), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::ReorganizedCollection)); /// // or prior position does not belong to the storage any more - /// assert_eq!(list.idx_err(&c), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&d), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(c), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(d), Some(NodeIdxError::OutOfBounds)); /// /// // indices can no longer be used to access the elements - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), None); - /// assert_eq!(list.get(&d), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), None); + /// assert_eq!(list.get(d), None); /// /// // we can recollect valid indices if necessary /// let idx: Vec<_> = list.indices().collect(); - /// assert_eq!(list.get(&idx[0]), Some(&'c')); - /// assert_eq!(list.get(&idx[1]), Some(&'a')); + /// assert_eq!(list.get(idx[0]), Some(&'c')); + /// assert_eq!(list.get(idx[1]), Some(&'a')); /// ``` pub fn into_lazy_reclaim(self) -> List { self.into() @@ -173,22 +173,22 @@ where /// /// // we can still use the indices to have constant time access to nodes /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); - /// assert_eq!(list.idx_err(&c), None); - /// assert_eq!(list.idx_err(&d), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(c), None); + /// assert_eq!(list.idx_err(d), None); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), Some(&'c')); - /// assert_eq!(list.get(&d), Some(&'d')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), Some(&'c')); + /// assert_eq!(list.get(d), Some(&'d')); /// /// // make auto again /// let mut list: DoublyList<_> = list.into_auto_reclaim(); /// /// // now removals might lead to reorganization if node utilization /// // falls below a certain threshold (75% when D=2). - /// let pop = list.remove(&d); + /// let pop = list.remove(d); /// assert_eq!(pop, 'd'); /// /// // 2 removed nodes reclaimed (b, d); 2 active nodes remains (c, a) @@ -196,22 +196,22 @@ where /// assert_eq!(list.node_utilization().num_closed_nodes, 0); /// /// // node positions might have change during reorganization - /// assert_eq!(list.idx_err(&a), Some(NodeIdxError::ReorganizedCollection)); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(a), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::ReorganizedCollection)); /// // or prior position does not belong to the storage any more - /// assert_eq!(list.idx_err(&c), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&d), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(c), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(d), Some(NodeIdxError::OutOfBounds)); /// /// // indices can no longer be used to access the elements - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), None); - /// assert_eq!(list.get(&d), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), None); + /// assert_eq!(list.get(d), None); /// /// // we can recollect valid indices if necessary /// let idx: Vec<_> = list.indices().collect(); - /// assert_eq!(list.get(&idx[0]), Some(&'c')); - /// assert_eq!(list.get(&idx[1]), Some(&'a')); + /// assert_eq!(list.get(idx[0]), Some(&'c')); + /// assert_eq!(list.get(idx[1]), Some(&'a')); /// ``` pub fn into_auto_reclaim(self) -> DoublyList { self.into() @@ -260,22 +260,22 @@ where /// /// // we can still use the indices to have constant time access to nodes /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); - /// assert_eq!(list.idx_err(&c), None); - /// assert_eq!(list.idx_err(&d), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(c), None); + /// assert_eq!(list.idx_err(d), None); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), Some(&'c')); - /// assert_eq!(list.get(&d), Some(&'d')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), Some(&'c')); + /// assert_eq!(list.get(d), Some(&'d')); /// /// // make auto again /// let mut list: DoublyList<_> = list.into_auto_reclaim(); /// /// // now removals might lead to reorganization if node utilization /// // falls below a certain threshold (75% when D=2). - /// let pop = list.remove(&d); + /// let pop = list.remove(d); /// assert_eq!(pop, 'd'); /// /// // 2 removed nodes reclaimed (b, d); 2 active nodes remains (c, a) @@ -283,22 +283,22 @@ where /// assert_eq!(list.node_utilization().num_closed_nodes, 0); /// /// // node positions might have change during reorganization - /// assert_eq!(list.idx_err(&a), Some(NodeIdxError::ReorganizedCollection)); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(a), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::ReorganizedCollection)); /// // or prior position does not belong to the storage any more - /// assert_eq!(list.idx_err(&c), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&d), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(c), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(d), Some(NodeIdxError::OutOfBounds)); /// /// // indices can no longer be used to access the elements - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), None); - /// assert_eq!(list.get(&d), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), None); + /// assert_eq!(list.get(d), None); /// /// // we can recollect valid indices if necessary /// let idx: Vec<_> = list.indices().collect(); - /// assert_eq!(list.get(&idx[0]), Some(&'c')); - /// assert_eq!(list.get(&idx[1]), Some(&'a')); + /// assert_eq!(list.get(idx[0]), Some(&'c')); + /// assert_eq!(list.get(idx[1]), Some(&'a')); /// ``` pub fn into_auto_reclaim_with_threshold(self) -> DoublyListThreshold { self.into() @@ -352,22 +352,22 @@ where /// /// // we can still use the indices to have constant time access to nodes /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); - /// assert_eq!(list.idx_err(&c), None); - /// assert_eq!(list.idx_err(&d), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(c), None); + /// assert_eq!(list.idx_err(d), None); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), Some(&'c')); - /// assert_eq!(list.get(&d), Some(&'d')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), Some(&'c')); + /// assert_eq!(list.get(d), Some(&'d')); /// /// // make auto again /// let mut list: DoublyList<_> = list.into_auto_reclaim(); /// /// // now removals might lead to reorganization if node utilization /// // falls below a certain threshold (75% when D=2). - /// let pop = list.remove(&d); + /// let pop = list.remove(d); /// assert_eq!(pop, 'd'); /// /// // 2 removed nodes reclaimed (b, d); 2 active nodes remains (c, a) @@ -375,22 +375,22 @@ where /// assert_eq!(list.node_utilization().num_closed_nodes, 0); /// /// // node positions might have change during reorganization - /// assert_eq!(list.idx_err(&a), Some(NodeIdxError::ReorganizedCollection)); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(a), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::ReorganizedCollection)); /// // or prior position does not belong to the storage any more - /// assert_eq!(list.idx_err(&c), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&d), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(c), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(d), Some(NodeIdxError::OutOfBounds)); /// /// // indices can no longer be used to access the elements - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), None); - /// assert_eq!(list.get(&d), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), None); + /// assert_eq!(list.get(d), None); /// /// // we can recollect valid indices if necessary /// let idx: Vec<_> = list.indices().collect(); - /// assert_eq!(list.get(&idx[0]), Some(&'c')); - /// assert_eq!(list.get(&idx[1]), Some(&'a')); + /// assert_eq!(list.get(idx[0]), Some(&'c')); + /// assert_eq!(list.get(idx[1]), Some(&'a')); /// ``` pub fn into_auto_reclaim(self) -> SinglyList { self.into() @@ -439,22 +439,22 @@ where /// /// // we can still use the indices to have constant time access to nodes /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); - /// assert_eq!(list.idx_err(&c), None); - /// assert_eq!(list.idx_err(&d), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(c), None); + /// assert_eq!(list.idx_err(d), None); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), Some(&'c')); - /// assert_eq!(list.get(&d), Some(&'d')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), Some(&'c')); + /// assert_eq!(list.get(d), Some(&'d')); /// /// // make auto again /// let mut list: DoublyList<_> = list.into_auto_reclaim(); /// /// // now removals might lead to reorganization if node utilization /// // falls below a certain threshold (75% when D=2). - /// let pop = list.remove(&d); + /// let pop = list.remove(d); /// assert_eq!(pop, 'd'); /// /// // 2 removed nodes reclaimed (b, d); 2 active nodes remains (c, a) @@ -462,22 +462,22 @@ where /// assert_eq!(list.node_utilization().num_closed_nodes, 0); /// /// // node positions might have change during reorganization - /// assert_eq!(list.idx_err(&a), Some(NodeIdxError::ReorganizedCollection)); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(a), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::ReorganizedCollection)); /// // or prior position does not belong to the storage any more - /// assert_eq!(list.idx_err(&c), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&d), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(c), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(d), Some(NodeIdxError::OutOfBounds)); /// /// // indices can no longer be used to access the elements - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&c), None); - /// assert_eq!(list.get(&d), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(c), None); + /// assert_eq!(list.get(d), None); /// /// // we can recollect valid indices if necessary /// let idx: Vec<_> = list.indices().collect(); - /// assert_eq!(list.get(&idx[0]), Some(&'c')); - /// assert_eq!(list.get(&idx[1]), Some(&'a')); + /// assert_eq!(list.get(idx[0]), Some(&'c')); + /// assert_eq!(list.get(idx[1]), Some(&'a')); /// ``` pub fn into_auto_reclaim_with_threshold(self) -> SinglyListThreshold { self.into() diff --git a/src/list/ends_traits/doubly_ends.rs b/src/list/ends_traits/doubly_ends.rs index 0363da8..30eb5d6 100644 --- a/src/list/ends_traits/doubly_ends.rs +++ b/src/list/ends_traits/doubly_ends.rs @@ -109,29 +109,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), None); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), None); - /// assert_eq!(list.idx_err(&f), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), None); + /// assert_eq!(list.idx_err(f), None); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), None); - /// assert_eq!(list.idx_err(&f), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), None); + /// assert_eq!(list.idx_err(f), Some(NodeIdxError::RemovedNode)); /// /// list.clear(); // all removed /// - /// assert_eq!(list.idx_err(&a), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&f), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(a), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(f), Some(NodeIdxError::OutOfBounds)); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -152,15 +152,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.idx_err(&c), None); + /// assert_eq!(list.idx_err(c), None); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.idx_err(&c), None); + /// assert_eq!(list.idx_err(c), None); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.idx_err(&c), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(c), Some(NodeIdxError::ReorganizedCollection)); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -174,8 +174,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.idx_err(&idx), None); - /// // assert_eq!(list.idx_err(&other_idx), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(idx), None); + /// // assert_eq!(list.idx_err(other_idx), Some(NodeIdxError::OutOfBounds)); /// ``` fn idx_err(&self, idx: DoublyIdx) -> Option { self.col().try_get_ptr(idx).err() @@ -200,29 +200,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.is_valid(&a), true); - /// assert_eq!(list.is_valid(&b), true); + /// assert_eq!(list.is_valid(a), true); + /// assert_eq!(list.is_valid(b), true); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.is_valid(&a), true); - /// assert_eq!(list.is_valid(&b), true); - /// assert_eq!(list.is_valid(&f), true); + /// assert_eq!(list.is_valid(a), true); + /// assert_eq!(list.is_valid(b), true); + /// assert_eq!(list.is_valid(f), true); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.is_valid(&a), true); - /// assert_eq!(list.is_valid(&b), true); - /// assert_eq!(list.is_valid(&f), false); + /// assert_eq!(list.is_valid(a), true); + /// assert_eq!(list.is_valid(b), true); + /// assert_eq!(list.is_valid(f), false); /// /// list.clear(); // all removed /// - /// assert_eq!(list.is_valid(&a), false); - /// assert_eq!(list.is_valid(&b), false); - /// assert_eq!(list.is_valid(&f), false); + /// assert_eq!(list.is_valid(a), false); + /// assert_eq!(list.is_valid(b), false); + /// assert_eq!(list.is_valid(f), false); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -243,15 +243,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.is_valid(&c), true); + /// assert_eq!(list.is_valid(c), true); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.is_valid(&c), true); + /// assert_eq!(list.is_valid(c), true); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.is_valid(&c), false); + /// assert_eq!(list.is_valid(c), false); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -265,8 +265,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.is_valid(&idx), true); - /// // assert_eq!(list.is_valid(&other_idx), false); + /// assert_eq!(list.is_valid(idx), true); + /// // assert_eq!(list.is_valid(other_idx), false); /// ``` fn is_valid(&self, idx: DoublyIdx) -> bool { self.col().try_get_ptr(idx).is_ok() @@ -305,29 +305,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), Some(&'f')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), Some(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), None); /// /// list.clear(); // all removed /// - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(f), None); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -348,15 +348,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.get(&c), Some(&'c')); + /// assert_eq!(list.get(c), Some(&'c')); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.get(&c), Some(&'c')); + /// assert_eq!(list.get(c), Some(&'c')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.get(&c), None); + /// assert_eq!(list.get(c), None); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -370,8 +370,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.get(&idx), Some(&'a')); - /// // assert_eq!(list.get(&other_idx), None); + /// assert_eq!(list.get(idx), Some(&'a')); + /// // assert_eq!(list.get(other_idx), None); /// ``` fn get<'a>(&'a self, idx: DoublyIdx) -> Option<&'a T> where @@ -416,29 +416,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Ok(&'f')); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Ok(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::RemovedNode)); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::RemovedNode)); /// /// list.clear(); // all removed /// - /// assert_eq!(list.try_get(&a), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&b), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(a), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(b), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::OutOfBounds)); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -459,15 +459,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.try_get(&c), Ok(&'c')); + /// assert_eq!(list.try_get(c), Ok(&'c')); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.try_get(&c), Ok(&'c')); + /// assert_eq!(list.try_get(c), Ok(&'c')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.try_get(&c), Err(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.try_get(c), Err(NodeIdxError::ReorganizedCollection)); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -481,8 +481,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.try_get(&idx), Ok(&'a')); - /// // assert_eq!(list.try_get(&other_idx), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(idx), Ok(&'a')); + /// // assert_eq!(list.try_get(other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` fn try_get<'a>(&'a self, idx: DoublyIdx) -> Result<&'a T, NodeIdxError> where @@ -518,13 +518,13 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let c = list.next_idx_of(&a).and_then(|b| list.next_idx_of(&b)).unwrap(); - /// let d = list.next_idx_of(&c).unwrap(); + /// let c = list.next_idx_of(a).and_then(|b| list.next_idx_of(b)).unwrap(); + /// let d = list.next_idx_of(c).unwrap(); /// - /// assert_eq!(list.get(&c), Some(&'c')); - /// assert_eq!(list.get(&d), Some(&'d')); + /// assert_eq!(list.get(c), Some(&'c')); + /// assert_eq!(list.get(d), Some(&'d')); /// - /// assert!(list.next_idx_of(&d).is_none()); + /// assert!(list.next_idx_of(d).is_none()); /// ``` fn next_idx_of(&self, idx: DoublyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); @@ -553,7 +553,7 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let c = list.next_idx_of(&a).and_then(|b| list.next_of(&b)); + /// let c = list.next_idx_of(a).and_then(|b| list.next_of(b)); /// assert_eq!(c, Some(&'c')); /// ``` fn next_of<'a>(&'a self, idx: DoublyIdx) -> Option<&'a T> @@ -585,13 +585,13 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let b = list.prev_idx_of(&d).and_then(|c| list.prev_idx_of(&c)).unwrap(); - /// let a = list.prev_idx_of(&b).unwrap(); + /// let b = list.prev_idx_of(d).and_then(|c| list.prev_idx_of(c)).unwrap(); + /// let a = list.prev_idx_of(b).unwrap(); /// - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(a), Some(&'a')); /// - /// assert!(list.prev_idx_of(&a).is_none()); + /// assert!(list.prev_idx_of(a).is_none()); /// ``` fn prev_idx_of(&self, idx: DoublyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); @@ -620,7 +620,7 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let a = list.prev_idx_of(&c).and_then(|b| list.prev_of(&b)); + /// let a = list.prev_idx_of(c).and_then(|b| list.prev_of(b)); /// assert_eq!(a, Some(&'a')); /// ``` fn prev_of<'a>(&'a self, idx: DoublyIdx) -> Option<&'a T> diff --git a/src/list/ends_traits/doubly_ends_mut.rs b/src/list/ends_traits/doubly_ends_mut.rs index 3a2c226..96903b6 100644 --- a/src/list/ends_traits/doubly_ends_mut.rs +++ b/src/list/ends_traits/doubly_ends_mut.rs @@ -107,33 +107,33 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); /// - /// *list.get_mut(&a).unwrap() = 'x'; + /// *list.get_mut(a).unwrap() = 'x'; /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.get(&a), Some(&'x')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), Some(&'f')); + /// assert_eq!(list.get(a), Some(&'x')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), Some(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// *list.get_mut(&a).unwrap() = 'y'; + /// *list.get_mut(a).unwrap() = 'y'; /// - /// assert_eq!(list.get(&a), Some(&'y')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), Some(&'y')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), None); /// /// list.clear(); // all removed /// - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(f), None); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -154,15 +154,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// *list.get_mut(&c).unwrap() = 'x'; + /// *list.get_mut(c).unwrap() = 'x'; /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.get(&c), Some(&'x')); + /// assert_eq!(list.get(c), Some(&'x')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.get(&c), None); + /// assert_eq!(list.get(c), None); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -176,8 +176,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert!(list.get_mut(&idx).is_some()); - /// // assert_eq!(list.get_mut(&other_idx), None); + /// assert!(list.get_mut(idx).is_some()); + /// // assert_eq!(list.get_mut(other_idx), None); /// ``` fn get_mut<'a>(&'a mut self, idx: DoublyIdx) -> Option<&'a mut T> where @@ -224,33 +224,33 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); /// - /// *list.try_get_mut(&a).unwrap() = 'x'; + /// *list.try_get_mut(a).unwrap() = 'x'; /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.try_get(&a), Ok(&'x')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Ok(&'f')); + /// assert_eq!(list.try_get(a), Ok(&'x')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Ok(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// *list.try_get_mut(&a).unwrap() = 'y'; + /// *list.try_get_mut(a).unwrap() = 'y'; /// - /// assert_eq!(list.try_get(&a), Ok(&'y')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::RemovedNode)); + /// assert_eq!(list.try_get(a), Ok(&'y')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::RemovedNode)); /// /// list.clear(); // all removed /// - /// assert_eq!(list.try_get(&a), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&b), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(a), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(b), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::OutOfBounds)); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -271,15 +271,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// *list.try_get_mut(&c).unwrap() = 'x'; + /// *list.try_get_mut(c).unwrap() = 'x'; /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.get(&c), Some(&'x')); + /// assert_eq!(list.get(c), Some(&'x')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.try_get_mut(&c), Err(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.try_get_mut(c), Err(NodeIdxError::ReorganizedCollection)); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -293,8 +293,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert!(list.try_get_mut(&idx).is_ok()); - /// // assert_eq!(list.try_get_mut(&other_idx), Err(NodeIdxError::OutOfBounds)); + /// assert!(list.try_get_mut(idx).is_ok()); + /// // assert_eq!(list.try_get_mut(other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` fn try_get_mut<'a>(&'a mut self, idx: DoublyIdx) -> Result<&'a mut T, NodeIdxError> where @@ -330,7 +330,7 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let c = list.next_idx_of(&a).and_then(|b| list.next_mut_of(&b)); + /// let c = list.next_idx_of(a).and_then(|b| list.next_mut_of(b)); /// *c.unwrap() = 'x'; /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'd'])); @@ -364,7 +364,7 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let a = list.prev_idx_of(&c).and_then(|b| list.prev_mut_of(&b)); + /// let a = list.prev_idx_of(c).and_then(|b| list.prev_mut_of(b)); /// *a.unwrap() = 'x'; /// /// assert!(list.eq_to_iter_vals(['x', 'b', 'c', 'd'])); @@ -477,13 +477,13 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5])); /// - /// list.move_next_to(&idx[4], &idx[1]); + /// list.move_next_to(idx[4], idx[1]); /// assert!(list.eq_to_iter_vals([0, 1, 4, 2, 3, 5])); /// - /// list.move_next_to(&idx[2], &idx[5]); + /// list.move_next_to(idx[2], idx[5]); /// assert!(list.eq_to_iter_vals([0, 1, 4, 3, 5, 2])); /// - /// list.move_next_to(&idx[3], &idx[0]); + /// list.move_next_to(idx[3], idx[0]); /// assert!(list.eq_to_iter_vals([0, 3, 1, 4, 5, 2])); /// ``` fn move_next_to(&mut self, idx: DoublyIdx, idx_target: DoublyIdx) { @@ -582,13 +582,13 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5])); /// - /// list.move_prev_to(&idx[4], &idx[1]); + /// list.move_prev_to(idx[4], idx[1]); /// assert!(list.eq_to_iter_vals([0, 4, 1, 2, 3, 5])); /// - /// list.move_prev_to(&idx[2], &idx[5]); + /// list.move_prev_to(idx[2], idx[5]); /// assert!(list.eq_to_iter_vals([0, 4, 1, 3, 2, 5])); /// - /// list.move_prev_to(&idx[3], &idx[0]); + /// list.move_prev_to(idx[3], idx[0]); /// assert!(list.eq_to_iter_vals([3, 0, 4, 1, 2, 5])); /// ``` fn move_prev_to(&mut self, idx: DoublyIdx, idx_target: DoublyIdx) { @@ -687,13 +687,13 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5])); /// - /// list.move_to_front(&idx[5]); + /// list.move_to_front(idx[5]); /// assert!(list.eq_to_iter_vals([5, 0, 1, 2, 3, 4])); /// - /// list.move_to_front(&idx[2]); + /// list.move_to_front(idx[2]); /// assert!(list.eq_to_iter_vals([2, 5, 0, 1, 3, 4])); /// - /// list.move_to_front(&idx[3]); + /// list.move_to_front(idx[3]); /// assert!(list.eq_to_iter_vals([3, 2, 5, 0, 1, 4])); /// ``` fn move_to_front(&mut self, idx: DoublyIdx) { @@ -719,13 +719,13 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5])); /// - /// list.move_to_back(&idx[1]); + /// list.move_to_back(idx[1]); /// assert!(list.eq_to_iter_vals([0, 2, 3, 4, 5, 1])); /// - /// list.move_to_back(&idx[4]); + /// list.move_to_back(idx[4]); /// assert!(list.eq_to_iter_vals([0, 2, 3, 5, 1, 4])); /// - /// list.move_to_back(&idx[2]); + /// list.move_to_back(idx[2]); /// assert!(list.eq_to_iter_vals([0, 3, 5, 1, 4, 2])); /// ``` fn move_to_back(&mut self, idx: DoublyIdx) { @@ -750,13 +750,13 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5])); /// - /// list.swap(&idx[1], &idx[5]); + /// list.swap(idx[1], idx[5]); /// assert!(list.eq_to_iter_vals([0, 5, 2, 3, 4, 1])); /// - /// list.swap(&idx[4], &idx[0]); + /// list.swap(idx[4], idx[0]); /// assert!(list.eq_to_iter_vals([4, 5, 2, 3, 0, 1])); /// - /// list.swap(&idx[3], &idx[5]); + /// list.swap(idx[3], idx[5]); /// assert!(list.eq_to_iter_vals([4, 3, 2, 5, 0, 1])); /// ``` fn swap(&mut self, idx_a: DoublyIdx, idx_b: DoublyIdx) { @@ -861,11 +861,11 @@ where /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5, 6, 7])); /// /// unsafe { - /// list.remove_link(&idx[0], &idx[1]); - /// list.remove_link(&idx[2], &idx[3]); - /// list.add_link(&idx[0], &idx[3]); - /// list.add_link(&idx[7], &idx[1]); - /// list.set_back(&idx[2]); + /// list.remove_link(idx[0], idx[1]); + /// list.remove_link(idx[2], idx[3]); + /// list.add_link(idx[0], idx[3]); + /// list.add_link(idx[7], idx[1]); + /// list.set_back(idx[2]); /// } /// /// assert!(list.eq_to_iter_vals([0, 3, 4, 5, 6, 7, 1, 2])); @@ -906,11 +906,11 @@ where /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5, 6, 7])); /// /// unsafe { - /// list.remove_link(&idx[0], &idx[1]); - /// list.remove_link(&idx[2], &idx[3]); - /// list.add_link(&idx[0], &idx[3]); - /// list.add_link(&idx[7], &idx[1]); - /// list.set_back(&idx[2]); + /// list.remove_link(idx[0], idx[1]); + /// list.remove_link(idx[2], idx[3]); + /// list.add_link(idx[0], idx[3]); + /// list.add_link(idx[7], idx[1]); + /// list.set_back(idx[2]); /// } /// /// assert!(list.eq_to_iter_vals([0, 3, 4, 5, 6, 7, 1, 2])); @@ -948,11 +948,11 @@ where /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5, 6, 7])); /// /// unsafe { - /// list.remove_link(&idx[0], &idx[1]); - /// list.remove_link(&idx[2], &idx[3]); - /// list.add_link(&idx[0], &idx[3]); - /// list.add_link(&idx[7], &idx[1]); - /// list.set_back(&idx[2]); + /// list.remove_link(idx[0], idx[1]); + /// list.remove_link(idx[2], idx[3]); + /// list.add_link(idx[0], idx[3]); + /// list.add_link(idx[7], idx[1]); + /// list.set_back(idx[2]); /// } /// /// assert!(list.eq_to_iter_vals([0, 3, 4, 5, 6, 7, 1, 2])); @@ -989,11 +989,11 @@ where /// assert!(list.eq_to_iter_vals([0, 1, 2, 3, 4, 5, 6, 7])); /// /// unsafe { - /// list.remove_link(&idx[0], &idx[1]); - /// list.remove_link(&idx[2], &idx[3]); - /// list.add_link(&idx[0], &idx[3]); - /// list.add_link(&idx[7], &idx[1]); - /// list.set_back(&idx[2]); + /// list.remove_link(idx[0], idx[1]); + /// list.remove_link(idx[2], idx[3]); + /// list.add_link(idx[0], idx[3]); + /// list.add_link(idx[7], idx[1]); + /// list.set_back(idx[2]); /// } /// /// assert!(list.eq_to_iter_vals([0, 3, 4, 5, 6, 7, 1, 2])); diff --git a/src/list/ends_traits/singly_ends.rs b/src/list/ends_traits/singly_ends.rs index 275bafc..e1d2d75 100644 --- a/src/list/ends_traits/singly_ends.rs +++ b/src/list/ends_traits/singly_ends.rs @@ -72,29 +72,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), None); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), None); - /// assert_eq!(list.idx_err(&f), None); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), None); + /// assert_eq!(list.idx_err(f), None); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.idx_err(&a), None); - /// assert_eq!(list.idx_err(&b), None); - /// assert_eq!(list.idx_err(&f), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(a), None); + /// assert_eq!(list.idx_err(b), None); + /// assert_eq!(list.idx_err(f), Some(NodeIdxError::RemovedNode)); /// /// list.clear(); // all removed /// - /// assert_eq!(list.idx_err(&a), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.idx_err(&f), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(a), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(f), Some(NodeIdxError::OutOfBounds)); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -115,15 +115,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.idx_err(&c), None); + /// assert_eq!(list.idx_err(c), None); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.idx_err(&c), None); + /// assert_eq!(list.idx_err(c), None); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.idx_err(&c), Some(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.idx_err(c), Some(NodeIdxError::ReorganizedCollection)); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -137,8 +137,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.idx_err(&idx), None); - /// // assert_eq!(list.idx_err(&other_idx), Some(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.idx_err(idx), None); + /// // assert_eq!(list.idx_err(other_idx), Some(NodeIdxError::OutOfBounds)); /// ``` fn idx_err(&self, idx: SinglyIdx) -> Option { self.col().try_get_ptr(idx).err() @@ -163,29 +163,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.is_valid(&a), true); - /// assert_eq!(list.is_valid(&b), true); + /// assert_eq!(list.is_valid(a), true); + /// assert_eq!(list.is_valid(b), true); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.is_valid(&a), true); - /// assert_eq!(list.is_valid(&b), true); - /// assert_eq!(list.is_valid(&f), true); + /// assert_eq!(list.is_valid(a), true); + /// assert_eq!(list.is_valid(b), true); + /// assert_eq!(list.is_valid(f), true); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.is_valid(&a), true); - /// assert_eq!(list.is_valid(&b), true); - /// assert_eq!(list.is_valid(&f), false); + /// assert_eq!(list.is_valid(a), true); + /// assert_eq!(list.is_valid(b), true); + /// assert_eq!(list.is_valid(f), false); /// /// list.clear(); // all removed /// - /// assert_eq!(list.is_valid(&a), false); - /// assert_eq!(list.is_valid(&b), false); - /// assert_eq!(list.is_valid(&f), false); + /// assert_eq!(list.is_valid(a), false); + /// assert_eq!(list.is_valid(b), false); + /// assert_eq!(list.is_valid(f), false); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -206,15 +206,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.is_valid(&c), true); + /// assert_eq!(list.is_valid(c), true); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.is_valid(&c), true); + /// assert_eq!(list.is_valid(c), true); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.is_valid(&c), false); + /// assert_eq!(list.is_valid(c), false); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -228,8 +228,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.is_valid(&idx), true); - /// // assert_eq!(list.is_valid(&other_idx), false); + /// assert_eq!(list.is_valid(idx), true); + /// // assert_eq!(list.is_valid(other_idx), false); /// ``` fn is_valid(&self, idx: SinglyIdx) -> bool { self.col().try_get_ptr(idx).is_ok() @@ -268,29 +268,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), Some(&'f')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), Some(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), None); /// /// list.clear(); // all removed /// - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(f), None); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -311,15 +311,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.get(&c), Some(&'c')); + /// assert_eq!(list.get(c), Some(&'c')); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.get(&c), Some(&'c')); + /// assert_eq!(list.get(c), Some(&'c')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.get(&c), None); + /// assert_eq!(list.get(c), None); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -333,8 +333,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.get(&idx), Some(&'a')); - /// // assert_eq!(list.get(&other_idx), None); + /// assert_eq!(list.get(idx), Some(&'a')); + /// // assert_eq!(list.get(other_idx), None); /// ``` fn get<'a>(&'a self, idx: SinglyIdx) -> Option<&'a T> where @@ -379,29 +379,29 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Ok(&'f')); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Ok(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::RemovedNode)); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::RemovedNode)); /// /// list.clear(); // all removed /// - /// assert_eq!(list.try_get(&a), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&b), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(a), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(b), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::OutOfBounds)); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -422,15 +422,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// assert_eq!(list.try_get(&c), Ok(&'c')); + /// assert_eq!(list.try_get(c), Ok(&'c')); /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.try_get(&c), Ok(&'c')); + /// assert_eq!(list.try_get(c), Ok(&'c')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.try_get(&c), Err(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.try_get(c), Err(NodeIdxError::ReorganizedCollection)); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -444,8 +444,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert_eq!(list.try_get(&idx), Ok(&'a')); - /// // assert_eq!(list.try_get(&other_idx), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(idx), Ok(&'a')); + /// // assert_eq!(list.try_get(other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` fn try_get<'a>(&'a self, idx: SinglyIdx) -> Result<&'a T, NodeIdxError> where @@ -481,13 +481,13 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let c = list.next_idx_of(&a).and_then(|b| list.next_idx_of(&b)).unwrap(); - /// let d = list.next_idx_of(&c).unwrap(); + /// let c = list.next_idx_of(a).and_then(|b| list.next_idx_of(b)).unwrap(); + /// let d = list.next_idx_of(c).unwrap(); /// - /// assert_eq!(list.get(&c), Some(&'c')); - /// assert_eq!(list.get(&d), Some(&'d')); + /// assert_eq!(list.get(c), Some(&'c')); + /// assert_eq!(list.get(d), Some(&'d')); /// - /// assert!(list.next_idx_of(&d).is_none()); + /// assert!(list.next_idx_of(d).is_none()); /// ``` fn next_idx_of(&self, idx: SinglyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); @@ -516,7 +516,7 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let c = list.next_idx_of(&a).and_then(|b| list.next_of(&b)); + /// let c = list.next_idx_of(a).and_then(|b| list.next_of(b)); /// assert_eq!(c, Some(&'c')); /// ``` fn next_of<'a>(&'a self, idx: SinglyIdx) -> Option<&'a T> diff --git a/src/list/ends_traits/singly_ends_mut.rs b/src/list/ends_traits/singly_ends_mut.rs index 9fff43d..d3925fa 100644 --- a/src/list/ends_traits/singly_ends_mut.rs +++ b/src/list/ends_traits/singly_ends_mut.rs @@ -74,33 +74,33 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.get(&a), Some(&'a')); - /// assert_eq!(list.get(&b), Some(&'b')); + /// assert_eq!(list.get(a), Some(&'a')); + /// assert_eq!(list.get(b), Some(&'b')); /// - /// *list.get_mut(&a).unwrap() = 'x'; + /// *list.get_mut(a).unwrap() = 'x'; /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.get(&a), Some(&'x')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), Some(&'f')); + /// assert_eq!(list.get(a), Some(&'x')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), Some(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// *list.get_mut(&a).unwrap() = 'y'; + /// *list.get_mut(a).unwrap() = 'y'; /// - /// assert_eq!(list.get(&a), Some(&'y')); - /// assert_eq!(list.get(&b), Some(&'b')); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), Some(&'y')); + /// assert_eq!(list.get(b), Some(&'b')); + /// assert_eq!(list.get(f), None); /// /// list.clear(); // all removed /// - /// assert_eq!(list.get(&a), None); - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.get(&f), None); + /// assert_eq!(list.get(a), None); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.get(f), None); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -121,15 +121,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// *list.get_mut(&c).unwrap() = 'x'; + /// *list.get_mut(c).unwrap() = 'x'; /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.get(&c), Some(&'x')); + /// assert_eq!(list.get(c), Some(&'x')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.get(&c), None); + /// assert_eq!(list.get(c), None); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -143,8 +143,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert!(list.get_mut(&idx).is_some()); - /// // assert_eq!(list.get_mut(&other_idx), None); + /// assert!(list.get_mut(idx).is_some()); + /// // assert_eq!(list.get_mut(other_idx), None); /// ``` fn get_mut<'a>(&'a mut self, idx: SinglyIdx) -> Option<&'a mut T> where @@ -191,33 +191,33 @@ where /// let a = list.push_back('a'); /// let b = list.push_back('b'); /// - /// assert_eq!(list.try_get(&a), Ok(&'a')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); + /// assert_eq!(list.try_get(a), Ok(&'a')); + /// assert_eq!(list.try_get(b), Ok(&'b')); /// - /// *list.try_get_mut(&a).unwrap() = 'x'; + /// *list.try_get_mut(a).unwrap() = 'x'; /// /// list.push_front('c'); /// list.push_back('d'); /// list.push_front('e'); /// let f = list.push_back('f'); /// - /// assert_eq!(list.try_get(&a), Ok(&'x')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Ok(&'f')); + /// assert_eq!(list.try_get(a), Ok(&'x')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Ok(&'f')); /// /// let _ = list.pop_back(); // f is removed /// - /// *list.try_get_mut(&a).unwrap() = 'y'; + /// *list.try_get_mut(a).unwrap() = 'y'; /// - /// assert_eq!(list.try_get(&a), Ok(&'y')); - /// assert_eq!(list.try_get(&b), Ok(&'b')); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::RemovedNode)); + /// assert_eq!(list.try_get(a), Ok(&'y')); + /// assert_eq!(list.try_get(b), Ok(&'b')); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::RemovedNode)); /// /// list.clear(); // all removed /// - /// assert_eq!(list.try_get(&a), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&b), Err(NodeIdxError::OutOfBounds)); - /// assert_eq!(list.try_get(&f), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(a), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(b), Err(NodeIdxError::OutOfBounds)); + /// assert_eq!(list.try_get(f), Err(NodeIdxError::OutOfBounds)); /// ``` /// /// In the following, removal of nodes invalidates indices due to reorganization. @@ -238,15 +238,15 @@ where /// list.push_back('d'); /// list.push_back('e'); /// - /// *list.try_get_mut(&c).unwrap() = 'x'; + /// *list.try_get_mut(c).unwrap() = 'x'; /// /// list.pop_back(); // does not lead to reorganization /// - /// assert_eq!(list.get(&c), Some(&'x')); + /// assert_eq!(list.get(c), Some(&'x')); /// /// list.pop_front(); // leads to reorganization /// - /// assert_eq!(list.try_get_mut(&c), Err(NodeIdxError::ReorganizedCollection)); + /// assert_eq!(list.try_get_mut(c), Err(NodeIdxError::ReorganizedCollection)); /// ``` /// /// In the final example, we attempt to access to a list element using an index created by another list. @@ -260,8 +260,8 @@ where /// let mut other_list = DoublyList::new(); /// let other_idx = other_list.push_back('a'); /// - /// assert!(list.try_get_mut(&idx).is_ok()); - /// // assert_eq!(list.try_get_mut(&other_idx), Err(NodeIdxError::OutOfBounds)); + /// assert!(list.try_get_mut(idx).is_ok()); + /// // assert_eq!(list.try_get_mut(other_idx), Err(NodeIdxError::OutOfBounds)); /// ``` fn try_get_mut<'a>(&'a mut self, idx: SinglyIdx) -> Result<&'a mut T, NodeIdxError> where @@ -297,7 +297,7 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let c = list.next_mut_of(&b); + /// let c = list.next_mut_of(b); /// *c.unwrap() = 'x'; /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'd'])); diff --git a/src/list/get_doubly.rs b/src/list/get_doubly.rs index 902f15f..13beba0 100644 --- a/src/list/get_doubly.rs +++ b/src/list/get_doubly.rs @@ -46,7 +46,7 @@ where /// /// let idx: Vec<_> = list.indices().collect(); /// - /// let slice = list.slice(&idx[1]..=&idx[3]); + /// let slice = list.slice(idx[1]..=idx[3]); /// assert_eq!(slice.front(), Some(&7)); /// assert_eq!(slice.back(), Some(&3)); /// assert!(slice.eq_to_iter_vals([7, 1, 3])); @@ -70,11 +70,11 @@ where /// let idx: Vec<_> = list.indices().collect(); /// /// // a..b where b comes later, hence, we get the slice a..b - /// let slice = list.slice(&idx[1]..&idx[4]); + /// let slice = list.slice(idx[1]..idx[4]); /// assert!(slice.eq_to_iter_vals([1, 2, 3])); /// /// // a..b where b comes earlier, then, we get the slice a..back - /// let slice = list.slice(&idx[4]..&idx[1]); + /// let slice = list.slice(idx[4]..idx[1]); /// assert!(slice.eq_to_iter_vals([4, 5, 6, 7, 8, 9])); /// ``` pub fn slice(&self, range: R) -> ListSlice<'_, Doubly, M> diff --git a/src/list/idx_doubly.rs b/src/list/idx_doubly.rs index 71b47f8..02e7097 100644 --- a/src/list/idx_doubly.rs +++ b/src/list/idx_doubly.rs @@ -33,7 +33,7 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd', 'e'])); /// - /// let value = list.remove(&idx); + /// let value = list.remove(idx); /// /// assert_eq!(value, 'b'); /// assert!(list.eq_to_iter_vals(['a', 'c', 'd', 'e'])); @@ -80,9 +80,9 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let x = list.insert_next_to(&b, 'x'); + /// let x = list.insert_next_to(b, 'x'); /// - /// assert_eq!(list.get(&x), Some(&'x')); + /// assert_eq!(list.get(x), Some(&'x')); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'c', 'd'])); ///``` pub fn insert_next_to(&mut self, idx: DoublyIdx, value: T) -> DoublyIdx { @@ -127,9 +127,9 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let x = list.insert_prev_to(&c, 'x'); + /// let x = list.insert_prev_to(c, 'x'); /// - /// assert_eq!(list.get(&x), Some(&'x')); + /// assert_eq!(list.get(x), Some(&'x')); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'c', 'd'])); ///``` pub fn insert_prev_to(&mut self, idx: DoublyIdx, value: T) -> DoublyIdx { @@ -171,13 +171,13 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd', 'e'])); /// - /// let value = list.try_remove(&idx); + /// let value = list.try_remove(idx); /// /// assert_eq!(value, Some('b')); /// assert!(list.eq_to_iter_vals(['a', 'c', 'd', 'e'])); - /// assert_eq!(list.idx_err(&idx), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.idx_err(idx), Some(NodeIdxError::RemovedNode)); /// - /// let value = list.try_remove(&idx); + /// let value = list.try_remove(idx); /// assert_eq!(value, None); /// ``` pub fn try_remove(&mut self, idx: DoublyIdx) -> Option { @@ -227,15 +227,15 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let x = list.try_insert_next_to(&b, 'x').unwrap(); + /// let x = list.try_insert_next_to(b, 'x').unwrap(); /// - /// assert_eq!(list.get(&x), Some(&'x')); + /// assert_eq!(list.get(x), Some(&'x')); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'c', 'd'])); /// - /// let _ = list.remove(&b); + /// let _ = list.remove(b); /// assert!(list.eq_to_iter_vals(['a', 'x', 'c', 'd'])); /// - /// let y = list.try_insert_next_to(&b, 'y'); + /// let y = list.try_insert_next_to(b, 'y'); /// assert_eq!(y, Err(NodeIdxError::RemovedNode)); /// assert!(list.eq_to_iter_vals(['a', 'x', 'c', 'd'])); // unchanged ///``` @@ -283,15 +283,15 @@ where /// /// assert!(list.eq_to_iter_vals(['a', 'b', 'c', 'd'])); /// - /// let x = list.try_insert_prev_to(&c, 'x').unwrap(); + /// let x = list.try_insert_prev_to(c, 'x').unwrap(); /// - /// assert_eq!(list.get(&x), Some(&'x')); + /// assert_eq!(list.get(x), Some(&'x')); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'c', 'd'])); /// - /// let _ = list.remove(&c); + /// let _ = list.remove(c); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'd'])); /// - /// let y = list.try_insert_prev_to(&c, 'y'); + /// let y = list.try_insert_prev_to(c, 'y'); /// assert_eq!(y, Err(NodeIdxError::RemovedNode)); /// assert!(list.eq_to_iter_vals(['a', 'b', 'x', 'd'])); // unchanged ///``` diff --git a/src/list/iter_traits/doubly_iterable.rs b/src/list/iter_traits/doubly_iterable.rs index c388c54..1fe33c8 100644 --- a/src/list/iter_traits/doubly_iterable.rs +++ b/src/list/iter_traits/doubly_iterable.rs @@ -128,12 +128,12 @@ where /// /// let idx: Vec<_> = list.indices().collect(); /// - /// assert_eq!(list.get(&idx[1]), Some(&1)); + /// assert_eq!(list.get(idx[1]), Some(&1)); /// /// // O(1) mutations through indices - /// list.insert_next_to(&idx[0], 42); - /// list.insert_prev_to(&idx[2], 7); - /// list.remove(&idx[1]); + /// list.insert_next_to(idx[0], 42); + /// list.insert_prev_to(idx[2], 7); + /// list.remove(idx[1]); /// /// assert!(list.eq_to_iter_vals([0, 42, 7, 2])); /// ``` @@ -175,24 +175,24 @@ where /// let list: DoublyList<_> = (0..8).collect(); /// let idx: Vec<_> = list.indices().collect(); /// - /// let iter = list.ring_iter(&idx[2]); + /// let iter = list.ring_iter(idx[2]); /// assert_eq!(iter.copied().collect::>(), [2, 3, 4, 5, 6, 7, 0, 1]); /// - /// let iter = list.ring_iter(&idx[4]); + /// let iter = list.ring_iter(idx[4]); /// assert_eq!(iter.copied().collect::>(), [4, 5, 6, 7, 0, 1, 2, 3]); /// /// // ring iterator is also double-ended - /// let iter = list.ring_iter(&idx[4]).rev(); + /// let iter = list.ring_iter(idx[4]).rev(); /// assert_eq!(iter.copied().collect::>(), [3, 2, 1, 0, 7, 6, 5, 4]); /// /// // ring iterators are also available for slices - /// let slice = list.slice(&idx[3]..&idx[7]); + /// let slice = list.slice(idx[3]..idx[7]); /// assert!(slice.eq_to_iter_vals([3, 4, 5, 6])); /// - /// let iter = slice.ring_iter(&idx[4]); + /// let iter = slice.ring_iter(idx[4]); /// assert_eq!(iter.copied().collect::>(), [4, 5, 6, 3,]); /// - /// let iter = slice.ring_iter(&idx[6]); + /// let iter = slice.ring_iter(idx[6]); /// assert_eq!(iter.copied().collect::>(), [6, 3, 4, 5]); /// ``` fn ring_iter<'a>( @@ -238,7 +238,7 @@ where /// let idx = list.push_back(2); /// list.push_back(3); /// - /// let mut iter = list.iter_from(&idx); + /// let mut iter = list.iter_from(idx); /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), Some(&3)); /// assert_eq!(iter.next(), None); @@ -272,7 +272,7 @@ where /// let idx = list.push_back(2); /// list.push_back(3); /// - /// let mut iter = list.iter_backward_from(&idx); + /// let mut iter = list.iter_backward_from(idx); /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), Some(&1)); /// assert_eq!(iter.next(), Some(&0)); @@ -303,7 +303,7 @@ where /// let tour: DoublyList<_> = ['a', 'b', 'c', 'd', 'e'].into_iter().collect(); /// let idx: Vec<_> = tour.indices().collect(); /// - /// let mut iter = tour.iter_links_from(&idx[1]); + /// let mut iter = tour.iter_links_from(idx[1]); /// /// assert_eq!(iter.next(), Some((&'b', &'c'))); /// assert_eq!(iter.next(), Some((&'c', &'d'))); diff --git a/src/list/iter_traits/doubly_iterable_mut.rs b/src/list/iter_traits/doubly_iterable_mut.rs index 24e76bd..bbbac01 100644 --- a/src/list/iter_traits/doubly_iterable_mut.rs +++ b/src/list/iter_traits/doubly_iterable_mut.rs @@ -68,7 +68,7 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3])); /// - /// for x in list.iter_mut_from(&idx) { + /// for x in list.iter_mut_from(idx) { /// *x += 10; /// } /// @@ -105,7 +105,7 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3])); /// - /// for x in list.iter_mut_backward_from(&idx) { + /// for x in list.iter_mut_backward_from(idx) { /// *x += 10; /// } /// @@ -153,7 +153,7 @@ where /// let mut list: DoublyList<_> = (0..5).collect(); /// let idx: Vec<_> = list.indices().collect(); /// - /// scan(list.ring_iter_mut(&idx[3])); + /// scan(list.ring_iter_mut(idx[3])); /// assert!(list.eq_to_iter_vals([7, 8, 10, 3, 7])); /// ``` fn ring_iter_mut<'a>(&'a mut self, pivot_idx: DoublyIdx) -> DoublyIterMutChain<'a, T, P> diff --git a/src/list/iter_traits/singly_iterable.rs b/src/list/iter_traits/singly_iterable.rs index fadf788..d6bc3ba 100644 --- a/src/list/iter_traits/singly_iterable.rs +++ b/src/list/iter_traits/singly_iterable.rs @@ -74,7 +74,7 @@ where /// /// let idx: Vec<_> = list.indices().collect(); /// - /// assert_eq!(list.get(&idx[1]), Some(&1)); + /// assert_eq!(list.get(idx[1]), Some(&1)); /// ``` fn indices<'a>(&'a self) -> impl Iterator> where @@ -121,7 +121,7 @@ where /// let idx = list.push_front(1); /// list.push_front(0); // 0->1->2->3 /// - /// let mut iter = list.iter_from(&idx); + /// let mut iter = list.iter_from(idx); /// assert_eq!(iter.next(), Some(&1)); /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), Some(&3)); diff --git a/src/list/iter_traits/singly_iterable_mut.rs b/src/list/iter_traits/singly_iterable_mut.rs index a140e02..c1accca 100644 --- a/src/list/iter_traits/singly_iterable_mut.rs +++ b/src/list/iter_traits/singly_iterable_mut.rs @@ -64,7 +64,7 @@ where /// /// assert!(list.eq_to_iter_vals([0, 1, 2, 3])); /// - /// for x in list.iter_mut_from(&idx) { + /// for x in list.iter_mut_from(idx) { /// *x += 10; /// } /// diff --git a/src/list/linear_eq.rs b/src/list/linear_eq.rs index cd5b2c1..f0e5102 100644 --- a/src/list/linear_eq.rs +++ b/src/list/linear_eq.rs @@ -31,23 +31,23 @@ where /// /// let b = b.unwrap(); /// - /// let data_b = list.get(&b); // O(1) + /// let data_b = list.get(b); // O(1) /// assert_eq!(data_b, Some(&'b')); /// /// // O(1) to create the iterators from the index - /// assert_eq!(&['b', 'c', 'd'], list.iter_from(&b).copied().collect::>().as_slice()); - /// assert_eq!(&['b', 'a'], list.iter_backward_from(&b).copied().collect::>().as_slice()); + /// assert_eq!(&['b', 'c', 'd'], list.iter_from(b).copied().collect::>().as_slice()); + /// assert_eq!(&['b', 'a'], list.iter_backward_from(b).copied().collect::>().as_slice()); /// - /// list.insert_prev_to(&b, 'X'); // O(1) - /// list.insert_next_to(&b, 'Y'); // O(1) + /// list.insert_prev_to(b, 'X'); // O(1) + /// list.insert_next_to(b, 'Y'); // O(1) /// assert!(list.eq_to_iter_vals(['a', 'X', 'b', 'Y', 'c', 'd'])); /// - /// let removed = list.remove(&b); // O(1) + /// let removed = list.remove(b); // O(1) /// assert_eq!(removed, 'b'); /// assert!(list.eq_to_iter_vals(['a', 'X', 'Y', 'c', 'd'])); /// - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); /// ``` pub fn idx_of(&self, value: &T) -> Option> { self.iter_ptr() @@ -131,23 +131,23 @@ where /// /// let b = b.unwrap(); /// - /// let data_b = list.get(&b); // O(1) + /// let data_b = list.get(b); // O(1) /// assert_eq!(data_b, Some(&'b')); /// /// // O(1) to create the iterators from the index - /// assert_eq!(&['b', 'c', 'd'], list.iter_from(&b).copied().collect::>().as_slice()); - /// assert_eq!(&['b', 'a'], list.iter_backward_from(&b).copied().collect::>().as_slice()); + /// assert_eq!(&['b', 'c', 'd'], list.iter_from(b).copied().collect::>().as_slice()); + /// assert_eq!(&['b', 'a'], list.iter_backward_from(b).copied().collect::>().as_slice()); /// - /// list.insert_prev_to(&b, 'X'); // O(1) - /// list.insert_next_to(&b, 'Y'); // O(1) + /// list.insert_prev_to(b, 'X'); // O(1) + /// list.insert_next_to(b, 'Y'); // O(1) /// assert!(list.eq_to_iter_vals(['a', 'X', 'b', 'Y', 'c', 'd'])); /// - /// let removed = list.remove(&b); // O(1) + /// let removed = list.remove(b); // O(1) /// assert_eq!(removed, 'b'); /// assert!(list.eq_to_iter_vals(['a', 'X', 'Y', 'c', 'd'])); /// - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); /// ``` pub fn idx_of(&self, value: &T) -> Option> { self.iter_ptr() @@ -222,23 +222,23 @@ where /// /// let b = b.unwrap(); /// - /// let data_b = list.get(&b); // O(1) + /// let data_b = list.get(b); // O(1) /// assert_eq!(data_b, Some(&'b')); /// /// // O(1) to create the iterators from the index - /// assert_eq!(&['b', 'c', 'd'], list.iter_from(&b).copied().collect::>().as_slice()); - /// assert_eq!(&['b', 'a'], list.iter_backward_from(&b).copied().collect::>().as_slice()); + /// assert_eq!(&['b', 'c', 'd'], list.iter_from(b).copied().collect::>().as_slice()); + /// assert_eq!(&['b', 'a'], list.iter_backward_from(b).copied().collect::>().as_slice()); /// - /// list.insert_prev_to(&b, 'X'); // O(1) - /// list.insert_next_to(&b, 'Y'); // O(1) + /// list.insert_prev_to(b, 'X'); // O(1) + /// list.insert_next_to(b, 'Y'); // O(1) /// assert!(list.eq_to_iter_vals(['a', 'X', 'b', 'Y', 'c', 'd'])); /// - /// let removed = list.remove(&b); // O(1) + /// let removed = list.remove(b); // O(1) /// assert_eq!(removed, 'b'); /// assert!(list.eq_to_iter_vals(['a', 'X', 'Y', 'c', 'd'])); /// - /// assert_eq!(list.get(&b), None); - /// assert_eq!(list.idx_err(&b), Some(NodeIdxError::RemovedNode)); + /// assert_eq!(list.get(b), None); + /// assert_eq!(list.idx_err(b), Some(NodeIdxError::RemovedNode)); /// ``` pub fn idx_of_from_back(&self, value: &T) -> Option> { self.iter_ptr() diff --git a/src/list/mut_doubly.rs b/src/list/mut_doubly.rs index b3284dc..068e4a6 100644 --- a/src/list/mut_doubly.rs +++ b/src/list/mut_doubly.rs @@ -250,7 +250,7 @@ where /// /// let idx: Vec<_> = list.indices().collect(); /// - /// let slice = list.slice(&idx[1]..=&idx[3]); + /// let slice = list.slice(idx[1]..=idx[3]); /// assert_eq!(slice.front(), Some(&7)); /// assert_eq!(slice.back(), Some(&3)); /// assert!(slice.eq_to_iter_vals([7, 1, 3])); @@ -274,11 +274,11 @@ where /// let idx: Vec<_> = list.indices().collect(); /// /// // a..b where b comes later, hence, we get the slice a..b - /// let slice = list.slice_mut(&idx[1]..&idx[4]); + /// let slice = list.slice_mut(idx[1]..idx[4]); /// assert!(slice.eq_to_iter_vals([1, 2, 3])); /// /// // a..b where b comes earlier, then, we get the slice a..back - /// let slice = list.slice_mut(&idx[4]..&idx[1]); + /// let slice = list.slice_mut(idx[4]..idx[1]); /// assert!(slice.eq_to_iter_vals([4, 5, 6, 7, 8, 9])); /// ``` pub fn slice_mut(&mut self, range: R) -> ListSliceMut<'_, Doubly, M, P> diff --git a/tests/reverse.rs b/tests/reverse.rs index 8b24aba..622af03 100644 --- a/tests/reverse.rs +++ b/tests/reverse.rs @@ -21,7 +21,7 @@ fn slice_reverse_empty() { let j = i; if i < idx.len() { - list.slice_mut(&idx[i]..&idx[j]).reverse(); + list.slice_mut(idx[i]..idx[j]).reverse(); assert!(list.eq_to_iter_refs(&expected)); } } @@ -37,7 +37,7 @@ fn slice_reverse_single() { let j = i; if i < idx.len() { - list.slice_mut(&idx[i]..=&idx[j]).reverse(); + list.slice_mut(idx[i]..=idx[j]).reverse(); assert!(list.eq_to_iter_refs(&expected)); } } @@ -56,7 +56,7 @@ fn slice_reverse_from_front() { if j < idx.len() { expected[0..=j].reverse(); - list.slice_mut(&idx[i]..=&idx[j]).reverse(); + list.slice_mut(idx[i]..=idx[j]).reverse(); assert!(list.eq_to_iter_refs(&expected)); } } @@ -75,7 +75,7 @@ fn slice_reverse_until_back() { if i < list.len() && j < list.len() { expected[i..=j].reverse(); - list.slice_mut(&idx[i]..=&idx[j]).reverse(); + list.slice_mut(idx[i]..=idx[j]).reverse(); assert!(list.eq_to_iter_refs(&expected)); } } @@ -93,7 +93,7 @@ fn slice_reverse_middle() { if i < list.len() && j < list.len() { expected[i..=j].reverse(); - list.slice_mut(&idx[i]..=&idx[j]).reverse(); + list.slice_mut(idx[i]..=idx[j]).reverse(); assert!(list.eq_to_iter_refs(&expected)); } } diff --git a/tests/slice_doubly.rs b/tests/slice_doubly.rs index 3d1c0d3..1cfa1f1 100644 --- a/tests/slice_doubly.rs +++ b/tests/slice_doubly.rs @@ -101,7 +101,7 @@ fn demo_usage() { let idx: Vec<_> = list.indices().collect(); - let slice = list.slice(&idx[1]..=&idx[3]); + let slice = list.slice(idx[1]..=idx[3]); assert_eq!(slice.front(), Some(&7)); assert_eq!(slice.back(), Some(&3)); assert!(slice.eq_to_iter_vals([7, 1, 3])); @@ -120,34 +120,34 @@ fn doubly_slice() { // empty for i in 0..n { - assert_empty_slice(&list.slice(&idx[i]..&idx[i])); + assert_empty_slice(&list.slice(idx[i]..idx[i])); } // single for i in 0..n { - let s = list.slice(&idx[i]..=&idx[i]); + let s = list.slice(idx[i]..=idx[i]); s.eq_to_iter_refs(&vec[i..=i]); if i != n - 1 { - let s = list.slice(&idx[i]..&idx[i + 1]); + let s = list.slice(idx[i]..idx[i + 1]); s.eq_to_iter_refs(&vec[i..=i]); } } // full list.slice(..).eq_to_iter_refs(&vec[..]); - list.slice(&idx[0]..).eq_to_iter_refs(&vec[0..]); - list.slice(..=&idx[n - 1]).eq_to_iter_refs(&vec[..(n - 1)]); - list.slice(&idx[0]..=&idx[n - 1]) + list.slice(idx[0]..).eq_to_iter_refs(&vec[0..]); + list.slice(..=idx[n - 1]).eq_to_iter_refs(&vec[..(n - 1)]); + list.slice(idx[0]..=idx[n - 1]) .eq_to_iter_refs(&vec[0..(n - 1)]); // arbitrary ranges for i in 0..n { for j in i..n { - let s = list.slice(&idx[i]..=&idx[j]); + let s = list.slice(idx[i]..=idx[j]); s.eq_to_iter_refs(&vec[i..=j]); - let s = list.slice(&idx[i]..&idx[j]); + let s = list.slice(idx[i]..idx[j]); s.eq_to_iter_refs(&vec[i..j]); } } diff --git a/tests/slice_iter_rev.rs b/tests/slice_iter_rev.rs index 75efb4a..0300b95 100644 --- a/tests/slice_iter_rev.rs +++ b/tests/slice_iter_rev.rs @@ -5,27 +5,27 @@ fn iter_rev_on_slice() { let list: DoublyList<_> = (0..10).collect(); let idx: Vec<_> = list.indices().collect(); - let slice = list.slice(&idx[3]..&idx[7]); + let slice = list.slice(idx[3]..idx[7]); let rev: Vec<_> = slice.iter().copied().rev().collect(); assert_eq!(rev, [6, 5, 4, 3]); - let slice = list.slice(&idx[3]..&idx[2]); + let slice = list.slice(idx[3]..idx[2]); let rev: Vec<_> = slice.iter().copied().rev().collect(); assert_eq!(rev, [1, 0]); - let slice = list.slice(&idx[0]..=&idx[9]); + let slice = list.slice(idx[0]..=idx[9]); let rev: Vec<_> = slice.iter().copied().rev().collect(); assert_eq!(rev, [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]); - let slice = list.slice(&idx[4]..=&idx[4]); + let slice = list.slice(idx[4]..=idx[4]); let rev: Vec<_> = slice.iter().copied().rev().collect(); assert_eq!(rev, [4]); - let slice = list.slice(&idx[9]..=&idx[9]); + let slice = list.slice(idx[9]..=idx[9]); let rev: Vec<_> = slice.iter().copied().rev().collect(); assert_eq!(rev, [9]); - let slice = list.slice(&idx[0]..&idx[0]); + let slice = list.slice(idx[0]..idx[0]); let rev: Vec<_> = slice.iter().copied().rev().collect(); assert_eq!(rev, []); } diff --git a/tests/slice_wrong_direction.rs b/tests/slice_wrong_direction.rs index 1977fe7..a92c33a 100644 --- a/tests/slice_wrong_direction.rs +++ b/tests/slice_wrong_direction.rs @@ -6,18 +6,18 @@ fn slice_in_wrong_direction() { let idx: Vec<_> = list.indices().collect(); - let slice = list.slice(&idx[1]..&idx[4]); + let slice = list.slice(idx[1]..idx[4]); assert!(slice.eq_to_iter_vals([1, 2, 3])); - let slice = list.slice(&idx[4]..&idx[1]); + let slice = list.slice(idx[4]..idx[1]); assert!(slice.eq_to_iter_vals([4, 5, 6, 7, 8, 9])); - let slice = list.slice(&idx[4]..=&idx[9]); + let slice = list.slice(idx[4]..=idx[9]); assert!(slice.eq_to_iter_vals([4, 5, 6, 7, 8, 9])); - let slice = list.slice(&idx[4]..=&idx[4]); + let slice = list.slice(idx[4]..=idx[4]); assert!(slice.eq_to_iter_vals([4])); - let slice = list.slice(&idx[4]..&idx[4]); + let slice = list.slice(idx[4]..idx[4]); assert!(slice.eq_to_iter_vals([])); } From 6c46aaf8a879a7cad38cc1124f05ff5101e9c3d4 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 21:23:07 +0100 Subject: [PATCH 06/16] copy fixes --- src/iter/doubly_iter.rs | 4 ++-- src/iter/doubly_iter_mut.rs | 8 ++++---- src/iter/doubly_iter_owned.rs | 12 ++++++------ src/iter/doubly_iter_ptr.rs | 8 ++++---- src/iter/doubly_link_iter.rs | 4 ++-- src/iter/doubly_link_iter_ptr.rs | 5 ++--- src/iter/singly_iter.rs | 2 +- src/iter/singly_iter_mut.rs | 6 +++--- src/iter/singly_iter_owned.rs | 6 +++--- src/iter/singly_iter_ptr.rs | 4 ++-- 10 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/iter/doubly_iter.rs b/src/iter/doubly_iter.rs index 5d3283c..b8685a0 100644 --- a/src/iter/doubly_iter.rs +++ b/src/iter/doubly_iter.rs @@ -34,7 +34,7 @@ where fn next(&mut self) -> Option { self.0 .next() - .map(|p| unsafe { self.0.col.data_unchecked(&p) }) + .map(|p| unsafe { self.0.col.data_unchecked(p) }) } } @@ -46,7 +46,7 @@ where fn next_back(&mut self) -> Option { self.0 .next_back() - .map(|p| unsafe { self.0.col.data_unchecked(&p) }) + .map(|p| unsafe { self.0.col.data_unchecked(p) }) } } diff --git a/src/iter/doubly_iter_mut.rs b/src/iter/doubly_iter_mut.rs index a7a2300..4920b57 100644 --- a/src/iter/doubly_iter_mut.rs +++ b/src/iter/doubly_iter_mut.rs @@ -53,11 +53,11 @@ where type Item = &'a mut T; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { - false => self.current = self.col.node(p).next().get().cloned(), + false => self.current = self.col.node(p).next().get(), true => self.end(), } @@ -73,12 +73,12 @@ where P: PinnedVec>>, { fn next_back(&mut self) -> Option { - match &self.current_back { + match self.current_back { Some(p) => { // SAFETY: collection as alive as guaranteed by the `col` field. let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { - false => self.current_back = self.col.node(p).prev().get().cloned(), + false => self.current_back = self.col.node(p).prev().get(), true => self.end(), } unsafe { &mut *ptr }.data_mut() diff --git a/src/iter/doubly_iter_owned.rs b/src/iter/doubly_iter_owned.rs index dba5900..f27b68f 100644 --- a/src/iter/doubly_iter_owned.rs +++ b/src/iter/doubly_iter_owned.rs @@ -20,8 +20,8 @@ where P: PinnedVec>>, { pub(crate) fn new(col: CoreCol, P>) -> Self { - let current = col.ends().get(0).cloned(); - let current_back = col.ends().get(1).cloned(); + let current = col.ends().get(0); + let current_back = col.ends().get(1); Self { col, current, @@ -42,11 +42,11 @@ where type Item = T; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { - false => self.current = self.col.node(p).next().get().cloned(), + false => self.current = self.col.node(p).next().get(), true => self.end(), } @@ -62,12 +62,12 @@ where P: PinnedVec>>, { fn next_back(&mut self) -> Option { - match &self.current_back { + match self.current_back { Some(p) => { // SAFETY: collection as alive as guaranteed by the `col` field. let ptr = unsafe { p.ptr_mut() }; match self.current == self.current_back { - false => self.current_back = self.col.node(p).prev().get().cloned(), + false => self.current_back = self.col.node(p).prev().get(), true => self.end(), } diff --git a/src/iter/doubly_iter_ptr.rs b/src/iter/doubly_iter_ptr.rs index f5282ca..ccf15f5 100644 --- a/src/iter/doubly_iter_ptr.rs +++ b/src/iter/doubly_iter_ptr.rs @@ -44,11 +44,11 @@ where type Item = NodePtr>; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { let ptr = Some(p.clone()); match self.current == self.current_back { - false => self.current = self.col.node(p).next().get().cloned(), + false => self.current = self.col.node(p).next().get(), true => self.end(), } @@ -64,12 +64,12 @@ where P: PinnedVec>>, { fn next_back(&mut self) -> Option { - match &self.current_back { + match self.current_back { Some(p) => { let ptr = Some(p.clone()); match self.current == self.current_back { - false => self.current_back = self.col.node(p).prev().get().cloned(), + false => self.current_back = self.col.node(p).prev().get(), true => self.end(), } diff --git a/src/iter/doubly_link_iter.rs b/src/iter/doubly_link_iter.rs index 6864611..156df41 100644 --- a/src/iter/doubly_link_iter.rs +++ b/src/iter/doubly_link_iter.rs @@ -33,8 +33,8 @@ where #[inline(always)] fn next(&mut self) -> Option { self.0.next().map(|p| { - (unsafe { self.0.col.data_unchecked(&p.0) }, unsafe { - self.0.col.data_unchecked(&p.1) + (unsafe { self.0.col.data_unchecked(p.0) }, unsafe { + self.0.col.data_unchecked(p.1) }) }) } diff --git a/src/iter/doubly_link_iter_ptr.rs b/src/iter/doubly_link_iter_ptr.rs index af8b6bd..b29528f 100644 --- a/src/iter/doubly_link_iter_ptr.rs +++ b/src/iter/doubly_link_iter_ptr.rs @@ -46,13 +46,12 @@ where type Item = PairPtr; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { let (prev, curr) = p.clone(); match Some(&curr) == self.current_back.as_ref() { false => { - // - let next = self.col.node(&curr).next().get().cloned(); + let next = self.col.node(curr).next().get(); let new_current = next.map(|next| (curr.clone(), next)); self.current = new_current; } diff --git a/src/iter/singly_iter.rs b/src/iter/singly_iter.rs index d47cf37..6fcdbbd 100644 --- a/src/iter/singly_iter.rs +++ b/src/iter/singly_iter.rs @@ -30,7 +30,7 @@ where fn next(&mut self) -> Option { self.0 .next() - .map(|p| unsafe { self.0.col.data_unchecked(&p) }) + .map(|p| unsafe { self.0.col.data_unchecked(p) }) } } diff --git a/src/iter/singly_iter_mut.rs b/src/iter/singly_iter_mut.rs index 6c6356f..ecfb47b 100644 --- a/src/iter/singly_iter_mut.rs +++ b/src/iter/singly_iter_mut.rs @@ -19,7 +19,7 @@ where P: PinnedVec>>, { pub(crate) fn new_old(col: &'a mut CoreCol, P>) -> Self { - let current = col.ends().get().cloned(); + let current = col.ends().get(); Self { col, current } } @@ -38,11 +38,11 @@ where type Item = &'a mut T; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { // SAFETY: collection as alive as guaranteed by the `col` field. let ptr = unsafe { p.ptr_mut() }; - self.current = self.col.node(p).next().get().cloned(); + self.current = self.col.node(p).next().get(); unsafe { &mut *ptr }.data_mut() } None => None, diff --git a/src/iter/singly_iter_owned.rs b/src/iter/singly_iter_owned.rs index 691dbf0..0ec3e89 100644 --- a/src/iter/singly_iter_owned.rs +++ b/src/iter/singly_iter_owned.rs @@ -19,7 +19,7 @@ where P: PinnedVec>>, { pub(crate) fn new(col: CoreCol, P>) -> Self { - let current = col.ends().get().cloned(); + let current = col.ends().get(); Self { col, current } } } @@ -31,11 +31,11 @@ where type Item = T; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { // SAFETY: collection as alive as guaranteed by the `col` field. let ptr = unsafe { p.ptr_mut() }; - self.current = self.col.node(p).next().get().cloned(); + self.current = self.col.node(p).next().get(); unsafe { &mut *ptr }.take_data() } None => None, diff --git a/src/iter/singly_iter_ptr.rs b/src/iter/singly_iter_ptr.rs index 17285b5..77df197 100644 --- a/src/iter/singly_iter_ptr.rs +++ b/src/iter/singly_iter_ptr.rs @@ -30,10 +30,10 @@ where type Item = NodePtr>; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { let ptr = Some(p.clone()); - self.current = self.col.node(p).next().get().cloned(); + self.current = self.col.node(p).next().get(); ptr } None => None, From 6326272c55eb92adc20f5bafc5d32a0bdd9f383c Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 21:26:11 +0100 Subject: [PATCH 07/16] copy fixes --- src/list/ends_traits/doubly_ends_mut.rs | 82 ++++++++++++------------- src/memory/singly_reclaimer.rs | 8 +-- src/pointers/doubly_ptr.rs | 4 +- src/pointers/singly_ptr.rs | 2 +- src/tests/doubly.rs | 4 +- src/tests/singly.rs | 6 +- 6 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/list/ends_traits/doubly_ends_mut.rs b/src/list/ends_traits/doubly_ends_mut.rs index 96903b6..68a1d19 100644 --- a/src/list/ends_traits/doubly_ends_mut.rs +++ b/src/list/ends_traits/doubly_ends_mut.rs @@ -38,8 +38,7 @@ where { self.ends_mut() .get(FRONT_IDX) - .cloned() - .map(|p| unsafe { self.col_mut().data_mut_unchecked(&p) }) + .map(|p| unsafe { self.col_mut().data_mut_unchecked(p) }) } /// ***O(1)*** Returns a mutable reference to the back of the list, @@ -68,8 +67,7 @@ where { self.ends_mut() .get(BACK_IDX) - .cloned() - .map(|p| unsafe { self.col_mut().data_mut_unchecked(&p) }) + .map(|p| unsafe { self.col_mut().data_mut_unchecked(p) }) } // idx @@ -406,21 +404,21 @@ where /// assert!(list.eq_to_iter_vals(['c', 'd', 'e', 'b', 'a'])); /// ``` fn reverse(&mut self) { - if let Some(front) = self.ends().get(FRONT_IDX).cloned() { - let back = self.ends().get(BACK_IDX).cloned().expect("exists"); + if let Some(front) = self.ends().get(FRONT_IDX) { + let back = self.ends().get(BACK_IDX).expect("exists"); if front == back { return; } - let new_next_of_front = self.col().node(&back).next().get().cloned(); - let new_prev_of_back = self.col().node(&front).prev().get().cloned(); + let new_next_of_front = self.col().node(back).next().get(); + let new_prev_of_back = self.col().node(front).prev().get(); let mut prev = front.clone(); - let mut new_next = self.col().node(&prev).next().get().cloned(); + let mut new_next = self.col().node(prev).next().get(); while let Some(next) = new_next { - new_next = self.col().node(&next).next().get().cloned(); + new_next = self.col().node(next).next().get(); self.link(&next, &prev); @@ -432,18 +430,18 @@ where match new_next_of_front { Some(new_next_of_front) => self.link(&front, &new_next_of_front), - None => self.col_mut().node_mut(&front).next_mut().set_none(), + None => self.col_mut().node_mut(front).next_mut().set_none(), } match new_prev_of_back { Some(new_prev_of_back) => self.link(&new_prev_of_back, &back), - None => self.col_mut().node_mut(&back).prev_mut().set_none(), + None => self.col_mut().node_mut(back).prev_mut().set_none(), } // ends - let old_col_front = self.col().ends().get(FRONT_IDX).cloned().expect("exists"); - let old_col_back = self.col().ends().get(BACK_IDX).cloned().expect("exists"); + let old_col_front = self.col().ends().get(FRONT_IDX).expect("exists"); + let old_col_back = self.col().ends().get(BACK_IDX).expect("exists"); self.ends_mut().set_some(FRONT_IDX, back.clone()); self.ends_mut().set_some(BACK_IDX, front.clone()); @@ -494,9 +492,9 @@ where return; } - let next = self.col().node(&prev).next().get().cloned(); - let old_next = self.col().node(&mid).next().get().cloned(); - let old_prev = self.col().node(&mid).prev().get().cloned(); + let next = self.col().node(prev).next().get(); + let old_next = self.col().node(mid).next().get(); + let old_prev = self.col().node(mid).prev().get(); // update the gap match (old_prev.clone(), old_next.clone()) { @@ -504,13 +502,13 @@ where (Some(old_prev), Some(old_next)) => self.link(&old_prev, &old_next), (Some(old_prev), None) => { // idx must be col.back - self.col_mut().node_mut(&old_prev).next_mut().set_none(); + self.col_mut().node_mut(old_prev).next_mut().set_none(); self.col_mut().ends_mut().set_some(BACK_IDX, old_prev); } (None, Some(old_next)) => { // idx must be col.front - self.col_mut().node_mut(&old_next).prev_mut().set_none(); + self.col_mut().node_mut(old_next).prev_mut().set_none(); self.col_mut().ends_mut().set_some(FRONT_IDX, old_next); } @@ -520,13 +518,13 @@ where // update the fill match next { Some(next) => self.link(&mid, &next), - None => self.col_mut().node_mut(&mid).next_mut().set_none(), + None => self.col_mut().node_mut(mid).next_mut().set_none(), } self.link(&prev, &mid); // custom ends - let old_front = self.ends().get(FRONT_IDX).cloned(); - let old_back = self.ends().get(BACK_IDX).cloned(); + let old_front = self.ends().get(FRONT_IDX); + let old_back = self.ends().get(BACK_IDX); if let Some(old_back) = old_back.clone() { match old_back == prev { @@ -599,9 +597,9 @@ where return; } - let prev = self.col().node(&next).prev().get().cloned(); - let old_next = self.col().node(&mid).next().get().cloned(); - let old_prev = self.col().node(&mid).prev().get().cloned(); + let prev = self.col().node(next).prev().get(); + let old_next = self.col().node(mid).next().get(); + let old_prev = self.col().node(mid).prev().get(); // update the gap match (old_prev.clone(), old_next.clone()) { @@ -609,13 +607,13 @@ where (Some(old_prev), Some(old_next)) => self.link(&old_prev, &old_next), (Some(old_prev), None) => { // idx must be col.back - self.col_mut().node_mut(&old_prev).next_mut().set_none(); + self.col_mut().node_mut(old_prev).next_mut().set_none(); self.col_mut().ends_mut().set_some(BACK_IDX, old_prev); } (None, Some(old_next)) => { // idx must be col.front - self.col_mut().node_mut(&old_next).prev_mut().set_none(); + self.col_mut().node_mut(old_next).prev_mut().set_none(); self.col_mut().ends_mut().set_some(FRONT_IDX, old_next); } @@ -625,13 +623,13 @@ where // update the fill match prev { Some(prev) => self.link(&prev, &mid), - None => self.col_mut().node_mut(&mid).prev_mut().set_none(), + None => self.col_mut().node_mut(mid).prev_mut().set_none(), } self.link(&mid, &next); // custom ends - let old_front = self.ends().get(FRONT_IDX).cloned(); - let old_back = self.ends().get(BACK_IDX).cloned(); + let old_front = self.ends().get(FRONT_IDX); + let old_back = self.ends().get(BACK_IDX); if let Some(old_front) = &old_front { match old_front == &next { @@ -767,10 +765,10 @@ where return; } - let p_a = self.col().node(&a).prev().get().cloned(); - let p_b = self.col().node(&b).prev().get().cloned(); - let n_a = self.col().node(&a).next().get().cloned(); - let n_b = self.col().node(&b).next().get().cloned(); + let p_a = self.col().node(a).prev().get(); + let p_b = self.col().node(b).prev().get(); + let n_a = self.col().node(a).next().get(); + let n_b = self.col().node(b).next().get(); match (n_a.clone(), n_b.clone()) { (Some(n_a), _) if b == n_a => self.move_next_to(idx_a, idx_b), @@ -778,45 +776,45 @@ where _ => { match p_a { Some(p_a) => self.link(&p_a, &b), - None => self.col_mut().node_mut(&b).prev_mut().set_none(), + None => self.col_mut().node_mut(b).prev_mut().set_none(), } match p_b { Some(p_b) => self.link(&p_b, &a), - None => self.col_mut().node_mut(&a).prev_mut().set_none(), + None => self.col_mut().node_mut(a).prev_mut().set_none(), } match n_a { Some(n_a) => self.link(&b, &n_a), - None => self.col_mut().node_mut(&b).next_mut().set_none(), + None => self.col_mut().node_mut(b).next_mut().set_none(), } match n_b { Some(n_b) => self.link(&a, &n_b), - None => self.col_mut().node_mut(&a).next_mut().set_none(), + None => self.col_mut().node_mut(a).next_mut().set_none(), } // cache custom ends - let custom_front = match self.ends().get(FRONT_IDX).cloned() { + let custom_front = match self.ends().get(FRONT_IDX) { Some(x) if x == a => Some(b.clone()), Some(x) if x == b => Some(a.clone()), _ => None, }; - let custom_back = match self.ends().get(BACK_IDX).cloned() { + let custom_back = match self.ends().get(BACK_IDX) { Some(x) if x == a => Some(b.clone()), Some(x) if x == b => Some(a.clone()), _ => None, }; // update col ends - match self.col().ends().get(FRONT_IDX).cloned() { + match self.col().ends().get(FRONT_IDX) { Some(x) if x == a => self.col_mut().ends_mut().set_some(FRONT_IDX, b.clone()), Some(x) if x == b => self.col_mut().ends_mut().set_some(FRONT_IDX, a.clone()), _ => {} } - match self.col().ends().get(BACK_IDX).cloned() { + match self.col().ends().get(BACK_IDX) { Some(x) if x == a => self.col_mut().ends_mut().set_some(BACK_IDX, b), Some(x) if x == b => self.col_mut().ends_mut().set_some(BACK_IDX, a), _ => {} diff --git a/src/memory/singly_reclaimer.rs b/src/memory/singly_reclaimer.rs index 8eeb283..fd6c2a3 100644 --- a/src/memory/singly_reclaimer.rs +++ b/src/memory/singly_reclaimer.rs @@ -12,7 +12,7 @@ impl MemoryReclaimer> for SinglyReclaimer { { let mut nodes_moved = false; - if let Some(mut occupied_ptr) = col.ends().get().cloned() { + if let Some(mut occupied_ptr) = col.ends().get() { let mut prev = core::ptr::null(); // SAFETY: lifetime of `forward` iterator is limited to this method @@ -22,9 +22,9 @@ impl MemoryReclaimer> for SinglyReclaimer { for (v, vacant_ptr) in forward { if unsafe { &*vacant_ptr }.is_closed() { loop { - let o = col.position_of_unchecked(&occupied_ptr); + let o = col.position_of_unchecked(occupied_ptr); - let next = col.node(&occupied_ptr).next().get().cloned(); + let next = col.node(occupied_ptr).next().get(); let swapped = o > v; match swapped { @@ -72,7 +72,7 @@ fn swap( match prev.is_null() { false => { - col.node_mut(&NodePtr::new(prev)) + col.node_mut(NodePtr::new(prev)) .next_mut() .set(node_ptr(vacant)); } diff --git a/src/pointers/doubly_ptr.rs b/src/pointers/doubly_ptr.rs index b71d643..d0429c9 100644 --- a/src/pointers/doubly_ptr.rs +++ b/src/pointers/doubly_ptr.rs @@ -61,7 +61,7 @@ pub trait DoublyPointer { /// Alternatively, you may use `NodeIdx` for safe access. #[inline(always)] unsafe fn next(&self) -> Option> { - unsafe { self.node() }.next().get().cloned() + unsafe { self.node() }.next().get() } /// Returns the pointer to the prev node if exists; None otherwise. @@ -77,6 +77,6 @@ pub trait DoublyPointer { /// Alternatively, you may use `NodeIdx` for safe access. #[inline(always)] unsafe fn prev(&self) -> Option> { - unsafe { self.node() }.prev().get().cloned() + unsafe { self.node() }.prev().get() } } diff --git a/src/pointers/singly_ptr.rs b/src/pointers/singly_ptr.rs index a7bc474..0521ab2 100644 --- a/src/pointers/singly_ptr.rs +++ b/src/pointers/singly_ptr.rs @@ -61,6 +61,6 @@ pub trait SinglyPointer { /// Alternatively, you may use `NodeIdx` for safe access. #[inline(always)] unsafe fn next(&self) -> Option> { - unsafe { self.node() }.next().get().cloned() + unsafe { self.node() }.next().get() } } diff --git a/src/tests/doubly.rs b/src/tests/doubly.rs index aab252d..7275438 100644 --- a/src/tests/doubly.rs +++ b/src/tests/doubly.rs @@ -109,14 +109,14 @@ where assert!(iter.next().is_none()); } - fn next(&self, ptr: &NodePtr>) -> Option> { + fn next(&self, ptr: NodePtr>) -> Option> { self.0.node(ptr).next().get().map(|p| { let next_node = self.0.node(p); (p.clone(), next_node) }) } - fn prev(&self, ptr: &NodePtr>) -> Option> { + fn prev(&self, ptr: NodePtr>) -> Option> { self.0.node(ptr).prev().get().map(|p| { let prev_node = self.0.node(p); (p.clone(), prev_node) diff --git a/src/tests/singly.rs b/src/tests/singly.rs index 28a8142..ddb49fd 100644 --- a/src/tests/singly.rs +++ b/src/tests/singly.rs @@ -67,9 +67,9 @@ where assert!(iter.next().is_none()); } - fn next(&self, ptr: &NodePtr>) -> Option> { - self.0.node(ptr).next().get().cloned().map(|p| { - let next_node = self.0.node(&p); + fn next(&self, ptr: NodePtr>) -> Option> { + self.0.node(ptr).next().get().map(|p| { + let next_node = self.0.node(p); (p, next_node) }) } From 213ff62e7800fb260a28d7260831fbcbcf6f63da Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 21:29:17 +0100 Subject: [PATCH 08/16] copy fixes --- src/list/linear.rs | 52 ++++++++++++++++---------------- src/list/mut_doubly.rs | 52 ++++++++++++++++---------------- src/list/mut_doubly_recursive.rs | 30 ++++++++---------- src/list/mut_singly.rs | 16 +++++----- 4 files changed, 72 insertions(+), 78 deletions(-) diff --git a/src/list/linear.rs b/src/list/linear.rs index 6d14cbe..dec58a8 100644 --- a/src/list/linear.rs +++ b/src/list/linear.rs @@ -45,13 +45,13 @@ where let prev = self.iter_ptr().nth(x - 1).expect(OOB); let idx = self.0.push(value); - if let Some(next) = self.0.node(&prev).next().get().cloned() { - self.0.node_mut(&idx).next_mut().set_some(next); + if let Some(next) = self.0.node(prev).next().get() { + self.0.node_mut(idx).next_mut().set_some(next); } - self.0.node_mut(&prev).next_mut().set_some(idx.clone()); + self.0.node_mut(prev).next_mut().set_some(idx); - NodeIdx::new(self.memory_state(), &idx) + NodeIdx::new(self.memory_state(), idx) } } } @@ -96,12 +96,12 @@ where (prev, idx) }; - match self.0.node(&idx).next().get().cloned() { - Some(next) => self.0.node_mut(&prev).next_mut().set_some(next), - None => self.0.node_mut(&prev).next_mut().set_none(), + match self.0.node(idx).next().get() { + Some(next) => self.0.node_mut(prev).next_mut().set_some(next), + None => self.0.node_mut(prev).next_mut().set_none(), } - Some(self.0.close_and_reclaim(&idx)) + Some(self.0.close_and_reclaim(idx)) } } } @@ -148,15 +148,15 @@ where _ => { let prev = self.iter_ptr().nth(position - 1).expect(OOB); let idx = self.0.push(value); - let next = self.0.node(&prev).next().get().cloned().expect("exists"); + let next = self.0.node(prev).next().get().expect("exists"); - self.0.node_mut(&prev).next_mut().set_some(idx.clone()); - self.0.node_mut(&next).prev_mut().set_some(idx.clone()); + self.0.node_mut(prev).next_mut().set_some(idx); + self.0.node_mut(next).prev_mut().set_some(idx); - self.0.node_mut(&idx).prev_mut().set_some(prev); - self.0.node_mut(&idx).next_mut().set_some(next); + self.0.node_mut(idx).prev_mut().set_some(prev); + self.0.node_mut(idx).next_mut().set_some(next); - NodeIdx::new(self.memory_state(), &idx) + NodeIdx::new(self.memory_state(), idx) } } } @@ -200,15 +200,15 @@ where let mut iter = self.iter_ptr().rev(); let next = iter.nth(x - 1).expect(OOB); let idx = self.0.push(value); - let prev = self.0.node(&next).prev().get().expect("exists").clone(); + let prev = self.0.node(next).prev().get().expect("exists"); - self.0.node_mut(&next).prev_mut().set_some(idx.clone()); - self.0.node_mut(&prev).next_mut().set_some(idx.clone()); + self.0.node_mut(next).prev_mut().set_some(idx); + self.0.node_mut(prev).next_mut().set_some(idx); - self.0.node_mut(&idx).prev_mut().set_some(prev); - self.0.node_mut(&idx).next_mut().set_some(next); + self.0.node_mut(idx).prev_mut().set_some(prev); + self.0.node_mut(idx).next_mut().set_some(next); - NodeIdx::new(self.memory_state(), &idx) + NodeIdx::new(self.memory_state(), idx) } } } @@ -255,10 +255,10 @@ where (prev, idx, next) }; - self.0.node_mut(&prev).next_mut().set_some(next.clone()); - self.0.node_mut(&next).prev_mut().set_some(prev); + self.0.node_mut(prev).next_mut().set_some(next); + self.0.node_mut(next).prev_mut().set_some(prev); - Some(self.0.close_and_reclaim(&idx)) + Some(self.0.close_and_reclaim(idx)) } } } @@ -305,10 +305,10 @@ where (prev, idx, next) }; - self.0.node_mut(&prev).next_mut().set_some(next.clone()); - self.0.node_mut(&next).prev_mut().set_some(prev); + self.0.node_mut(prev).next_mut().set_some(next); + self.0.node_mut(next).prev_mut().set_some(prev); - Some(self.0.close_and_reclaim(&idx)) + Some(self.0.close_and_reclaim(idx)) } } } diff --git a/src/list/mut_doubly.rs b/src/list/mut_doubly.rs index 068e4a6..0ee1d69 100644 --- a/src/list/mut_doubly.rs +++ b/src/list/mut_doubly.rs @@ -35,8 +35,8 @@ where /// assert_eq!(Some(&'z'), list.front()); /// ``` pub fn swap_front(&mut self, new_front: T) -> Option { - match self.0.ends().get(FRONT_IDX).cloned() { - Some(p) => Some(self.0.swap_data(&p, new_front)), + match self.0.ends().get(FRONT_IDX) { + Some(p) => Some(self.0.swap_data(p, new_front)), None => { self.push_front(new_front); None @@ -66,8 +66,8 @@ where /// assert_eq!(Some(&'z'), list.back()); /// ``` pub fn swap_back(&mut self, new_back: T) -> Option { - match self.0.ends().get(BACK_IDX).cloned() { - Some(p) => Some(self.0.swap_data(&p, new_back)), + match self.0.ends().get(BACK_IDX) { + Some(p) => Some(self.0.swap_data(p, new_back)), None => { self.push_back(new_back); None @@ -96,19 +96,19 @@ where pub fn push_front(&mut self, value: T) -> DoublyIdx { let idx = self.0.push(value); - match self.0.ends().get(FRONT_IDX).cloned() { + match self.0.ends().get(FRONT_IDX) { Some(front) => { - self.0.node_mut(&front).prev_mut().set_some(idx.clone()); - self.0.node_mut(&idx).next_mut().set_some(front); - self.0.ends_mut().set_some(FRONT_IDX, idx.clone()); + self.0.node_mut(front).prev_mut().set_some(idx); + self.0.node_mut(idx).next_mut().set_some(front); + self.0.ends_mut().set_some(FRONT_IDX, idx); } None => { - self.0.ends_mut().set_some(FRONT_IDX, idx.clone()); - self.0.ends_mut().set_some(BACK_IDX, idx.clone()); + self.0.ends_mut().set_some(FRONT_IDX, idx); + self.0.ends_mut().set_some(BACK_IDX, idx); } } - NodeIdx::new(self.0.memory_state(), &idx) + NodeIdx::new(self.0.memory_state(), idx) } /// ***O(1)*** Pushes the `value` to the `back` of the list. @@ -132,19 +132,19 @@ where pub fn push_back(&mut self, value: T) -> DoublyIdx { let idx = self.0.push(value); - match self.0.ends().get(BACK_IDX).cloned() { + match self.0.ends().get(BACK_IDX) { Some(back) => { - self.0.node_mut(&back).next_mut().set_some(idx.clone()); - self.0.node_mut(&idx).prev_mut().set_some(back); - self.0.ends_mut().set_some(BACK_IDX, idx.clone()); + self.0.node_mut(back).next_mut().set_some(idx); + self.0.node_mut(idx).prev_mut().set_some(back); + self.0.ends_mut().set_some(BACK_IDX, idx); } None => { - self.0.ends_mut().set_some(FRONT_IDX, idx.clone()); - self.0.ends_mut().set_some(BACK_IDX, idx.clone()); + self.0.ends_mut().set_some(FRONT_IDX, idx); + self.0.ends_mut().set_some(BACK_IDX, idx); } } - NodeIdx::new(self.0.memory_state(), &idx) + NodeIdx::new(self.0.memory_state(), idx) } /// ***O(1)*** Pops and returns the value at the `front` of the list; returns None if the list is empty. @@ -167,15 +167,15 @@ where /// assert!(list.is_empty()); /// ``` pub fn pop_front(&mut self) -> Option { - self.0.ends().get(FRONT_IDX).cloned().map(|front| { - match self.0.node(&front).next().get().cloned() { + self.0.ends().get(FRONT_IDX).map(|front| { + match self.0.node(front).next().get() { Some(new_front) => { - self.0.node_mut(&new_front).prev_mut().clear(); + self.0.node_mut(new_front).prev_mut().clear(); self.0.ends_mut().set_some(FRONT_IDX, new_front); } None => self.0.ends_mut().clear(), } - self.0.close_and_reclaim(&front) + self.0.close_and_reclaim(front) }) } @@ -199,15 +199,15 @@ where /// assert!(list.is_empty()); /// ``` pub fn pop_back(&mut self) -> Option { - self.0.ends().get(BACK_IDX).cloned().map(|back| { - match self.0.node(&back).prev().get().cloned() { + self.0.ends().get(BACK_IDX).map(|back| { + match self.0.node(back).prev().get() { Some(new_back) => { - self.0.node_mut(&new_back).next_mut().clear(); + self.0.node_mut(new_back).next_mut().clear(); self.0.ends_mut().set_some(BACK_IDX, new_back); } None => self.0.ends_mut().clear(), } - self.0.close_and_reclaim(&back) + self.0.close_and_reclaim(back) }) } diff --git a/src/list/mut_doubly_recursive.rs b/src/list/mut_doubly_recursive.rs index 8d5fb7e..feb6ba3 100644 --- a/src/list/mut_doubly_recursive.rs +++ b/src/list/mut_doubly_recursive.rs @@ -46,18 +46,15 @@ where (_, false) => { /* no update when new is empty */ } (false, true) => { let new_front = ends.get(FRONT_IDX).expect("exists"); - self.0.ends_mut().set_some(FRONT_IDX, new_front.clone()); + self.0.ends_mut().set_some(FRONT_IDX, new_front); } (true, true) => { - let new_front = ends.get(FRONT_IDX).expect("exists").clone(); - let new_back = ends.get(BACK_IDX).expect("exists").clone(); - let old_front = self.0.ends().get(FRONT_IDX).expect("exists").clone(); + let new_front = ends.get(FRONT_IDX).expect("exists"); + let new_back = ends.get(BACK_IDX).expect("exists"); + let old_front = self.0.ends().get(FRONT_IDX).expect("exists"); - self.0 - .node_mut(&old_front) - .prev_mut() - .set_some(new_back.clone()); - self.0.node_mut(&new_back).next_mut().set_some(old_front); + self.0.node_mut(old_front).prev_mut().set_some(new_back); + self.0.node_mut(new_back).next_mut().set_some(old_front); self.0.ends_mut().set_some(FRONT_IDX, new_front); } @@ -107,19 +104,16 @@ where match (old_back_exists, new_back_exists) { (_, false) => { /* no update when new is empty */ } (false, true) => { - let new_back = ends.get(BACK_IDX).expect("exists").clone(); + let new_back = ends.get(BACK_IDX).expect("exists"); self.0.ends_mut().set_some(BACK_IDX, new_back); } (true, true) => { - let new_front = ends.get(FRONT_IDX).expect("exists").clone(); - let new_back = ends.get(BACK_IDX).expect("exists").clone(); - let old_back = self.0.ends().get(BACK_IDX).expect("exists").clone(); + let new_front = ends.get(FRONT_IDX).expect("exists"); + let new_back = ends.get(BACK_IDX).expect("exists"); + let old_back = self.0.ends().get(BACK_IDX).expect("exists"); - self.0 - .node_mut(&old_back) - .next_mut() - .set_some(new_front.clone()); - self.0.node_mut(&new_front).prev_mut().set_some(old_back); + self.0.node_mut(old_back).next_mut().set_some(new_front); + self.0.node_mut(new_front).prev_mut().set_some(old_back); self.0.ends_mut().set_some(BACK_IDX, new_back); } diff --git a/src/list/mut_singly.rs b/src/list/mut_singly.rs index 38a38e8..2b08f71 100644 --- a/src/list/mut_singly.rs +++ b/src/list/mut_singly.rs @@ -30,8 +30,8 @@ where /// assert_eq!(Some(&'z'), list.front()); /// ``` pub fn swap_front(&mut self, new_front: T) -> Option { - match self.0.ends().get().cloned() { - Some(p) => Some(self.0.swap_data(&p, new_front)), + match self.0.ends().get() { + Some(p) => Some(self.0.swap_data(p, new_front)), None => { self.push_front(new_front); None @@ -60,13 +60,13 @@ where pub fn push_front(&mut self, value: T) -> SinglyIdx { let idx = self.0.push(value); - if let Some(front) = self.0.ends().get().cloned() { - self.0.node_mut(&idx).next_mut().set_some(front.clone()); + if let Some(front) = self.0.ends().get() { + self.0.node_mut(idx).next_mut().set_some(front.clone()); } self.0.ends_mut().set_some(idx.clone()); - NodeIdx::new(self.0.memory_state(), &idx) + NodeIdx::new(self.0.memory_state(), idx) } /// ***O(1)*** Pops and returns the value at the `front` of the list; returns None if the list is empty. @@ -89,12 +89,12 @@ where /// assert!(list.is_empty()); /// ``` pub fn pop_front(&mut self) -> Option { - self.0.ends().get().cloned().map(|front| { - match self.0.node(&front).next().get().cloned() { + self.0.ends().get().map(|front| { + match self.0.node(front).next().get() { Some(new_front) => self.0.ends_mut().set_some(new_front.clone()), None => self.0.ends_mut().clear(), } - self.0.close_and_reclaim(&front) + self.0.close_and_reclaim(front) }) } From a6031b83642d4e38b863e20d9dd1b0746e5d4a48 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 21:34:21 +0100 Subject: [PATCH 09/16] copy fixes --- src/list/idx_doubly.rs | 84 ++++++++++----------- src/list/iter_traits/doubly_iterable.rs | 34 ++++----- src/list/iter_traits/doubly_iterable_mut.rs | 14 ++-- src/list/iter_traits/singly_iterable.rs | 8 +- src/list/iter_traits/singly_iterable_mut.rs | 2 +- src/list/linear_eq.rs | 24 +++--- 6 files changed, 82 insertions(+), 84 deletions(-) diff --git a/src/list/idx_doubly.rs b/src/list/idx_doubly.rs index 02e7097..9ce3894 100644 --- a/src/list/idx_doubly.rs +++ b/src/list/idx_doubly.rs @@ -41,21 +41,21 @@ where pub fn remove(&mut self, idx: DoublyIdx) -> T { let idx = self.0.try_get_ptr(idx).expect(IDX_ERR); let [prev, next] = { - let node = self.0.node(&idx); - [node.prev().get().cloned(), node.next().get().cloned()] + let node = self.0.node(idx); + [node.prev().get(), node.next().get()] }; - match prev.clone() { - Some(prev) => self.0.node_mut(&prev).next_mut().set(next.clone()), - None => self.0.ends_mut().set(FRONT_IDX, next.clone()), + match prev { + Some(prev) => self.0.node_mut(prev).next_mut().set(next), + None => self.0.ends_mut().set(FRONT_IDX, next), } match next { - Some(next) => self.0.node_mut(&next).prev_mut().set(prev), + Some(next) => self.0.node_mut(next).prev_mut().set(prev), None => self.0.ends_mut().set(BACK_IDX, prev), } - self.0.close_and_reclaim(&idx) + self.0.close_and_reclaim(idx) } /// ***O(1)*** Inserts the given `value` as the next of the node with the given `idx`. @@ -87,21 +87,21 @@ where ///``` pub fn insert_next_to(&mut self, idx: DoublyIdx, value: T) -> DoublyIdx { let prev = self.0.try_get_ptr(idx).expect(IDX_ERR); - let next = self.0.node(&prev).next().get().cloned(); + let next = self.0.node(prev).next().get(); let idx = self.0.push(value); - self.0.node_mut(&prev).next_mut().set_some(idx.clone()); - self.0.node_mut(&idx).prev_mut().set_some(prev); + self.0.node_mut(prev).next_mut().set_some(idx); + self.0.node_mut(idx).prev_mut().set_some(prev); match next { Some(next) => { - self.0.node_mut(&next).prev_mut().set_some(idx.clone()); - self.0.node_mut(&idx).next_mut().set_some(next); + self.0.node_mut(next).prev_mut().set_some(idx); + self.0.node_mut(idx).next_mut().set_some(next); } - None => self.0.ends_mut().set_some(BACK_IDX, idx.clone()), + None => self.0.ends_mut().set_some(BACK_IDX, idx), } - NodeIdx::new(self.memory_state(), &idx) + NodeIdx::new(self.memory_state(), idx) } /// ***O(1)*** Inserts the given `value` as the next of the node with the given `idx`. @@ -134,21 +134,21 @@ where ///``` pub fn insert_prev_to(&mut self, idx: DoublyIdx, value: T) -> DoublyIdx { let next = self.0.try_get_ptr(idx).expect(IDX_ERR); - let prev = self.0.node(&next).prev().get().cloned(); + let prev = self.0.node(next).prev().get(); let idx = self.0.push(value); - self.0.node_mut(&next).prev_mut().set_some(idx.clone()); - self.0.node_mut(&idx).next_mut().set_some(next); + self.0.node_mut(next).prev_mut().set_some(idx); + self.0.node_mut(idx).next_mut().set_some(next); match prev { Some(prev) => { - self.0.node_mut(&prev).next_mut().set_some(idx.clone()); - self.0.node_mut(&idx).prev_mut().set_some(prev); + self.0.node_mut(prev).next_mut().set_some(idx); + self.0.node_mut(idx).prev_mut().set_some(prev); } - None => self.0.ends_mut().set_some(FRONT_IDX, idx.clone()), + None => self.0.ends_mut().set_some(FRONT_IDX, idx), } - NodeIdx::new(self.memory_state(), &idx) + NodeIdx::new(self.memory_state(), idx) } /// ***O(1)*** Removes and returns value at the given `idx` of the list. @@ -186,21 +186,21 @@ where true => { let idx = idx.node_ptr(); let [prev, next] = { - let node = self.0.node(&idx); - [node.prev().get().cloned(), node.next().get().cloned()] + let node = self.0.node(idx); + [node.prev().get(), node.next().get()] }; - match prev.clone() { - Some(prev) => self.0.node_mut(&prev).next_mut().set(next.clone()), - None => self.0.ends_mut().set(FRONT_IDX, next.clone()), + match prev { + Some(prev) => self.0.node_mut(prev).next_mut().set(next), + None => self.0.ends_mut().set(FRONT_IDX, next), } match next { - Some(next) => self.0.node_mut(&next).prev_mut().set(prev), + Some(next) => self.0.node_mut(next).prev_mut().set(prev), None => self.0.ends_mut().set(BACK_IDX, prev), } - Some(self.0.close_and_reclaim(&idx)) + Some(self.0.close_and_reclaim(idx)) } false => None, } @@ -245,21 +245,21 @@ where value: T, ) -> Result, NodeIdxError> { let prev = self.0.try_get_ptr(idx)?; - let next = self.0.node(&prev).next().get().cloned(); + let next = self.0.node(prev).next().get(); let idx = self.0.push(value); - self.0.node_mut(&prev).next_mut().set_some(idx.clone()); - self.0.node_mut(&idx).prev_mut().set_some(prev); + self.0.node_mut(prev).next_mut().set_some(idx); + self.0.node_mut(idx).prev_mut().set_some(prev); match next { Some(next) => { - self.0.node_mut(&next).prev_mut().set_some(idx.clone()); - self.0.node_mut(&idx).next_mut().set_some(next); + self.0.node_mut(next).prev_mut().set_some(idx); + self.0.node_mut(idx).next_mut().set_some(next); } - None => self.0.ends_mut().set_some(BACK_IDX, idx.clone()), + None => self.0.ends_mut().set_some(BACK_IDX, idx), } - Ok(NodeIdx::new(self.memory_state(), &idx)) + Ok(NodeIdx::new(self.memory_state(), idx)) } /// ***O(1)*** Inserts the given `value` as the next of the node with the given `idx`. @@ -301,20 +301,20 @@ where value: T, ) -> Result, NodeIdxError> { let next = self.0.try_get_ptr(idx)?; - let prev = self.0.node(&next).prev().get().cloned(); + let prev = self.0.node(next).prev().get(); let idx = self.0.push(value); - self.0.node_mut(&next).prev_mut().set_some(idx.clone()); - self.0.node_mut(&idx).next_mut().set_some(next); + self.0.node_mut(next).prev_mut().set_some(idx); + self.0.node_mut(idx).next_mut().set_some(next); match prev { Some(prev) => { - self.0.node_mut(&prev).next_mut().set_some(idx.clone()); - self.0.node_mut(&idx).prev_mut().set_some(prev); + self.0.node_mut(prev).next_mut().set_some(idx); + self.0.node_mut(idx).prev_mut().set_some(prev); } - None => self.0.ends_mut().set_some(FRONT_IDX, idx.clone()), + None => self.0.ends_mut().set_some(FRONT_IDX, idx), } - Ok(NodeIdx::new(self.memory_state(), &idx)) + Ok(NodeIdx::new(self.memory_state(), idx)) } } diff --git a/src/list/iter_traits/doubly_iterable.rs b/src/list/iter_traits/doubly_iterable.rs index 1fe33c8..769e552 100644 --- a/src/list/iter_traits/doubly_iterable.rs +++ b/src/list/iter_traits/doubly_iterable.rs @@ -21,8 +21,8 @@ where where M: 'a, { - let a = self.ends().get(FRONT_IDX).cloned(); - let b = self.ends().get(BACK_IDX).cloned(); + let a = self.ends().get(FRONT_IDX); + let b = self.ends().get(BACK_IDX); DoublyIterPtr::new(self.col(), a, b) } @@ -68,8 +68,8 @@ where where M: 'a, { - let a = self.ends().get(FRONT_IDX).cloned(); - let b = self.ends().get(BACK_IDX).cloned(); + let a = self.ends().get(FRONT_IDX); + let b = self.ends().get(BACK_IDX); DoublyIter::new(self.col(), a, b) } @@ -95,15 +95,13 @@ where where M: 'a, { - let a = self.ends().get(FRONT_IDX).cloned(); - let b = a - .as_ref() - .and_then(|a| self.col().node(a).next().get().cloned()); + let a = self.ends().get(FRONT_IDX); + let b = a.and_then(|a| self.col().node(a).next().get()); let begin = match (a, b) { (Some(a), Some(b)) => Some((a, b)), _ => None, }; - let end = self.ends().get(BACK_IDX).cloned(); + let end = self.ends().get(BACK_IDX); DoublyLinkIter::new(self.col(), begin, end) } @@ -144,7 +142,7 @@ where P: 'a, { let s = self.col().memory_state(); - self.iter_ptr().map(move |ptr| DoublyIdx::new(s, &ptr)) + self.iter_ptr().map(move |ptr| DoublyIdx::new(s, ptr)) } /// Returns an iterator of pointers to the elements of the list. @@ -205,11 +203,11 @@ where let iter1 = self.iter_from(pivot_idx); let pivot = self.col().try_get_ptr(pivot_idx).expect(OOB); - let a = self.ends().get(FRONT_IDX).expect(OOB).clone(); + let a = self.ends().get(FRONT_IDX).expect(OOB); let iter2 = match pivot == a { true => DoublyIter::new(self.col(), None, None), - false => match self.col().node(&pivot).prev().get().cloned() { + false => match self.col().node(pivot).prev().get() { Some(b) => DoublyIter::new(self.col(), Some(a), Some(b)), None => DoublyIter::new(self.col(), None, None), }, @@ -248,7 +246,7 @@ where M: 'a, { let a = self.col().try_get_ptr(idx).expect(OOB); - let b = self.ends().get(BACK_IDX).cloned(); + let b = self.ends().get(BACK_IDX); DoublyIter::new(self.col(), Some(a), b) } @@ -283,7 +281,7 @@ where M: 'a, { let b = self.col().try_get_ptr(idx).expect(OOB); - let a = self.ends().get(FRONT_IDX).cloned(); + let a = self.ends().get(FRONT_IDX); DoublyIter::new(self.col(), a, Some(b)).rev() } @@ -316,9 +314,9 @@ where M: 'a, { let a = self.col().try_get_ptr(idx).expect(OOB); - let b = self.col().node(&a).next().get().cloned(); + let b = self.col().node(a).next().get(); let begin = b.map(|b| (a, b)); - let end = self.ends().get(BACK_IDX).cloned(); + let end = self.ends().get(BACK_IDX); DoublyLinkIter::new(self.col(), begin, end) } @@ -405,7 +403,7 @@ where .iter() .map(|n| match n.prev().get() { Some(x) => { - let x = self.col().node(&x).data().unwrap(); + let x = self.col().node(x).data().unwrap(); alloc::format!("{} ", x) } None => "x ".to_string(), @@ -427,7 +425,7 @@ where .iter() .map(|n| match n.next().get() { Some(x) => { - let x = self.col().node(&x).data().unwrap(); + let x = self.col().node(x).data().unwrap(); alloc::format!("{} ", x) } None => "x ".to_string(), diff --git a/src/list/iter_traits/doubly_iterable_mut.rs b/src/list/iter_traits/doubly_iterable_mut.rs index bbbac01..c9fa255 100644 --- a/src/list/iter_traits/doubly_iterable_mut.rs +++ b/src/list/iter_traits/doubly_iterable_mut.rs @@ -39,8 +39,8 @@ where where M: 'a, { - let a = self.ends().get(FRONT_IDX).cloned(); - let b = self.ends().get(BACK_IDX).cloned(); + let a = self.ends().get(FRONT_IDX); + let b = self.ends().get(BACK_IDX); DoublyIterMut::new(self.col_mut(), a, b) } @@ -79,7 +79,7 @@ where M: 'a, { let a = self.col().try_get_ptr(idx).expect(OOB); - let b = self.ends().get(BACK_IDX).cloned(); + let b = self.ends().get(BACK_IDX); DoublyIterMut::new(self.col_mut(), Some(a), b) } @@ -116,7 +116,7 @@ where M: 'a, { let b = self.col().try_get_ptr(idx).expect(OOB); - let a = self.col().ends().get(FRONT_IDX).cloned(); + let a = self.col().ends().get(FRONT_IDX); DoublyIterMut::new(self.col_mut(), a, Some(b)).rev() } @@ -161,10 +161,10 @@ where M: 'a, { let a1 = self.col().try_get_ptr(pivot_idx).expect(OOB); - let b1 = self.ends().get(BACK_IDX).cloned().expect(OOB); + let b1 = self.ends().get(BACK_IDX).expect(OOB); - let a2 = self.ends().get(FRONT_IDX).cloned().expect(OOB); - let b2 = self.col().node(&a1).prev().get().cloned(); + let a2 = self.ends().get(FRONT_IDX).expect(OOB); + let b2 = self.col().node(a1).prev().get(); let second = match a1 == a2 { true => [None, None], diff --git a/src/list/iter_traits/singly_iterable.rs b/src/list/iter_traits/singly_iterable.rs index d6bc3ba..59273bd 100644 --- a/src/list/iter_traits/singly_iterable.rs +++ b/src/list/iter_traits/singly_iterable.rs @@ -20,7 +20,7 @@ where where M: 'a, { - let a = self.ends().get().cloned(); + let a = self.ends().get(); SinglyIterPtr::new(self.col(), a) } @@ -49,7 +49,7 @@ where where M: 'a, { - let a = self.ends().get().cloned(); + let a = self.ends().get(); SinglyIter::new(self.col(), a) } @@ -83,7 +83,7 @@ where P: 'a, { let s = self.col().memory_state(); - self.iter_ptr().map(move |ptr| SinglyIdx::new(s, &ptr)) + self.iter_ptr().map(move |ptr| SinglyIdx::new(s, ptr)) } /// Returns an iterator of pointers to the elements of the list. @@ -218,7 +218,7 @@ where .iter() .map(|n| match n.next().get() { Some(x) => { - let x = self.col().node(&x).data().unwrap(); + let x = self.col().node(x).data().unwrap(); alloc::format!("{} ", x) } None => "x ".to_string(), diff --git a/src/list/iter_traits/singly_iterable_mut.rs b/src/list/iter_traits/singly_iterable_mut.rs index c1accca..06e6898 100644 --- a/src/list/iter_traits/singly_iterable_mut.rs +++ b/src/list/iter_traits/singly_iterable_mut.rs @@ -36,7 +36,7 @@ where where M: 'a, { - let a = self.ends().get().cloned(); + let a = self.ends().get(); SinglyIterMut::new(self.col_mut(), a) } diff --git a/src/list/linear_eq.rs b/src/list/linear_eq.rs index f0e5102..40e40f0 100644 --- a/src/list/linear_eq.rs +++ b/src/list/linear_eq.rs @@ -51,8 +51,8 @@ where /// ``` pub fn idx_of(&self, value: &T) -> Option> { self.iter_ptr() - .find(|p| self.0.node(p).data().is_some_and(|d| d == value)) - .map(|p| NodeIdx::new(self.memory_state(), &p)) + .find(|p| self.0.node(*p).data().is_some_and(|d| d == value)) + .map(|p| NodeIdx::new(self.memory_state(), p)) } /// ***O(n)*** Performs a forward search from the front and returns `true` if there exists a node with value equal to the given `value`. @@ -71,7 +71,7 @@ where /// ``` pub fn contains(&self, value: &T) -> bool { self.iter_ptr() - .any(|p| self.0.node(&p).data().is_some_and(|d| d == value)) + .any(|p| self.0.node(p).data().is_some_and(|d| d == value)) } /// ***O(n)*** Performs a forward search from the front and returns the position of the first node with value equal to the given `value`. @@ -94,7 +94,7 @@ where pub fn position_of_value(&self, value: &T) -> Option { self.iter_ptr().enumerate().find_map(|(i, p)| { self.0 - .node(&p) + .node(p) .data() .is_some_and(|d| d == value) .then_some(i) @@ -151,8 +151,8 @@ where /// ``` pub fn idx_of(&self, value: &T) -> Option> { self.iter_ptr() - .find(|p| self.0.node(p).data().is_some_and(|d| d == value)) - .map(|p| NodeIdx::new(self.memory_state(), &p)) + .find(|p| self.0.node(*p).data().is_some_and(|d| d == value)) + .map(|p| NodeIdx::new(self.memory_state(), p)) } /// ***O(n)*** Performs a forward search from the front and returns `true` if there exists a node with value equal to the given `value`. @@ -171,7 +171,7 @@ where /// ``` pub fn contains(&self, value: &T) -> bool { self.iter_ptr() - .any(|p| self.0.node(&p).data().is_some_and(|d| d == value)) + .any(|p| self.0.node(p).data().is_some_and(|d| d == value)) } /// ***O(n)*** Performs a forward search from the front and returns the position of the first node with value equal to the given `value`. @@ -194,7 +194,7 @@ where pub fn position_of_value(&self, value: &T) -> Option { self.iter_ptr().enumerate().find_map(|(i, p)| { self.0 - .node(&p) + .node(p) .data() .is_some_and(|d| d == value) .then_some(i) @@ -243,8 +243,8 @@ where pub fn idx_of_from_back(&self, value: &T) -> Option> { self.iter_ptr() .rev() - .find(|p| self.0.node(p).data().is_some_and(|d| d == value)) - .map(|p| NodeIdx::new(self.memory_state(), &p)) + .find(|p| self.0.node(*p).data().is_some_and(|d| d == value)) + .map(|p| NodeIdx::new(self.memory_state(), p)) } /// ***O(n)*** Performs a backward search from the back and returns `true` if there exists a node with value equal to the given `value`. @@ -264,7 +264,7 @@ where pub fn contains_from_back(&self, value: &T) -> bool { self.iter_ptr() .rev() - .any(|p| self.0.node(&p).data().is_some_and(|d| d == value)) + .any(|p| self.0.node(p).data().is_some_and(|d| d == value)) } /// ***O(n)*** Performs a backward search from the back and returns the position of the first node with value equal to the given `value`. @@ -287,7 +287,7 @@ where pub fn position_of_from_back(&self, value: &T) -> Option { self.iter_ptr().rev().enumerate().find_map(|(i, p)| { self.0 - .node(&p) + .node(p) .data() .is_some_and(|d| d == value) .then_some(i) From 02a08693b56ec57d7032225f0e358d55a18f256b Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 21:37:13 +0100 Subject: [PATCH 10/16] copy fixes --- src/list/ends_traits/doubly_ends.rs | 4 ++-- src/list/ends_traits/doubly_ends_mut.rs | 30 ++++++++++++------------- src/list/ends_traits/singly_ends.rs | 2 +- src/list/ends_traits/singly_ends_mut.rs | 3 +-- src/list/helper_traits/col.rs | 2 +- src/list/helper_traits/doubly_ends.rs | 14 ++++++------ 6 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/list/ends_traits/doubly_ends.rs b/src/list/ends_traits/doubly_ends.rs index 30eb5d6..6b4b221 100644 --- a/src/list/ends_traits/doubly_ends.rs +++ b/src/list/ends_traits/doubly_ends.rs @@ -528,7 +528,7 @@ where /// ``` fn next_idx_of(&self, idx: DoublyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); - let next_ptr = self.col().node(&ptr).next().get(); + let next_ptr = self.col().node(ptr).next().get(); next_ptr.map(|p| DoublyIdx::new(self.col().memory_state(), p)) } @@ -595,7 +595,7 @@ where /// ``` fn prev_idx_of(&self, idx: DoublyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); - let prev_ptr = self.col().node(&ptr).prev().get(); + let prev_ptr = self.col().node(ptr).prev().get(); prev_ptr.map(|p| DoublyIdx::new(self.col().memory_state(), p)) } diff --git a/src/list/ends_traits/doubly_ends_mut.rs b/src/list/ends_traits/doubly_ends_mut.rs index 68a1d19..ec65126 100644 --- a/src/list/ends_traits/doubly_ends_mut.rs +++ b/src/list/ends_traits/doubly_ends_mut.rs @@ -420,7 +420,7 @@ where while let Some(next) = new_next { new_next = self.col().node(next).next().get(); - self.link(&next, &prev); + self.link(next, prev); prev = next; if prev == back { @@ -429,12 +429,12 @@ where } match new_next_of_front { - Some(new_next_of_front) => self.link(&front, &new_next_of_front), + Some(new_next_of_front) => self.link(front, new_next_of_front), None => self.col_mut().node_mut(front).next_mut().set_none(), } match new_prev_of_back { - Some(new_prev_of_back) => self.link(&new_prev_of_back, &back), + Some(new_prev_of_back) => self.link(new_prev_of_back, back), None => self.col_mut().node_mut(back).prev_mut().set_none(), } @@ -499,7 +499,7 @@ where // update the gap match (old_prev.clone(), old_next.clone()) { (Some(old_prev), _) if old_prev == prev => return, - (Some(old_prev), Some(old_next)) => self.link(&old_prev, &old_next), + (Some(old_prev), Some(old_next)) => self.link(old_prev, old_next), (Some(old_prev), None) => { // idx must be col.back self.col_mut().node_mut(old_prev).next_mut().set_none(); @@ -517,10 +517,10 @@ where // update the fill match next { - Some(next) => self.link(&mid, &next), + Some(next) => self.link(mid, next), None => self.col_mut().node_mut(mid).next_mut().set_none(), } - self.link(&prev, &mid); + self.link(prev, mid); // custom ends let old_front = self.ends().get(FRONT_IDX); @@ -604,7 +604,7 @@ where // update the gap match (old_prev.clone(), old_next.clone()) { (_, Some(old_next)) if old_next == next => return, - (Some(old_prev), Some(old_next)) => self.link(&old_prev, &old_next), + (Some(old_prev), Some(old_next)) => self.link(old_prev, old_next), (Some(old_prev), None) => { // idx must be col.back self.col_mut().node_mut(old_prev).next_mut().set_none(); @@ -622,10 +622,10 @@ where // update the fill match prev { - Some(prev) => self.link(&prev, &mid), + Some(prev) => self.link(prev, mid), None => self.col_mut().node_mut(mid).prev_mut().set_none(), } - self.link(&mid, &next); + self.link(mid, next); // custom ends let old_front = self.ends().get(FRONT_IDX); @@ -775,22 +775,22 @@ where (_, Some(n_b)) if a == n_b => self.move_next_to(idx_b, idx_a), _ => { match p_a { - Some(p_a) => self.link(&p_a, &b), + Some(p_a) => self.link(p_a, b), None => self.col_mut().node_mut(b).prev_mut().set_none(), } match p_b { - Some(p_b) => self.link(&p_b, &a), + Some(p_b) => self.link(p_b, a), None => self.col_mut().node_mut(a).prev_mut().set_none(), } match n_a { - Some(n_a) => self.link(&b, &n_a), + Some(n_a) => self.link(b, n_a), None => self.col_mut().node_mut(b).next_mut().set_none(), } match n_b { - Some(n_b) => self.link(&a, &n_b), + Some(n_b) => self.link(a, n_b), None => self.col_mut().node_mut(a).next_mut().set_none(), } @@ -875,7 +875,7 @@ where unsafe fn add_link(&mut self, a: DoublyIdx, b: DoublyIdx) { let a = self.col().try_get_ptr(a).expect(OOB); let b = self.col().try_get_ptr(b).expect(OOB); - self.link(&a, &b); + self.link(a, b); } /// ***O(1)*** Removes a link between `a` and `b`; i.e., @@ -920,7 +920,7 @@ where unsafe fn remove_link(&mut self, a: DoublyIdx, b: DoublyIdx) { let a = self.col().try_get_ptr(a).expect(OOB); let b = self.col().try_get_ptr(b).expect(OOB); - self.unlink(&a, &b); + self.unlink(a, b); } /// ***O(1)*** Sets the `front` of the list as the `new_front`. diff --git a/src/list/ends_traits/singly_ends.rs b/src/list/ends_traits/singly_ends.rs index e1d2d75..cef9b29 100644 --- a/src/list/ends_traits/singly_ends.rs +++ b/src/list/ends_traits/singly_ends.rs @@ -491,7 +491,7 @@ where /// ``` fn next_idx_of(&self, idx: SinglyIdx) -> Option> { let ptr = self.col().try_get_ptr(idx).expect(IDX_ERR); - let next_ptr = self.col().node(&ptr).next().get(); + let next_ptr = self.col().node(ptr).next().get(); next_ptr.map(|p| SinglyIdx::new(self.col().memory_state(), p)) } diff --git a/src/list/ends_traits/singly_ends_mut.rs b/src/list/ends_traits/singly_ends_mut.rs index d3925fa..f1f214f 100644 --- a/src/list/ends_traits/singly_ends_mut.rs +++ b/src/list/ends_traits/singly_ends_mut.rs @@ -35,8 +35,7 @@ where { self.ends_mut() .get() - .cloned() - .map(|p| unsafe { self.col_mut().data_mut_unchecked(&p) }) + .map(|p| unsafe { self.col_mut().data_mut_unchecked(p) }) } // idx diff --git a/src/list/helper_traits/col.rs b/src/list/helper_traits/col.rs index 49b8998..f0ffefe 100644 --- a/src/list/helper_traits/col.rs +++ b/src/list/helper_traits/col.rs @@ -12,7 +12,7 @@ where /// Returns a reference to the underlying self referential collection. fn col(&self) -> &SelfRefCol; - fn ptr_to_idx(&self, idx: &NodePtr) -> NodeIdx { + fn ptr_to_idx(&self, idx: NodePtr) -> NodeIdx { NodeIdx::new(self.col().memory_state(), idx) } } diff --git a/src/list/helper_traits/doubly_ends.rs b/src/list/helper_traits/doubly_ends.rs index ffdb7d1..7633c4f 100644 --- a/src/list/helper_traits/doubly_ends.rs +++ b/src/list/helper_traits/doubly_ends.rs @@ -23,10 +23,10 @@ where let begin = match range.start_bound() { Excluded(x) => { let ptr = self.col().try_get_ptr(*x)?; - self.col().node(&ptr).next().get().cloned() + self.col().node(ptr).next().get() } Included(x) => Some(self.col().try_get_ptr(*x)?), - Unbounded => self.col().ends().get(FRONT_IDX).cloned(), + Unbounded => self.col().ends().get(FRONT_IDX), }; Ok(begin) @@ -43,12 +43,12 @@ where Excluded(x) => { let ptr = self.col().try_get_ptr(*x)?; match ptr == front { - false => self.col().node(&ptr).prev().get().cloned(), + false => self.col().node(ptr).prev().get(), true => None, } } Included(x) => Some(self.col().try_get_ptr(*x)?), - Unbounded => self.ends().get(BACK_IDX).cloned(), + Unbounded => self.ends().get(BACK_IDX), }; Ok(end) @@ -87,13 +87,13 @@ where // links #[inline(always)] - fn is_linked(&self, prev: &NodePtr>, next: &NodePtr>) -> bool { + fn is_linked(&self, prev: NodePtr>, next: NodePtr>) -> bool { self.col().node(prev).next().get() == Some(next) && self.col().node(next).prev().get() == Some(prev) } #[inline(always)] - fn link(&mut self, prev: &NodePtr>, next: &NodePtr>) { + fn link(&mut self, prev: NodePtr>, next: NodePtr>) { self.col_mut() .node_mut(prev) .next_mut() @@ -105,7 +105,7 @@ where } #[inline(always)] - fn unlink(&mut self, prev: &NodePtr>, next: &NodePtr>) { + fn unlink(&mut self, prev: NodePtr>, next: NodePtr>) { debug_assert!(self.is_linked(prev, next)); self.col_mut().node_mut(prev).next_mut().set_none(); From 71fabe0e2de96b8570378674a66837fe5b1bae8a Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 22:00:12 +0100 Subject: [PATCH 11/16] copy fixes --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 169dc08..5c9729d 100644 --- a/README.md +++ b/README.md @@ -87,16 +87,16 @@ _The suffix "\_x" indicates that the iterators yield elements in arbitrary order Linked lists are all about traversal. Therefore, the linked lists defined in this crate, especially the **DoublyList**, provide various useful ways to iterate over the data: -| | | -| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`iter()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter) | from front to back of the list | -| `iter().rev()` | from back to front | -| [`iter_from(idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_from) | forward starting from the node with the given index to the back | -| [`iter_backward_from(idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_backward_from) | backward starting from the node with the given index to the front | -| [`ring_iter(pivot_idx: &DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.ring_iter) | forward starting from the pivot node with the given index until the node before the pivot node, linking back to the front and giving the list the **circular behavior** | -| [`iter_links()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_links) | forward over the links, rather than nodes, from front to back | -| [`iter_x()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.iter_x) | over elements in an arbitrary order, which is often faster when the order is not required | -| | | +| | | +| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`iter()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter) | from front to back of the list | +| `iter().rev()` | from back to front | +| [`iter_from(idx: DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_from) | forward starting from the node with the given index to the back | +| [`iter_backward_from(idx: DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_backward_from) | backward starting from the node with the given index to the front | +| [`ring_iter(pivot_idx: DoublyIdx)`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.ring_iter) | forward starting from the pivot node with the given index until the node before the pivot node, linking back to the front and giving the list the **circular behavior** | +| [`iter_links()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/trait.DoublyIterable.html#method.iter_links) | forward over the links, rather than nodes, from front to back | +| [`iter_x()`](https://docs.rs/orx-linked-list/latest/orx_linked_list/type.DoublyList.html#method.iter_x) | over elements in an arbitrary order, which is often faster when the order is not required | +| | | As typical, above-mentioned methods have the "\_mut" suffixed versions for iterating over mutable references. From 6dda815efe0f9ae9849fdd18d7e0674956feba85 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 22:12:31 +0100 Subject: [PATCH 12/16] clippy copy clone fixes --- src/iter/doubly_iter_mut_chain.rs | 5 ++--- src/iter/doubly_iter_ptr.rs | 4 ++-- src/iter/doubly_link_iter_ptr.rs | 6 +++--- src/iter/singly_iter_ptr.rs | 2 +- src/list/ends_traits/doubly_ends_mut.rs | 14 +++++++------- src/list/mut_singly.rs | 4 ++-- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/iter/doubly_iter_mut_chain.rs b/src/iter/doubly_iter_mut_chain.rs index e78e243..eacdd68 100644 --- a/src/iter/doubly_iter_mut_chain.rs +++ b/src/iter/doubly_iter_mut_chain.rs @@ -26,7 +26,7 @@ where first: [Option>>; 2], second: [Option>>; 2], ) -> Self { - let iter = DoublyIterMut::new(col, first[0].clone(), first[1].clone()); + let iter = DoublyIterMut::new(col, first[0], first[1]); let [second_front, second_back] = second; Self { iter, @@ -50,8 +50,7 @@ where true => None, false => { self.consumed_first = true; - self.iter - .restart_for(self.second_front.clone(), self.second_back.clone()); + self.iter.restart_for(self.second_front, self.second_back); self.iter.next() } }, diff --git a/src/iter/doubly_iter_ptr.rs b/src/iter/doubly_iter_ptr.rs index ccf15f5..3894127 100644 --- a/src/iter/doubly_iter_ptr.rs +++ b/src/iter/doubly_iter_ptr.rs @@ -89,8 +89,8 @@ where fn clone(&self) -> Self { Self { col: self.col, - current: self.current.clone(), - current_back: self.current_back.clone(), + current: self.current, + current_back: self.current_back, } } } diff --git a/src/iter/doubly_link_iter_ptr.rs b/src/iter/doubly_link_iter_ptr.rs index b29528f..a071120 100644 --- a/src/iter/doubly_link_iter_ptr.rs +++ b/src/iter/doubly_link_iter_ptr.rs @@ -48,7 +48,7 @@ where fn next(&mut self) -> Option { match self.current { Some(p) => { - let (prev, curr) = p.clone(); + let (prev, curr) = p; match Some(&curr) == self.current_back.as_ref() { false => { let next = self.col.node(curr).next().get(); @@ -74,8 +74,8 @@ where fn clone(&self) -> Self { Self { col: self.col, - current: self.current.clone(), - current_back: self.current_back.clone(), + current: self.current, + current_back: self.current_back, } } } diff --git a/src/iter/singly_iter_ptr.rs b/src/iter/singly_iter_ptr.rs index 77df197..585197d 100644 --- a/src/iter/singly_iter_ptr.rs +++ b/src/iter/singly_iter_ptr.rs @@ -50,7 +50,7 @@ where fn clone(&self) -> Self { Self { col: self.col, - current: self.current.clone(), + current: self.current, } } } diff --git a/src/list/ends_traits/doubly_ends_mut.rs b/src/list/ends_traits/doubly_ends_mut.rs index ec65126..176e15b 100644 --- a/src/list/ends_traits/doubly_ends_mut.rs +++ b/src/list/ends_traits/doubly_ends_mut.rs @@ -414,7 +414,7 @@ where let new_next_of_front = self.col().node(back).next().get(); let new_prev_of_back = self.col().node(front).prev().get(); - let mut prev = front.clone(); + let mut prev = front; let mut new_next = self.col().node(prev).next().get(); while let Some(next) = new_next { @@ -443,11 +443,11 @@ where let old_col_front = self.col().ends().get(FRONT_IDX).expect("exists"); let old_col_back = self.col().ends().get(BACK_IDX).expect("exists"); - self.ends_mut().set_some(FRONT_IDX, back.clone()); - self.ends_mut().set_some(BACK_IDX, front.clone()); + self.ends_mut().set_some(FRONT_IDX, back); + self.ends_mut().set_some(BACK_IDX, front); if front == old_col_front { - self.col_mut().ends_mut().set_some(FRONT_IDX, back.clone()); + self.col_mut().ends_mut().set_some(FRONT_IDX, back); } if back == old_col_back { @@ -526,7 +526,7 @@ where let old_front = self.ends().get(FRONT_IDX); let old_back = self.ends().get(BACK_IDX); - if let Some(old_back) = old_back.clone() { + if let Some(old_back) = old_back { match old_back == prev { true => { // new node placed in front @@ -535,7 +535,7 @@ where false => { if old_back == mid { // old front is moved away - let old_front = old_front.clone().expect("exists"); + let old_front = old_front.expect("exists"); match mid == old_front { false => { let new_back = old_prev.expect("exists"); @@ -640,7 +640,7 @@ where false => { if old_front == &mid { // old front is moved away - let old_back = old_back.clone().expect("exists"); + let old_back = old_back.expect("exists"); match mid == old_back { false => { let new_front = old_next.expect("exists"); diff --git a/src/list/mut_singly.rs b/src/list/mut_singly.rs index 2b08f71..b243410 100644 --- a/src/list/mut_singly.rs +++ b/src/list/mut_singly.rs @@ -61,7 +61,7 @@ where let idx = self.0.push(value); if let Some(front) = self.0.ends().get() { - self.0.node_mut(idx).next_mut().set_some(front.clone()); + self.0.node_mut(idx).next_mut().set_some(front); } self.0.ends_mut().set_some(idx.clone()); @@ -91,7 +91,7 @@ where pub fn pop_front(&mut self) -> Option { self.0.ends().get().map(|front| { match self.0.node(front).next().get() { - Some(new_front) => self.0.ends_mut().set_some(new_front.clone()), + Some(new_front) => self.0.ends_mut().set_some(new_front), None => self.0.ends_mut().clear(), } self.0.close_and_reclaim(front) From f1aa4f2e300ee56f3eafcc05f6dd7695ac1e880c Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 22:13:54 +0100 Subject: [PATCH 13/16] fix clippy clone copy --- src/iter/doubly_iter_ptr.rs | 4 ++-- src/iter/singly_iter_ptr.rs | 2 +- src/list/ends_traits/doubly_ends_mut.rs | 4 ++-- src/list/helper_traits/doubly_ends.rs | 10 ++-------- src/list/mut_singly.rs | 2 +- src/tests/doubly.rs | 4 ++-- 6 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/iter/doubly_iter_ptr.rs b/src/iter/doubly_iter_ptr.rs index 3894127..687a2ce 100644 --- a/src/iter/doubly_iter_ptr.rs +++ b/src/iter/doubly_iter_ptr.rs @@ -46,7 +46,7 @@ where fn next(&mut self) -> Option { match self.current { Some(p) => { - let ptr = Some(p.clone()); + let ptr = Some(p); match self.current == self.current_back { false => self.current = self.col.node(p).next().get(), true => self.end(), @@ -66,7 +66,7 @@ where fn next_back(&mut self) -> Option { match self.current_back { Some(p) => { - let ptr = Some(p.clone()); + let ptr = Some(p); match self.current == self.current_back { false => self.current_back = self.col.node(p).prev().get(), diff --git a/src/iter/singly_iter_ptr.rs b/src/iter/singly_iter_ptr.rs index 585197d..ccdb17c 100644 --- a/src/iter/singly_iter_ptr.rs +++ b/src/iter/singly_iter_ptr.rs @@ -32,7 +32,7 @@ where fn next(&mut self) -> Option { match self.current { Some(p) => { - let ptr = Some(p.clone()); + let ptr = Some(p); self.current = self.col.node(p).next().get(); ptr } diff --git a/src/list/ends_traits/doubly_ends_mut.rs b/src/list/ends_traits/doubly_ends_mut.rs index 176e15b..35a76ce 100644 --- a/src/list/ends_traits/doubly_ends_mut.rs +++ b/src/list/ends_traits/doubly_ends_mut.rs @@ -497,7 +497,7 @@ where let old_prev = self.col().node(mid).prev().get(); // update the gap - match (old_prev.clone(), old_next.clone()) { + match (old_prev, old_next) { (Some(old_prev), _) if old_prev == prev => return, (Some(old_prev), Some(old_next)) => self.link(old_prev, old_next), (Some(old_prev), None) => { @@ -602,7 +602,7 @@ where let old_prev = self.col().node(mid).prev().get(); // update the gap - match (old_prev.clone(), old_next.clone()) { + match (old_prev, old_next) { (_, Some(old_next)) if old_next == next => return, (Some(old_prev), Some(old_next)) => self.link(old_prev, old_next), (Some(old_prev), None) => { diff --git a/src/list/helper_traits/doubly_ends.rs b/src/list/helper_traits/doubly_ends.rs index 7633c4f..3cc563a 100644 --- a/src/list/helper_traits/doubly_ends.rs +++ b/src/list/helper_traits/doubly_ends.rs @@ -94,14 +94,8 @@ where #[inline(always)] fn link(&mut self, prev: NodePtr>, next: NodePtr>) { - self.col_mut() - .node_mut(prev) - .next_mut() - .set_some(next.clone()); - self.col_mut() - .node_mut(next) - .prev_mut() - .set_some(prev.clone()); + self.col_mut().node_mut(prev).next_mut().set_some(next); + self.col_mut().node_mut(next).prev_mut().set_some(prev); } #[inline(always)] diff --git a/src/list/mut_singly.rs b/src/list/mut_singly.rs index b243410..30fa226 100644 --- a/src/list/mut_singly.rs +++ b/src/list/mut_singly.rs @@ -64,7 +64,7 @@ where self.0.node_mut(idx).next_mut().set_some(front); } - self.0.ends_mut().set_some(idx.clone()); + self.0.ends_mut().set_some(idx); NodeIdx::new(self.0.memory_state(), idx) } diff --git a/src/tests/doubly.rs b/src/tests/doubly.rs index 7275438..8786776 100644 --- a/src/tests/doubly.rs +++ b/src/tests/doubly.rs @@ -112,14 +112,14 @@ where fn next(&self, ptr: NodePtr>) -> Option> { self.0.node(ptr).next().get().map(|p| { let next_node = self.0.node(p); - (p.clone(), next_node) + (p, next_node) }) } fn prev(&self, ptr: NodePtr>) -> Option> { self.0.node(ptr).prev().get().map(|p| { let prev_node = self.0.node(p); - (p.clone(), prev_node) + (p, prev_node) }) } } From 61d67af1ab1bb0e9bb5b263ee7fc82f5c88f8a27 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 22:14:54 +0100 Subject: [PATCH 14/16] fix clippy clone copy --- src/iter/doubly_link_iter_ptr.rs | 2 +- src/list/ends_traits/doubly_ends_mut.rs | 18 +++++++++--------- tests/slice_doubly.rs | 4 ++-- tests/slice_mut_doubly.rs | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/iter/doubly_link_iter_ptr.rs b/src/iter/doubly_link_iter_ptr.rs index a071120..691de21 100644 --- a/src/iter/doubly_link_iter_ptr.rs +++ b/src/iter/doubly_link_iter_ptr.rs @@ -52,7 +52,7 @@ where match Some(&curr) == self.current_back.as_ref() { false => { let next = self.col.node(curr).next().get(); - let new_current = next.map(|next| (curr.clone(), next)); + let new_current = next.map(|next| (curr, next)); self.current = new_current; } true => self.end(), diff --git a/src/list/ends_traits/doubly_ends_mut.rs b/src/list/ends_traits/doubly_ends_mut.rs index 35a76ce..126761b 100644 --- a/src/list/ends_traits/doubly_ends_mut.rs +++ b/src/list/ends_traits/doubly_ends_mut.rs @@ -530,7 +530,7 @@ where match old_back == prev { true => { // new node placed in front - self.ends_mut().set_some(BACK_IDX, mid.clone()) + self.ends_mut().set_some(BACK_IDX, mid) } false => { if old_back == mid { @@ -635,7 +635,7 @@ where match old_front == &next { true => { // new node placed in front - self.ends_mut().set_some(FRONT_IDX, mid.clone()) + self.ends_mut().set_some(FRONT_IDX, mid) } false => { if old_front == &mid { @@ -770,7 +770,7 @@ where let n_a = self.col().node(a).next().get(); let n_b = self.col().node(b).next().get(); - match (n_a.clone(), n_b.clone()) { + match (n_a, n_b) { (Some(n_a), _) if b == n_a => self.move_next_to(idx_a, idx_b), (_, Some(n_b)) if a == n_b => self.move_next_to(idx_b, idx_a), _ => { @@ -796,21 +796,21 @@ where // cache custom ends let custom_front = match self.ends().get(FRONT_IDX) { - Some(x) if x == a => Some(b.clone()), - Some(x) if x == b => Some(a.clone()), + Some(x) if x == a => Some(b), + Some(x) if x == b => Some(a), _ => None, }; let custom_back = match self.ends().get(BACK_IDX) { - Some(x) if x == a => Some(b.clone()), - Some(x) if x == b => Some(a.clone()), + Some(x) if x == a => Some(b), + Some(x) if x == b => Some(a), _ => None, }; // update col ends match self.col().ends().get(FRONT_IDX) { - Some(x) if x == a => self.col_mut().ends_mut().set_some(FRONT_IDX, b.clone()), - Some(x) if x == b => self.col_mut().ends_mut().set_some(FRONT_IDX, a.clone()), + Some(x) if x == a => self.col_mut().ends_mut().set_some(FRONT_IDX, b), + Some(x) if x == b => self.col_mut().ends_mut().set_some(FRONT_IDX, a), _ => {} } diff --git a/tests/slice_doubly.rs b/tests/slice_doubly.rs index 1cfa1f1..18f1656 100644 --- a/tests/slice_doubly.rs +++ b/tests/slice_doubly.rs @@ -23,7 +23,7 @@ fn empty_from_nonempty() { let c = list.push_back('c'); assert!(list.eq_to_iter_vals(['a', 'b', 'c'])); - let indices = [a.clone(), b.clone(), c.clone()]; + let indices = [a, b, c.clone()]; for x in &indices { assert_empty_slice(&list.slice(x..x)); @@ -40,7 +40,7 @@ fn singleton_slice() { let expected = ['a', 'b', 'c']; assert!(list.eq_to_iter_refs(expected.iter())); - let indices = [a.clone(), b.clone(), c.clone()]; + let indices = [a, b, c.clone()]; for (i, x) in indices.iter().enumerate() { let slice = list.slice(x..=x); diff --git a/tests/slice_mut_doubly.rs b/tests/slice_mut_doubly.rs index c64b72e..c3dc214 100644 --- a/tests/slice_mut_doubly.rs +++ b/tests/slice_mut_doubly.rs @@ -23,7 +23,7 @@ fn empty_from_nonempty() { let c = list.push_back('c'); assert!(list.eq_to_iter_vals(['a', 'b', 'c'])); - let indices = [a.clone(), b.clone(), c.clone()]; + let indices = [a, b, c.clone()]; for x in &indices { assert_empty_slice(&list.slice_mut(x..x)); @@ -39,7 +39,7 @@ fn singleton_slice() { let expected = ['x', 'y', 'z']; - let indices = [a.clone(), b.clone(), c.clone()]; + let indices = [a, b, c.clone()]; for (i, x) in indices.iter().copied().enumerate() { let mut slice = list.slice_mut(x..=x); From 19c95813e988eb39337ccc54a7e5f153ff3f781c Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 22:17:41 +0100 Subject: [PATCH 15/16] clippy fix for safety documentation --- src/list/common_traits/index.rs | 2 +- src/pointers/doubly_ptr.rs | 7 +++++++ src/pointers/singly_ptr.rs | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/list/common_traits/index.rs b/src/list/common_traits/index.rs index 0288e9b..095b7bc 100644 --- a/src/list/common_traits/index.rs +++ b/src/list/common_traits/index.rs @@ -65,7 +65,7 @@ where } } -impl<'i, T, M, P> IndexMut> for List, M, P> +impl IndexMut> for List, M, P> where M: MemoryPolicy>, P: PinnedVec>>, diff --git a/src/pointers/doubly_ptr.rs b/src/pointers/doubly_ptr.rs index d0429c9..fd0a165 100644 --- a/src/pointers/doubly_ptr.rs +++ b/src/pointers/doubly_ptr.rs @@ -14,6 +14,13 @@ impl DoublyPointer for DoublyPtr { /// A node pointer in a doubly linked list. pub trait DoublyPointer { /// Returns the raw pointer to the node. + /// + /// # SAFETY + /// + /// This method is unsafe as node pointers implement `Send` and `Sync`. + /// + /// It is safe dereference the received pointer if we know that `is_valid_for(col)` would + /// return `true` where `col` is the collection that this pointer is created from. unsafe fn raw_ptr(&self) -> *mut Node>; /// Returns a reference to the node. diff --git a/src/pointers/singly_ptr.rs b/src/pointers/singly_ptr.rs index 0521ab2..036f2c6 100644 --- a/src/pointers/singly_ptr.rs +++ b/src/pointers/singly_ptr.rs @@ -14,6 +14,13 @@ impl SinglyPointer for SinglyPtr { /// A node pointer in a Singly linked list. pub trait SinglyPointer { /// Returns the raw pointer to the node. + /// + /// # SAFETY + /// + /// This method is unsafe as node pointers implement `Send` and `Sync`. + /// + /// It is safe dereference the received pointer if we know that `is_valid_for(col)` would + /// return `true` where `col` is the collection that this pointer is created from. unsafe fn raw_ptr(&self) -> *mut Node>; /// Returns a reference to the node. From 11a5b423e1f9c12442d0936d2bd11e182a336e37 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 22 Nov 2025 22:42:20 +0100 Subject: [PATCH 16/16] target orx-selfref-col temporary branch --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3e8528d..4c3d5a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "orx-linked-list" -version = "3.10.0" +version = "4.0.0" edition = "2024" authors = ["orxfun "] description = "A linked list implementation with unique features and an extended list of constant time methods providing high performance traversals and mutations." @@ -16,7 +16,7 @@ orx-pinned-vec = { version = "3.21.0", default-features = false } orx-fixed-vec = { version = "3.22.0", default-features = false } orx-split-vec = { version = "3.22.0", default-features = false } orx-concurrent-iter = { version = "3.1.0", default-features = false } -orx-selfref-col = { path = "../orx-selfref-col", default-features = false } +orx-selfref-col = { git = "https://github.com/orxfun/orx-selfref-col.git", branch = "make-NodeIdx-Send", default-features = false } orx-parallel = { version = "3.3.0", default-features = false, optional = true } [dev-dependencies]