Rollup merge of #135890 - GrigorenkoPV:deque-pop-if, r=thomcc
Implement `VecDeque::pop_front_if` & `VecDeque::pop_back_if` Tracking issue: #135889
This commit is contained in:
commit
be15391703
3 changed files with 86 additions and 0 deletions
|
|
@ -1735,6 +1735,52 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Removes and returns the first element from the deque if the predicate
|
||||
/// returns `true`, or [`None`] if the predicate returns false or the deque
|
||||
/// is empty (the predicate will not be called in that case).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(vec_deque_pop_if)]
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let mut deque: VecDeque<i32> = vec![0, 1, 2, 3, 4].into();
|
||||
/// let pred = |x: &mut i32| *x % 2 == 0;
|
||||
///
|
||||
/// assert_eq!(deque.pop_front_if(pred), Some(0));
|
||||
/// assert_eq!(deque, [1, 2, 3, 4]);
|
||||
/// assert_eq!(deque.pop_front_if(pred), None);
|
||||
/// ```
|
||||
#[unstable(feature = "vec_deque_pop_if", issue = "135889")]
|
||||
pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
|
||||
let first = self.front_mut()?;
|
||||
if predicate(first) { self.pop_front() } else { None }
|
||||
}
|
||||
|
||||
/// Removes and returns the last element from the deque if the predicate
|
||||
/// returns `true`, or [`None`] if the predicate returns false or the deque
|
||||
/// is empty (the predicate will not be called in that case).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(vec_deque_pop_if)]
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let mut deque: VecDeque<i32> = vec![0, 1, 2, 3, 4].into();
|
||||
/// let pred = |x: &mut i32| *x % 2 == 0;
|
||||
///
|
||||
/// assert_eq!(deque.pop_back_if(pred), Some(4));
|
||||
/// assert_eq!(deque, [0, 1, 2, 3]);
|
||||
/// assert_eq!(deque.pop_back_if(pred), None);
|
||||
/// ```
|
||||
#[unstable(feature = "vec_deque_pop_if", issue = "135889")]
|
||||
pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
|
||||
let first = self.back_mut()?;
|
||||
if predicate(first) { self.pop_back() } else { None }
|
||||
}
|
||||
|
||||
/// Prepends an element to the deque.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#![feature(str_as_str)]
|
||||
#![feature(strict_provenance_lints)]
|
||||
#![feature(vec_pop_if)]
|
||||
#![feature(vec_deque_pop_if)]
|
||||
#![feature(unique_rc_arc)]
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
#![allow(internal_features)]
|
||||
|
|
|
|||
|
|
@ -80,6 +80,45 @@ fn test_parameterized<T: Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
|
|||
assert_eq!(deq[3].clone(), d.clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop_if() {
|
||||
let mut deq: VecDeque<_> = vec![0, 1, 2, 3, 4].into();
|
||||
let pred = |x: &mut i32| *x % 2 == 0;
|
||||
|
||||
assert_eq!(deq.pop_front_if(pred), Some(0));
|
||||
assert_eq!(deq, [1, 2, 3, 4]);
|
||||
|
||||
assert_eq!(deq.pop_front_if(pred), None);
|
||||
assert_eq!(deq, [1, 2, 3, 4]);
|
||||
|
||||
assert_eq!(deq.pop_back_if(pred), Some(4));
|
||||
assert_eq!(deq, [1, 2, 3]);
|
||||
|
||||
assert_eq!(deq.pop_back_if(pred), None);
|
||||
assert_eq!(deq, [1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop_if_empty() {
|
||||
let mut deq = VecDeque::<i32>::new();
|
||||
assert_eq!(deq.pop_front_if(|_| true), None);
|
||||
assert_eq!(deq.pop_back_if(|_| true), None);
|
||||
assert!(deq.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop_if_mutates() {
|
||||
let mut v: VecDeque<_> = vec![-1, 1].into();
|
||||
let pred = |x: &mut i32| {
|
||||
*x *= 2;
|
||||
false
|
||||
};
|
||||
assert_eq!(v.pop_front_if(pred), None);
|
||||
assert_eq!(v, [-2, 1]);
|
||||
assert_eq!(v.pop_back_if(pred), None);
|
||||
assert_eq!(v, [-2, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_push_front_grow() {
|
||||
let mut deq = VecDeque::new();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue