1
+ use std:: fmt;
1
2
use crate :: raw:: { Allocator , Bucket , Global , RawDrain , RawIntoIter , RawIter , RawTable } ;
2
3
use crate :: { Equivalent , TryReserveError } ;
3
4
use core:: borrow:: Borrow ;
@@ -975,12 +976,9 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
975
976
/// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
976
977
/// whether you choose to keep or remove it.
977
978
///
978
- /// When the returned DrainedFilter is dropped, any remaining elements that satisfy
979
- /// the predicate are dropped from the table.
980
- ///
981
- /// It is unspecified how many more elements will be subjected to the closure
982
- /// if a panic occurs in the closure, or a panic occurs while dropping an element,
983
- /// or if the `DrainFilter` value is leaked.
979
+ /// If the returned `DrainFilter` is not exhausted, e.g. because it is dropped without iterating
980
+ /// or the iteration short-circuits, then the remaining elements will be retained.
981
+ /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
984
982
///
985
983
/// Keeps the allocated memory for reuse.
986
984
///
@@ -1007,9 +1005,8 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
1007
1005
/// let d = map.drain_filter(|k, _v| k % 2 != 0);
1008
1006
/// }
1009
1007
///
1010
- /// // But the map lens have been reduced by half
1011
- /// // even if we do not use DrainFilter iterator.
1012
- /// assert_eq!(map.len(), 4);
1008
+ /// // DrainFilter was not exhausted, therefore no elements were drained.
1009
+ /// assert_eq!(map.len(), 8);
1013
1010
/// ```
1014
1011
#[ cfg_attr( feature = "inline-more" , inline) ]
1015
1012
pub fn drain_filter < F > ( & mut self , f : F ) -> DrainFilter < ' _ , K , V , F , A >
@@ -2739,6 +2736,7 @@ impl<K, V, A: Allocator + Clone> Drain<'_, K, V, A> {
2739
2736
///
2740
2737
/// assert_eq!(map.len(), 1);
2741
2738
/// ```
2739
+ #[ must_use = "Iterators are lazy unless consumed" ]
2742
2740
pub struct DrainFilter < ' a , K , V , F , A : Allocator + Clone = Global >
2743
2741
where
2744
2742
F : FnMut ( & K , & mut V ) -> bool ,
@@ -2747,30 +2745,6 @@ where
2747
2745
inner : DrainFilterInner < ' a , K , V , A > ,
2748
2746
}
2749
2747
2750
- impl < ' a , K , V , F , A > Drop for DrainFilter < ' a , K , V , F , A >
2751
- where
2752
- F : FnMut ( & K , & mut V ) -> bool ,
2753
- A : Allocator + Clone ,
2754
- {
2755
- #[ cfg_attr( feature = "inline-more" , inline) ]
2756
- fn drop ( & mut self ) {
2757
- while let Some ( item) = self . next ( ) {
2758
- let guard = ConsumeAllOnDrop ( self ) ;
2759
- drop ( item) ;
2760
- mem:: forget ( guard) ;
2761
- }
2762
- }
2763
- }
2764
-
2765
- pub ( super ) struct ConsumeAllOnDrop < ' a , T : Iterator > ( pub & ' a mut T ) ;
2766
-
2767
- impl < T : Iterator > Drop for ConsumeAllOnDrop < ' _ , T > {
2768
- #[ cfg_attr( feature = "inline-more" , inline) ]
2769
- fn drop ( & mut self ) {
2770
- self . 0 . for_each ( drop) ;
2771
- }
2772
- }
2773
-
2774
2748
impl < K , V , F , A > Iterator for DrainFilter < ' _ , K , V , F , A >
2775
2749
where
2776
2750
F : FnMut ( & K , & mut V ) -> bool ,
@@ -8159,7 +8133,7 @@ mod test_map {
8159
8133
}
8160
8134
{
8161
8135
let mut map: HashMap < i32 , i32 > = ( 0 ..8 ) . map ( |x| ( x, x * 10 ) ) . collect ( ) ;
8162
- drop ( map. drain_filter ( |& k, _| k % 2 == 0 ) ) ;
8136
+ map. drain_filter ( |& k, _| k % 2 == 0 ) . for_each ( drop ) ;
8163
8137
assert_eq ! ( map. len( ) , 4 ) ;
8164
8138
}
8165
8139
}
0 commit comments