34: add BinaryHeap.pop_unchecked r=japaric a=japaric



Co-authored-by: Jorge Aparicio <jorge@japaric.io>
This commit is contained in:
bors[bot] 2018-04-28 05:42:19 +00:00
commit 6419bc2386

View File

@ -10,6 +10,7 @@
use core::cmp::Ordering;
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::{mem, ptr, slice};
use generic_array::ArrayLength;
@ -249,13 +250,23 @@ where
/// assert_eq!(heap.pop(), None);
/// ```
pub fn pop(&mut self) -> Option<T> {
self.data.pop().map(|mut item| {
if !self.is_empty() {
mem::swap(&mut item, &mut self.data[0]);
self.sift_down_to_bottom(0);
}
item
})
if self.is_empty() {
None
} else {
Some(unsafe { self.pop_unchecked() })
}
}
/// Removes the *top* (greatest if max-heap, smallest if min-heap) item from the binary heap and
/// returns it, without checking if the binary heap is empty.
pub unsafe fn pop_unchecked(&mut self) -> T {
let mut item = self.data.pop_unchecked();
if !self.is_empty() {
mem::swap(&mut item, &mut self.data[0]);
self.sift_down_to_bottom(0);
}
item
}
/// Pushes an item onto the binary heap.
@ -333,7 +344,7 @@ where
struct Hole<'a, T: 'a> {
data: &'a mut [T],
/// `elt` is always `Some` from new until drop.
elt: Option<T>,
elt: ManuallyDrop<T>,
pos: usize,
}
@ -347,7 +358,7 @@ impl<'a, T> Hole<'a, T> {
let elt = ptr::read(data.get_unchecked(pos));
Hole {
data,
elt: Some(elt),
elt: ManuallyDrop::new(elt),
pos,
}
}
@ -360,7 +371,7 @@ impl<'a, T> Hole<'a, T> {
/// Returns a reference to the element removed.
#[inline]
fn element(&self) -> &T {
self.elt.as_ref().unwrap()
&self.elt
}
/// Returns a reference to the element at `index`.
@ -393,7 +404,7 @@ impl<'a, T> Drop for Hole<'a, T> {
// fill the hole again
unsafe {
let pos = self.pos;
ptr::write(self.data.get_unchecked_mut(pos), self.elt.take().unwrap());
ptr::write(self.data.get_unchecked_mut(pos), ptr::read(&*self.elt));
}
}
}