From 2366dee8e9cb41d963900c8d5128f810a87fc6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Mon, 19 Jan 2015 10:48:01 +0100 Subject: [PATCH 1/3] Make VecMap::into_iter consume the VecMap This is a breaking change. To fix it you should pass the VecMap by value instead of by reference. [breaking-change] --- src/libcollections/vec_map.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index d4ce266d3e211..94ae1bece86f7 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -265,7 +265,7 @@ impl VecMap { } /// Returns an iterator visiting all key-value pairs in ascending order by - /// the keys, emptying (but not consuming) the original `VecMap`. + /// the keys, consuming the original `VecMap`. /// The iterator's element type is `(uint, &'r V)`. /// /// # Examples @@ -284,14 +284,13 @@ impl VecMap { /// 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 - let values = replace(&mut self.v, vec!()); - IntoIter { iter: values.into_iter().enumerate().filter_map(filter) } + IntoIter { iter: self.v.into_iter().enumerate().filter_map(filter) } } /// Return the number of elements in the map. From c3ac929ba966666fbe9c72eb97e38d5e37ad11e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Mon, 19 Jan 2015 11:06:15 +0100 Subject: [PATCH 2/3] Add a Drain iterator to VecMap --- src/libcollections/vec_map.rs | 61 +++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 94ae1bece86f7..93f3e192d6d5e 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,7 +264,7 @@ impl VecMap { } } - /// Returns an iterator visiting all key-value pairs in ascending order by + /// 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)`. /// @@ -278,7 +278,6 @@ 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")]); @@ -293,6 +292,34 @@ impl VecMap { 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 + + Drain { iter: self.v.drain().enumerate().filter_map(filter) } + } + /// Return the number of elements in the map. /// /// # Examples @@ -672,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; From b4090aa730640bc0dbd06a8ec5cf32b842c166e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Mon, 19 Jan 2015 15:36:07 +0100 Subject: [PATCH 3/3] Add test for #21328 --- src/libcollections/vec_map.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 93f3e192d6d5e..7ff2e9535886c 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -966,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]