@@ -2,6 +2,7 @@ use super::hash_map::HashMap;
22use std:: hash:: Hash ;
33use std:: borrow:: Borrow ;
44use std:: iter:: FromIterator ;
5+ use std:: ops:: BitAnd ;
56
67/// A hash set implementation with HashSet
78pub struct HashSet < T > where T : Hash + Eq {
@@ -63,16 +64,16 @@ impl<T> HashSet<T> where T: Hash + Eq {
6364 }
6465
6566 /// Returns an iterator visiting all items present in `self` and `other`
66- ///
67+ ///
6768 /// The union of set `self` and set `other` is composed by chaining `self.iter()` with items
6869 /// that are only present in `other` (i.e. `other.difference(self)`)
6970 pub fn union < ' a > ( & ' a self , other : & ' a HashSet < T > ) -> impl Iterator < Item = & T > + ' a {
7071 self . iter ( ) . chain ( other. difference ( self ) )
7172 }
7273
7374 /// Returns an iterator visiting items present in `self` but not in `other`
74- ///
75- ///
75+ ///
76+ ///
7677 pub fn difference < ' a > ( & ' a self , other : & ' a HashSet < T > ) -> impl Iterator < Item = & T > {
7778 Difference { iter : self . iter ( ) , other }
7879 }
@@ -115,6 +116,17 @@ impl<'a, T, I> Iterator for Difference<'a, T, I>
115116 }
116117}
117118
119+ impl < T > BitAnd for HashSet < T >
120+ where
121+ T : Hash + Eq + Clone ,
122+ {
123+ type Output = HashSet < T > ;
124+
125+ fn bitand ( self , rhs : Self ) -> HashSet < T > {
126+ self . union ( & rhs) . cloned ( ) . collect ( )
127+ }
128+ }
129+
118130#[ cfg( test) ]
119131mod hash_set {
120132 use super :: HashSet ;
@@ -189,28 +201,27 @@ mod hash_set {
189201 assert_eq ! ( union . contains( & "cat" ) , true , "union of s1 and s2 contains cat (from s1)" ) ;
190202 assert_eq ! ( union . contains( & "dog" ) , true , "union of s1 and s2 contains dog (from s1)" ) ;
191203 assert_eq ! ( union . contains( & "rat" ) , true , "union of s1 and s2 contains rat (from s2)" ) ;
204+ assert_eq ! ( union . len( ) , 3 , "length of union is 3" ) ;
205+ }
192206
193- // // Also works with HashSet<String>
194- // let mut s1: HashSet<String> = HashSet::new();
195- // s1.insert("cat".to_string());
196- // s1.insert("dog".to_string());
197-
198- // let mut s2: HashSet<String> = HashSet::new();
199- // s2.insert("rat".to_string());
207+ #[ test]
208+ fn bitand ( ) {
209+ let mut s1: HashSet < & str > = HashSet :: new ( ) ;
210+ s1. insert ( "cat" ) ;
211+ s1. insert ( "dog" ) ;
200212
201- // let union = s1.union(&s2).collect();
202- // assert!(union.contains("cat"));
203- // assert!(union.contains("dog"));
204- // assert!(union.contains("rat"));
213+ let mut s2: HashSet < & str > = HashSet :: new ( ) ;
214+ s2. insert ( "rat" ) ;
205215
206216 // TODO: Overload the '&' operator!
207- // let union = s1 & s2;
208- // assert!(union.contains("cat"));
209- // assert!(union.contains("dog"));
210- // assert!(union.contains("rat"));
217+ let union = s1 & s2;
218+ assert ! ( union . contains( "cat" ) , "union of s1 and s2 contains cat (from s1)" ) ;
219+ assert ! ( union . contains( "dog" ) , "union of s1 and s2 contains dog (from s1)" ) ;
220+ assert ! ( union . contains( "rat" ) , "union of s1 and s2 contains rat (from s2)" ) ;
221+ assert_eq ! ( union . len( ) , 3 , "length of union is 3" ) ;
211222 }
212-
213-
223+
224+
214225 #[ test]
215226 fn difference ( ) {
216227 let mut s1 = HashSet :: new ( ) ;
@@ -225,5 +236,6 @@ mod hash_set {
225236 assert_eq ! ( difference. contains( & "dog" ) , true , "dog is in s1 but not in s2, therefore included in difference" ) ;
226237 assert_eq ! ( difference. contains( & "cat" ) , false , "cat is in both s1 and s2, therefore not included in difference" ) ;
227238 assert_eq ! ( difference. contains( & "rat" ) , false , "rat is from s2, therefore not included in difference" ) ;
239+ assert_eq ! ( difference. len( ) , 1 , "length of difference is 1" ) ;
228240 }
229241}
0 commit comments