diff --git a/Cargo.toml b/Cargo.toml index 409dbaa..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 = { version = "2.14.0", 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] diff --git a/README.md b/README.md index 260c5c4..5c9729d 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/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 { 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 244e3ea..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 = 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(), + false => self.current = self.col.node(p).next().get(), true => self.end(), } @@ -73,11 +73,12 @@ where P: PinnedVec>>, { fn next_back(&mut self) -> Option { - match &self.current_back { + 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(), + 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_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_owned.rs b/src/iter/doubly_iter_owned.rs index c3e899e..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 = 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(), + false => self.current = self.col.node(p).next().get(), true => self.end(), } @@ -62,11 +62,12 @@ where P: PinnedVec>>, { fn next_back(&mut self) -> Option { - match &self.current_back { + 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(), + 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..687a2ce 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()); + let ptr = Some(p); 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()); + let ptr = Some(p); 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(), } @@ -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.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..691de21 100644 --- a/src/iter/doubly_link_iter_ptr.rs +++ b/src/iter/doubly_link_iter_ptr.rs @@ -46,14 +46,13 @@ where type Item = PairPtr; fn next(&mut self) -> Option { - match &self.current { + 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().cloned(); - let new_current = next.map(|next| (curr.clone(), next)); + let next = self.col.node(curr).next().get(); + let new_current = next.map(|next| (curr, next)); self.current = new_current; } true => self.end(), @@ -75,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.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 ae7aa97..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,10 +38,11 @@ where type Item = &'a mut T; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { - let ptr = p.ptr_mut(); - self.current = self.col.node(p).next().get().cloned(); + // SAFETY: collection as alive as guaranteed by the `col` field. + let ptr = unsafe { p.ptr_mut() }; + 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 d8dcd37..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,10 +31,11 @@ where type Item = T; fn next(&mut self) -> Option { - match &self.current { + match self.current { Some(p) => { - let ptr = p.ptr_mut(); - self.current = self.col.node(p).next().get().cloned(); + // SAFETY: collection as alive as guaranteed by the `col` field. + let ptr = unsafe { p.ptr_mut() }; + 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..ccdb17c 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(); + let ptr = Some(p); + self.current = self.col.node(p).next().get(); ptr } None => None, @@ -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/common_traits/index.rs b/src/list/common_traits/index.rs index 4bd246e..095b7bc 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 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/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 cb0ba4e..6b4b221 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,10 +174,10 @@ 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 { + 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,10 +265,10 @@ 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 { + 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,10 +370,10 @@ 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> + fn get<'a>(&'a self, idx: DoublyIdx) -> Option<&'a T> where M: 'a, P: 'a, @@ -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,10 +481,10 @@ 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> + fn try_get<'a>(&'a self, idx: DoublyIdx) -> Result<&'a T, NodeIdxError> where M: 'a, P: 'a, @@ -518,17 +518,17 @@ 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> { + 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)) } @@ -553,15 +553,15 @@ 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> + 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`. @@ -585,17 +585,17 @@ 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> { + 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)) } @@ -620,15 +620,15 @@ 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> + 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..126761b 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 @@ -107,33 +105,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 +152,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,10 +174,10 @@ 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> + fn get_mut<'a>(&'a mut self, idx: DoublyIdx) -> Option<&'a mut T> where M: 'a, P: 'a, @@ -224,33 +222,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 +269,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,10 +291,10 @@ 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> + fn try_get_mut<'a>(&'a mut self, idx: DoublyIdx) -> Result<&'a mut T, NodeIdxError> where M: 'a, P: 'a, @@ -330,17 +328,17 @@ 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'])); /// ``` - 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`. @@ -364,17 +362,17 @@ 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'])); /// ``` - 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). @@ -406,23 +404,23 @@ 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 prev = front; + 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); + self.link(next, prev); prev = next; if prev == back { @@ -431,25 +429,25 @@ 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(), + 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), - None => self.col_mut().node_mut(&back).prev_mut().set_none(), + Some(new_prev_of_back) => self.link(new_prev_of_back, back), + 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()); + 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 { @@ -477,16 +475,16 @@ 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) { + 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); @@ -494,23 +492,23 @@ 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()) { + 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), 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); } @@ -519,25 +517,25 @@ where // update the fill match next { - Some(next) => self.link(&mid, &next), - None => self.col_mut().node_mut(&mid).next_mut().set_none(), + 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).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() { + if let Some(old_back) = old_back { 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 { // 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"); @@ -582,16 +580,16 @@ 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) { + 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); @@ -599,23 +597,23 @@ 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()) { + 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), 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); } @@ -624,25 +622,25 @@ where // update the fill match prev { - Some(prev) => self.link(&prev, &mid), - None => self.col_mut().node_mut(&mid).prev_mut().set_none(), + 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).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 { 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 { // 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"); @@ -687,19 +685,19 @@ 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) { + 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` @@ -719,19 +717,19 @@ 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) { + 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`. @@ -750,16 +748,16 @@ 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) { + 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); @@ -767,56 +765,56 @@ 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()) { + 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), _ => { match p_a { - Some(p_a) => self.link(&p_a, &b), - None => self.col_mut().node_mut(&b).prev_mut().set_none(), + 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), - None => self.col_mut().node_mut(&a).prev_mut().set_none(), + 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), - None => self.col_mut().node_mut(&b).next_mut().set_none(), + 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), - None => self.col_mut().node_mut(&a).next_mut().set_none(), + Some(n_b) => self.link(a, n_b), + None => self.col_mut().node_mut(a).next_mut().set_none(), } // cache custom ends - let custom_front = match self.ends().get(FRONT_IDX).cloned() { - Some(x) if x == a => Some(b.clone()), - Some(x) if x == b => Some(a.clone()), + let custom_front = match self.ends().get(FRONT_IDX) { + Some(x) if x == a => Some(b), + Some(x) if x == b => Some(a), _ => None, }; - let custom_back = match self.ends().get(BACK_IDX).cloned() { - Some(x) if x == a => Some(b.clone()), - Some(x) if x == b => Some(a.clone()), + let custom_back = match self.ends().get(BACK_IDX) { + 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).cloned() { - 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(FRONT_IDX) { + 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), _ => {} } - 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), _ => {} @@ -861,11 +859,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])); @@ -874,10 +872,10 @@ 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); + self.link(a, b); } /// ***O(1)*** Removes a link between `a` and `b`; i.e., @@ -906,11 +904,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])); @@ -919,10 +917,10 @@ 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); + self.unlink(a, b); } /// ***O(1)*** Sets the `front` of the list as the `new_front`. @@ -948,11 +946,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])); @@ -961,7 +959,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); } @@ -989,11 +987,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])); @@ -1002,7 +1000,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..cef9b29 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,10 +137,10 @@ 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 { + 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,10 +228,10 @@ 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 { + 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,10 +333,10 @@ 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> + fn get<'a>(&'a self, idx: SinglyIdx) -> Option<&'a T> where M: 'a, P: 'a, @@ -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,10 +444,10 @@ 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> + fn try_get<'a>(&'a self, idx: SinglyIdx) -> Result<&'a T, NodeIdxError> where M: 'a, P: 'a, @@ -481,17 +481,17 @@ 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> { + 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)) } @@ -516,15 +516,15 @@ 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> + 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..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 @@ -74,33 +73,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 +120,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,10 +142,10 @@ 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> + fn get_mut<'a>(&'a mut self, idx: SinglyIdx) -> Option<&'a mut T> where M: 'a, P: 'a, @@ -191,33 +190,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 +237,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,10 +259,10 @@ 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> + fn try_get_mut<'a>(&'a mut self, idx: SinglyIdx) -> Result<&'a mut T, NodeIdxError> where M: 'a, P: 'a, @@ -297,17 +296,17 @@ 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'])); /// ``` - 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..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,17 +70,16 @@ 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<'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/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 e3003e2..3cc563a 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)?; - self.col().node(&ptr).next().get().cloned() + let ptr = self.col().try_get_ptr(*x)?; + self.col().node(ptr).next().get() } - Included(x) => Some(self.col().try_get_ptr(x)?), - Unbounded => self.col().ends().get(FRONT_IDX).cloned(), + Included(x) => Some(self.col().try_get_ptr(*x)?), + Unbounded => self.col().ends().get(FRONT_IDX), }; 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 { - false => self.col().node(&ptr).prev().get().cloned(), + let ptr = self.col().try_get_ptr(*x)?; + match ptr == front { + 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(), + Included(x) => Some(self.col().try_get_ptr(*x)?), + Unbounded => self.ends().get(BACK_IDX), }; 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(); @@ -96,25 +87,19 @@ 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>) { - self.col_mut() - .node_mut(prev) - .next_mut() - .set_some(next.clone()); - self.col_mut() - .node_mut(next) - .prev_mut() - .set_some(prev.clone()); + fn link(&mut self, prev: NodePtr>, next: NodePtr>) { + self.col_mut().node_mut(prev).next_mut().set_some(next); + self.col_mut().node_mut(next).prev_mut().set_some(prev); } #[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(); diff --git a/src/list/idx_doubly.rs b/src/list/idx_doubly.rs index b8c94c8..9ce3894 100644 --- a/src/list/idx_doubly.rs +++ b/src/list/idx_doubly.rs @@ -33,29 +33,29 @@ 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'])); /// ``` - 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); - [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`. @@ -80,28 +80,28 @@ 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 { + 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`. @@ -127,28 +127,28 @@ 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 { + 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. @@ -171,36 +171,36 @@ 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 { + 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 => { 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, } @@ -227,39 +227,39 @@ 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 ///``` pub fn try_insert_next_to( &mut self, - idx: &DoublyIdx, + idx: DoublyIdx, 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`. @@ -283,38 +283,38 @@ 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 ///``` pub fn try_insert_prev_to( &mut self, - idx: &DoublyIdx, + idx: DoublyIdx, 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 89d021f..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) } @@ -128,12 +126,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])); /// ``` @@ -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. @@ -175,29 +173,29 @@ 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>( &'a self, - pivot_idx: &DoublyIdx, + pivot_idx: DoublyIdx, ) -> Chain, DoublyIter<'a, T, P>> where M: 'a, @@ -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), }, @@ -238,17 +236,17 @@ 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); /// ``` - 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, { 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) } @@ -272,18 +270,18 @@ 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)); /// 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, { 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() } @@ -303,7 +301,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'))); @@ -311,14 +309,14 @@ 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, { 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 f03695a..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) } @@ -68,18 +68,18 @@ 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; /// } /// /// 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, { 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) } @@ -105,18 +105,18 @@ 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; /// } /// /// 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, { 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() } @@ -153,18 +153,18 @@ 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> + fn ring_iter_mut<'a>(&'a mut self, pivot_idx: DoublyIdx) -> DoublyIterMutChain<'a, T, P> 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 671ba95..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) } @@ -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 @@ -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. @@ -121,13 +121,13 @@ 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)); /// 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, { @@ -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 7f02c7a..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) } @@ -64,13 +64,13 @@ 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; /// } /// /// 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/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/linear_eq.rs b/src/list/linear_eq.rs index cd5b2c1..40e40f0 100644 --- a/src/list/linear_eq.rs +++ b/src/list/linear_eq.rs @@ -31,28 +31,28 @@ 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() - .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) @@ -131,28 +131,28 @@ 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() - .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) @@ -222,29 +222,29 @@ 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() .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) diff --git a/src/list/mut_doubly.rs b/src/list/mut_doubly.rs index e597dc8..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) }) } @@ -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,17 +274,16 @@ 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<'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 } 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..30fa226 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); } - self.0.ends_mut().set_some(idx.clone()); + self.0.ends_mut().set_some(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. @@ -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() { - Some(new_front) => self.0.ends_mut().set_some(new_front.clone()), + self.0.ends().get().map(|front| { + match self.0.node(front).next().get() { + Some(new_front) => self.0.ends_mut().set_some(new_front), None => self.0.ends_mut().clear(), } - self.0.close_and_reclaim(&front) + self.0.close_and_reclaim(front) }) } 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..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,18 +22,22 @@ 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 { 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 { @@ -68,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 f2579fc..fd0a165 100644 --- a/src/pointers/doubly_ptr.rs +++ b/src/pointers/doubly_ptr.rs @@ -6,15 +6,22 @@ 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>; + /// + /// # 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. /// @@ -61,7 +68,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 +84,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 f2be2cf..036f2c6 100644 --- a/src/pointers/singly_ptr.rs +++ b/src/pointers/singly_ptr.rs @@ -6,15 +6,22 @@ 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>; + /// + /// # 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. /// @@ -61,6 +68,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..8786776 100644 --- a/src/tests/doubly.rs +++ b/src/tests/doubly.rs @@ -109,17 +109,17 @@ 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) + (p, 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) + (p, 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) }) } 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_doubly.rs b/tests/slice_doubly.rs index 3d1c0d3..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); @@ -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_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..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,9 +39,9 @@ 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().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] 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([])); }