From 765806ef1ee93b352b724aa76870d23d82894e4e Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Fri, 12 Dec 2014 00:04:47 -0600 Subject: [PATCH] Use wrapper structs for `BTreeMap`'s iterators. 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 keys and values iterators of `BTreeMap` 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/btree/map.rs | 34 +++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index e49a8ddbe5a..e45e91b93ba 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -26,6 +26,7 @@ use core::default::Default; use core::{iter, fmt, mem}; use core::fmt::Show; +use core::iter::Map; use ring_buf::RingBuf; @@ -107,12 +108,14 @@ pub struct MoveEntries { } /// An iterator over a BTreeMap's keys. -pub type Keys<'a, K, V> = - iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>; +pub struct Keys<'a, K: 'a, V: 'a> { + inner: Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K> +} /// An iterator over a BTreeMap's values. -pub type Values<'a, K, V> = - iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>; +pub struct Values<'a, K: 'a, V: 'a> { + inner: Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V> +} /// A view into a single entry in a map, which may either be vacant or occupied. pub enum Entry<'a, K:'a, V:'a> { @@ -1061,6 +1064,25 @@ fn next_back(&mut self) -> Option<(K, V)> { self.inner.next_back() } impl ExactSizeIterator<(K, V)> for MoveEntries {} +impl<'a, K, V> Iterator<&'a K> for Keys<'a, K, V> { + fn next(&mut self) -> Option<(&'a K)> { self.inner.next() } + fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } +} +impl<'a, K, V> DoubleEndedIterator<&'a K> for Keys<'a, K, V> { + fn next_back(&mut self) -> Option<(&'a K)> { self.inner.next_back() } +} +impl<'a, K, V> ExactSizeIterator<&'a K> for Keys<'a, K, V> {} + + +impl<'a, K, V> Iterator<&'a V> for Values<'a, K, V> { + fn next(&mut self) -> Option<(&'a V)> { self.inner.next() } + fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } +} +impl<'a, K, V> DoubleEndedIterator<&'a V> for Values<'a, K, V> { + fn next_back(&mut self) -> Option<(&'a V)> { self.inner.next_back() } +} +impl<'a, K, V> ExactSizeIterator<&'a V> for Values<'a, K, V> {} + impl<'a, K: Ord, V> VacantEntry<'a, K, V> { /// Sets the value of the entry with the VacantEntry's key, @@ -1211,7 +1233,7 @@ pub fn into_iter(self) -> MoveEntries { pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { fn first((a, _): (A, B)) -> A { a } - self.iter().map(first) + Keys { inner: self.iter().map(first) } } /// Gets an iterator over the values of the map. @@ -1232,7 +1254,7 @@ fn first((a, _): (A, B)) -> A { a } pub fn values<'a>(&'a self) -> Values<'a, K, V> { fn second((_, b): (A, B)) -> B { b } - self.iter().map(second) + Values { inner: self.iter().map(second) } } /// Return the number of elements in the map. -- 2.44.0