16 #ifndef OR_TOOLS_UTIL_BITSET_H_
17 #define OR_TOOLS_UTIL_BITSET_H_
48 n = (n & m2) + ((n >> 2) & m2);
49 n = (n + (n >> 4)) & m4;
54 n -= (n >> 1) & 0x55555555UL;
55 n = (n & 0x33333333) + ((n >> 2) & 0x33333333UL);
56 n = (n + (n >> 4)) & 0x0F0F0F0FUL;
59 return n & 0x0000003FUL;
70 #define USE_DEBRUIJN true // if true, use de Bruijn bit forward scanner.
71 #if defined(__GNUC__) || defined(__llvm__)
72 #define USE_FAST_LEAST_SIGNIFICANT_BIT true // if true, use fast lsb.
75 #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
76 inline int LeastSignificantBitPosition64Fast(
uint64 n) {
77 return n == 0 ? 0 : __builtin_ctzll(n);
83 static const int kTab[64] = {
85 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 52, 20, 58,
86 5, 17, 26, 56, 15, 38, 29, 40, 10, 49, 53, 31, 21, 34, 59, 42,
87 63, 6, 12, 18, 24, 27, 51, 57, 16, 55, 37, 39, 48, 30, 33, 41,
88 62, 11, 23, 50, 54, 36, 47, 32, 61, 22, 35, 46, 60, 45, 44, 43,
90 return kTab[((n & (~n + 1)) * kSeq) >> 58];
96 if (n & 0x00000000FFFFFFFFLL) {
101 if (n & 0x000000000000FFFFLL) {
106 if (n & 0x00000000000000FFLL) {
111 if (n & 0x000000000000000FLL) {
116 if (n & 0x0000000000000003LL) {
121 if (n & 0x0000000000000001LL) {
129 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
130 return LeastSignificantBitPosition64Fast(n);
131 #elif defined(USE_DEBRUIJN)
138 #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
139 inline int LeastSignificantBitPosition32Fast(
uint32 n) {
140 return n == 0 ? 0 : __builtin_ctzl(n);
145 static const uint32 kSeq = 0x077CB531U;
146 static const int kTab[32] = {
147 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20,
148 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19,
149 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
150 return kTab[((n & (~n + 1)) * kSeq) >> 27];
154 if (n == 0)
return 0;
156 if (n & 0x0000FFFFL) {
161 if (n & 0x000000FFL) {
166 if (n & 0x0000000FL) {
171 if (n & 0x00000003L) {
176 if (n & 0x00000001L) {
184 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
185 return LeastSignificantBitPosition32Fast(n);
186 #elif defined(USE_DEBRUIJN)
194 #if USE_FAST_LEAST_SIGNIFICANT_BIT
195 inline int MostSignificantBitPosition64Fast(
uint64 n) {
198 const int offset = __builtin_clzll(1);
199 return n == 0 ? 0 : (offset - __builtin_clzll(n));
232 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
233 return MostSignificantBitPosition64Fast(n);
239 #if USE_FAST_LEAST_SIGNIFICANT_BIT
240 inline int MostSignificantBitPosition32Fast(
uint32 n) {
244 const int offset = __builtin_clzl(1);
245 return n == 0 ? 0 : (offset - __builtin_clzl(n));
274 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
275 return MostSignificantBitPosition32Fast(n);
282 #undef USE_FAST_LEAST_SIGNIFICANT_BIT
411 template <
typename IndexType =
int64>
414 Bitset64() : size_(), data_(), end_(*this, true) {}
416 : size_(Value(
size) > 0 ?
size : IndexType(0)),
421 IndexType
size()
const {
return size_; }
433 size_ = Value(
size) > 0 ?
size : IndexType(0);
440 size_ = Value(
size) > 0 ?
size : IndexType(0);
445 const size_t bit_length =
static_cast<size_t>(
BitLength64(Value(size_)));
446 const size_t to_clear =
std::min(data_.size(), bit_length);
447 data_.resize(bit_length, 0);
448 memset(data_.data(), 0, to_clear *
sizeof(
int64));
511 data_[offset] = other.data_[offset];
517 template <
typename OtherIndexType>
519 const int64 min_size =
std::min(data_.size(), other.data_.size());
520 if (min_size == 0)
return;
521 const uint64 last_common_bucket = data_[min_size - 1];
522 memcpy(data_.data(), other.data_.data(), min_size *
sizeof(
uint64));
523 if (data_.size() >= other.data_.size()) {
526 data_[min_size - 1] &= ~bitmask;
527 data_[min_size - 1] |= (bitmask & last_common_bucket);
532 template <
typename OtherIndexType>
535 memcpy(data_.data(), other.data_.data(), data_.size() *
sizeof(
uint64));
542 const int min_size =
std::min(data_.size(), other.data_.size());
543 for (
int i = 0; i < min_size; ++i) {
544 data_[i] &= other.data_[i];
546 for (
int i = min_size; i < data_.size(); ++i) {
555 const int min_size =
std::min(data_.size(), other.data_.size());
556 for (
int i = 0; i < min_size; ++i) {
557 data_[i] |= other.data_[i];
568 : bitset_(data_), index_(0), base_index_(0), current_(0) {
569 if (bitset_.data_.empty()) {
572 current_ = bitset_.data_[0];
578 bool Ok()
const {
return index_ != -1; }
583 return IndexType(index_);
591 const int size = bitset_.data_.size();
594 }
while (bucket <
size && bitset_.data_[bucket] == 0);
595 if (bucket ==
size) {
599 current_ = bitset_.data_[bucket];
605 current_ &= current_ - 1;
610 : bitset_(data_), index_(0), base_index_(0), current_(0) {
611 if (at_end || bitset_.data_.empty()) {
614 current_ = bitset_.data_[0];
619 return index_ != other.index_;
621 IndexType
operator*()
const {
return IndexType(index_); }
636 Iterator
begin()
const {
return Iterator(*
this); }
637 Iterator
end()
const {
return end_; }
646 DCHECK_EQ(data_.size(), other1.data_.size());
647 DCHECK_EQ(data_.size(), other2.data_.size());
648 DCHECK(use1 == 0 || use1 == 1);
649 DCHECK(use2 == 0 || use2 == 1);
652 data_[bucket] ^= ((1ull << pos) & data_[bucket]) ^
653 ((use1 << pos) & other1.data_[bucket]) ^
654 ((use2 << pos) & other2.data_[bucket]);
660 for (IndexType i(0); i <
size(); ++i) {
661 output +=
IsSet(i) ?
"1" :
"0";
672 std::vector<uint64> data_;
678 template <
class OtherIndexType>
689 : size_(size), top_(-1), data_(
BitLength64(size), 0) {}
715 int bucket_index =
static_cast<int>(
BitOffset64(i));
717 for (--bucket_index; bucket_index >= 0; --bucket_index) {
723 int Top()
const {
return top_; }
728 int bucket_index =
static_cast<int>(
BitOffset64(top_));
731 if (bucket_index == 0) {
735 bucket = data_[--bucket_index];
741 top_ =
static_cast<int>(
BitShift64(bucket_index) +
748 std::vector<uint64> data_;
753 template <
typename IntType>
754 inline int64 Bitset64<IntType>::Value(IntType
input)
const {
756 return input.value();
766 template <
typename IntegerType =
int64>
771 IntegerType
size()
const {
return bitset_.size(); }
773 for (
const IntegerType i : to_clear_) bitset_.ClearBucket(i);
782 const int kSparseThreshold = 300;
783 if (to_clear_.size() * kSparseThreshold < size) {
785 bitset_.Resize(size);
787 bitset_.ClearAndResize(size);
792 if (size < bitset_.size()) {
794 for (IntegerType
index : to_clear_) {
796 to_clear_[new_index] =
index;
800 to_clear_.resize(new_index);
802 bitset_.Resize(size);
806 if (!bitset_[
index]) {
808 to_clear_.push_back(
index);
813 return to_clear_.size();
834 std::vector<IntegerType> to_clear_;
840 #endif // OR_TOOLS_UTIL_BITSET_H_