Skip to content

Commit 78effe7

Browse files
author
blake2-ppc
committed
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.
1 parent 8046218 commit 78effe7

File tree

1 file changed

+17
-37
lines changed

1 file changed

+17
-37
lines changed

src/libstd/hashmap.rs

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
1919
use clone::Clone;
2020
use cmp::{Eq, Equiv};
2121
use hash::Hash;
22-
use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain, range};
22+
use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, range};
23+
use iterator::{FilterMap, Chain, Repeat, Zip};
2324
use num;
2425
use option::{None, Option, Some};
2526
use rand::RngUtil;
@@ -712,10 +713,12 @@ impl<T:Hash + Eq> HashSet<T> {
712713
}
713714

714715
/// Visit the values representing the difference
715-
pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>)
716-
-> SetAlgebraIter<'a, T> {
717-
EnvFilterIterator{iter: self.iter(), env: other,
718-
filter: |elt, other| !other.contains(elt) }
716+
pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraIter<'a, T> {
717+
Repeat::new(other)
718+
.zip(self.iter())
719+
.filter_map(|(other, elt)| {
720+
if !other.contains(elt) { Some(elt) } else { None }
721+
})
719722
}
720723

721724
/// Visit the values representing the symmetric difference
@@ -727,8 +730,11 @@ impl<T:Hash + Eq> HashSet<T> {
727730
/// Visit the values representing the intersection
728731
pub fn intersection_iter<'a>(&'a self, other: &'a HashSet<T>)
729732
-> SetAlgebraIter<'a, T> {
730-
EnvFilterIterator{iter: self.iter(), env: other,
731-
filter: |elt, other| other.contains(elt) }
733+
Repeat::new(other)
734+
.zip(self.iter())
735+
.filter_map(|(other, elt)| {
736+
if other.contains(elt) { Some(elt) } else { None }
737+
})
732738
}
733739

734740
/// Visit the values representing the union
@@ -756,38 +762,12 @@ impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
756762
}
757763
}
758764

759-
// FIXME #7814: use std::iterator::FilterIterator
760-
/// Building block for Set operation iterators
761-
pub struct EnvFilterIterator<A, Env, I> {
762-
priv env: Env,
763-
priv filter: &'static fn(&A, Env) -> bool,
764-
priv iter: I,
765-
}
766-
767-
impl<'self, A, Env: Clone, I: Iterator<&'self A>> Iterator<&'self A>
768-
for EnvFilterIterator<A, Env, I> {
769-
#[inline]
770-
fn next(&mut self) -> Option<&'self A> {
771-
loop {
772-
match self.iter.next() {
773-
Some(elt) => if (self.filter)(elt, self.env.clone()) {
774-
return Some(elt)
775-
},
776-
None => return None,
777-
}
778-
}
779-
}
780-
781-
#[inline]
782-
fn size_hint(&self) -> (uint, Option<uint>) {
783-
let (_, upper) = self.iter.size_hint();
784-
(0, upper)
785-
}
786-
}
787-
765+
// `Repeat` is used to feed the filter closure an explicit capture
766+
// of a reference to the other set
788767
/// Set operations iterator
789768
pub type SetAlgebraIter<'self, T> =
790-
EnvFilterIterator<T, &'self HashSet<T>, HashSetIterator<'self, T>>;
769+
FilterMap<'static,(&'self HashSet<T>, &'self T), &'self T,
770+
Zip<Repeat<&'self HashSet<T>>,HashSetIterator<'self,T>>>;
791771

792772

793773
#[cfg(test)]

0 commit comments

Comments
 (0)