Skip to content

Commit

Permalink
Use wrapper structs for BTreeSet's iterators.
Browse files Browse the repository at this point in the history
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].
  • Loading branch information
csouth3 committed Dec 16, 2014
1 parent 765806e commit a81c3ab
Showing 1 changed file with 29 additions and 7 deletions.
36 changes: 29 additions & 7 deletions src/libcollections/btree/set.rs
Expand Up @@ -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
Expand All @@ -33,11 +33,14 @@ pub struct BTreeSet<T>{
}

/// 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<T> =
iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>;
pub struct MoveItems<T> {
iter: Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>
}

/// A lazy iterator producing elements in the set difference (in-order).
pub struct DifferenceItems<'a, T:'a> {
Expand Down Expand Up @@ -105,7 +108,7 @@ impl<T> BTreeSet<T> {
/// ```
#[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.
Expand All @@ -124,7 +127,7 @@ impl<T> BTreeSet<T> {
pub fn into_iter(self) -> MoveItems<T> {
fn first<A, B>((a, _): (A, B)) -> A { a }

self.map.into_iter().map(first)
MoveItems { iter: self.map.into_iter().map(first) }
}
}

Expand Down Expand Up @@ -635,6 +638,25 @@ impl<T: Show> Show for BTreeSet<T> {
}
}

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<uint>) { 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<T> Iterator<T> for MoveItems<T> {
fn next(&mut self) -> Option<T> { self.iter.next() }
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
}
impl<T> DoubleEndedIterator<T> for MoveItems<T> {
fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
}
impl<T> ExactSizeIterator<T> for MoveItems<T> {}

/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
short: Ordering, long: Ordering) -> Ordering {
Expand Down

0 comments on commit a81c3ab

Please sign in to comment.