@@ -1264,6 +1264,66 @@ impl<K, V> BTreeMap<K, V> {
12641264 BTreeMap { root : Some ( right_root) , length : right_len }
12651265 }
12661266
1267+ /// Removes at once all keys within the range from the map, returning the
1268+ /// removed key-value pairs as an iterator in ascending key order. If the
1269+ /// iterator is dropped before being fully consumed, it drops the remaining
1270+ /// removed key-value pairs.
1271+ ///
1272+ /// The returned iterator keeps a mutable borrow on the map to allow
1273+ /// optimizing its implementation.
1274+ ///
1275+ /// # Panics
1276+ ///
1277+ /// Panics if range `start > end`.
1278+ /// Panics if range `start == end` and both bounds are `Excluded`.
1279+ /// May panic if the [`Ord`] implementation of type `T` is ill-defined,
1280+ /// either because it does not form a total order or because it does not
1281+ /// correspond to the [`Ord`] implementation of type `K`.
1282+ ///
1283+ /// # Leaking
1284+ ///
1285+ /// If the returned iterator goes out of scope without being dropped (due to
1286+ /// [`mem::forget`], for example), the map may have lost and leaked
1287+ /// key-value pairs arbitrarily, including key-value pairs outside the range.
1288+ ///
1289+ /// # Examples
1290+ ///
1291+ /// ```
1292+ /// #![feature(btree_drain)]
1293+ /// use std::collections::BTreeMap;
1294+ ///
1295+ /// let mut a = BTreeMap::new();
1296+ /// a.insert(1, "a");
1297+ /// a.insert(2, "b");
1298+ /// a.insert(3, "c");
1299+ /// a.insert(17, "d");
1300+ /// a.insert(41, "e");
1301+ ///
1302+ /// let b: Vec<_> = a.drain(3..33).collect();
1303+ /// assert_eq!(b, vec![(3, "c"), (17, "d")]);
1304+ /// assert_eq!(a.len(), 3);
1305+ /// ```
1306+ #[ unstable( feature = "btree_drain" , issue = "81074" ) ]
1307+ pub fn drain < T : ?Sized , R > ( & mut self , range : R ) -> Drain < ' _ , K , V >
1308+ where
1309+ T : Ord ,
1310+ K : Borrow < T > + Ord ,
1311+ R : RangeBounds < T > ,
1312+ {
1313+ let inner = if let Some ( left_root) = self . root . as_mut ( ) {
1314+ let total_num = self . length ;
1315+ let right_root = left_root. split_off_range ( range) ;
1316+ let ( new_left_len, right_len) =
1317+ Root :: calc_split_length ( total_num, & left_root, & right_root) ;
1318+ self . length = new_left_len;
1319+ let right_range = right_root. into_dying ( ) . full_range ( ) ;
1320+ IntoIter { range : right_range, length : right_len }
1321+ } else {
1322+ IntoIter { range : LazyLeafRange :: none ( ) , length : 0 }
1323+ } ;
1324+ Drain { inner, _marker : PhantomData }
1325+ }
1326+
12671327 /// Creates an iterator that visits all elements (key-value pairs) in
12681328 /// ascending key order and uses a closure to determine if an element should
12691329 /// be removed. If the closure returns `true`, the element is removed from
@@ -1712,6 +1772,37 @@ impl<K, V> Clone for Values<'_, K, V> {
17121772 }
17131773}
17141774
1775+ /// An iterator produced by calling `drain` on BTreeMap.
1776+ #[ unstable( feature = "btree_drain" , issue = "81074" ) ]
1777+ #[ derive( Debug ) ]
1778+ pub struct Drain < ' a , K , V > {
1779+ inner : IntoIter < K , V > ,
1780+ _marker : PhantomData < & ' a mut BTreeMap < K , V > > ,
1781+ }
1782+
1783+ #[ unstable( feature = "btree_drain" , issue = "81074" ) ]
1784+ impl < K , V > Iterator for Drain < ' _ , K , V > {
1785+ type Item = ( K , V ) ;
1786+
1787+ fn next ( & mut self ) -> Option < ( K , V ) > {
1788+ self . inner . next ( )
1789+ }
1790+
1791+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1792+ self . inner . size_hint ( )
1793+ }
1794+ }
1795+
1796+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1797+ impl < K , V > ExactSizeIterator for Drain < ' _ , K , V > {
1798+ fn len ( & self ) -> usize {
1799+ self . inner . len ( )
1800+ }
1801+ }
1802+
1803+ #[ stable( feature = "fused" , since = "1.26.0" ) ]
1804+ impl < K , V > FusedIterator for Drain < ' _ , K , V > { }
1805+
17151806/// An iterator produced by calling `drain_filter` on BTreeMap.
17161807#[ unstable( feature = "btree_drain_filter" , issue = "70530" ) ]
17171808pub struct DrainFilter < ' a , K , V , F >
0 commit comments