@@ -19,7 +19,8 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
19
19
use clone:: Clone ;
20
20
use cmp:: { Eq , Equiv } ;
21
21
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 } ;
23
24
use num;
24
25
use option:: { None , Option , Some } ;
25
26
use rand:: RngUtil ;
@@ -712,10 +713,12 @@ impl<T:Hash + Eq> HashSet<T> {
712
713
}
713
714
714
715
/// 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
+ } )
719
722
}
720
723
721
724
/// Visit the values representing the symmetric difference
@@ -727,8 +730,11 @@ impl<T:Hash + Eq> HashSet<T> {
727
730
/// Visit the values representing the intersection
728
731
pub fn intersection_iter < ' a > ( & ' a self , other : & ' a HashSet < T > )
729
732
-> 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
+ } )
732
738
}
733
739
734
740
/// Visit the values representing the union
@@ -756,38 +762,12 @@ impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
756
762
}
757
763
}
758
764
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
788
767
/// Set operations iterator
789
768
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 > > > ;
791
771
792
772
793
773
#[ cfg( test) ]
0 commit comments