@@ -15,7 +15,7 @@ use core::prelude::*;
15
15
use core:: cmp;
16
16
use core:: default:: Default ;
17
17
use core:: fmt;
18
- use core:: iter:: { Map , Zip } ;
18
+ use core:: iter:: { Map , Take , Zip } ;
19
19
use core:: ops;
20
20
use core:: slice;
21
21
use core:: uint;
@@ -382,21 +382,6 @@ impl cmp::PartialEq for Bitv {
382
382
383
383
impl cmp:: Eq for Bitv { }
384
384
385
- #[ inline]
386
- fn iterate_bits ( base : uint , bits : uint , f: |uint| -> bool) -> bool {
387
- if bits == 0 {
388
- return true ;
389
- }
390
- for i in range ( 0 u, uint:: BITS ) {
391
- if bits & ( 1 << i) != 0 {
392
- if !f ( base + i) {
393
- return false ;
394
- }
395
- }
396
- }
397
- return true ;
398
- }
399
-
400
385
/// An iterator for `Bitv`.
401
386
pub struct Bits < ' a > {
402
387
bitv : & ' a Bitv ,
@@ -553,39 +538,45 @@ impl BitvSet {
553
538
BitPositions { set : self , next_idx : 0 }
554
539
}
555
540
556
- pub fn difference ( & self , other : & BitvSet , f: |& uint| -> bool) -> bool {
557
- for ( i, w1, w2) in self . commons ( other) {
558
- if !iterate_bits ( i, w1 & !w2, |b| f ( & b) ) {
559
- return false
560
- }
561
- } ;
562
- /* everything we have that they don't also shows up */
563
- self . outliers ( other) . advance ( |( mine, i, w) |
564
- !mine || iterate_bits ( i, w, |b| f ( & b) )
565
- )
566
- }
567
-
568
- pub fn symmetric_difference ( & self , other : & BitvSet , f: |& uint| -> bool)
569
- -> bool {
570
- for ( i, w1, w2) in self . commons ( other) {
571
- if !iterate_bits ( i, w1 ^ w2, |b| f ( & b) ) {
572
- return false
573
- }
574
- } ;
575
- self . outliers ( other) . advance ( |( _, i, w) | iterate_bits ( i, w, |b| f ( & b) ) )
541
+ pub fn difference < ' a > ( & ' a self , other : & ' a BitvSet ) -> TwoBitPositions < ' a > {
542
+ TwoBitPositions {
543
+ set : self ,
544
+ other : other,
545
+ merge : |w1, w2| w1 & !w2,
546
+ current_word : 0 ,
547
+ next_idx : 0
548
+ }
576
549
}
577
550
578
- pub fn intersection ( & self , other : & BitvSet , f: |& uint| -> bool) -> bool {
579
- self . commons ( other) . advance ( |( i, w1, w2) | iterate_bits ( i, w1 & w2, |b| f ( & b) ) )
551
+ pub fn symmetric_difference < ' a > ( & ' a self , other : & ' a BitvSet ) -> TwoBitPositions < ' a > {
552
+ TwoBitPositions {
553
+ set : self ,
554
+ other : other,
555
+ merge : |w1, w2| w1 ^ w2,
556
+ current_word : 0 ,
557
+ next_idx : 0
558
+ }
580
559
}
581
560
582
- pub fn union ( & self , other : & BitvSet , f: |& uint| -> bool) -> bool {
583
- for ( i, w1, w2) in self . commons ( other) {
584
- if !iterate_bits ( i, w1 | w2, |b| f ( & b) ) {
585
- return false
586
- }
587
- } ;
588
- self . outliers ( other) . advance ( |( _, i, w) | iterate_bits ( i, w, |b| f ( & b) ) )
561
+ pub fn intersection < ' a > ( & ' a self , other : & ' a BitvSet ) -> Take < TwoBitPositions < ' a > > {
562
+ let min = cmp:: min ( self . capacity ( ) , other. capacity ( ) ) ;
563
+ TwoBitPositions {
564
+ set : self ,
565
+ other : other,
566
+ merge : |w1, w2| w1 & w2,
567
+ current_word : 0 ,
568
+ next_idx : 0
569
+ } . take ( min)
570
+ }
571
+
572
+ pub fn union < ' a > ( & ' a self , other : & ' a BitvSet ) -> TwoBitPositions < ' a > {
573
+ TwoBitPositions {
574
+ set : self ,
575
+ other : other,
576
+ merge : |w1, w2| w1 | w2,
577
+ current_word : 0 ,
578
+ next_idx : 0
579
+ }
589
580
}
590
581
}
591
582
@@ -634,7 +625,7 @@ impl Set<uint> for BitvSet {
634
625
}
635
626
636
627
fn is_disjoint ( & self , other : & BitvSet ) -> bool {
637
- self . intersection ( other, |_| false )
628
+ self . intersection ( other) . count ( ) > 0
638
629
}
639
630
640
631
fn is_subset ( & self , other : & BitvSet ) -> bool {
@@ -737,6 +728,14 @@ pub struct BitPositions<'a> {
737
728
next_idx : uint
738
729
}
739
730
731
+ pub struct TwoBitPositions < ' a > {
732
+ set : & ' a BitvSet ,
733
+ other : & ' a BitvSet ,
734
+ merge : |uint , uint |: ' a -> uint,
735
+ current_word: uint ,
736
+ next_idx : uint
737
+ }
738
+
740
739
impl < ' a > Iterator < uint > for BitPositions < ' a > {
741
740
#[ inline]
742
741
fn next ( & mut self ) -> Option < uint > {
@@ -757,6 +756,41 @@ impl<'a> Iterator<uint> for BitPositions<'a> {
757
756
}
758
757
}
759
758
759
+ impl < ' a > Iterator < uint > for TwoBitPositions < ' a > {
760
+ #[ inline]
761
+ fn next ( & mut self ) -> Option < uint > {
762
+ while self . next_idx < self . set . capacity ( ) ||
763
+ self . next_idx < self . other . capacity ( ) {
764
+ let bit_idx = self . next_idx % uint:: BITS ;
765
+ if bit_idx == 0 {
766
+ let & BitvSet ( ref s_bitv) = self . set ;
767
+ let & BitvSet ( ref o_bitv) = self . other ;
768
+ // Merging the two words is a bit of an awkward dance since
769
+ // one Bitv might be longer than the other
770
+ let word_idx = self . next_idx / uint:: BITS ;
771
+ let w1 = if word_idx < s_bitv. storage . len ( ) {
772
+ * s_bitv. storage . get ( word_idx)
773
+ } else { 0 } ;
774
+ let w2 = if word_idx < o_bitv. storage . len ( ) {
775
+ * o_bitv. storage . get ( word_idx)
776
+ } else { 0 } ;
777
+ self . current_word = ( self . merge ) ( w1, w2) ;
778
+ }
779
+
780
+ self . next_idx += 1 ;
781
+ if self . current_word & ( 1 << bit_idx) != 0 {
782
+ return Some ( self . next_idx - 1 ) ;
783
+ }
784
+ }
785
+ return None ;
786
+ }
787
+
788
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
789
+ let cap = cmp:: max ( self . set . capacity ( ) , self . other . capacity ( ) ) ;
790
+ ( 0 , Some ( cap - self . next_idx ) )
791
+ }
792
+ }
793
+
760
794
#[ cfg( test) ]
761
795
mod tests {
762
796
use std:: prelude:: * ;
@@ -1274,8 +1308,8 @@ mod tests {
1274
1308
1275
1309
let mut i = 0 ;
1276
1310
let expected = [ 3 , 5 , 11 , 77 ] ;
1277
- a. intersection ( & b, |x| {
1278
- assert_eq ! ( * x, expected[ i] ) ;
1311
+ a. intersection ( & b) . advance ( |x| {
1312
+ assert_eq ! ( x, expected[ i] ) ;
1279
1313
i += 1 ;
1280
1314
true
1281
1315
} ) ;
@@ -1298,8 +1332,8 @@ mod tests {
1298
1332
1299
1333
let mut i = 0 ;
1300
1334
let expected = [ 1 , 5 , 500 ] ;
1301
- a. difference ( & b, |x| {
1302
- assert_eq ! ( * x, expected[ i] ) ;
1335
+ a. difference ( & b) . advance ( |x| {
1336
+ assert_eq ! ( x, expected[ i] ) ;
1303
1337
i += 1 ;
1304
1338
true
1305
1339
} ) ;
@@ -1324,8 +1358,8 @@ mod tests {
1324
1358
1325
1359
let mut i = 0 ;
1326
1360
let expected = [ 1 , 5 , 11 , 14 , 220 ] ;
1327
- a. symmetric_difference ( & b, |x| {
1328
- assert_eq ! ( * x, expected[ i] ) ;
1361
+ a. symmetric_difference ( & b) . advance ( |x| {
1362
+ assert_eq ! ( x, expected[ i] ) ;
1329
1363
i += 1 ;
1330
1364
true
1331
1365
} ) ;
@@ -1353,8 +1387,8 @@ mod tests {
1353
1387
1354
1388
let mut i = 0 ;
1355
1389
let expected = [ 1 , 3 , 5 , 9 , 11 , 13 , 19 , 24 , 160 ] ;
1356
- a. union ( & b, |x| {
1357
- assert_eq ! ( * x, expected[ i] ) ;
1390
+ a. union ( & b) . advance ( |x| {
1391
+ assert_eq ! ( x, expected[ i] ) ;
1358
1392
i += 1 ;
1359
1393
true
1360
1394
} ) ;
0 commit comments