diff options
| author | blake2-ppc <blake2-ppc> | 2013-08-03 21:34:00 +0200 |
|---|---|---|
| committer | blake2-ppc <blake2-ppc> | 2013-08-06 04:05:07 +0200 |
| commit | 78effe762666f64de28c890ea1a15672c712f390 (patch) | |
| tree | e4c65a3b91eb44075eeb5d8681327058056fea0e /src/libstd | |
| parent | 8046218f0f18b853df571d85ac4ace003c3905b9 (diff) | |
| download | rust-78effe762666f64de28c890ea1a15672c712f390.tar.gz rust-78effe762666f64de28c890ea1a15672c712f390.zip | |
std: Rewrite the HashSet set operation iterators
Use the Repeat iterator to carry the "explicit closure capture" that was previously done with the custom EnvFilterIterator.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/hashmap.rs | 54 |
1 files changed, 17 insertions, 37 deletions
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 658f854c50d..fbc471c0ae0 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -19,7 +19,8 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; use clone::Clone; use cmp::{Eq, Equiv}; use hash::Hash; -use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain, range}; +use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, range}; +use iterator::{FilterMap, Chain, Repeat, Zip}; use num; use option::{None, Option, Some}; use rand::RngUtil; @@ -712,10 +713,12 @@ impl<T:Hash + Eq> HashSet<T> { } /// Visit the values representing the difference - pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>) - -> SetAlgebraIter<'a, T> { - EnvFilterIterator{iter: self.iter(), env: other, - filter: |elt, other| !other.contains(elt) } + pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraIter<'a, T> { + Repeat::new(other) + .zip(self.iter()) + .filter_map(|(other, elt)| { + if !other.contains(elt) { Some(elt) } else { None } + }) } /// Visit the values representing the symmetric difference @@ -727,8 +730,11 @@ impl<T:Hash + Eq> HashSet<T> { /// Visit the values representing the intersection pub fn intersection_iter<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraIter<'a, T> { - EnvFilterIterator{iter: self.iter(), env: other, - filter: |elt, other| other.contains(elt) } + Repeat::new(other) + .zip(self.iter()) + .filter_map(|(other, elt)| { + if other.contains(elt) { Some(elt) } else { None } + }) } /// Visit the values representing the union @@ -756,38 +762,12 @@ impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> { } } -// FIXME #7814: use std::iterator::FilterIterator -/// Building block for Set operation iterators -pub struct EnvFilterIterator<A, Env, I> { - priv env: Env, - priv filter: &'static fn(&A, Env) -> bool, - priv iter: I, -} - -impl<'self, A, Env: Clone, I: Iterator<&'self A>> Iterator<&'self A> - for EnvFilterIterator<A, Env, I> { - #[inline] - fn next(&mut self) -> Option<&'self A> { - loop { - match self.iter.next() { - Some(elt) => if (self.filter)(elt, self.env.clone()) { - return Some(elt) - }, - None => return None, - } - } - } - - #[inline] - fn size_hint(&self) -> (uint, Option<uint>) { - let (_, upper) = self.iter.size_hint(); - (0, upper) - } -} - +// `Repeat` is used to feed the filter closure an explicit capture +// of a reference to the other set /// Set operations iterator pub type SetAlgebraIter<'self, T> = - EnvFilterIterator<T, &'self HashSet<T>, HashSetIterator<'self, T>>; + FilterMap<'static,(&'self HashSet<T>, &'self T), &'self T, + Zip<Repeat<&'self HashSet<T>>,HashSetIterator<'self,T>>>; #[cfg(test)] |
