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;
}
/// 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
/// 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
}
}
-// 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)]