16
16
#[ mutable_doc] ;
17
17
18
18
use container:: { Container , Mutable , Map , MutableMap , Set , MutableSet } ;
19
+ use clone:: Clone ;
19
20
use cmp:: { Eq , Equiv } ;
20
21
use hash:: Hash ;
21
- use iterator:: { Iterator , IteratorUtil , FromIterator } ;
22
+ use iterator:: { Iterator , IteratorUtil , FromIterator , ChainIterator } ;
22
23
use num;
23
24
use option:: { None , Option , Some } ;
24
25
use rand:: RngUtil ;
@@ -703,25 +704,24 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
703
704
704
705
/// Visit the values representing the difference
705
706
fn difference( & self , other: & HashSet < T > , f: & fn( & T ) -> bool) -> bool {
706
- self . iter ( ) . advance( |v| other . contains ( v ) || f ( v ) )
707
+ self . difference_iter ( other ) . advance( f )
707
708
}
708
709
709
710
/// Visit the values representing the symmetric difference
710
711
fn symmetric_difference( & self ,
711
712
other: & HashSet < T > ,
712
713
f: & fn( & T ) -> bool ) -> bool {
713
- self . difference ( other, |t| f ( t ) ) && other . difference ( self , |t| f ( t ) )
714
+ self . symmetric_difference_iter ( other) . advance ( f )
714
715
}
715
716
716
717
/// Visit the values representing the intersection
717
718
fn intersection( & self , other: & HashSet < T > , f: & fn( & T ) -> bool) -> bool {
718
- self . iter ( ) . advance( |v| !other . contains ( v ) || f ( v ) )
719
+ self . intersection_iter ( other ) . advance( f )
719
720
}
720
721
721
722
/// Visit the values representing the union
722
723
fn union ( & self , other: & HashSet < T > , f: & fn( & T ) -> bool) -> bool {
723
- self . iter( ) . advance( |t| f( t) ) &&
724
- other. iter( ) . advance( |v| self . contains( v) || f( v) )
724
+ self . union_iter( other) . advance( f)
725
725
}
726
726
}
727
727
@@ -776,6 +776,33 @@ impl<T:Hash + Eq> HashSet<T> {
776
776
pub fn iter < ' a > ( & ' a self) -> HashSetIterator <' a, T > {
777
777
HashSetIterator { iter : self . map. buckets. iter( ) }
778
778
}
779
+
780
+ /// Visit the values representing the difference
781
+ pub fn difference_iter < ' a > ( & ' a self, other: & ' a HashSet < T > )
782
+ -> SetAlgebraIter < ' a , T > {
783
+ EnvFilterIterator { iter : self . iter( ) , env : other,
784
+ filter : |elt, other| !other. contains( elt) }
785
+ }
786
+
787
+ /// Visit the values representing the symmetric difference
788
+ pub fn symmetric_difference_iter < ' a > ( & ' a self, other: & ' a HashSet < T > )
789
+ -> ChainIterator < & ' a T , SetAlgebraIter < ' a , T > , SetAlgebraIter < ' a , T > > {
790
+ self . difference_iter( other) . chain_( other. difference_iter( self ) )
791
+ }
792
+
793
+ /// Visit the values representing the intersection
794
+ pub fn intersection_iter < ' a > ( & ' a self, other: & ' a HashSet < T > )
795
+ -> SetAlgebraIter < ' a , T > {
796
+ EnvFilterIterator { iter : self . iter( ) , env : other,
797
+ filter : |elt, other | other. contains( elt) }
798
+ }
799
+
800
+ /// Visit the values representing the union
801
+ pub fn union_iter < ' a > ( & ' a self, other: & ' a HashSet < T > )
802
+ -> ChainIterator < & ' a T , HashSetIterator < ' a , T > , SetAlgebraIter < ' a , T > > {
803
+ self . iter ( ) . chain_( other. difference_iter( self ) )
804
+ }
805
+
779
806
}
780
807
781
808
impl < K : Eq + Hash , T : Iterator < K > > FromIterator < K , T > for HashSet < K > {
@@ -791,6 +818,39 @@ impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
791
818
}
792
819
}
793
820
821
+ // FIXME #7814: use std::iterator::FilterIterator
822
+ /// Building block for Set operation iterators
823
+ pub struct EnvFilterIterator < A , Env , I > {
824
+ priv env: Env ,
825
+ priv filter: & ' static fn ( & A , Env ) -> bool ,
826
+ priv iter: I ,
827
+ }
828
+
829
+ impl <' self , A , Env : Clone , I : Iterator < & ' self A > > Iterator < & ' self A >
830
+ for EnvFilterIterator < A , Env , I > {
831
+ #[ inline]
832
+ fn next( & mut self ) -> Option < & ' self A > {
833
+ loop {
834
+ match self . iter. next( ) {
835
+ Some ( elt) => if ( self . filter) ( elt, self . env. clone( ) ) {
836
+ return Some ( elt)
837
+ } ,
838
+ None => return None ,
839
+ }
840
+ }
841
+ }
842
+
843
+ #[ inline]
844
+ fn size_hint( & self ) -> ( uint, Option < uint > ) {
845
+ let ( _, upper) = self . iter. size_hint( ) ;
846
+ ( 0 , upper)
847
+ }
848
+ }
849
+
850
+ /// Set operations iterator
851
+ pub type SetAlgebraIter < ' self , T > =
852
+ EnvFilterIterator < T , & ' self HashSet < T > , HashSetIterator < ' self , T > > ;
853
+
794
854
795
855
#[ cfg( test) ]
796
856
mod test_map {
@@ -1126,7 +1186,7 @@ mod test_set {
1126
1186
1127
1187
let mut i = 0 ;
1128
1188
let expected = [ 3 , 5 , 11 , 77 ] ;
1129
- for a. intersection ( & b) |x| {
1189
+ for a. intersection_iter ( & b) . advance |x| {
1130
1190
assert ! ( expected. contains( x) ) ;
1131
1191
i += 1
1132
1192
}
@@ -1149,7 +1209,7 @@ mod test_set {
1149
1209
1150
1210
let mut i = 0 ;
1151
1211
let expected = [ 1 , 5 , 11 ] ;
1152
- for a. difference ( & b) |x| {
1212
+ for a. difference_iter ( & b) . advance |x| {
1153
1213
assert ! ( expected. contains( x) ) ;
1154
1214
i += 1
1155
1215
}
@@ -1175,7 +1235,7 @@ mod test_set {
1175
1235
1176
1236
let mut i = 0 ;
1177
1237
let expected = [ -2 , 1 , 5 , 11 , 14 , 22 ] ;
1178
- for a. symmetric_difference ( & b) |x| {
1238
+ for a. symmetric_difference_iter ( & b) . advance |x| {
1179
1239
assert ! ( expected. contains( x) ) ;
1180
1240
i += 1
1181
1241
}
@@ -1205,7 +1265,7 @@ mod test_set {
1205
1265
1206
1266
let mut i = 0 ;
1207
1267
let expected = [ -2 , 1 , 3 , 5 , 9 , 11 , 13 , 16 , 19 , 24 ] ;
1208
- for a. union ( & b) |x| {
1268
+ for a. union_iter ( & b) . advance |x| {
1209
1269
assert ! ( expected. contains( x) ) ;
1210
1270
i += 1
1211
1271
}
0 commit comments