@@ -296,6 +296,111 @@ impl<T: Idx> From<GrowableBitSet<T>> for BitSet<T> {
296
296
}
297
297
}
298
298
299
+ impl < T > Clone for BitSet < T > {
300
+ fn clone ( & self ) -> Self {
301
+ BitSet { domain_size : self . domain_size , words : self . words . clone ( ) , marker : PhantomData }
302
+ }
303
+
304
+ fn clone_from ( & mut self , from : & Self ) {
305
+ self . domain_size = from. domain_size ;
306
+ self . words . clone_from ( & from. words ) ;
307
+ }
308
+ }
309
+
310
+ impl < T : Idx > fmt:: Debug for BitSet < T > {
311
+ fn fmt ( & self , w : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
312
+ w. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
313
+ }
314
+ }
315
+
316
+ impl < T : Idx > ToString for BitSet < T > {
317
+ fn to_string ( & self ) -> String {
318
+ let mut result = String :: new ( ) ;
319
+ let mut sep = '[' ;
320
+
321
+ // Note: this is a little endian printout of bytes.
322
+
323
+ // i tracks how many bits we have printed so far.
324
+ let mut i = 0 ;
325
+ for word in & self . words {
326
+ let mut word = * word;
327
+ for _ in 0 ..WORD_BYTES {
328
+ // for each byte in `word`:
329
+ let remain = self . domain_size - i;
330
+ // If less than a byte remains, then mask just that many bits.
331
+ let mask = if remain <= 8 { ( 1 << remain) - 1 } else { 0xFF } ;
332
+ assert ! ( mask <= 0xFF ) ;
333
+ let byte = word & mask;
334
+
335
+ result. push_str ( & format ! ( "{sep}{byte:02x}" ) ) ;
336
+
337
+ if remain <= 8 {
338
+ break ;
339
+ }
340
+ word >>= 8 ;
341
+ i += 8 ;
342
+ sep = '-' ;
343
+ }
344
+ sep = '|' ;
345
+ }
346
+ result. push ( ']' ) ;
347
+
348
+ result
349
+ }
350
+ }
351
+
352
+ pub struct BitIter < ' a , T : Idx > {
353
+ /// A copy of the current word, but with any already-visited bits cleared.
354
+ /// (This lets us use `trailing_zeros()` to find the next set bit.) When it
355
+ /// is reduced to 0, we move onto the next word.
356
+ word : Word ,
357
+
358
+ /// The offset (measured in bits) of the current word.
359
+ offset : usize ,
360
+
361
+ /// Underlying iterator over the words.
362
+ iter : slice:: Iter < ' a , Word > ,
363
+
364
+ marker : PhantomData < T > ,
365
+ }
366
+
367
+ impl < ' a , T : Idx > BitIter < ' a , T > {
368
+ #[ inline]
369
+ fn new ( words : & ' a [ Word ] ) -> BitIter < ' a , T > {
370
+ // We initialize `word` and `offset` to degenerate values. On the first
371
+ // call to `next()` we will fall through to getting the first word from
372
+ // `iter`, which sets `word` to the first word (if there is one) and
373
+ // `offset` to 0. Doing it this way saves us from having to maintain
374
+ // additional state about whether we have started.
375
+ BitIter {
376
+ word : 0 ,
377
+ offset : usize:: MAX - ( WORD_BITS - 1 ) ,
378
+ iter : words. iter ( ) ,
379
+ marker : PhantomData ,
380
+ }
381
+ }
382
+ }
383
+
384
+ impl < ' a , T : Idx > Iterator for BitIter < ' a , T > {
385
+ type Item = T ;
386
+ fn next ( & mut self ) -> Option < T > {
387
+ loop {
388
+ if self . word != 0 {
389
+ // Get the position of the next set bit in the current word,
390
+ // then clear the bit.
391
+ let bit_pos = self . word . trailing_zeros ( ) as usize ;
392
+ self . word ^= 1 << bit_pos;
393
+ return Some ( T :: new ( bit_pos + self . offset ) ) ;
394
+ }
395
+
396
+ // Move onto the next word. `wrapping_add()` is needed to handle
397
+ // the degenerate initial value given to `offset` in `new()`.
398
+ self . word = * self . iter . next ( ) ?;
399
+ self . offset = self . offset . wrapping_add ( WORD_BITS ) ;
400
+ }
401
+ }
402
+ }
403
+
299
404
/// A fixed-size bitset type with a partially dense, partially sparse
300
405
/// representation. The bitset is broken into chunks, and chunks that are all
301
406
/// zeros or all ones are represented and handled very efficiently.
@@ -958,117 +1063,12 @@ fn sequential_update<T: Idx>(
958
1063
it. fold ( false , |changed, elem| self_update ( elem) | changed)
959
1064
}
960
1065
961
- impl < T > Clone for BitSet < T > {
962
- fn clone ( & self ) -> Self {
963
- BitSet { domain_size : self . domain_size , words : self . words . clone ( ) , marker : PhantomData }
964
- }
965
-
966
- fn clone_from ( & mut self , from : & Self ) {
967
- self . domain_size = from. domain_size ;
968
- self . words . clone_from ( & from. words ) ;
969
- }
970
- }
971
-
972
- impl < T : Idx > fmt:: Debug for BitSet < T > {
973
- fn fmt ( & self , w : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
974
- w. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
975
- }
976
- }
977
-
978
1066
impl < T : Idx > fmt:: Debug for ChunkedBitSet < T > {
979
1067
fn fmt ( & self , w : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
980
1068
w. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
981
1069
}
982
1070
}
983
1071
984
- impl < T : Idx > ToString for BitSet < T > {
985
- fn to_string ( & self ) -> String {
986
- let mut result = String :: new ( ) ;
987
- let mut sep = '[' ;
988
-
989
- // Note: this is a little endian printout of bytes.
990
-
991
- // i tracks how many bits we have printed so far.
992
- let mut i = 0 ;
993
- for word in & self . words {
994
- let mut word = * word;
995
- for _ in 0 ..WORD_BYTES {
996
- // for each byte in `word`:
997
- let remain = self . domain_size - i;
998
- // If less than a byte remains, then mask just that many bits.
999
- let mask = if remain <= 8 { ( 1 << remain) - 1 } else { 0xFF } ;
1000
- assert ! ( mask <= 0xFF ) ;
1001
- let byte = word & mask;
1002
-
1003
- result. push_str ( & format ! ( "{sep}{byte:02x}" ) ) ;
1004
-
1005
- if remain <= 8 {
1006
- break ;
1007
- }
1008
- word >>= 8 ;
1009
- i += 8 ;
1010
- sep = '-' ;
1011
- }
1012
- sep = '|' ;
1013
- }
1014
- result. push ( ']' ) ;
1015
-
1016
- result
1017
- }
1018
- }
1019
-
1020
- pub struct BitIter < ' a , T : Idx > {
1021
- /// A copy of the current word, but with any already-visited bits cleared.
1022
- /// (This lets us use `trailing_zeros()` to find the next set bit.) When it
1023
- /// is reduced to 0, we move onto the next word.
1024
- word : Word ,
1025
-
1026
- /// The offset (measured in bits) of the current word.
1027
- offset : usize ,
1028
-
1029
- /// Underlying iterator over the words.
1030
- iter : slice:: Iter < ' a , Word > ,
1031
-
1032
- marker : PhantomData < T > ,
1033
- }
1034
-
1035
- impl < ' a , T : Idx > BitIter < ' a , T > {
1036
- #[ inline]
1037
- fn new ( words : & ' a [ Word ] ) -> BitIter < ' a , T > {
1038
- // We initialize `word` and `offset` to degenerate values. On the first
1039
- // call to `next()` we will fall through to getting the first word from
1040
- // `iter`, which sets `word` to the first word (if there is one) and
1041
- // `offset` to 0. Doing it this way saves us from having to maintain
1042
- // additional state about whether we have started.
1043
- BitIter {
1044
- word : 0 ,
1045
- offset : usize:: MAX - ( WORD_BITS - 1 ) ,
1046
- iter : words. iter ( ) ,
1047
- marker : PhantomData ,
1048
- }
1049
- }
1050
- }
1051
-
1052
- impl < ' a , T : Idx > Iterator for BitIter < ' a , T > {
1053
- type Item = T ;
1054
- fn next ( & mut self ) -> Option < T > {
1055
- loop {
1056
- if self . word != 0 {
1057
- // Get the position of the next set bit in the current word,
1058
- // then clear the bit.
1059
- let bit_pos = self . word . trailing_zeros ( ) as usize ;
1060
- self . word ^= 1 << bit_pos;
1061
- return Some ( T :: new ( bit_pos + self . offset ) ) ;
1062
- }
1063
-
1064
- // Move onto the next word. `wrapping_add()` is needed to handle
1065
- // the degenerate initial value given to `offset` in `new()`.
1066
- self . word = * self . iter . next ( ) ?;
1067
- self . offset = self . offset . wrapping_add ( WORD_BITS ) ;
1068
- }
1069
- }
1070
- }
1071
-
1072
1072
#[ inline]
1073
1073
fn bitwise < Op > ( out_vec : & mut [ Word ] , in_vec : & [ Word ] , op : Op ) -> bool
1074
1074
where
0 commit comments