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.
This commit is contained in:
blake2-ppc 2013-08-03 21:34:00 +02:00
parent 8046218f0f
commit 78effe7626

View File

@ -19,7 +19,8 @@
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 @@ pub fn consume(self) -> HashSetConsumeIterator<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 @@ pub fn symmetric_difference_iter<'a>(&'a self, other: &'a 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 @@ fn extend(&mut self, iter: &mut T) {
}
}
// 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)]