about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-08-03 21:34:00 +0200
committerblake2-ppc <blake2-ppc>2013-08-06 04:05:07 +0200
commit78effe762666f64de28c890ea1a15672c712f390 (patch)
treee4c65a3b91eb44075eeb5d8681327058056fea0e /src/libstd
parent8046218f0f18b853df571d85ac4ace003c3905b9 (diff)
downloadrust-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.rs54
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)]