]> git.proxmox.com Git - rustc.git/blobdiff - library/alloc/src/vec/mod.rs
New upstream version 1.58.1+dfsg1
[rustc.git] / library / alloc / src / vec / mod.rs
index 20a16869cb3f8bfd06966a9fc2053ca57daa43a6..85759917765fa6e3d91afa9fd468956c83afdc70 100644 (file)
@@ -1272,6 +1272,9 @@ impl<T, A: Allocator> Vec<T, A> {
     /// The removed element is replaced by the last element of the vector.
     ///
     /// This does not preserve ordering, but is *O*(1).
+    /// If you need to preserve the element order, use [`remove`] instead.
+    ///
+    /// [`remove`]: Vec::remove
     ///
     /// # Panics
     ///
@@ -1305,10 +1308,11 @@ impl<T, A: Allocator> Vec<T, A> {
             // We replace self[index] with the last element. Note that if the
             // bounds check above succeeds there must be a last element (which
             // can be self[index] itself).
-            let last = ptr::read(self.as_ptr().add(len - 1));
-            let hole = self.as_mut_ptr().add(index);
+            let value = ptr::read(self.as_ptr().add(index));
+            let base_ptr = self.as_mut_ptr();
+            ptr::copy(base_ptr.add(len - 1), base_ptr.add(index), 1);
             self.set_len(len - 1);
-            ptr::replace(hole, last)
+            value
         }
     }
 
@@ -1367,7 +1371,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// shifting all elements after it to the left.
     ///
     /// Note: Because this shifts over the remaining elements, it has a
-    /// worst-case performance of O(n). If you don't need the order of elements
+    /// worst-case performance of *O*(*n*). If you don't need the order of elements
     /// to be preserved, use [`swap_remove`] instead.
     ///
     /// [`swap_remove`]: Vec::swap_remove
@@ -1443,6 +1447,34 @@ impl<T, A: Allocator> Vec<T, A> {
     pub fn retain<F>(&mut self, mut f: F)
     where
         F: FnMut(&T) -> bool,
+    {
+        self.retain_mut(|elem| f(elem));
+    }
+
+    /// Retains only the elements specified by the predicate, passing a mutable reference to it.
+    ///
+    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
+    /// This method operates in place, visiting each element exactly once in the
+    /// original order, and preserves the order of the retained elements.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(vec_retain_mut)]
+    ///
+    /// let mut vec = vec![1, 2, 3, 4];
+    /// vec.retain_mut(|x| if *x > 3 {
+    ///     false
+    /// } else {
+    ///     *x += 1;
+    ///     true
+    /// });
+    /// assert_eq!(vec, [2, 3, 4]);
+    /// ```
+    #[unstable(feature = "vec_retain_mut", issue = "90829")]
+    pub fn retain_mut<F>(&mut self, mut f: F)
+    where
+        F: FnMut(&mut T) -> bool,
     {
         let original_len = self.len();
         // Avoid double drop if the drop guard is not executed,
@@ -1495,7 +1527,7 @@ impl<T, A: Allocator> Vec<T, A> {
             g: &mut BackshiftOnDrop<'_, T, A>,
         ) -> bool
         where
-            F: FnMut(&T) -> bool,
+            F: FnMut(&mut T) -> bool,
         {
             // SAFETY: Unchecked element must be valid.
             let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) };