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 ;
@@ -510,19 +511,6 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
510
511
self . iter ( ) . advance ( |( _, v) | blk ( v) )
511
512
}
512
513
513
- /// Iterate over the map and mutate the contained values
514
- pub fn mutate_values ( & mut self , blk : & fn ( & K , & mut V ) -> bool ) -> bool {
515
- for uint:: range( 0 , self . buckets. len( ) ) |i| {
516
- match self . buckets [ i] {
517
- Some ( Bucket { key : ref key, value : ref mut value, _} ) => {
518
- if !blk ( key, value) { return false ; }
519
- }
520
- None => ( )
521
- }
522
- }
523
- return true ;
524
- }
525
-
526
514
/// An iterator visiting all key-value pairs in arbitrary order.
527
515
/// Iterator element type is (&'a K, &'a V).
528
516
pub fn iter < ' a > ( & ' a self ) -> HashMapIterator < ' a , K , V > {
@@ -716,25 +704,24 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
716
704
717
705
/// Visit the values representing the difference
718
706
fn difference( & self , other: & HashSet < T > , f: & fn( & T ) -> bool) -> bool {
719
- self . iter ( ) . advance( |v| other . contains ( v ) || f ( v ) )
707
+ self . difference_iter ( other ) . advance( f )
720
708
}
721
709
722
710
/// Visit the values representing the symmetric difference
723
711
fn symmetric_difference( & self ,
724
712
other: & HashSet < T > ,
725
713
f: & fn( & T ) -> bool ) -> bool {
726
- self . difference ( other, |t| f ( t ) ) && other . difference ( self , |t| f ( t ) )
714
+ self . symmetric_difference_iter ( other) . advance ( f )
727
715
}
728
716
729
717
/// Visit the values representing the intersection
730
718
fn intersection( & self , other: & HashSet < T > , f: & fn( & T ) -> bool) -> bool {
731
- self . iter ( ) . advance( |v| !other . contains ( v ) || f ( v ) )
719
+ self . intersection_iter ( other ) . advance( f )
732
720
}
733
721
734
722
/// Visit the values representing the union
735
723
fn union ( & self , other: & HashSet < T > , f: & fn( & T ) -> bool) -> bool {
736
- self . iter( ) . advance( |t| f( t) ) &&
737
- other. iter( ) . advance( |v| self . contains( v) || f( v) )
724
+ self . union_iter( other) . advance( f)
738
725
}
739
726
}
740
727
@@ -789,6 +776,33 @@ impl<T:Hash + Eq> HashSet<T> {
789
776
pub fn iter < ' a > ( & ' a self) -> HashSetIterator <' a, T > {
790
777
HashSetIterator { iter : self . map. buckets. iter( ) }
791
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
+
792
806
}
793
807
794
808
impl < K : Eq + Hash , T : Iterator < K > > FromIterator < K , T > for HashSet < K > {
@@ -804,6 +818,39 @@ impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
804
818
}
805
819
}
806
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
+
807
854
808
855
#[ cfg( test) ]
809
856
mod test_map {
@@ -1139,7 +1186,7 @@ mod test_set {
1139
1186
1140
1187
let mut i = 0 ;
1141
1188
let expected = [ 3 , 5 , 11 , 77 ] ;
1142
- for a. intersection ( & b) |x| {
1189
+ for a. intersection_iter ( & b) . advance |x| {
1143
1190
assert ! ( expected. contains( x) ) ;
1144
1191
i += 1
1145
1192
}
@@ -1162,7 +1209,7 @@ mod test_set {
1162
1209
1163
1210
let mut i = 0 ;
1164
1211
let expected = [ 1 , 5 , 11 ] ;
1165
- for a. difference ( & b) |x| {
1212
+ for a. difference_iter ( & b) . advance |x| {
1166
1213
assert ! ( expected. contains( x) ) ;
1167
1214
i += 1
1168
1215
}
@@ -1188,7 +1235,7 @@ mod test_set {
1188
1235
1189
1236
let mut i = 0 ;
1190
1237
let expected = [ -2 , 1 , 5 , 11 , 14 , 22 ] ;
1191
- for a. symmetric_difference ( & b) |x| {
1238
+ for a. symmetric_difference_iter ( & b) . advance |x| {
1192
1239
assert ! ( expected. contains( x) ) ;
1193
1240
i += 1
1194
1241
}
@@ -1218,7 +1265,7 @@ mod test_set {
1218
1265
1219
1266
let mut i = 0 ;
1220
1267
let expected = [ -2 , 1 , 3 , 5 , 9 , 11 , 13 , 16 , 19 , 24 ] ;
1221
- for a. union ( & b) |x| {
1268
+ for a. union_iter ( & b) . advance |x| {
1222
1269
assert ! ( expected. contains( x) ) ;
1223
1270
i += 1
1224
1271
}
0 commit comments