From a81c3ab468ad7aebcab8a545b196e74c2fb3ac32 Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Fri, 12 Dec 2014 23:14:57 -0600 Subject: [PATCH] Use wrapper structs for `BTreeSet`'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 iterators of `BTreeSet` 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/set.rs | 36 ++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index c6d1898b87efe..dbba5ebdc9968 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -17,8 +17,8 @@ use btree_map::{BTreeMap, Keys, MoveEntries}; use std::hash::Hash; use core::borrow::BorrowFrom; use core::default::Default; -use core::{iter, fmt}; -use core::iter::Peekable; +use core::fmt; +use core::iter::{Peekable, Map}; use core::fmt::Show; // FIXME(conventions): implement bounded iterators @@ -33,11 +33,14 @@ pub struct BTreeSet{ } /// An iterator over a BTreeSet's items. -pub type Items<'a, T> = Keys<'a, T, ()>; +pub struct Items<'a, T: 'a> { + iter: Keys<'a, T, ()> +} /// An owning iterator over a BTreeSet's items. -pub type MoveItems = - iter::Map<(T, ()), T, MoveEntries, fn((T, ())) -> T>; +pub struct MoveItems { + iter: Map<(T, ()), T, MoveEntries, fn((T, ())) -> T> +} /// A lazy iterator producing elements in the set difference (in-order). pub struct DifferenceItems<'a, T:'a> { @@ -105,7 +108,7 @@ impl BTreeSet { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> Items<'a, T> { - self.map.keys() + Items { iter: self.map.keys() } } /// Gets an iterator for moving out the BtreeSet's contents. @@ -124,7 +127,7 @@ impl BTreeSet { pub fn into_iter(self) -> MoveItems { fn first((a, _): (A, B)) -> A { a } - self.map.into_iter().map(first) + MoveItems { iter: self.map.into_iter().map(first) } } } @@ -635,6 +638,25 @@ impl Show for BTreeSet { } } +impl<'a, T> Iterator<&'a T> for Items<'a, T> { + fn next(&mut self) -> Option<&'a T> { self.iter.next() } + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +} +impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> { + fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() } +} +impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {} + + +impl Iterator for MoveItems { + fn next(&mut self) -> Option { self.iter.next() } + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +} +impl DoubleEndedIterator for MoveItems { + fn next_back(&mut self) -> Option { self.iter.next_back() } +} +impl ExactSizeIterator for MoveItems {} + /// Compare `x` and `y`, but return `short` if x is None and `long` if y is None fn cmp_opt(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {