about summary refs log tree commit diff
path: root/library/alloc/tests
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-03-27 05:21:18 +0100
committerGitHub <noreply@github.com>2024-03-27 05:21:18 +0100
commit19a40ec5bf41d4bf5a8635be511ac9cb84308f25 (patch)
treef17426859245d97e33698d2ee87cb979ca0470fe /library/alloc/tests
parentfc51dbd379ec80000343fa03315a113b2389c454 (diff)
parent07d3806eb1a9dcfc6acdc54476c9cc2b7bbbad7b (diff)
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?
Diffstat (limited to 'library/alloc/tests')
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/vec.rs30
2 files changed, 31 insertions, 0 deletions
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index f58998fbd79..04709af5c0a 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -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)]
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index f1f841fe190..71d79893e01 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -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!