Skip to content

Commit b9bb126

Browse files
authoredApr 8, 2020
Rollup merge of #70850 - ssomers:btreemap_first_last, r=Amanieu
BTreeMap first last proposal tweaks Clean-up and following up on a request in #62924. Trying the reviewer of the original code #65637... r? @scottmcm
2 parents 54abd4f + 8212b97 commit b9bb126

File tree

1 file changed

+76
-48
lines changed
  • src/liballoc/collections/btree

1 file changed

+76
-48
lines changed
 

Diff for: ‎src/liballoc/collections/btree/map.rs

+76-48
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
653653
/// assert_eq!(map.first_key_value(), Some((&1, &"b")));
654654
/// ```
655655
#[unstable(feature = "map_first_last", issue = "62924")]
656-
pub fn first_key_value<T: ?Sized>(&self) -> Option<(&K, &V)>
657-
where
658-
T: Ord,
659-
K: Borrow<T>,
660-
{
656+
pub fn first_key_value(&self) -> Option<(&K, &V)> {
661657
let front = self.root.as_ref()?.as_ref().first_leaf_edge();
662658
front.right_kv().ok().map(Handle::into_kv)
663659
}
@@ -667,36 +663,54 @@ impl<K: Ord, V> BTreeMap<K, V> {
667663
///
668664
/// # Examples
669665
///
670-
/// Contrived way to `clear` a map:
671-
///
672666
/// ```
673667
/// #![feature(map_first_last)]
674668
/// use std::collections::BTreeMap;
675669
///
676670
/// let mut map = BTreeMap::new();
677671
/// map.insert(1, "a");
678672
/// map.insert(2, "b");
679-
/// while let Some(entry) = map.first_entry() {
680-
/// let (key, val) = entry.remove_entry();
681-
/// assert!(!map.contains_key(&key));
673+
/// if let Some(mut entry) = map.first_entry() {
674+
/// if *entry.key() > 0 {
675+
/// entry.insert("first");
676+
/// }
682677
/// }
678+
/// assert_eq!(*map.get(&1).unwrap(), "first");
679+
/// assert_eq!(*map.get(&2).unwrap(), "b");
683680
/// ```
684681
#[unstable(feature = "map_first_last", issue = "62924")]
685-
pub fn first_entry<T: ?Sized>(&mut self) -> Option<OccupiedEntry<'_, K, V>>
686-
where
687-
T: Ord,
688-
K: Borrow<T>,
689-
{
682+
pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
690683
let front = self.root.as_mut()?.as_mut().first_leaf_edge();
691-
if let Ok(kv) = front.right_kv() {
692-
Some(OccupiedEntry {
693-
handle: kv.forget_node_type(),
694-
length: &mut self.length,
695-
_marker: PhantomData,
696-
})
697-
} else {
698-
None
699-
}
684+
let kv = front.right_kv().ok()?;
685+
Some(OccupiedEntry {
686+
handle: kv.forget_node_type(),
687+
length: &mut self.length,
688+
_marker: PhantomData,
689+
})
690+
}
691+
692+
/// Removes and returns the first element in the map.
693+
/// The key of this element is the minimum key that was in the map.
694+
///
695+
/// # Examples
696+
///
697+
/// Draining elements in ascending order, while keeping a usable map each iteration.
698+
///
699+
/// ```
700+
/// #![feature(map_first_last)]
701+
/// use std::collections::BTreeMap;
702+
///
703+
/// let mut map = BTreeMap::new();
704+
/// map.insert(1, "a");
705+
/// map.insert(2, "b");
706+
/// while let Some((key, _val)) = map.pop_first() {
707+
/// assert!(map.iter().all(|(k, _v)| *k > key));
708+
/// }
709+
/// assert!(map.is_empty());
710+
/// ```
711+
#[unstable(feature = "map_first_last", issue = "62924")]
712+
pub fn pop_first(&mut self) -> Option<(K, V)> {
713+
self.first_entry().map(|entry| entry.remove_entry())
700714
}
701715

702716
/// Returns the last key-value pair in the map.
@@ -716,11 +730,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
716730
/// assert_eq!(map.last_key_value(), Some((&2, &"a")));
717731
/// ```
718732
#[unstable(feature = "map_first_last", issue = "62924")]
719-
pub fn last_key_value<T: ?Sized>(&self) -> Option<(&K, &V)>
720-
where
721-
T: Ord,
722-
K: Borrow<T>,
723-
{
733+
pub fn last_key_value(&self) -> Option<(&K, &V)> {
724734
let back = self.root.as_ref()?.as_ref().last_leaf_edge();
725735
back.left_kv().ok().map(Handle::into_kv)
726736
}
@@ -730,36 +740,54 @@ impl<K: Ord, V> BTreeMap<K, V> {
730740
///
731741
/// # Examples
732742
///
733-
/// Contrived way to `clear` a map:
734-
///
735743
/// ```
736744
/// #![feature(map_first_last)]
737745
/// use std::collections::BTreeMap;
738746
///
739747
/// let mut map = BTreeMap::new();
740748
/// map.insert(1, "a");
741749
/// map.insert(2, "b");
742-
/// while let Some(entry) = map.last_entry() {
743-
/// let (key, val) = entry.remove_entry();
744-
/// assert!(!map.contains_key(&key));
750+
/// if let Some(mut entry) = map.last_entry() {
751+
/// if *entry.key() > 0 {
752+
/// entry.insert("last");
753+
/// }
745754
/// }
755+
/// assert_eq!(*map.get(&1).unwrap(), "a");
756+
/// assert_eq!(*map.get(&2).unwrap(), "last");
746757
/// ```
747758
#[unstable(feature = "map_first_last", issue = "62924")]
748-
pub fn last_entry<T: ?Sized>(&mut self) -> Option<OccupiedEntry<'_, K, V>>
749-
where
750-
T: Ord,
751-
K: Borrow<T>,
752-
{
759+
pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
753760
let back = self.root.as_mut()?.as_mut().last_leaf_edge();
754-
if let Ok(kv) = back.left_kv() {
755-
Some(OccupiedEntry {
756-
handle: kv.forget_node_type(),
757-
length: &mut self.length,
758-
_marker: PhantomData,
759-
})
760-
} else {
761-
None
762-
}
761+
let kv = back.left_kv().ok()?;
762+
Some(OccupiedEntry {
763+
handle: kv.forget_node_type(),
764+
length: &mut self.length,
765+
_marker: PhantomData,
766+
})
767+
}
768+
769+
/// Removes and returns the last element in the map.
770+
/// The key of this element is the maximum key that was in the map.
771+
///
772+
/// # Examples
773+
///
774+
/// Draining elements in descending order, while keeping a usable map each iteration.
775+
///
776+
/// ```
777+
/// #![feature(map_first_last)]
778+
/// use std::collections::BTreeMap;
779+
///
780+
/// let mut map = BTreeMap::new();
781+
/// map.insert(1, "a");
782+
/// map.insert(2, "b");
783+
/// while let Some((key, _val)) = map.pop_last() {
784+
/// assert!(map.iter().all(|(k, _v)| *k < key));
785+
/// }
786+
/// assert!(map.is_empty());
787+
/// ```
788+
#[unstable(feature = "map_first_last", issue = "62924")]
789+
pub fn pop_last(&mut self) -> Option<(K, V)> {
790+
self.last_entry().map(|entry| entry.remove_entry())
763791
}
764792

765793
/// Returns `true` if the map contains a value for the specified key.

0 commit comments

Comments
 (0)