diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index d4ce266d3e211..7ff2e9535886c 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -186,7 +186,7 @@ impl VecMap { } } - /// Returns an iterator visiting all keys in ascending order by the keys. + /// Returns an iterator visiting all keys in ascending order of the keys. /// The iterator's element type is `uint`. #[stable] pub fn keys<'r>(&'r self) -> Keys<'r, V> { @@ -196,7 +196,7 @@ impl VecMap { Keys { iter: self.iter().map(first) } } - /// Returns an iterator visiting all values in ascending order by the keys. + /// Returns an iterator visiting all values in ascending order of the keys. /// The iterator's element type is `&'r V`. #[stable] pub fn values<'r>(&'r self) -> Values<'r, V> { @@ -206,7 +206,7 @@ impl VecMap { Values { iter: self.iter().map(second) } } - /// Returns an iterator visiting all key-value pairs in ascending order by the keys. + /// Returns an iterator visiting all key-value pairs in ascending order of the keys. /// The iterator's element type is `(uint, &'r V)`. /// /// # Examples @@ -233,7 +233,7 @@ impl VecMap { } } - /// Returns an iterator visiting all key-value pairs in ascending order by the keys, + /// Returns an iterator visiting all key-value pairs in ascending order of the keys, /// with mutable references to the values. /// The iterator's element type is `(uint, &'r mut V)`. /// @@ -264,8 +264,8 @@ impl VecMap { } } - /// Returns an iterator visiting all key-value pairs in ascending order by - /// the keys, emptying (but not consuming) the original `VecMap`. + /// Returns an iterator visiting all key-value pairs in ascending order of + /// the keys, consuming the original `VecMap`. /// The iterator's element type is `(uint, &'r V)`. /// /// # Examples @@ -278,20 +278,46 @@ impl VecMap { /// map.insert(3, "c"); /// map.insert(2, "b"); /// - /// // Not possible with .iter() /// let vec: Vec<(uint, &str)> = map.into_iter().collect(); /// /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); /// ``` #[stable] - pub fn into_iter(&mut self) -> IntoIter { + pub fn into_iter(self) -> IntoIter { + fn filter((i, v): (uint, Option)) -> Option<(uint, A)> { + v.map(|v| (i, v)) + } + let filter: fn((uint, Option)) -> Option<(uint, V)> = filter; // coerce to fn ptr + + IntoIter { iter: self.v.into_iter().enumerate().filter_map(filter) } + } + + /// Returns an iterator visiting all key-value pairs in ascending order of + /// the keys, emptying (but not consuming) the original `VecMap`. + /// The iterator's element type is `(uint, &'r V)`. Keeps the allocated memory for reuse. + /// + /// # Examples + /// + /// ``` + /// use std::collections::VecMap; + /// + /// let mut map = VecMap::new(); + /// map.insert(1, "a"); + /// map.insert(3, "c"); + /// map.insert(2, "b"); + /// + /// let vec: Vec<(uint, &str)> = map.drain().collect(); + /// + /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn drain<'a>(&'a mut self) -> Drain<'a, V> { fn filter((i, v): (uint, Option)) -> Option<(uint, A)> { v.map(|v| (i, v)) } let filter: fn((uint, Option)) -> Option<(uint, V)> = filter; // coerce to fn ptr - let values = replace(&mut self.v, vec!()); - IntoIter { iter: values.into_iter().enumerate().filter_map(filter) } + Drain { iter: self.v.drain().enumerate().filter_map(filter) } } /// Return the number of elements in the map. @@ -673,6 +699,28 @@ pub struct IntoIter { fn((uint, Option)) -> Option<(uint, V)>> } +#[unstable] +pub struct Drain<'a, V> { + iter: FilterMap< + (uint, Option), + (uint, V), + Enumerate>>, + fn((uint, Option)) -> Option<(uint, V)>> +} + +#[unstable] +impl<'a, V> Iterator for Drain<'a, V> { + type Item = (uint, V); + + fn next(&mut self) -> Option<(uint, V)> { self.iter.next() } + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +} + +#[unstable] +impl<'a, V> DoubleEndedIterator for Drain<'a, V> { + fn next_back(&mut self) -> Option<(uint, V)> { self.iter.next_back() } +} + #[stable] impl<'a, V> Iterator for Keys<'a, V> { type Item = uint; @@ -918,7 +966,19 @@ mod test_map { assert_eq!(v, box 2i); } assert!(called); - m.insert(2, box 1i); + } + + #[test] + fn test_drain_iterator() { + let mut map = VecMap::new(); + map.insert(1, "a"); + map.insert(3, "c"); + map.insert(2, "b"); + + let vec: Vec<(usize, &str)> = map.drain().collect(); + + assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + assert_eq!(map.len(), 0); } #[test]