]> git.lizzy.rs Git - rust.git/commitdiff
std: Rewrite the HashSet set operation iterators
authorblake2-ppc <blake2-ppc>
Sat, 3 Aug 2013 19:34:00 +0000 (21:34 +0200)
committerblake2-ppc <blake2-ppc>
Tue, 6 Aug 2013 02:05:07 +0000 (04:05 +0200)
Use the Repeat iterator to carry the "explicit closure capture" that was
previously done with the custom EnvFilterIterator.

src/libstd/hashmap.rs

index 658f854c50d81ea80a9716ff9b2937add905e7db..fbc471c0ae05d4b289235134ec8366d040459437 100644 (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)]