From 81f9a319265ddbe6b7823b50c29e3aff076d82c1 Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Wed, 10 Dec 2014 23:12:31 -0600 Subject: [PATCH] Change `VecMap`'s iterators to use wrapper structs instead of typedefs. Using a type alias for iterator implementations is fragile since this exposes the implementation to users of the iterator, and any changes could break existing code. This commit changes the iterators of `VecMap` to use proper new types, rather than type aliases. However, since it is fair-game to treat a type-alias as the aliased type, this is a: [breaking-change]. --- src/libcollections/vec_map.rs | 59 ++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index cc2fd0a664690..fab595c2e05d1 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -18,7 +18,7 @@ use core::prelude::*; use core::default::Default; use core::fmt; use core::iter; -use core::iter::{Enumerate, FilterMap}; +use core::iter::{Enumerate, FilterMap, Map}; use core::mem::replace; use core::ops::FnOnce; @@ -144,7 +144,7 @@ impl VecMap { pub fn keys<'r>(&'r self) -> Keys<'r, V> { fn first((a, _): (A, B)) -> A { a } - self.iter().map(first) + Keys { iter: self.iter().map(first) } } /// Returns an iterator visiting all values in ascending order by the keys. @@ -153,7 +153,7 @@ impl VecMap { pub fn values<'r>(&'r self) -> Values<'r, V> { fn second((_, b): (A, B)) -> B { b } - self.iter().map(second) + Values { iter: self.iter().map(second) } } /// Returns an iterator visiting all key-value pairs in ascending order by the keys. @@ -240,7 +240,7 @@ impl VecMap { } let values = replace(&mut self.v, vec!()); - values.into_iter().enumerate().filter_map(filter) + MoveItems { iter: values.into_iter().enumerate().filter_map(filter) } } /// Return the number of elements in the map. @@ -603,7 +603,7 @@ macro_rules! double_ended_iterator { } } -/// Forward iterator over a map. +/// An iterator over the key-value pairs of a map. pub struct Entries<'a, V:'a> { front: uint, back: uint, @@ -613,7 +613,7 @@ pub struct Entries<'a, V:'a> { iterator!(impl Entries -> (uint, &'a V), as_ref) double_ended_iterator!(impl Entries -> (uint, &'a V), as_ref) -/// Forward iterator over the key-value pairs of a map, with the +/// An iterator over the key-value pairs of a map, with the /// values being mutable. pub struct MutEntries<'a, V:'a> { front: uint, @@ -624,19 +624,50 @@ pub struct MutEntries<'a, V:'a> { iterator!(impl MutEntries -> (uint, &'a mut V), as_mut) double_ended_iterator!(impl MutEntries -> (uint, &'a mut V), as_mut) -/// Forward iterator over the keys of a map -pub type Keys<'a, V> = iter::Map<(uint, &'a V), uint, Entries<'a, V>, fn((uint, &'a V)) -> uint>; +/// An iterator over the keys of a map. +pub struct Keys<'a, V: 'a> { + iter: Map<(uint, &'a V), uint, Entries<'a, V>, fn((uint, &'a V)) -> uint> +} -/// Forward iterator over the values of a map -pub type Values<'a, V> = - iter::Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V>; +/// An iterator over the values of a map. +pub struct Values<'a, V: 'a> { + iter: Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V> +} -/// Iterator over the key-value pairs of a map, the iterator consumes the map -pub type MoveItems = FilterMap< +/// A consuming iterator over the key-value pairs of a map. +pub struct MoveItems { + iter: FilterMap< (uint, Option), (uint, V), Enumerate>>, - fn((uint, Option)) -> Option<(uint, V)>>; + fn((uint, Option)) -> Option<(uint, V)>> +} + +impl<'a, V> Iterator for Keys<'a, V> { + fn next(&mut self) -> Option { self.iter.next() } + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +} +impl<'a, V> DoubleEndedIterator for Keys<'a, V> { + fn next_back(&mut self) -> Option { self.iter.next_back() } +} + + +impl<'a, V> Iterator<&'a V> for Values<'a, V> { + fn next(&mut self) -> Option<(&'a V)> { self.iter.next() } + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +} +impl<'a, V> DoubleEndedIterator<&'a V> for Values<'a, V> { + fn next_back(&mut self) -> Option<(&'a V)> { self.iter.next_back() } +} + + +impl Iterator<(uint, V)> for MoveItems { + fn next(&mut self) -> Option<(uint, V)> { self.iter.next() } + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +} +impl DoubleEndedIterator<(uint, V)> for MoveItems { + fn next_back(&mut self) -> Option<(uint, V)> { self.iter.next_back() } +} #[cfg(test)] mod test_map {