diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 963b88eda56..8efc4cd50c1 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -160,9 +160,7 @@ use core::ptr; use slice; -use vec::Vec; - -// FIXME(conventions): implement into_iter +use vec::{mod, Vec}; /// A priority queue implemented with a binary heap. /// @@ -243,6 +241,27 @@ pub fn iter<'a>(&'a self) -> Items<'a, T> { Items { iter: self.data.iter() } } + /// Creates a consuming iterator, that is, one that moves each value out of + /// the binary heap in arbitrary order. The binary heap cannot be used + /// after calling this. + /// + /// # Example + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let pq = BinaryHeap::from_vec(vec![1i, 2, 3, 4]); + /// + /// // Print 1, 2, 3, 4 in arbitrary order + /// for x in pq.into_iter() { + /// // x has type int, not &int + /// println!("{}", x); + /// } + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn into_iter(self) -> MoveItems { + MoveItems { iter: self.data.into_iter() } + } + /// Returns the greatest item in a queue, or `None` if it is empty. /// /// # Example @@ -548,6 +567,26 @@ fn next(&mut self) -> Option<(&'a T)> { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } +/// An iterator that moves out of a `BinaryHeap`. +pub struct MoveItems { + iter: vec::MoveItems, +} + +impl Iterator for MoveItems { + #[inline] + fn next(&mut self) -> Option { self.iter.next() } + + #[inline] + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +} + +impl DoubleEndedIterator for MoveItems { + #[inline] + fn next_back(&mut self) -> Option { self.iter.next_back() } +} + +impl ExactSize for MoveItems {} + impl FromIterator for BinaryHeap { fn from_iter>(mut iter: Iter) -> BinaryHeap { let vec: Vec = iter.collect(); @@ -586,6 +625,43 @@ fn test_iterator() { } } + #[test] + fn test_move_iter() { + let data = vec!(5i, 9, 3); + let iterout = vec!(9i, 5, 3); + let pq = BinaryHeap::from_vec(data); + + let v: Vec = pq.into_iter().collect(); + assert_eq!(v, iterout); + } + + #[test] + fn test_move_iter_size_hint() { + let data = vec!(5i, 9); + let pq = BinaryHeap::from_vec(data); + + let mut it = pq.into_iter(); + + assert_eq!(it.size_hint(), (2, Some(2))); + assert_eq!(it.next(), Some(9i)); + + assert_eq!(it.size_hint(), (1, Some(1))); + assert_eq!(it.next(), Some(5i)); + + assert_eq!(it.size_hint(), (0, Some(0))); + assert_eq!(it.next(), None); + } + + #[test] + fn test_move_iter_reverse() { + let data = vec!(5i, 9, 3); + let iterout = vec!(3i, 5, 9); + let pq = BinaryHeap::from_vec(data); + + let v: Vec = pq.into_iter().rev().collect(); + assert_eq!(v, iterout); + } + #[test] fn test_top_and_pop() { let data = vec!(2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1);