Skip to content

Commit 59bbbfd

Browse files
matthiaskrgrgitbot
authored and
gitbot
committed
Rollup merge of rust-lang#135890 - GrigorenkoPV:deque-pop-if, r=thomcc
Implement `VecDeque::pop_front_if` & `VecDeque::pop_back_if` Tracking issue: rust-lang#135889
2 parents decbeed + 28681bf commit 59bbbfd

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

Diff for: alloc/src/collections/vec_deque/mod.rs

+46
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,52 @@ impl<T, A: Allocator> VecDeque<T, A> {
17351735
}
17361736
}
17371737

1738+
/// Removes and returns the first element from the deque if the predicate
1739+
/// returns `true`, or [`None`] if the predicate returns false or the deque
1740+
/// is empty (the predicate will not be called in that case).
1741+
///
1742+
/// # Examples
1743+
///
1744+
/// ```
1745+
/// #![feature(vec_deque_pop_if)]
1746+
/// use std::collections::VecDeque;
1747+
///
1748+
/// let mut deque: VecDeque<i32> = vec![0, 1, 2, 3, 4].into();
1749+
/// let pred = |x: &mut i32| *x % 2 == 0;
1750+
///
1751+
/// assert_eq!(deque.pop_front_if(pred), Some(0));
1752+
/// assert_eq!(deque, [1, 2, 3, 4]);
1753+
/// assert_eq!(deque.pop_front_if(pred), None);
1754+
/// ```
1755+
#[unstable(feature = "vec_deque_pop_if", issue = "135889")]
1756+
pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
1757+
let first = self.front_mut()?;
1758+
if predicate(first) { self.pop_front() } else { None }
1759+
}
1760+
1761+
/// Removes and returns the last element from the deque if the predicate
1762+
/// returns `true`, or [`None`] if the predicate returns false or the deque
1763+
/// is empty (the predicate will not be called in that case).
1764+
///
1765+
/// # Examples
1766+
///
1767+
/// ```
1768+
/// #![feature(vec_deque_pop_if)]
1769+
/// use std::collections::VecDeque;
1770+
///
1771+
/// let mut deque: VecDeque<i32> = vec![0, 1, 2, 3, 4].into();
1772+
/// let pred = |x: &mut i32| *x % 2 == 0;
1773+
///
1774+
/// assert_eq!(deque.pop_back_if(pred), Some(4));
1775+
/// assert_eq!(deque, [0, 1, 2, 3]);
1776+
/// assert_eq!(deque.pop_back_if(pred), None);
1777+
/// ```
1778+
#[unstable(feature = "vec_deque_pop_if", issue = "135889")]
1779+
pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
1780+
let first = self.back_mut()?;
1781+
if predicate(first) { self.pop_back() } else { None }
1782+
}
1783+
17381784
/// Prepends an element to the deque.
17391785
///
17401786
/// # Examples

Diff for: alloc/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#![feature(str_as_str)]
3939
#![feature(strict_provenance_lints)]
4040
#![feature(vec_pop_if)]
41+
#![feature(vec_deque_pop_if)]
4142
#![feature(unique_rc_arc)]
4243
#![feature(macro_metavar_expr_concat)]
4344
#![allow(internal_features)]

Diff for: alloc/tests/vec_deque.rs

+39
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,45 @@ fn test_parameterized<T: Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
8080
assert_eq!(deq[3].clone(), d.clone());
8181
}
8282

83+
#[test]
84+
fn test_pop_if() {
85+
let mut deq: VecDeque<_> = vec![0, 1, 2, 3, 4].into();
86+
let pred = |x: &mut i32| *x % 2 == 0;
87+
88+
assert_eq!(deq.pop_front_if(pred), Some(0));
89+
assert_eq!(deq, [1, 2, 3, 4]);
90+
91+
assert_eq!(deq.pop_front_if(pred), None);
92+
assert_eq!(deq, [1, 2, 3, 4]);
93+
94+
assert_eq!(deq.pop_back_if(pred), Some(4));
95+
assert_eq!(deq, [1, 2, 3]);
96+
97+
assert_eq!(deq.pop_back_if(pred), None);
98+
assert_eq!(deq, [1, 2, 3]);
99+
}
100+
101+
#[test]
102+
fn test_pop_if_empty() {
103+
let mut deq = VecDeque::<i32>::new();
104+
assert_eq!(deq.pop_front_if(|_| true), None);
105+
assert_eq!(deq.pop_back_if(|_| true), None);
106+
assert!(deq.is_empty());
107+
}
108+
109+
#[test]
110+
fn test_pop_if_mutates() {
111+
let mut v: VecDeque<_> = vec![-1, 1].into();
112+
let pred = |x: &mut i32| {
113+
*x *= 2;
114+
false
115+
};
116+
assert_eq!(v.pop_front_if(pred), None);
117+
assert_eq!(v, [-2, 1]);
118+
assert_eq!(v.pop_back_if(pred), None);
119+
assert_eq!(v, [-2, 2]);
120+
}
121+
83122
#[test]
84123
fn test_push_front_grow() {
85124
let mut deq = VecDeque::new();

0 commit comments

Comments
 (0)