@@ -1151,7 +1151,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
11511151 K : Ord ,
11521152 F : FnMut ( & K , & mut V ) -> bool ,
11531153 {
1154- self . extract_if ( |k, v| !f ( k, v) ) . for_each ( drop) ;
1154+ self . extract_if ( .. , |k, v| !f ( k, v) ) . for_each ( drop) ;
11551155 }
11561156
11571157 /// Moves all elements from `other` into `self`, leaving `other` empty.
@@ -1429,27 +1429,30 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
14291429 /// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), [1, 3, 5, 7]);
14301430 /// ```
14311431 #[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
1432- pub fn extract_if < F > ( & mut self , pred : F ) -> ExtractIf < ' _ , K , V , F , A >
1432+ pub fn extract_if < F , R > ( & mut self , range : R , pred : F ) -> ExtractIf < ' _ , K , V , R , F , A >
14331433 where
14341434 K : Ord ,
1435+ R : RangeBounds < K > ,
14351436 F : FnMut ( & K , & mut V ) -> bool ,
14361437 {
1437- let ( inner, alloc) = self . extract_if_inner ( ) ;
1438+ let ( inner, alloc) = self . extract_if_inner ( range ) ;
14381439 ExtractIf { pred, inner, alloc }
14391440 }
14401441
1441- pub ( super ) fn extract_if_inner ( & mut self ) -> ( ExtractIfInner < ' _ , K , V > , A )
1442+ pub ( super ) fn extract_if_inner < R > ( & mut self , range : R ) -> ( ExtractIfInner < ' _ , K , V , R > , A )
14421443 where
14431444 K : Ord ,
1445+ R : RangeBounds < K > ,
14441446 {
14451447 if let Some ( root) = self . root . as_mut ( ) {
14461448 let ( root, dormant_root) = DormantMutRef :: new ( root) ;
1447- let front = root. borrow_mut ( ) . first_leaf_edge ( ) ;
1449+ let first = root. borrow_mut ( ) . lower_bound ( SearchBound :: from_range ( range . start_bound ( ) ) ) ;
14481450 (
14491451 ExtractIfInner {
14501452 length : & mut self . length ,
14511453 dormant_root : Some ( dormant_root) ,
1452- cur_leaf_edge : Some ( front) ,
1454+ cur_leaf_edge : Some ( first) ,
1455+ range,
14531456 } ,
14541457 ( * self . alloc ) . clone ( ) ,
14551458 )
@@ -1459,6 +1462,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
14591462 length : & mut self . length ,
14601463 dormant_root : None ,
14611464 cur_leaf_edge : None ,
1465+ range,
14621466 } ,
14631467 ( * self . alloc ) . clone ( ) ,
14641468 )
@@ -1917,18 +1921,19 @@ pub struct ExtractIf<
19171921 ' a ,
19181922 K ,
19191923 V ,
1924+ R ,
19201925 F ,
19211926 #[ unstable( feature = "allocator_api" , issue = "32838" ) ] A : Allocator + Clone = Global ,
19221927> {
19231928 pred : F ,
1924- inner : ExtractIfInner < ' a , K , V > ,
1929+ inner : ExtractIfInner < ' a , K , V , R > ,
19251930 /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
19261931 alloc : A ,
19271932}
19281933
19291934/// Most of the implementation of ExtractIf are generic over the type
19301935/// of the predicate, thus also serving for BTreeSet::ExtractIf.
1931- pub ( super ) struct ExtractIfInner < ' a , K , V > {
1936+ pub ( super ) struct ExtractIfInner < ' a , K , V , R > {
19321937 /// Reference to the length field in the borrowed map, updated live.
19331938 length : & ' a mut usize ,
19341939 /// Buried reference to the root field in the borrowed map.
@@ -1938,10 +1943,13 @@ pub(super) struct ExtractIfInner<'a, K, V> {
19381943 /// Empty if the map has no root, if iteration went beyond the last leaf edge,
19391944 /// or if a panic occurred in the predicate.
19401945 cur_leaf_edge : Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ,
1946+ /// Range over which iteration was requested. We don't need the left side, but we
1947+ /// can't extract the right side without requiring K: Clone.
1948+ range : R ,
19411949}
19421950
19431951#[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
1944- impl < K , V , F , A > fmt:: Debug for ExtractIf < ' _ , K , V , F , A >
1952+ impl < K , V , R , F , A > fmt:: Debug for ExtractIf < ' _ , K , V , R , F , A >
19451953where
19461954 K : fmt:: Debug ,
19471955 V : fmt:: Debug ,
@@ -1953,8 +1961,10 @@ where
19531961}
19541962
19551963#[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
1956- impl < K , V , F , A : Allocator + Clone > Iterator for ExtractIf < ' _ , K , V , F , A >
1964+ impl < K , V , R , F , A : Allocator + Clone > Iterator for ExtractIf < ' _ , K , V , R , F , A >
19571965where
1966+ K : PartialOrd ,
1967+ R : RangeBounds < K > ,
19581968 F : FnMut ( & K , & mut V ) -> bool ,
19591969{
19601970 type Item = ( K , V ) ;
@@ -1968,7 +1978,7 @@ where
19681978 }
19691979}
19701980
1971- impl < ' a , K , V > ExtractIfInner < ' a , K , V > {
1981+ impl < ' a , K , V , R > ExtractIfInner < ' a , K , V , R > {
19721982 /// Allow Debug implementations to predict the next element.
19731983 pub ( super ) fn peek ( & self ) -> Option < ( & K , & V ) > {
19741984 let edge = self . cur_leaf_edge . as_ref ( ) ?;
@@ -1978,10 +1988,22 @@ impl<'a, K, V> ExtractIfInner<'a, K, V> {
19781988 /// Implementation of a typical `ExtractIf::next` method, given the predicate.
19791989 pub ( super ) fn next < F , A : Allocator + Clone > ( & mut self , pred : & mut F , alloc : A ) -> Option < ( K , V ) >
19801990 where
1991+ K : PartialOrd ,
1992+ R : RangeBounds < K > ,
19811993 F : FnMut ( & K , & mut V ) -> bool ,
19821994 {
19831995 while let Ok ( mut kv) = self . cur_leaf_edge . take ( ) ?. next_kv ( ) {
19841996 let ( k, v) = kv. kv_mut ( ) ;
1997+
1998+ // On creation, we navigated directly to the left bound, so we need only check the
1999+ // right bound here to decide whether to stop.
2000+ match self . range . end_bound ( ) {
2001+ Bound :: Included ( ref end) if ( * k) . le ( end) => ( ) ,
2002+ Bound :: Excluded ( ref end) if ( * k) . lt ( end) => ( ) ,
2003+ Bound :: Unbounded => ( ) ,
2004+ _ => return None ,
2005+ }
2006+
19852007 if pred ( k, v) {
19862008 * self . length -= 1 ;
19872009 let ( kv, pos) = kv. remove_kv_tracking (
@@ -2013,7 +2035,13 @@ impl<'a, K, V> ExtractIfInner<'a, K, V> {
20132035}
20142036
20152037#[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
2016- impl < K , V , F > FusedIterator for ExtractIf < ' _ , K , V , F > where F : FnMut ( & K , & mut V ) -> bool { }
2038+ impl < K , V , R , F > FusedIterator for ExtractIf < ' _ , K , V , R , F >
2039+ where
2040+ K : PartialOrd ,
2041+ R : RangeBounds < K > ,
2042+ F : FnMut ( & K , & mut V ) -> bool ,
2043+ {
2044+ }
20172045
20182046#[ stable( feature = "btree_range" , since = "1.17.0" ) ]
20192047impl < ' a , K , V > Iterator for Range < ' a , K , V > {
0 commit comments