]> git.lizzy.rs Git - rust.git/commitdiff
Use wrapper structs for `BTreeMap`'s iterators.
authorChase Southwood <chase.southwood@gmail.com>
Fri, 12 Dec 2014 06:04:47 +0000 (00:04 -0600)
committerChase Southwood <chase.southwood@gmail.com>
Tue, 16 Dec 2014 01:26:28 +0000 (19:26 -0600)
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

index e49a8ddbe5ab8054fed030b8bdb2231374dc4a50..e45e91b93ba4215a71307b2efe277b455fce011f 100644 (file)
@@ -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<K, V> {
 }
 
 /// 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<K, V> ExactSizeIterator<(K, V)> for MoveEntries<K, V> {}
 
 
+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<uint>) { 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<uint>) { 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<K, V> {
     pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
         fn first<A, B>((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, B>((a, _): (A, B)) -> A { a }
     pub fn values<'a>(&'a self) -> Values<'a, K, V> {
         fn second<A, B>((_, b): (A, B)) -> B { b }
 
-        self.iter().map(second)
+        Values { inner: self.iter().map(second) }
     }
 
     /// Return the number of elements in the map.