@@ -1151,7 +1151,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
1151
1151
K : Ord ,
1152
1152
F : FnMut ( & K , & mut V ) -> bool ,
1153
1153
{
1154
- self . extract_if ( |k, v| !f ( k, v) ) . for_each ( drop) ;
1154
+ self . extract_if ( .. , |k, v| !f ( k, v) ) . for_each ( drop) ;
1155
1155
}
1156
1156
1157
1157
/// Moves all elements from `other` into `self`, leaving `other` empty.
@@ -1427,27 +1427,30 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
1427
1427
/// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), [1, 3, 5, 7]);
1428
1428
/// ```
1429
1429
#[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
1430
- pub fn extract_if < F > ( & mut self , pred : F ) -> ExtractIf < ' _ , K , V , F , A >
1430
+ pub fn extract_if < F , R > ( & mut self , range : R , pred : F ) -> ExtractIf < ' _ , K , V , R , F , A >
1431
1431
where
1432
1432
K : Ord ,
1433
+ R : RangeBounds < K > ,
1433
1434
F : FnMut ( & K , & mut V ) -> bool ,
1434
1435
{
1435
- let ( inner, alloc) = self . extract_if_inner ( ) ;
1436
+ let ( inner, alloc) = self . extract_if_inner ( range ) ;
1436
1437
ExtractIf { pred, inner, alloc }
1437
1438
}
1438
1439
1439
- pub ( super ) fn extract_if_inner ( & mut self ) -> ( ExtractIfInner < ' _ , K , V > , A )
1440
+ pub ( super ) fn extract_if_inner < R > ( & mut self , range : R ) -> ( ExtractIfInner < ' _ , K , V , R > , A )
1440
1441
where
1441
1442
K : Ord ,
1443
+ R : RangeBounds < K > ,
1442
1444
{
1443
1445
if let Some ( root) = self . root . as_mut ( ) {
1444
1446
let ( root, dormant_root) = DormantMutRef :: new ( root) ;
1445
- let front = root. borrow_mut ( ) . first_leaf_edge ( ) ;
1447
+ let first = root. borrow_mut ( ) . lower_bound ( SearchBound :: from_range ( range . start_bound ( ) ) ) ;
1446
1448
(
1447
1449
ExtractIfInner {
1448
1450
length : & mut self . length ,
1449
1451
dormant_root : Some ( dormant_root) ,
1450
- cur_leaf_edge : Some ( front) ,
1452
+ cur_leaf_edge : Some ( first) ,
1453
+ range,
1451
1454
} ,
1452
1455
( * self . alloc ) . clone ( ) ,
1453
1456
)
@@ -1457,6 +1460,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
1457
1460
length : & mut self . length ,
1458
1461
dormant_root : None ,
1459
1462
cur_leaf_edge : None ,
1463
+ range,
1460
1464
} ,
1461
1465
( * self . alloc ) . clone ( ) ,
1462
1466
)
@@ -1915,18 +1919,19 @@ pub struct ExtractIf<
1915
1919
' a ,
1916
1920
K ,
1917
1921
V ,
1922
+ R ,
1918
1923
F ,
1919
1924
#[ unstable( feature = "allocator_api" , issue = "32838" ) ] A : Allocator + Clone = Global ,
1920
1925
> {
1921
1926
pred : F ,
1922
- inner : ExtractIfInner < ' a , K , V > ,
1927
+ inner : ExtractIfInner < ' a , K , V , R > ,
1923
1928
/// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
1924
1929
alloc : A ,
1925
1930
}
1926
1931
1927
1932
/// Most of the implementation of ExtractIf are generic over the type
1928
1933
/// of the predicate, thus also serving for BTreeSet::ExtractIf.
1929
- pub ( super ) struct ExtractIfInner < ' a , K , V > {
1934
+ pub ( super ) struct ExtractIfInner < ' a , K , V , R > {
1930
1935
/// Reference to the length field in the borrowed map, updated live.
1931
1936
length : & ' a mut usize ,
1932
1937
/// Buried reference to the root field in the borrowed map.
@@ -1936,10 +1941,13 @@ pub(super) struct ExtractIfInner<'a, K, V> {
1936
1941
/// Empty if the map has no root, if iteration went beyond the last leaf edge,
1937
1942
/// or if a panic occurred in the predicate.
1938
1943
cur_leaf_edge : Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ,
1944
+ /// Range over which iteration was requested. We don't need the left side, but we
1945
+ /// can't extract the right side without requiring K: Clone.
1946
+ range : R ,
1939
1947
}
1940
1948
1941
1949
#[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
1942
- impl < K , V , F , A > fmt:: Debug for ExtractIf < ' _ , K , V , F , A >
1950
+ impl < K , V , R , F , A > fmt:: Debug for ExtractIf < ' _ , K , V , R , F , A >
1943
1951
where
1944
1952
K : fmt:: Debug ,
1945
1953
V : fmt:: Debug ,
@@ -1951,8 +1959,10 @@ where
1951
1959
}
1952
1960
1953
1961
#[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
1954
- impl < K , V , F , A : Allocator + Clone > Iterator for ExtractIf < ' _ , K , V , F , A >
1962
+ impl < K , V , R , F , A : Allocator + Clone > Iterator for ExtractIf < ' _ , K , V , R , F , A >
1955
1963
where
1964
+ K : PartialOrd ,
1965
+ R : RangeBounds < K > ,
1956
1966
F : FnMut ( & K , & mut V ) -> bool ,
1957
1967
{
1958
1968
type Item = ( K , V ) ;
@@ -1966,7 +1976,7 @@ where
1966
1976
}
1967
1977
}
1968
1978
1969
- impl < ' a , K , V > ExtractIfInner < ' a , K , V > {
1979
+ impl < ' a , K , V , R > ExtractIfInner < ' a , K , V , R > {
1970
1980
/// Allow Debug implementations to predict the next element.
1971
1981
pub ( super ) fn peek ( & self ) -> Option < ( & K , & V ) > {
1972
1982
let edge = self . cur_leaf_edge . as_ref ( ) ?;
@@ -1976,10 +1986,15 @@ impl<'a, K, V> ExtractIfInner<'a, K, V> {
1976
1986
/// Implementation of a typical `ExtractIf::next` method, given the predicate.
1977
1987
pub ( super ) fn next < F , A : Allocator + Clone > ( & mut self , pred : & mut F , alloc : A ) -> Option < ( K , V ) >
1978
1988
where
1989
+ K : PartialOrd ,
1990
+ R : RangeBounds < K > ,
1979
1991
F : FnMut ( & K , & mut V ) -> bool ,
1980
1992
{
1981
1993
while let Ok ( mut kv) = self . cur_leaf_edge . take ( ) ?. next_kv ( ) {
1982
1994
let ( k, v) = kv. kv_mut ( ) ;
1995
+ if !self . range . contains ( k) {
1996
+ return None ;
1997
+ }
1983
1998
if pred ( k, v) {
1984
1999
* self . length -= 1 ;
1985
2000
let ( kv, pos) = kv. remove_kv_tracking (
@@ -2011,7 +2026,13 @@ impl<'a, K, V> ExtractIfInner<'a, K, V> {
2011
2026
}
2012
2027
2013
2028
#[ unstable( feature = "btree_extract_if" , issue = "70530" ) ]
2014
- impl < K , V , F > FusedIterator for ExtractIf < ' _ , K , V , F > where F : FnMut ( & K , & mut V ) -> bool { }
2029
+ impl < K , V , R , F > FusedIterator for ExtractIf < ' _ , K , V , R , F >
2030
+ where
2031
+ K : PartialOrd ,
2032
+ R : RangeBounds < K > ,
2033
+ F : FnMut ( & K , & mut V ) -> bool ,
2034
+ {
2035
+ }
2015
2036
2016
2037
#[ stable( feature = "btree_range" , since = "1.17.0" ) ]
2017
2038
impl < ' a , K , V > Iterator for Range < ' a , K , V > {
0 commit comments