49 const Bitvector::IntType Bitvector::all_1_ = (((1ul << 32) - 1) << 32) + ((1ul << 32) - 1);
51 const std::array<Bitvector::IntType, Bitvector::IntSize> Bitvector::bit_mask_ =
53 1ul << 0, 1ul << 1, 1ul << 2, 1ul << 3, 1ul << 4, 1ul << 5, 1ul << 6, 1ul << 7,
54 1ul << 8, 1ul << 9, 1ul << 10, 1ul << 11, 1ul << 12, 1ul << 13, 1ul << 14, 1ul << 15,
55 1ul << 16, 1ul << 17, 1ul << 18, 1ul << 19, 1ul << 20, 1ul << 21, 1ul << 22, 1ul << 23,
56 1ul << 24, 1ul << 25, 1ul << 26, 1ul << 27, 1ul << 28, 1ul << 29, 1ul << 30, 1ul << 31,
57 1ul << 32, 1ul << 33, 1ul << 34, 1ul << 35, 1ul << 36, 1ul << 37, 1ul << 38, 1ul << 39,
58 1ul << 40, 1ul << 41, 1ul << 42, 1ul << 43, 1ul << 44, 1ul << 45, 1ul << 46, 1ul << 47,
59 1ul << 48, 1ul << 49, 1ul << 50, 1ul << 51, 1ul << 52, 1ul << 53, 1ul << 54, 1ul << 55,
60 1ul << 56, 1ul << 57, 1ul << 58, 1ul << 59, 1ul << 60, 1ul << 61, 1ul << 62, 1ul << 63
63 const std::array<Bitvector::IntType, Bitvector::IntSize> Bitvector::ones_mask_ =
65 Bitvector::all_0_, Bitvector::all_1_ >> 63, Bitvector::all_1_ >> 62, Bitvector::all_1_ >> 61,
66 Bitvector::all_1_ >> 60, Bitvector::all_1_ >> 59, Bitvector::all_1_ >> 58, Bitvector::all_1_ >> 57,
67 Bitvector::all_1_ >> 56, Bitvector::all_1_ >> 55, Bitvector::all_1_ >> 54, Bitvector::all_1_ >> 53,
68 Bitvector::all_1_ >> 52, Bitvector::all_1_ >> 51, Bitvector::all_1_ >> 50, Bitvector::all_1_ >> 49,
69 Bitvector::all_1_ >> 48, Bitvector::all_1_ >> 47, Bitvector::all_1_ >> 46, Bitvector::all_1_ >> 45,
70 Bitvector::all_1_ >> 44, Bitvector::all_1_ >> 43, Bitvector::all_1_ >> 42, Bitvector::all_1_ >> 41,
71 Bitvector::all_1_ >> 40, Bitvector::all_1_ >> 39, Bitvector::all_1_ >> 38, Bitvector::all_1_ >> 37,
72 Bitvector::all_1_ >> 36, Bitvector::all_1_ >> 35, Bitvector::all_1_ >> 34, Bitvector::all_1_ >> 33,
73 Bitvector::all_1_ >> 32, Bitvector::all_1_ >> 31, Bitvector::all_1_ >> 30, Bitvector::all_1_ >> 29,
74 Bitvector::all_1_ >> 28, Bitvector::all_1_ >> 27, Bitvector::all_1_ >> 26, Bitvector::all_1_ >> 25,
75 Bitvector::all_1_ >> 24, Bitvector::all_1_ >> 23, Bitvector::all_1_ >> 22, Bitvector::all_1_ >> 21,
76 Bitvector::all_1_ >> 20, Bitvector::all_1_ >> 19, Bitvector::all_1_ >> 18, Bitvector::all_1_ >> 17,
77 Bitvector::all_1_ >> 16, Bitvector::all_1_ >> 15, Bitvector::all_1_ >> 14, Bitvector::all_1_ >> 13,
78 Bitvector::all_1_ >> 12, Bitvector::all_1_ >> 11, Bitvector::all_1_ >> 10, Bitvector::all_1_ >> 9,
79 Bitvector::all_1_ >> 8, Bitvector::all_1_ >> 7, Bitvector::all_1_ >> 6, Bitvector::all_1_ >> 5,
80 Bitvector::all_1_ >> 4, Bitvector::all_1_ >> 3, Bitvector::all_1_ >> 2, Bitvector::all_1_ >> 1
83 const std::array<Bitvector::IntType, 4> Bitvector::count_mask_ =
101 "Bitvector::all_1_ is not all one"
113 auto const n = std::min( data_.size(), other.data_.size() );
114 for(
size_t i = 0; i < n; ++i ) {
115 data_[i] = other.data_[i];
123 for(
size_t i = 0; i < values.size(); ++i ) {
124 switch( values[i] ) {
131 throw std::invalid_argument(
132 "Cannot construct Bitvector from std::string that contains characters "
133 "other than 0 and 1."
158 if( first >= size_ || last > size_ || first > last ) {
159 throw std::out_of_range(
164 assert( first < size_ );
165 assert( last <= size_ );
166 assert( first <= last );
169 if( first == last ) {
177 auto const f_wrd_idx = first /
IntSize;
178 auto const l_wrd_idx = (last - 1) /
IntSize;
179 auto const f_bit_idx = first %
IntSize;
180 auto const l_bit_idx = last %
IntSize;
181 assert( f_wrd_idx < data_.size() );
182 assert( l_wrd_idx < data_.size() );
183 assert( f_bit_idx < ones_mask_.size() );
184 assert( l_bit_idx < ones_mask_.size() );
188 auto const f_mask = ~ones_mask_[ f_bit_idx ];
189 auto const l_mask = l_bit_idx == 0 ? all_1_ : ones_mask_[ l_bit_idx ];
192 if( f_wrd_idx == l_wrd_idx ) {
194 data_[ f_wrd_idx ] |= ( f_mask & l_mask );
196 data_[ f_wrd_idx ] &= ~( f_mask & l_mask );
200 data_[ f_wrd_idx ] |= f_mask;
201 for(
size_t i = f_wrd_idx + 1; i < l_wrd_idx; ++i ) {
204 data_[ l_wrd_idx ] |= l_mask;
206 data_[ f_wrd_idx ] &= ~f_mask;
207 for(
size_t i = f_wrd_idx + 1; i < l_wrd_idx; ++i ) {
210 data_[ l_wrd_idx ] &= ~l_mask;
221 if( size_ != rhs.size_ ) {
222 throw std::runtime_error(
223 "Cannot use operator `&` or `&=` on Bitvectors of different size. "
224 "Use bitwise_and() instead."
228 for(
size_t i = 0; i < data_.size(); ++i ) {
229 data_[i] &= rhs.data_[i];
236 if( size_ != rhs.size_ ) {
237 throw std::runtime_error(
238 "Cannot use operator `|` or `|=` on Bitvectors of different size. "
239 "Use bitwise_or() instead."
243 for(
size_t i = 0; i < data_.size(); ++i ) {
244 data_[i] |= rhs.data_[i];
251 if( size_ != rhs.size_ ) {
252 throw std::runtime_error(
253 "Cannot use operator `^` or `^=` on Bitvectors of different size. "
254 "Use bitwise_xor() instead."
258 for(
size_t i = 0; i < data_.size(); ++i ) {
259 data_[i] ^= rhs.data_[i];
294 if (size_ != other.size_) {
297 for(
size_t i = 0; i < data_.size(); ++i ) {
298 if (data_[i] != other.data_[i]) {
307 return !(*
this == other);
318 for(
auto x : data_ ) {
337 if( first >= size_ || last > size_ || first > last ) {
338 throw std::invalid_argument(
339 "Cannot compute pop count for Bitvector of size " +
std::to_string( size_ ) +
343 assert( first < size_ );
344 assert( last <= size_ );
345 assert( first <= last );
348 if( first == last ) {
360 auto const f_wrd_idx = first /
IntSize;
361 auto const l_wrd_idx = (last - 1) /
IntSize;
362 auto const f_bit_idx = first %
IntSize;
363 auto const l_bit_idx = last %
IntSize;
364 assert( f_wrd_idx < data_.size() );
365 assert( l_wrd_idx < data_.size() );
366 assert( f_bit_idx < ones_mask_.size() );
367 assert( l_bit_idx < ones_mask_.size() );
371 auto f_word = data_[ f_wrd_idx ];
372 auto l_word = data_[ l_wrd_idx ];
379 f_word &= ~ones_mask_[ f_bit_idx ];
380 if( l_bit_idx != 0 ) {
381 l_word &= ones_mask_[ l_bit_idx ];
386 if( f_wrd_idx == l_wrd_idx ) {
389 result = count_( f_word & l_word );
392 result = count_( f_word ) + count_( l_word );
393 for(
size_t i = f_wrd_idx + 1; i < l_wrd_idx; ++i ) {
394 result += count_( data_[i] );
402 for(
auto word : data_ ) {
413 if( start >= size_ ) {
426 auto find_next_set_in_word_ = [](
IntType word ) {
437 if(
sizeof(word) <=
sizeof(
unsigned int) ) {
438 return ffs(
static_cast<unsigned int>( word )) - 1;
439 }
else if(
sizeof(word) <=
sizeof(
unsigned long) ) {
440 return ffsl(
static_cast<unsigned long>( word )) - 1;
442 return ffsll(word) - 1;
454 auto wrd_idx = start /
IntSize;
455 auto bit_idx = start %
IntSize;
456 assert( wrd_idx < data_.size() );
457 assert( bit_idx < ones_mask_.size() );
458 auto word = data_[wrd_idx];
463 word &= ~( ones_mask_[ bit_idx ]);
465 return wrd_idx *
IntSize + find_next_set_in_word_( word );
471 while( wrd_idx < data_.size() && data_[wrd_idx] == 0 ) {
474 if( wrd_idx == data_.size() ) {
478 assert( wrd_idx < data_.size() );
479 assert( data_[wrd_idx] != 0 );
480 return wrd_idx *
IntSize + find_next_set_in_word_( data_[wrd_idx] );
486 for(
auto word : data_ ) {
495 for(
auto word : data_ ) {
504 for(
size_t i = 0; i < data_.size(); ++i ) {
505 data_[i] = ~ data_[i];
514 if( size_ > 0 &&
get(0) ) {
522 const auto v = value ? all_1_ : all_0_;
523 for(
size_t i = 0; i < data_.size(); ++i ) {
537 void Bitvector::unset_padding_()
540 if(( size_ %
IntSize ) == 0 ) {
541 assert( size_ /
IntSize == data_.size() );
546 assert( size_ /
IntSize + 1 == data_.size() );
547 assert( size_ %
IntSize < ones_mask_.size() );
548 data_.back() &= ones_mask_[ size_ %
IntSize ];
559 size_t Bitvector::count_( IntType x )
564 x -= (x >> 1) & count_mask_[0];
567 x = (x & count_mask_[1]) + ((x >> 2) & count_mask_[1]);
570 x = (x + (x >> 4)) & count_mask_[2];
573 return (x * count_mask_[3]) >> 56;
583 for(
size_t i = 0; i < size_; ++i ) {
584 res += (*this)[i] ?
"1" :
"0";
585 if( (i+1) % 64 == 0 ) {
587 }
else if( (i+1) % 8 == 0 ) {
596 std::string res =
"";
597 for(
size_t i = 0; i <
IntSize; ++i ) {
598 res += (x & bit_mask_[i] ?
"1" :
"0");
599 if( (i+1) % 8 == 0 ) {