@@ -19,7 +19,8 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
1919use clone:: Clone ;
2020use cmp:: { Eq , Equiv } ;
2121use 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 } ;
2324use num;
2425use option:: { None , Option , Some } ;
2526use 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
789768pub 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