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:
parent
8046218f0f
commit
78effe7626
@ -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)]
|
||||
|
Loading…
Reference in New Issue
Block a user