about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-11-15 13:39:54 +0100
committerGitHub <noreply@github.com>2020-11-15 13:39:54 +0100
commitaa685e2024874860c71887c4e18d916f1d989af8 (patch)
tree5c25105cf1940785291890326be6a4b387e2a6cd /library/alloc/src
parent00396cb23a630be87f3914f5eaf0f49d086e92d8 (diff)
parentbf6902ca61ae6e91a3ab95bed88426926f245d02 (diff)
downloadrust-aa685e2024874860c71887c4e18d916f1d989af8.tar.gz
rust-aa685e2024874860c71887c4e18d916f1d989af8.zip
Rollup merge of #79026 - mbrubeck:btree_retain, r=m-ou-se
Implement BTreeMap::retain and BTreeSet::retain

Adds new methods `BTreeMap::retain` and `BTreeSet::retain`.  These are implemented on top of `drain_filter` (#70530).

The API of these methods is identical to `HashMap::retain` and `HashSet::retain`, which were implemented in #39560 and stabilized in #36648.  The docs and tests are also copied from HashMap/HashSet.

The new methods are unstable, behind the `btree_retain` feature gate, with tracking issue #79025.  See also rust-lang/rfcs#1338.
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/collections/btree/map.rs24
-rw-r--r--library/alloc/src/collections/btree/map/tests.rs11
-rw-r--r--library/alloc/src/collections/btree/set.rs24
-rw-r--r--library/alloc/src/collections/btree/set/tests.rs11
4 files changed, 70 insertions, 0 deletions
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 49122f53d33..7151d3763f0 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -863,6 +863,30 @@ impl<K: Ord, V> BTreeMap<K, V> {
         }
     }
 
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(btree_retain)]
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map: BTreeMap<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
+    /// // Keep only the elements with even-numbered keys.
+    /// map.retain(|&k, _| k % 2 == 0);
+    /// assert!(map.into_iter().eq(vec![(0, 0), (2, 20), (4, 40), (6, 60)]));
+    /// ```
+    #[inline]
+    #[unstable(feature = "btree_retain", issue = "79025")]
+    pub fn retain<F>(&mut self, mut f: F)
+    where
+        F: FnMut(&K, &mut V) -> bool,
+    {
+        self.drain_filter(|k, v| !f(k, v));
+    }
+
     /// Moves all elements from `other` into `Self`, leaving `other` empty.
     ///
     /// # Examples
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index dd3ebcccf76..11dbb584abd 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -808,6 +808,17 @@ fn test_range_mut() {
     map.check();
 }
 
+#[test]
+fn test_retain() {
+    let mut map: BTreeMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
+
+    map.retain(|&k, _| k % 2 == 0);
+    assert_eq!(map.len(), 50);
+    assert_eq!(map[&2], 20);
+    assert_eq!(map[&4], 40);
+    assert_eq!(map[&6], 60);
+}
+
 mod test_drain_filter {
     use super::*;
 
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 684019f8f5f..1a807100653 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -798,6 +798,30 @@ impl<T: Ord> BTreeSet<T> {
         Recover::take(&mut self.map, value)
     }
 
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(btree_retain)]
+    /// use std::collections::BTreeSet;
+    ///
+    /// let xs = [1, 2, 3, 4, 5, 6];
+    /// let mut set: BTreeSet<i32> = xs.iter().cloned().collect();
+    /// // Keep only the even numbers.
+    /// set.retain(|&k| k % 2 == 0);
+    /// assert!(set.iter().eq([2, 4, 6].iter()));
+    /// ```
+    #[unstable(feature = "btree_retain", issue = "79025")]
+    pub fn retain<F>(&mut self, mut f: F)
+    where
+        F: FnMut(&T) -> bool,
+    {
+        self.drain_filter(|v| !f(v));
+    }
+
     /// Moves all elements from `other` into `Self`, leaving `other` empty.
     ///
     /// # Examples
diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs
index 52cde8299e4..ef40a048a38 100644
--- a/library/alloc/src/collections/btree/set/tests.rs
+++ b/library/alloc/src/collections/btree/set/tests.rs
@@ -325,6 +325,17 @@ fn test_is_subset() {
 }
 
 #[test]
+fn test_retain() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let mut set: BTreeSet<i32> = xs.iter().cloned().collect();
+    set.retain(|&k| k % 2 == 0);
+    assert_eq!(set.len(), 3);
+    assert!(set.contains(&2));
+    assert!(set.contains(&4));
+    assert!(set.contains(&6));
+}
+
+#[test]
 fn test_drain_filter() {
     let mut x: BTreeSet<_> = [1].iter().copied().collect();
     let mut y: BTreeSet<_> = [1].iter().copied().collect();