1616#[ mutable_doc] ;
1717
1818use container:: { Container , Mutable , Map , MutableMap , Set , MutableSet } ;
19+ use clone:: Clone ;
1920use cmp:: { Eq , Equiv } ;
2021use hash:: Hash ;
21- use iterator:: { Iterator , IteratorUtil , FromIterator } ;
22+ use iterator:: { Iterator , IteratorUtil , FromIterator , ChainIterator } ;
2223use num;
2324use option:: { None , Option , Some } ;
2425use rand:: RngUtil ;
@@ -510,19 +511,6 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
510511 self . iter ( ) . advance ( |( _, v) | blk ( v) )
511512 }
512513
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-
526514 /// An iterator visiting all key-value pairs in arbitrary order.
527515 /// Iterator element type is (&'a K, &'a V).
528516 pub fn iter < ' a > ( & ' a self ) -> HashMapIterator < ' a , K , V > {
@@ -716,25 +704,24 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
716704
717705 /// Visit the values representing the difference
718706 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 )
720708 }
721709
722710 /// Visit the values representing the symmetric difference
723711 fn symmetric_difference( & self ,
724712 other: & HashSet < T > ,
725713 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 )
727715 }
728716
729717 /// Visit the values representing the intersection
730718 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 )
732720 }
733721
734722 /// Visit the values representing the union
735723 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)
738725 }
739726}
740727
@@ -789,6 +776,33 @@ impl<T:Hash + Eq> HashSet<T> {
789776 pub fn iter < ' a > ( & ' a self) -> HashSetIterator <' a, T > {
790777 HashSetIterator { iter : self . map. buckets. iter( ) }
791778 }
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+
792806}
793807
794808impl < 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> {
804818 }
805819}
806820
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+
807854
808855#[ cfg( test) ]
809856mod test_map {
@@ -1139,7 +1186,7 @@ mod test_set {
11391186
11401187 let mut i = 0 ;
11411188 let expected = [ 3 , 5 , 11 , 77 ] ;
1142- for a. intersection ( & b) |x| {
1189+ for a. intersection_iter ( & b) . advance |x| {
11431190 assert ! ( expected. contains( x) ) ;
11441191 i += 1
11451192 }
@@ -1162,7 +1209,7 @@ mod test_set {
11621209
11631210 let mut i = 0 ;
11641211 let expected = [ 1 , 5 , 11 ] ;
1165- for a. difference ( & b) |x| {
1212+ for a. difference_iter ( & b) . advance |x| {
11661213 assert ! ( expected. contains( x) ) ;
11671214 i += 1
11681215 }
@@ -1188,7 +1235,7 @@ mod test_set {
11881235
11891236 let mut i = 0 ;
11901237 let expected = [ -2 , 1 , 5 , 11 , 14 , 22 ] ;
1191- for a. symmetric_difference ( & b) |x| {
1238+ for a. symmetric_difference_iter ( & b) . advance |x| {
11921239 assert ! ( expected. contains( x) ) ;
11931240 i += 1
11941241 }
@@ -1218,7 +1265,7 @@ mod test_set {
12181265
12191266 let mut i = 0 ;
12201267 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| {
12221269 assert ! ( expected. contains( x) ) ;
12231270 i += 1
12241271 }
0 commit comments