mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Rollup merge of #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: #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?
This commit is contained in:
commit
19a40ec5bf
@ -170,6 +170,7 @@
|
||||
#![feature(unicode_internals)]
|
||||
#![feature(unsize)]
|
||||
#![feature(utf8_chunks)]
|
||||
#![feature(vec_pop_if)]
|
||||
// tidy-alphabetical-end
|
||||
//
|
||||
// Language features:
|
||||
|
@ -2058,6 +2058,31 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes and returns the last element in a vector if the predicate
|
||||
/// returns `true`, or [`None`] if the predicate returns false or the vector
|
||||
/// is empty.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(vec_pop_if)]
|
||||
///
|
||||
/// let mut vec = vec![1, 2, 3, 4];
|
||||
/// let pred = |x: &mut i32| *x % 2 == 0;
|
||||
///
|
||||
/// assert_eq!(vec.pop_if(pred), Some(4));
|
||||
/// assert_eq!(vec, [1, 2, 3]);
|
||||
/// assert_eq!(vec.pop_if(pred), None);
|
||||
/// ```
|
||||
#[unstable(feature = "vec_pop_if", issue = "122741")]
|
||||
pub fn pop_if<F>(&mut self, f: F) -> Option<T>
|
||||
where
|
||||
F: FnOnce(&mut T) -> bool,
|
||||
{
|
||||
let last = self.last_mut()?;
|
||||
if f(last) { self.pop() } else { None }
|
||||
}
|
||||
|
||||
/// Moves all the elements of `other` into `self`, leaving `other` empty.
|
||||
///
|
||||
/// # Panics
|
||||
|
@ -43,6 +43,7 @@
|
||||
#![feature(strict_provenance)]
|
||||
#![feature(drain_keep_rest)]
|
||||
#![feature(local_waker)]
|
||||
#![feature(vec_pop_if)]
|
||||
#![allow(internal_features)]
|
||||
#![deny(fuzzy_provenance_casts)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
@ -2644,6 +2644,36 @@ fn test_vec_from_array_mut_ref() {
|
||||
assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop_if() {
|
||||
let mut v = vec![1, 2, 3, 4];
|
||||
let pred = |x: &mut i32| *x % 2 == 0;
|
||||
|
||||
assert_eq!(v.pop_if(pred), Some(4));
|
||||
assert_eq!(v, [1, 2, 3]);
|
||||
|
||||
assert_eq!(v.pop_if(pred), None);
|
||||
assert_eq!(v, [1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop_if_empty() {
|
||||
let mut v = Vec::<i32>::new();
|
||||
assert_eq!(v.pop_if(|_| true), None);
|
||||
assert!(v.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop_if_mutates() {
|
||||
let mut v = vec![1];
|
||||
let pred = |x: &mut i32| {
|
||||
*x += 1;
|
||||
false
|
||||
};
|
||||
assert_eq!(v.pop_if(pred), None);
|
||||
assert_eq!(v, [2]);
|
||||
}
|
||||
|
||||
/// This assortment of tests, in combination with miri, verifies we handle UB on fishy arguments
|
||||
/// in the stdlib. Draining and extending the allocation are fairly well-tested earlier, but
|
||||
/// `vec.insert(usize::MAX, val)` once slipped by!
|
||||
|
Loading…
Reference in New Issue
Block a user