@@ -296,6 +296,111 @@ impl<T: Idx> From<GrowableBitSet<T>> for BitSet<T> {
296296 }
297297}
298298
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+
299404/// A fixed-size bitset type with a partially dense, partially sparse
300405/// representation. The bitset is broken into chunks, and chunks that are all
301406/// zeros or all ones are represented and handled very efficiently.
@@ -958,117 +1063,12 @@ fn sequential_update<T: Idx>(
9581063 it. fold ( false , |changed, elem| self_update ( elem) | changed)
9591064}
9601065
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-
9781066impl < T : Idx > fmt:: Debug for ChunkedBitSet < T > {
9791067 fn fmt ( & self , w : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
9801068 w. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
9811069 }
9821070}
9831071
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-
10721072#[ inline]
10731073fn bitwise < Op > ( out_vec : & mut [ Word ] , in_vec : & [ Word ] , op : Op ) -> bool
10741074where
0 commit comments