From bdbe56ecb837ce462f99508837ff66fc09d23cd8 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Sat, 4 Apr 2020 20:32:07 +0200 Subject: [PATCH 1/3] BTreeMap first/last: simplify implementations --- src/liballoc/collections/btree/map.rs | 54 ++++++++------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 70968964f476e..c782fb4f6a9bb 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -653,11 +653,7 @@ impl BTreeMap { /// assert_eq!(map.first_key_value(), Some((&1, &"b"))); /// ``` #[unstable(feature = "map_first_last", issue = "62924")] - pub fn first_key_value(&self) -> Option<(&K, &V)> - where - T: Ord, - K: Borrow, - { + pub fn first_key_value(&self) -> Option<(&K, &V)> { let front = self.root.as_ref()?.as_ref().first_leaf_edge(); front.right_kv().ok().map(Handle::into_kv) } @@ -682,21 +678,14 @@ impl BTreeMap { /// } /// ``` #[unstable(feature = "map_first_last", issue = "62924")] - pub fn first_entry(&mut self) -> Option> - where - T: Ord, - K: Borrow, - { + pub fn first_entry(&mut self) -> Option> { let front = self.root.as_mut()?.as_mut().first_leaf_edge(); - if let Ok(kv) = front.right_kv() { - Some(OccupiedEntry { - handle: kv.forget_node_type(), - length: &mut self.length, - _marker: PhantomData, - }) - } else { - None - } + let kv = front.right_kv().ok()?; + Some(OccupiedEntry { + handle: kv.forget_node_type(), + length: &mut self.length, + _marker: PhantomData, + }) } /// Returns the last key-value pair in the map. @@ -716,11 +705,7 @@ impl BTreeMap { /// assert_eq!(map.last_key_value(), Some((&2, &"a"))); /// ``` #[unstable(feature = "map_first_last", issue = "62924")] - pub fn last_key_value(&self) -> Option<(&K, &V)> - where - T: Ord, - K: Borrow, - { + pub fn last_key_value(&self) -> Option<(&K, &V)> { let back = self.root.as_ref()?.as_ref().last_leaf_edge(); back.left_kv().ok().map(Handle::into_kv) } @@ -745,21 +730,14 @@ impl BTreeMap { /// } /// ``` #[unstable(feature = "map_first_last", issue = "62924")] - pub fn last_entry(&mut self) -> Option> - where - T: Ord, - K: Borrow, - { + pub fn last_entry(&mut self) -> Option> { let back = self.root.as_mut()?.as_mut().last_leaf_edge(); - if let Ok(kv) = back.left_kv() { - Some(OccupiedEntry { - handle: kv.forget_node_type(), - length: &mut self.length, - _marker: PhantomData, - }) - } else { - None - } + let kv = back.left_kv().ok()?; + Some(OccupiedEntry { + handle: kv.forget_node_type(), + length: &mut self.length, + _marker: PhantomData, + }) } /// Returns `true` if the map contains a value for the specified key. From c23ee767d94a8ea5e0aa782731f89f4e00fbdc7e Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Mon, 6 Apr 2020 19:03:18 +0200 Subject: [PATCH 2/3] BTreeMap first/last: make examples more to the point --- src/liballoc/collections/btree/map.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index c782fb4f6a9bb..d550856b6edf3 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -663,8 +663,6 @@ impl BTreeMap { /// /// # Examples /// - /// Contrived way to `clear` a map: - /// /// ``` /// #![feature(map_first_last)] /// use std::collections::BTreeMap; @@ -672,10 +670,13 @@ impl BTreeMap { /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// map.insert(2, "b"); - /// while let Some(entry) = map.first_entry() { - /// let (key, val) = entry.remove_entry(); - /// assert!(!map.contains_key(&key)); + /// if let Some(mut entry) = map.first_entry() { + /// if *entry.key() > 0 { + /// entry.insert("first"); + /// } /// } + /// assert_eq!(*map.get(&1).unwrap(), "first"); + /// assert_eq!(*map.get(&2).unwrap(), "b"); /// ``` #[unstable(feature = "map_first_last", issue = "62924")] pub fn first_entry(&mut self) -> Option> { @@ -715,8 +716,6 @@ impl BTreeMap { /// /// # Examples /// - /// Contrived way to `clear` a map: - /// /// ``` /// #![feature(map_first_last)] /// use std::collections::BTreeMap; @@ -724,10 +723,13 @@ impl BTreeMap { /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); /// map.insert(2, "b"); - /// while let Some(entry) = map.last_entry() { - /// let (key, val) = entry.remove_entry(); - /// assert!(!map.contains_key(&key)); + /// if let Some(mut entry) = map.last_entry() { + /// if *entry.key() > 0 { + /// entry.insert("last"); + /// } /// } + /// assert_eq!(*map.get(&1).unwrap(), "a"); + /// assert_eq!(*map.get(&2).unwrap(), "last"); /// ``` #[unstable(feature = "map_first_last", issue = "62924")] pub fn last_entry(&mut self) -> Option> { From 8212b9772e486ae272639fb22ee3b6e7f9047d3f Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Sun, 5 Apr 2020 18:56:07 +0200 Subject: [PATCH 3/3] BTreeMap first/last: add pop methods --- src/liballoc/collections/btree/map.rs | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index d550856b6edf3..a1e59b2e6afb3 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -689,6 +689,30 @@ impl BTreeMap { }) } + /// Removes and returns the first element in the map. + /// The key of this element is the minimum key that was in the map. + /// + /// # Examples + /// + /// Draining elements in ascending order, while keeping a usable map each iteration. + /// + /// ``` + /// #![feature(map_first_last)] + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1, "a"); + /// map.insert(2, "b"); + /// while let Some((key, _val)) = map.pop_first() { + /// assert!(map.iter().all(|(k, _v)| *k > key)); + /// } + /// assert!(map.is_empty()); + /// ``` + #[unstable(feature = "map_first_last", issue = "62924")] + pub fn pop_first(&mut self) -> Option<(K, V)> { + self.first_entry().map(|entry| entry.remove_entry()) + } + /// Returns the last key-value pair in the map. /// The key in this pair is the maximum key in the map. /// @@ -742,6 +766,30 @@ impl BTreeMap { }) } + /// Removes and returns the last element in the map. + /// The key of this element is the maximum key that was in the map. + /// + /// # Examples + /// + /// Draining elements in descending order, while keeping a usable map each iteration. + /// + /// ``` + /// #![feature(map_first_last)] + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1, "a"); + /// map.insert(2, "b"); + /// while let Some((key, _val)) = map.pop_last() { + /// assert!(map.iter().all(|(k, _v)| *k < key)); + /// } + /// assert!(map.is_empty()); + /// ``` + #[unstable(feature = "map_first_last", issue = "62924")] + pub fn pop_last(&mut self) -> Option<(K, V)> { + self.last_entry().map(|entry| entry.remove_entry()) + } + /// Returns `true` if the map contains a value for the specified key. /// /// The key may be any borrowed form of the map's key type, but the ordering