Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 19a40ec

Browse files
Rollup merge of rust-lang#123107 - avandesa:vec_pop_if, r=joboet
Implement `Vec::pop_if` This PR adds `Vec::pop_if` to the public API, behind the `vec_pop_if` feature. ```rust impl<T> Vec<T> { pub fn pop_if<F>(&mut self, f: F) -> Option<T> where F: FnOnce(&mut T) -> bool; } ``` Tracking issue: rust-lang#122741 ## Open questions - [ ] Should the first unit test be split up? - [ ] I don't see any guidance on ordering of methods in impl blocks, should I move the method elsewhere?
2 parents fc51dbd + 07d3806 commit 19a40ec

File tree

4 files changed

+57
-0
lines changed

4 files changed

+57
-0
lines changed

‎library/alloc/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
#![feature(unicode_internals)]
171171
#![feature(unsize)]
172172
#![feature(utf8_chunks)]
173+
#![feature(vec_pop_if)]
173174
// tidy-alphabetical-end
174175
//
175176
// Language features:

‎library/alloc/src/vec/mod.rs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,6 +2058,31 @@ impl<T, A: Allocator> Vec<T, A> {
20582058
}
20592059
}
20602060

2061+
/// Removes and returns the last element in a vector if the predicate
2062+
/// returns `true`, or [`None`] if the predicate returns false or the vector
2063+
/// is empty.
2064+
///
2065+
/// # Examples
2066+
///
2067+
/// ```
2068+
/// #![feature(vec_pop_if)]
2069+
///
2070+
/// let mut vec = vec![1, 2, 3, 4];
2071+
/// let pred = |x: &mut i32| *x % 2 == 0;
2072+
///
2073+
/// assert_eq!(vec.pop_if(pred), Some(4));
2074+
/// assert_eq!(vec, [1, 2, 3]);
2075+
/// assert_eq!(vec.pop_if(pred), None);
2076+
/// ```
2077+
#[unstable(feature = "vec_pop_if", issue = "122741")]
2078+
pub fn pop_if<F>(&mut self, f: F) -> Option<T>
2079+
where
2080+
F: FnOnce(&mut T) -> bool,
2081+
{
2082+
let last = self.last_mut()?;
2083+
if f(last) { self.pop() } else { None }
2084+
}
2085+
20612086
/// Moves all the elements of `other` into `self`, leaving `other` empty.
20622087
///
20632088
/// # Panics

‎library/alloc/tests/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#![feature(strict_provenance)]
4444
#![feature(drain_keep_rest)]
4545
#![feature(local_waker)]
46+
#![feature(vec_pop_if)]
4647
#![allow(internal_features)]
4748
#![deny(fuzzy_provenance_casts)]
4849
#![deny(unsafe_op_in_unsafe_fn)]

‎library/alloc/tests/vec.rs‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,6 +2644,36 @@ fn test_vec_from_array_mut_ref() {
26442644
assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
26452645
}
26462646

2647+
#[test]
2648+
fn test_pop_if() {
2649+
let mut v = vec![1, 2, 3, 4];
2650+
let pred = |x: &mut i32| *x % 2 == 0;
2651+
2652+
assert_eq!(v.pop_if(pred), Some(4));
2653+
assert_eq!(v, [1, 2, 3]);
2654+
2655+
assert_eq!(v.pop_if(pred), None);
2656+
assert_eq!(v, [1, 2, 3]);
2657+
}
2658+
2659+
#[test]
2660+
fn test_pop_if_empty() {
2661+
let mut v = Vec::<i32>::new();
2662+
assert_eq!(v.pop_if(|_| true), None);
2663+
assert!(v.is_empty());
2664+
}
2665+
2666+
#[test]
2667+
fn test_pop_if_mutates() {
2668+
let mut v = vec![1];
2669+
let pred = |x: &mut i32| {
2670+
*x += 1;
2671+
false
2672+
};
2673+
assert_eq!(v.pop_if(pred), None);
2674+
assert_eq!(v, [2]);
2675+
}
2676+
26472677
/// This assortment of tests, in combination with miri, verifies we handle UB on fishy arguments
26482678
/// in the stdlib. Draining and extending the allocation are fairly well-tested earlier, but
26492679
/// `vec.insert(usize::MAX, val)` once slipped by!

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /