@@ -636,7 +636,7 @@ impl<T: Idx> GrowableBitSet<T> {
636636///
637637/// All operations that involve a row and/or column index will panic if the
638638/// index exceeds the relevant bound.
639- #[ derive( Clone , Debug ) ]
639+ #[ derive( Clone , Debug , Eq , PartialEq , RustcDecodable , RustcEncodable ) ]
640640pub struct BitMatrix < R : Idx , C : Idx > {
641641 num_rows : usize ,
642642 num_columns : usize ,
@@ -658,6 +658,23 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
658658 }
659659 }
660660
661+ /// Creates a new matrix, with `row` used as the value for every row.
662+ pub fn from_row_n ( row : & BitSet < C > , num_rows : usize ) -> BitMatrix < R , C > {
663+ let num_columns = row. domain_size ( ) ;
664+ let words_per_row = num_words ( num_columns) ;
665+ assert_eq ! ( words_per_row, row. words( ) . len( ) ) ;
666+ BitMatrix {
667+ num_rows,
668+ num_columns,
669+ words : iter:: repeat ( row. words ( ) ) . take ( num_rows) . flatten ( ) . cloned ( ) . collect ( ) ,
670+ marker : PhantomData ,
671+ }
672+ }
673+
674+ pub fn rows ( & self ) -> impl Iterator < Item = R > {
675+ ( 0 ..self . num_rows ) . map ( R :: new)
676+ }
677+
661678 /// The range of bits for a given row.
662679 fn range ( & self , row : R ) -> ( usize , usize ) {
663680 let words_per_row = num_words ( self . num_columns ) ;
@@ -737,6 +754,49 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
737754 changed
738755 }
739756
757+ /// Adds the bits from `with` to the bits from row `write`, and
758+ /// returns `true` if anything changed.
759+ pub fn union_row_with ( & mut self , with : & BitSet < C > , write : R ) -> bool {
760+ assert ! ( write. index( ) < self . num_rows) ;
761+ assert_eq ! ( with. domain_size( ) , self . num_columns) ;
762+ let ( write_start, write_end) = self . range ( write) ;
763+ let mut changed = false ;
764+ for ( read_index, write_index) in ( 0 ..with. words ( ) . len ( ) ) . zip ( write_start..write_end) {
765+ let word = self . words [ write_index] ;
766+ let new_word = word | with. words ( ) [ read_index] ;
767+ self . words [ write_index] = new_word;
768+ changed |= word != new_word;
769+ }
770+ changed
771+ }
772+
773+ /// Sets every cell in `row` to true.
774+ pub fn insert_all_into_row ( & mut self , row : R ) {
775+ assert ! ( row. index( ) < self . num_rows) ;
776+ let ( start, end) = self . range ( row) ;
777+ let words = & mut self . words [ ..] ;
778+ for index in start..end {
779+ words[ index] = !0 ;
780+ }
781+ self . clear_excess_bits ( row) ;
782+ }
783+
784+ /// Clear excess bits in the final word of the row.
785+ fn clear_excess_bits ( & mut self , row : R ) {
786+ let num_bits_in_final_word = self . num_columns % WORD_BITS ;
787+ if num_bits_in_final_word > 0 {
788+ let mask = ( 1 << num_bits_in_final_word) - 1 ;
789+ let ( _, end) = self . range ( row) ;
790+ let final_word_idx = end - 1 ;
791+ self . words [ final_word_idx] &= mask;
792+ }
793+ }
794+
795+ /// Gets a slice of the underlying words.
796+ pub fn words ( & self ) -> & [ Word ] {
797+ & self . words
798+ }
799+
740800 /// Iterates through all the columns set to true in a given row of
741801 /// the matrix.
742802 pub fn iter < ' a > ( & ' a self , row : R ) -> BitIter < ' a , C > {
@@ -748,6 +808,12 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
748808 marker : PhantomData ,
749809 }
750810 }
811+
812+ /// Returns the number of elements in `row`.
813+ pub fn count ( & self , row : R ) -> usize {
814+ let ( start, end) = self . range ( row) ;
815+ self . words [ start..end] . iter ( ) . map ( |e| e. count_ones ( ) as usize ) . sum ( )
816+ }
751817}
752818
753819/// A fixed-column-size, variable-row-size 2D bit matrix with a moderately
@@ -1057,6 +1123,7 @@ fn matrix_iter() {
10571123 matrix. insert ( 2 , 99 ) ;
10581124 matrix. insert ( 4 , 0 ) ;
10591125 matrix. union_rows ( 3 , 5 ) ;
1126+ matrix. insert_all_into_row ( 6 ) ;
10601127
10611128 let expected = [ 99 ] ;
10621129 let mut iter = expected. iter ( ) ;
@@ -1068,6 +1135,7 @@ fn matrix_iter() {
10681135
10691136 let expected = [ 22 , 75 ] ;
10701137 let mut iter = expected. iter ( ) ;
1138+ assert_eq ! ( matrix. count( 3 ) , expected. len( ) ) ;
10711139 for i in matrix. iter ( 3 ) {
10721140 let j = * iter. next ( ) . unwrap ( ) ;
10731141 assert_eq ! ( i, j) ;
@@ -1076,6 +1144,7 @@ fn matrix_iter() {
10761144
10771145 let expected = [ 0 ] ;
10781146 let mut iter = expected. iter ( ) ;
1147+ assert_eq ! ( matrix. count( 4 ) , expected. len( ) ) ;
10791148 for i in matrix. iter ( 4 ) {
10801149 let j = * iter. next ( ) . unwrap ( ) ;
10811150 assert_eq ! ( i, j) ;
@@ -1084,11 +1153,24 @@ fn matrix_iter() {
10841153
10851154 let expected = [ 22 , 75 ] ;
10861155 let mut iter = expected. iter ( ) ;
1156+ assert_eq ! ( matrix. count( 5 ) , expected. len( ) ) ;
10871157 for i in matrix. iter ( 5 ) {
10881158 let j = * iter. next ( ) . unwrap ( ) ;
10891159 assert_eq ! ( i, j) ;
10901160 }
10911161 assert ! ( iter. next( ) . is_none( ) ) ;
1162+
1163+ assert_eq ! ( matrix. count( 6 ) , 100 ) ;
1164+ let mut count = 0 ;
1165+ for ( idx, i) in matrix. iter ( 6 ) . enumerate ( ) {
1166+ assert_eq ! ( idx, i) ;
1167+ count += 1 ;
1168+ }
1169+ assert_eq ! ( count, 100 ) ;
1170+
1171+ if let Some ( i) = matrix. iter ( 7 ) . next ( ) {
1172+ panic ! ( "expected no elements in row, but contains element {:?}" , i) ;
1173+ }
10921174}
10931175
10941176#[ test]
0 commit comments