@@ -497,6 +497,50 @@ impl<K, V, S> HashMap<K, V, S> {
497
497
Drain { base : self . base . drain ( ) }
498
498
}
499
499
500
+ /// Creates an iterator which uses a closure to determine if an element should be removed.
501
+ ///
502
+ /// If the closure returns true, the element is removed from the map and yielded.
503
+ /// If the closure returns false, or panics, the element remains in the map and will not be
504
+ /// yielded.
505
+ ///
506
+ /// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
507
+ /// whether you choose to keep or remove it.
508
+ ///
509
+ /// If the iterator is only partially consumed or not consumed at all, each of the remaining
510
+ /// elements will still be subjected to the closure and removed and dropped if it returns true.
511
+ ///
512
+ /// It is unspecified how many more elements will be subjected to the closure
513
+ /// if a panic occurs in the closure, or a panic occurs while dropping an element,
514
+ /// or if the `DrainFilter` value is leaked.
515
+ ///
516
+ /// # Examples
517
+ ///
518
+ /// Splitting a map into even and odd keys, reusing the original map:
519
+ ///
520
+ /// ```
521
+ /// #![feature(hash_drain_filter)]
522
+ /// use std::collections::HashMap;
523
+ ///
524
+ /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
525
+ /// let drained: HashMap<i32, i32> = map.drain_filter(|k, _v| k % 2 == 0).collect();
526
+ ///
527
+ /// let mut evens = drained.keys().copied().collect::<Vec<_>>();
528
+ /// let mut odds = map.keys().copied().collect::<Vec<_>>();
529
+ /// evens.sort();
530
+ /// odds.sort();
531
+ ///
532
+ /// assert_eq!(evens, vec![0, 2, 4, 6]);
533
+ /// assert_eq!(odds, vec![1, 3, 5, 7]);
534
+ /// ```
535
+ #[ inline]
536
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
537
+ pub fn drain_filter < F > ( & mut self , pred : F ) -> DrainFilter < ' _ , K , V , F >
538
+ where
539
+ F : FnMut ( & K , & mut V ) -> bool ,
540
+ {
541
+ DrainFilter { base : self . base . drain_filter ( pred) }
542
+ }
543
+
500
544
/// Clears the map, removing all key-value pairs. Keeps the allocated memory
501
545
/// for reuse.
502
546
///
@@ -1190,6 +1234,19 @@ impl<'a, K, V> Drain<'a, K, V> {
1190
1234
}
1191
1235
}
1192
1236
1237
+ /// A draining, filtering iterator over the entries of a `HashMap`.
1238
+ ///
1239
+ /// This `struct` is created by the [`drain_filter`] method on [`HashMap`].
1240
+ ///
1241
+ /// [`drain_filter`]: HashMap::drain_filter
1242
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
1243
+ pub struct DrainFilter < ' a , K , V , F >
1244
+ where
1245
+ F : FnMut ( & K , & mut V ) -> bool ,
1246
+ {
1247
+ base : base:: DrainFilter < ' a , K , V , F > ,
1248
+ }
1249
+
1193
1250
/// A mutable iterator over the values of a `HashMap`.
1194
1251
///
1195
1252
/// This `struct` is created by the [`values_mut`] method on [`HashMap`]. See its
@@ -1247,16 +1304,16 @@ pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
1247
1304
#[ unstable( feature = "hash_raw_entry" , issue = "56167" ) ]
1248
1305
pub enum RawEntryMut < ' a , K : ' a , V : ' a , S : ' a > {
1249
1306
/// An occupied entry.
1250
- Occupied ( RawOccupiedEntryMut < ' a , K , V > ) ,
1307
+ Occupied ( RawOccupiedEntryMut < ' a , K , V , S > ) ,
1251
1308
/// A vacant entry.
1252
1309
Vacant ( RawVacantEntryMut < ' a , K , V , S > ) ,
1253
1310
}
1254
1311
1255
1312
/// A view into an occupied entry in a `HashMap`.
1256
1313
/// It is part of the [`RawEntryMut`] enum.
1257
1314
#[ unstable( feature = "hash_raw_entry" , issue = "56167" ) ]
1258
- pub struct RawOccupiedEntryMut < ' a , K : ' a , V : ' a > {
1259
- base : base:: RawOccupiedEntryMut < ' a , K , V > ,
1315
+ pub struct RawOccupiedEntryMut < ' a , K : ' a , V : ' a , S : ' a > {
1316
+ base : base:: RawOccupiedEntryMut < ' a , K , V , S > ,
1260
1317
}
1261
1318
1262
1319
/// A view into a vacant entry in a `HashMap`.
@@ -1457,7 +1514,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
1457
1514
}
1458
1515
}
1459
1516
1460
- impl < ' a , K , V > RawOccupiedEntryMut < ' a , K , V > {
1517
+ impl < ' a , K , V , S > RawOccupiedEntryMut < ' a , K , V , S > {
1461
1518
/// Gets a reference to the key in the entry.
1462
1519
#[ inline]
1463
1520
#[ unstable( feature = "hash_raw_entry" , issue = "56167" ) ]
@@ -1597,7 +1654,7 @@ impl<K: Debug, V: Debug, S> Debug for RawEntryMut<'_, K, V, S> {
1597
1654
}
1598
1655
1599
1656
#[ unstable( feature = "hash_raw_entry" , issue = "56167" ) ]
1600
- impl < K : Debug , V : Debug > Debug for RawOccupiedEntryMut < ' _ , K , V > {
1657
+ impl < K : Debug , V : Debug , S > Debug for RawOccupiedEntryMut < ' _ , K , V , S > {
1601
1658
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1602
1659
f. debug_struct ( "RawOccupiedEntryMut" )
1603
1660
. field ( "key" , self . key ( ) )
@@ -1990,6 +2047,36 @@ where
1990
2047
}
1991
2048
}
1992
2049
2050
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
2051
+ impl < K , V , F > Iterator for DrainFilter < ' _ , K , V , F >
2052
+ where
2053
+ F : FnMut ( & K , & mut V ) -> bool ,
2054
+ {
2055
+ type Item = ( K , V ) ;
2056
+
2057
+ #[ inline]
2058
+ fn next ( & mut self ) -> Option < ( K , V ) > {
2059
+ self . base . next ( )
2060
+ }
2061
+ #[ inline]
2062
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2063
+ self . base . size_hint ( )
2064
+ }
2065
+ }
2066
+
2067
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
2068
+ impl < K , V , F > FusedIterator for DrainFilter < ' _ , K , V , F > where F : FnMut ( & K , & mut V ) -> bool { }
2069
+
2070
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
2071
+ impl < ' a , K , V , F > fmt:: Debug for DrainFilter < ' a , K , V , F >
2072
+ where
2073
+ F : FnMut ( & K , & mut V ) -> bool ,
2074
+ {
2075
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2076
+ f. pad ( "DrainFilter { .. }" )
2077
+ }
2078
+ }
2079
+
1993
2080
impl < ' a , K , V > Entry < ' a , K , V > {
1994
2081
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1995
2082
/// Ensures a value is in the entry by inserting the default if empty, and returns
@@ -2698,7 +2785,7 @@ fn map_entry<'a, K: 'a, V: 'a>(raw: base::RustcEntry<'a, K, V>) -> Entry<'a, K,
2698
2785
}
2699
2786
2700
2787
#[ inline]
2701
- fn map_try_reserve_error ( err : hashbrown:: TryReserveError ) -> TryReserveError {
2788
+ pub ( super ) fn map_try_reserve_error ( err : hashbrown:: TryReserveError ) -> TryReserveError {
2702
2789
match err {
2703
2790
hashbrown:: TryReserveError :: CapacityOverflow => TryReserveError :: CapacityOverflow ,
2704
2791
hashbrown:: TryReserveError :: AllocError { layout } => {
0 commit comments