about summary refs log tree commit diff
path: root/src/libcollections/binary_heap.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-21 07:22:45 +0000
committerbors <bors@rust-lang.org>2014-12-21 07:22:45 +0000
commitce468e643a9e048900e5495948737efdf5bb2385 (patch)
tree8e07b9c8b42ba241bd6e9ecc51a1d35be064ad07 /src/libcollections/binary_heap.rs
parentcc19e3380b4b7c63b6f1f79d1dfc213ea00e16cf (diff)
parentd57f25907bc4247b4d98efce5ab6948c35baa12d (diff)
downloadrust-ce468e643a9e048900e5495948737efdf5bb2385.tar.gz
rust-ce468e643a9e048900e5495948737efdf5bb2385.zip
auto merge of #19946 : cgaebel/rust/hashmap-drain-iter, r=gankro
It is useful to move all the elements out of a hashmap without deallocating
the underlying buffer. It came up in IRC, and this patch implements it as
`drain`.

r? @Gankro
cc: @frankmcsherry
Diffstat (limited to 'src/libcollections/binary_heap.rs')
-rw-r--r--src/libcollections/binary_heap.rs41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index e1c06736b36..a12bfcdbd18 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -551,9 +551,18 @@ impl<T: Ord> BinaryHeap<T> {
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
+    /// Clears the queue, returning an iterator over the removed elements.
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn drain<'a>(&'a mut self) -> Drain<'a, T> {
+        Drain {
+            iter: self.data.drain(),
+        }
+    }
+
     /// Drops all items from the queue.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn clear(&mut self) { self.data.truncate(0) }
+    pub fn clear(&mut self) { self.drain(); }
 }
 
 /// `BinaryHeap` iterator.
@@ -596,6 +605,26 @@ impl<T> DoubleEndedIterator<T> for MoveItems<T> {
 
 impl<T> ExactSizeIterator<T> for MoveItems<T> {}
 
+/// An iterator that drains a `BinaryHeap`.
+pub struct Drain<'a, T: 'a> {
+    iter: vec::Drain<'a, T>,
+}
+
+impl<'a, T: 'a> Iterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> { self.iter.next() }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
+}
+
+impl<'a, T: 'a> DoubleEndedIterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
+}
+
+impl<'a, T: 'a> ExactSizeIterator<T> for Drain<'a, T> {}
+
 impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
     fn from_iter<Iter: Iterator<T>>(iter: Iter) -> BinaryHeap<T> {
         let vec: Vec<T> = iter.collect();
@@ -819,4 +848,14 @@ mod tests {
             assert_eq!(q.pop().unwrap(), x);
         }
     }
+
+    #[test]
+    fn test_drain() {
+        let mut q: BinaryHeap<_> =
+            [9u, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
+
+        assert_eq!(q.drain().take(5).count(), 5);
+
+        assert!(q.is_empty());
+    }
 }