Skip to content

Commit 66b82be

Browse files
authored
Auto merge of #33830 - moosingin3space:feature/mutable-high-priority-binaryheap, r=alexcrichton
Mutable access to the top element of a BinaryHeap An implementation of the library change discussed here: rust-lang/rfcs#1626
2 parents b8deebe + 2a34a7b commit 66b82be

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

src/libcollections/binary_heap.rs

+68
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@
151151
#![allow(missing_docs)]
152152
#![stable(feature = "rust1", since = "1.0.0")]
153153

154+
use core::ops::{Drop, Deref, DerefMut};
154155
use core::iter::FromIterator;
155156
use core::mem::swap;
156157
use core::mem::size_of;
@@ -218,6 +219,37 @@ pub struct BinaryHeap<T> {
218219
data: Vec<T>,
219220
}
220221

222+
/// A container object that represents the result of the [`peek_mut()`] method
223+
/// on `BinaryHeap`. See its documentation for details.
224+
///
225+
/// [`peek_mut()`]: struct.BinaryHeap.html#method.peek_mut
226+
#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
227+
pub struct PeekMut<'a, T: 'a + Ord> {
228+
heap: &'a mut BinaryHeap<T>
229+
}
230+
231+
#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
232+
impl<'a, T: Ord> Drop for PeekMut<'a, T> {
233+
fn drop(&mut self) {
234+
self.heap.sift_down(0);
235+
}
236+
}
237+
238+
#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
239+
impl<'a, T: Ord> Deref for PeekMut<'a, T> {
240+
type Target = T;
241+
fn deref(&self) -> &T {
242+
&self.heap.data[0]
243+
}
244+
}
245+
246+
#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
247+
impl<'a, T: Ord> DerefMut for PeekMut<'a, T> {
248+
fn deref_mut(&mut self) -> &mut T {
249+
&mut self.heap.data[0]
250+
}
251+
}
252+
221253
#[stable(feature = "rust1", since = "1.0.0")]
222254
impl<T: Clone> Clone for BinaryHeap<T> {
223255
fn clone(&self) -> Self {
@@ -323,6 +355,42 @@ impl<T: Ord> BinaryHeap<T> {
323355
self.data.get(0)
324356
}
325357

358+
/// Returns a mutable reference to the greatest item in the binary heap, or
359+
/// `None` if it is empty.
360+
///
361+
/// Note: If the `PeekMut` value is leaked, the heap may be in an
362+
/// inconsistent state.
363+
///
364+
/// # Examples
365+
///
366+
/// Basic usage:
367+
///
368+
/// ```
369+
/// #![feature(binary_heap_peek_mut)]
370+
/// use std::collections::BinaryHeap;
371+
/// let mut heap = BinaryHeap::new();
372+
/// assert!(heap.peek_mut().is_none());
373+
///
374+
/// heap.push(1);
375+
/// heap.push(5);
376+
/// heap.push(2);
377+
/// {
378+
/// let mut val = heap.peek_mut().unwrap();
379+
/// *val = 0;
380+
/// }
381+
/// assert_eq!(heap.peek(), Some(&2));
382+
/// ```
383+
#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
384+
pub fn peek_mut(&mut self) -> Option<PeekMut<T>> {
385+
if self.is_empty() {
386+
None
387+
} else {
388+
Some(PeekMut {
389+
heap: self
390+
})
391+
}
392+
}
393+
326394
/// Returns the number of elements the binary heap can hold without reallocating.
327395
///
328396
/// # Examples

src/libcollectionstest/binary_heap.rs

+18
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ fn test_peek_and_pop() {
8181
}
8282
}
8383

84+
#[test]
85+
fn test_peek_mut() {
86+
let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
87+
let mut heap = BinaryHeap::from(data);
88+
assert_eq!(heap.peek(), Some(&10));
89+
{
90+
let mut top = heap.peek_mut().unwrap();
91+
*top -= 2;
92+
}
93+
assert_eq!(heap.peek(), Some(&9));
94+
}
95+
8496
#[test]
8597
fn test_push() {
8698
let mut heap = BinaryHeap::from(vec![2, 4, 9]);
@@ -192,6 +204,12 @@ fn test_empty_peek() {
192204
assert!(empty.peek().is_none());
193205
}
194206

207+
#[test]
208+
fn test_empty_peek_mut() {
209+
let mut empty = BinaryHeap::<i32>::new();
210+
assert!(empty.peek_mut().is_none());
211+
}
212+
195213
#[test]
196214
fn test_empty_replace() {
197215
let mut heap = BinaryHeap::new();

src/libcollectionstest/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#![feature(binary_heap_extras)]
1414
#![feature(binary_heap_append)]
15+
#![feature(binary_heap_peek_mut)]
1516
#![feature(box_syntax)]
1617
#![feature(btree_append)]
1718
#![feature(btree_split_off)]

0 commit comments

Comments
 (0)