/// 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
///
// 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
}
}
/// 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
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,
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) };