Rollup merge of #91215 - GuillaumeGomez:vec-deque-retain-mut, r=m-ou-se

Implement VecDeque::retain_mut

Part of https://github.com/rust-lang/rust/issues/90829.

In https://github.com/rust-lang/rust/pull/90772, someone suggested that `retain_mut` should also be implemented on `VecDeque`. I think that it follows the same logic (coherency). So first: is it ok? Second: should I create a new feature for it or can we put it into the same one?

r? `@joshtriplett`
This commit is contained in:
Matthias Krüger 2021-12-05 00:37:59 +01:00 committed by GitHub
commit 4af985ac00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2148,6 +2148,37 @@ impl<T, A: Allocator> VecDeque<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.
///
/// In other words, remove all elements `e` such that `f(&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)]
///
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
/// buf.extend(1..5);
/// buf.retain_mut(|x| if *x % 2 == 0 {
/// *x += 1;
/// true
/// } else {
/// false
/// });
/// assert_eq!(buf, [3, 5]);
/// ```
#[unstable(feature = "vec_retain_mut", issue = "90829")]
pub fn retain_mut<F>(&mut self, mut f: F)
where
F: FnMut(&mut T) -> bool,
{
let len = self.len();
let mut idx = 0;
@ -2155,7 +2186,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
// Stage 1: All values are retained.
while cur < len {
if !f(&self[cur]) {
if !f(&mut self[cur]) {
cur += 1;
break;
}
@ -2164,7 +2195,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
}
// Stage 2: Swap retained value into current idx.
while cur < len {
if !f(&self[cur]) {
if !f(&mut self[cur]) {
cur += 1;
continue;
}
@ -2173,7 +2204,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
cur += 1;
idx += 1;
}
// Stage 3: Trancate all values after idx.
// Stage 3: Truncate all values after idx.
if cur != idx {
self.truncate(idx);
}