Add PeekMut::pop
A fairly common workflow is to put a bunch of stuff into a binary heap and then mutate the top value until its empty. This both makes that a bit more convenient (no need to save a boolean off and pop after to avoid borrowck issues), and a bit more efficient since you only shift once.
This commit is contained in:
parent
6c9bb42ecc
commit
f2cb47adf9
3 changed files with 34 additions and 5 deletions
|
@ -153,8 +153,7 @@
|
||||||
|
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
use core::iter::{FromIterator, FusedIterator};
|
use core::iter::{FromIterator, FusedIterator};
|
||||||
use core::mem::swap;
|
use core::mem::{swap, size_of};
|
||||||
use core::mem::size_of;
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
|
@ -226,12 +225,15 @@ pub struct BinaryHeap<T> {
|
||||||
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
|
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
|
||||||
pub struct PeekMut<'a, T: 'a + Ord> {
|
pub struct PeekMut<'a, T: 'a + Ord> {
|
||||||
heap: &'a mut BinaryHeap<T>,
|
heap: &'a mut BinaryHeap<T>,
|
||||||
|
sift: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
|
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
|
||||||
impl<'a, T: Ord> Drop for PeekMut<'a, T> {
|
impl<'a, T: Ord> Drop for PeekMut<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.heap.sift_down(0);
|
if self.sift {
|
||||||
|
self.heap.sift_down(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,6 +252,16 @@ impl<'a, T: Ord> DerefMut for PeekMut<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Ord> PeekMut<'a, T> {
|
||||||
|
/// Removes the peeked value from the heap and returns it.
|
||||||
|
#[unstable(feature = "binary_heap_peek_mut_pop", issue = "0")]
|
||||||
|
pub fn pop(mut this: PeekMut<'a, T>) -> T {
|
||||||
|
let value = this.heap.pop().unwrap();
|
||||||
|
this.sift = false;
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: Clone> Clone for BinaryHeap<T> {
|
impl<T: Clone> Clone for BinaryHeap<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -385,7 +397,10 @@ impl<T: Ord> BinaryHeap<T> {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(PeekMut { heap: self })
|
Some(PeekMut {
|
||||||
|
heap: self,
|
||||||
|
sift: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::collections::BinaryHeap;
|
use std::collections::BinaryHeap;
|
||||||
use std::collections::binary_heap::Drain;
|
use std::collections::binary_heap::{Drain, PeekMut};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator() {
|
fn test_iterator() {
|
||||||
|
@ -94,6 +94,19 @@ fn test_peek_mut() {
|
||||||
assert_eq!(heap.peek(), Some(&9));
|
assert_eq!(heap.peek(), Some(&9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_peek_mut_pop() {
|
||||||
|
let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
|
||||||
|
let mut heap = BinaryHeap::from(data);
|
||||||
|
assert_eq!(heap.peek(), Some(&10));
|
||||||
|
{
|
||||||
|
let mut top = heap.peek_mut().unwrap();
|
||||||
|
*top -= 2;
|
||||||
|
assert_eq!(PeekMut::pop(top), 8);
|
||||||
|
}
|
||||||
|
assert_eq!(heap.peek(), Some(&9));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_push() {
|
fn test_push() {
|
||||||
let mut heap = BinaryHeap::from(vec![2, 4, 9]);
|
let mut heap = BinaryHeap::from(vec![2, 4, 9]);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
#![feature(binary_heap_extras)]
|
#![feature(binary_heap_extras)]
|
||||||
|
#![feature(binary_heap_peek_mut_pop)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(btree_range)]
|
#![feature(btree_range)]
|
||||||
#![feature(collections)]
|
#![feature(collections)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue