diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-02-20 10:49:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-20 10:49:08 +0100 |
| commit | f7ce5ff19c801a08c7b5aa2ff6f7f552e9de4a39 (patch) | |
| tree | c85d40526c5596303aeac01d5f4a38e816bc3532 /src/liballoc | |
| parent | de362d88ea17ab23ca2483cb798bc7aeb81a48f5 (diff) | |
| parent | c797ce7877dff9189d828247493dfcada9c10e43 (diff) | |
| download | rust-f7ce5ff19c801a08c7b5aa2ff6f7f552e9de4a39.tar.gz rust-f7ce5ff19c801a08c7b5aa2ff6f7f552e9de4a39.zip | |
Rollup merge of #68705 - BijanT:ll_remove, r=Mark-Simulacrum
Add LinkedList::remove() LinkedList::remove() removes the element at the specified index and returns it. I added this because I think having a remove function would be useful to have, and similar functions are in other containers, like Vec and HashMap. I'm not sure if adding a feature like this requires an RFC or not, so I'm sorry if this PR is premature.
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/collections/linked_list.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index b88ca8a0fb0..f8f987efeb8 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -878,6 +878,52 @@ impl<T> LinkedList<T> { unsafe { self.split_off_after_node(split_node, at) } } + /// Removes the element at the given index and returns it. + /// + /// This operation should compute in O(n) time. + /// + /// # Panics + /// Panics if at >= len + /// + /// # Examples + /// + /// ``` + /// #![feature(linked_list_remove)] + /// use std::collections::LinkedList; + /// + /// let mut d = LinkedList::new(); + /// + /// d.push_front(1); + /// d.push_front(2); + /// d.push_front(3); + /// + /// assert_eq!(d.remove(1), 2); + /// assert_eq!(d.remove(0), 3); + /// assert_eq!(d.remove(0), 1); + /// ``` + #[unstable(feature = "linked_list_remove", issue = "69210")] + pub fn remove(&mut self, at: usize) -> T { + let len = self.len(); + assert!(at < len, "Cannot remove at an index outside of the list bounds"); + + // Below, we iterate towards the node at the given index, either from + // the start or the end, depending on which would be faster. + let offset_from_end = len - at - 1; + if at <= offset_from_end { + let mut cursor = self.cursor_front_mut(); + for _ in 0..at { + cursor.move_next(); + } + cursor.remove_current().unwrap() + } else { + let mut cursor = self.cursor_back_mut(); + for _ in 0..offset_from_end { + cursor.move_prev(); + } + cursor.remove_current().unwrap() + } + } + /// Creates an iterator which uses a closure to determine if an element should be removed. /// /// If the closure returns true, then the element is removed and yielded. |
