Skip to content

Use wrapper structs for iterators in BTreeMap/Set and HashMap/Set #19770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 17, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use std::hash::{Writer, Hash};
use core::default::Default;
use core::{iter, fmt, mem};
use core::fmt::Show;
use core::iter::Map;

use ring_buf::RingBuf;

Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -1061,6 +1064,25 @@ impl<K, V> DoubleEndedIterator<(K, V)> for MoveEntries<K, V> {
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,
Expand Down Expand Up @@ -1211,7 +1233,7 @@ impl<K, V> BTreeMap<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.
Expand All @@ -1232,7 +1254,7 @@ impl<K, V> BTreeMap<K, V> {
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.
Expand Down
36 changes: 29 additions & 7 deletions src/libcollections/btree/set.rs
Original file line number Diff line number Diff line change
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
64 changes: 29 additions & 35 deletions src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use cmp::{max, Eq, Equiv, PartialEq};
use default::Default;
use fmt::{mod, Show};
use hash::{Hash, Hasher, RandomSipHasher};
use iter::{mod, Iterator, IteratorExt, FromIterator, Extend};
use iter::{mod, Iterator, IteratorExt, FromIterator, Extend, Map};
use kinds::Sized;
use mem::{mod, replace};
use num::{Int, UnsignedInt};
Expand Down Expand Up @@ -859,7 +859,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
pub fn keys(&self) -> Keys<K, V> {
fn first<A, B>((a, _): (A, B)) -> A { a }

self.iter().map(first)
Keys { inner: self.iter().map(first) }
}

/// An iterator visiting all values in arbitrary order.
Expand All @@ -883,7 +883,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
pub fn values(&self) -> Values<K, V> {
fn second<A, B>((_, b): (A, B)) -> B { b }

self.iter().map(second)
Values { inner: self.iter().map(second) }
}

/// An iterator visiting all key-value pairs in arbitrary order.
Expand Down Expand Up @@ -1335,6 +1335,16 @@ pub struct MoveEntries<K, V> {
>
}

/// HashMap keys iterator
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>
}

/// HashMap values iterator
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 occupied location in a HashMap
pub struct OccupiedEntry<'a, K:'a, V:'a> {
elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
Expand Down Expand Up @@ -1365,36 +1375,28 @@ enum VacantEntryState<K, V, M> {
}

impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
#[inline]
fn next(&mut self) -> Option<(&'a K, &'a V)> {
self.inner.next()
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
self.inner.size_hint()
}
#[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() }
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
#[inline]
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
self.inner.next()
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
self.inner.size_hint()
}
#[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() }
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
#[inline]
fn next(&mut self) -> Option<(K, V)> {
self.inner.next()
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
self.inner.size_hint()
}
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<'a, K, V> Iterator<&'a K> for Keys<'a, K, V> {
#[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() }
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<'a, K, V> Iterator<&'a V> for Values<'a, K, V> {
#[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() }
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<'a, K, V> OccupiedEntry<'a, K, V> {
Expand Down Expand Up @@ -1448,14 +1450,6 @@ impl<'a, K, V> VacantEntry<'a, K, V> {
}
}

/// HashMap keys iterator
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>;

/// HashMap values iterator
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>;

impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
let (lower, _) = iter.size_hint();
Expand Down
Loading