From 78effe762666f64de28c890ea1a15672c712f390 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Sat, 3 Aug 2013 21:34:00 +0200 Subject: [PATCH] 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. --- src/libstd/hashmap.rs | 54 ++++++++++++++----------------------------- 1 file 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 HashSet { } /// Visit the values representing the difference - pub fn difference_iter<'a>(&'a self, other: &'a HashSet) - -> 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) -> 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 HashSet { /// Visit the values representing the intersection pub fn intersection_iter<'a>(&'a self, other: &'a HashSet) -> 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> Extendable for HashSet { } } -// FIXME #7814: use std::iterator::FilterIterator -/// Building block for Set operation iterators -pub struct EnvFilterIterator { - 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 { - #[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) { - 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, HashSetIterator<'self, T>>; + FilterMap<'static,(&'self HashSet, &'self T), &'self T, + Zip>,HashSetIterator<'self,T>>>; #[cfg(test)]