about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathan Moos <moosingin3space@gmail.com>2016-05-23 16:59:11 -0700
committerNathan Moos <moosingin3space@gmail.com>2016-06-21 12:10:38 -0700
commit2a34a7b83914f3ff7d2d52827b4c92bffefb5f92 (patch)
treece03454fe1ffc6c36206b541f6f790a1c88bf12a
parent4ba60aba387b19267cace9759d9cf14682b72871 (diff)
downloadrust-2a34a7b83914f3ff7d2d52827b4c92bffefb5f92.tar.gz
rust-2a34a7b83914f3ff7d2d52827b4c92bffefb5f92.zip
implemented peek_mut and unit tests
-rw-r--r--src/libcollections/binary_heap.rs68
-rw-r--r--src/libcollectionstest/binary_heap.rs18
-rw-r--r--src/libcollectionstest/lib.rs1
3 files changed, 87 insertions, 0 deletions
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index 43c6e6e8120..140801737bc 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -151,6 +151,7 @@
 #![allow(missing_docs)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use core::ops::{Drop, Deref, DerefMut};
 use core::iter::FromIterator;
 use core::mem::swap;
 use core::mem::size_of;
@@ -218,6 +219,37 @@ pub struct BinaryHeap<T> {
     data: Vec<T>,
 }
 
+/// A container object that represents the result of the [`peek_mut()`] method
+/// on `BinaryHeap`. See its documentation for details.
+///
+/// [`peek_mut()`]: struct.BinaryHeap.html#method.peek_mut
+#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+pub struct PeekMut<'a, T: 'a + Ord> {
+    heap: &'a mut BinaryHeap<T>
+}
+
+#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+impl<'a, T: Ord> Drop for PeekMut<'a, T> {
+    fn drop(&mut self) {
+        self.heap.sift_down(0);
+    }
+}
+
+#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+impl<'a, T: Ord> Deref for PeekMut<'a, T> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        &self.heap.data[0]
+    }
+}
+
+#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+impl<'a, T: Ord> DerefMut for PeekMut<'a, T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.heap.data[0]
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone> Clone for BinaryHeap<T> {
     fn clone(&self) -> Self {
@@ -323,6 +355,42 @@ impl<T: Ord> BinaryHeap<T> {
         self.data.get(0)
     }
 
+    /// Returns a mutable reference to the greatest item in the binary heap, or
+    /// `None` if it is empty.
+    ///
+    /// Note: If the `PeekMut` value is leaked, the heap may be in an
+    /// inconsistent state.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(binary_heap_peek_mut)]
+    /// use std::collections::BinaryHeap;
+    /// let mut heap = BinaryHeap::new();
+    /// assert!(heap.peek_mut().is_none());
+    ///
+    /// heap.push(1);
+    /// heap.push(5);
+    /// heap.push(2);
+    /// {
+    ///     let mut val = heap.peek_mut().unwrap();
+    ///     *val = 0;
+    /// }
+    /// assert_eq!(heap.peek(), Some(&2));
+    /// ```
+    #[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+    pub fn peek_mut(&mut self) -> Option<PeekMut<T>> {
+        if self.is_empty() {
+            None
+        } else {
+            Some(PeekMut {
+                heap: self
+            })
+        }
+    }
+
     /// Returns the number of elements the binary heap can hold without reallocating.
     ///
     /// # Examples
diff --git a/src/libcollectionstest/binary_heap.rs b/src/libcollectionstest/binary_heap.rs
index 58194fe75f7..be933abe41f 100644
--- a/src/libcollectionstest/binary_heap.rs
+++ b/src/libcollectionstest/binary_heap.rs
@@ -82,6 +82,18 @@ fn test_peek_and_pop() {
 }
 
 #[test]
+fn test_peek_mut() {
+    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!(heap.peek(), Some(&9));
+}
+
+#[test]
 fn test_push() {
     let mut heap = BinaryHeap::from(vec![2, 4, 9]);
     assert_eq!(heap.len(), 3);
@@ -193,6 +205,12 @@ fn test_empty_peek() {
 }
 
 #[test]
+fn test_empty_peek_mut() {
+    let mut empty = BinaryHeap::<i32>::new();
+    assert!(empty.peek_mut().is_none());
+}
+
+#[test]
 fn test_empty_replace() {
     let mut heap = BinaryHeap::new();
     assert!(heap.replace(5).is_none());
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index 400d6140948..6161bad7468 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -12,6 +12,7 @@
 
 #![feature(binary_heap_extras)]
 #![feature(binary_heap_append)]
+#![feature(binary_heap_peek_mut)]
 #![feature(box_syntax)]
 #![feature(btree_append)]
 #![feature(btree_split_off)]