@@ -76,6 +76,25 @@ use std::hash;
7676use { Collection , Mutable , Set , MutableSet , MutableSeq } ;
7777use vec:: Vec ;
7878
79+ // Take two BitV's, and return iterators of their words, where the shorter one
80+ // has been padded with 0's
81+ macro_rules! match_words(
82+ ( $a_expr: expr, $b_expr: expr) => ( {
83+ let a = $a_expr;
84+ let b = $b_expr;
85+ let a_len = a. storage. len( ) ;
86+ let b_len = b. storage. len( ) ;
87+
88+ // have to uselessly pretend to pad the longer one for type matching
89+ if a_len < b_len {
90+ ( a. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( b_len) . skip( a_len) ) ,
91+ b. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( 0 ) . skip( 0 ) ) )
92+ } else {
93+ ( a. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( 0 ) . skip( 0 ) ) ,
94+ b. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( a_len) . skip( b_len) ) )
95+ }
96+ } )
97+ )
7998
8099static TRUE : bool = true ;
81100static FALSE : bool = false ;
@@ -970,7 +989,7 @@ impl<'a> RandomAccessIterator<bool> for Bits<'a> {
970989/// assert!(bv.eq_vec([true, true, false, true,
971990/// false, false, false, false]));
972991/// ```
973- #[ deriving( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
992+ #[ deriving( Clone ) ]
974993pub struct BitvSet ( Bitv ) ;
975994
976995impl Default for BitvSet {
@@ -993,6 +1012,32 @@ impl Extendable<bool> for BitvSet {
9931012 }
9941013}
9951014
1015+ impl PartialOrd for BitvSet {
1016+ #[ inline]
1017+ fn partial_cmp ( & self , other : & BitvSet ) -> Option < Ordering > {
1018+ let ( a_iter, b_iter) = match_words ! ( self . get_ref( ) , other. get_ref( ) ) ;
1019+ iter:: order:: partial_cmp ( a_iter, b_iter)
1020+ }
1021+ }
1022+
1023+ impl Ord for BitvSet {
1024+ #[ inline]
1025+ fn cmp ( & self , other : & BitvSet ) -> Ordering {
1026+ let ( a_iter, b_iter) = match_words ! ( self . get_ref( ) , other. get_ref( ) ) ;
1027+ iter:: order:: cmp ( a_iter, b_iter)
1028+ }
1029+ }
1030+
1031+ impl cmp:: PartialEq for BitvSet {
1032+ #[ inline]
1033+ fn eq ( & self , other : & BitvSet ) -> bool {
1034+ let ( a_iter, b_iter) = match_words ! ( self . get_ref( ) , other. get_ref( ) ) ;
1035+ iter:: order:: eq ( a_iter, b_iter)
1036+ }
1037+ }
1038+
1039+ impl cmp:: Eq for BitvSet { }
1040+
9961041impl BitvSet {
9971042 /// Create a new bit vector set with initially no contents.
9981043 ///
@@ -1142,10 +1187,18 @@ impl BitvSet {
11421187 // Unwrap Bitvs
11431188 let & BitvSet ( ref mut self_bitv) = self ;
11441189 let & BitvSet ( ref other_bitv) = other;
1190+
11451191 // Expand the vector if necessary
11461192 self_bitv. reserve ( other_bitv. capacity ( ) ) ;
1147- // Apply values
1148- for ( i, w) in other_bitv. mask_words ( 0 ) {
1193+
1194+ // virtually pad other with 0's for equal lengths
1195+ let self_len = self_bitv. storage . len ( ) ;
1196+ let other_len = other_bitv. storage . len ( ) ;
1197+ let mut other_words = other_bitv. mask_words ( 0 )
1198+ . chain ( iter:: Repeat :: new ( 0 u) . enumerate ( ) . take ( self_len) . skip ( other_len) ) ;
1199+
1200+ // Apply values found in other
1201+ for ( i, w) in other_words {
11491202 let old = self_bitv. storage [ i] ;
11501203 let new = f ( old, w) ;
11511204 * self_bitv. storage . get_mut ( i) = new;
@@ -2214,6 +2267,64 @@ mod tests {
22142267 assert ! ( set1. is_subset( & set2) ) ; // { 2 } { 2, 4 }
22152268 }
22162269
2270+ #[ test]
2271+ fn test_bitv_set_intersect_with ( ) {
2272+ // Explicitly 0'ed bits
2273+ let mut a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2274+ let mut b = BitvSet :: from_bitv ( from_bytes ( [ 0b00000000 ] ) ) ;
2275+ let c = a. clone ( ) ;
2276+ a. intersect_with ( & b) ;
2277+ b. intersect_with ( & c) ;
2278+ assert ! ( a. is_empty( ) ) ;
2279+ assert ! ( b. is_empty( ) ) ;
2280+
2281+ // Uninitialized bits should behave like 0's
2282+ let mut a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2283+ let mut b = BitvSet :: new ( ) ;
2284+ let c = a. clone ( ) ;
2285+ a. intersect_with ( & b) ;
2286+ b. intersect_with ( & c) ;
2287+ assert ! ( a. is_empty( ) ) ;
2288+ assert ! ( b. is_empty( ) ) ;
2289+
2290+ // Standard
2291+ let mut a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2292+ let mut b = BitvSet :: from_bitv ( from_bytes ( [ 0b01100010 ] ) ) ;
2293+ let c = a. clone ( ) ;
2294+ a. intersect_with ( & b) ;
2295+ b. intersect_with ( & c) ;
2296+ assert_eq ! ( a. len( ) , 2 ) ;
2297+ assert_eq ! ( b. len( ) , 2 ) ;
2298+ }
2299+
2300+ #[ test]
2301+ fn test_bitv_set_eq ( ) {
2302+ let a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2303+ let b = BitvSet :: from_bitv ( from_bytes ( [ 0b00000000 ] ) ) ;
2304+ let c = BitvSet :: new ( ) ;
2305+
2306+ assert ! ( a == a) ;
2307+ assert ! ( a != b) ;
2308+ assert ! ( a != c) ;
2309+ assert ! ( b == b) ;
2310+ assert ! ( b == c) ;
2311+ assert ! ( c == c) ;
2312+ }
2313+
2314+ #[ test]
2315+ fn test_bitv_set_cmp ( ) {
2316+ let a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2317+ let b = BitvSet :: from_bitv ( from_bytes ( [ 0b00000000 ] ) ) ;
2318+ let c = BitvSet :: new ( ) ;
2319+
2320+ assert_eq ! ( a. cmp( & b) , Greater ) ;
2321+ assert_eq ! ( a. cmp( & c) , Greater ) ;
2322+ assert_eq ! ( b. cmp( & a) , Less ) ;
2323+ assert_eq ! ( b. cmp( & c) , Equal ) ;
2324+ assert_eq ! ( c. cmp( & a) , Less ) ;
2325+ assert_eq ! ( c. cmp( & b) , Equal ) ;
2326+ }
2327+
22172328 #[ test]
22182329 fn test_bitv_remove ( ) {
22192330 let mut a = BitvSet :: new ( ) ;
0 commit comments