about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-02-20 10:49:08 +0100
committerGitHub <noreply@github.com>2020-02-20 10:49:08 +0100
commitf7ce5ff19c801a08c7b5aa2ff6f7f552e9de4a39 (patch)
treec85d40526c5596303aeac01d5f4a38e816bc3532 /src/liballoc
parentde362d88ea17ab23ca2483cb798bc7aeb81a48f5 (diff)
parentc797ce7877dff9189d828247493dfcada9c10e43 (diff)
downloadrust-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.rs46
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.