Rollup merge of #68834 - ssomers:btree_first_last_fix68829, r=KodrAus

Fix and test implementation of BTreeMap's first/last_entry, pop_first/last

Properly implement and test `first_entry` & `last_entry` to fix problem report #68829
This commit is contained in:
Dylan DPC 2020-02-09 00:53:52 +01:00 committed by GitHub
commit cb87c958ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 21 deletions

View File

@ -675,13 +675,15 @@ pub fn first_entry<T: ?Sized>(&mut self) -> Option<OccupiedEntry<'_, K, V>>
T: Ord,
K: Borrow<T>,
{
match self.length {
0 => None,
_ => Some(OccupiedEntry {
handle: self.root.as_mut().first_kv(),
let front = self.root.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
}
}
@ -736,13 +738,15 @@ pub fn last_entry<T: ?Sized>(&mut self) -> Option<OccupiedEntry<'_, K, V>>
T: Ord,
K: Borrow<T>,
{
match self.length {
0 => None,
_ => Some(OccupiedEntry {
handle: self.root.as_mut().last_kv(),
let back = self.root.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
}
}

View File

@ -23,6 +23,11 @@ fn test_basic_large() {
assert_eq!(map.len(), i + 1);
}
assert_eq!(map.first_key_value(), Some((&0, &0)));
assert_eq!(map.last_key_value(), Some((&(size - 1), &(10 * (size - 1)))));
assert_eq!(map.first_entry().unwrap().key(), &0);
assert_eq!(map.last_entry().unwrap().key(), &(size - 1));
for i in 0..size {
assert_eq!(map.get(&i).unwrap(), &(i * 10));
}

View File

@ -487,21 +487,26 @@ fn test_first_last() {
a.insert(2);
assert_eq!(a.first(), Some(&1));
assert_eq!(a.last(), Some(&2));
a.insert(3);
for i in 3..=12 {
a.insert(i);
}
assert_eq!(a.first(), Some(&1));
assert_eq!(a.last(), Some(&3));
assert_eq!(a.len(), 3);
assert_eq!(a.last(), Some(&12));
assert_eq!(a.pop_first(), Some(1));
assert_eq!(a.len(), 2);
assert_eq!(a.pop_last(), Some(3));
assert_eq!(a.len(), 1);
assert_eq!(a.pop_last(), Some(12));
assert_eq!(a.pop_first(), Some(2));
assert_eq!(a.len(), 0);
assert_eq!(a.pop_last(), None);
assert_eq!(a.len(), 0);
assert_eq!(a.pop_last(), Some(11));
assert_eq!(a.pop_first(), Some(3));
assert_eq!(a.pop_last(), Some(10));
assert_eq!(a.pop_first(), Some(4));
assert_eq!(a.pop_first(), Some(5));
assert_eq!(a.pop_first(), Some(6));
assert_eq!(a.pop_first(), Some(7));
assert_eq!(a.pop_first(), Some(8));
assert_eq!(a.clone().pop_last(), Some(9));
assert_eq!(a.pop_first(), Some(9));
assert_eq!(a.pop_first(), None);
assert_eq!(a.len(), 0);
assert_eq!(a.pop_last(), None);
}
fn rand_data(len: usize) -> Vec<u32> {