16 #ifndef OR_TOOLS_UTIL_BITSET_H_
17 #define OR_TOOLS_UTIL_BITSET_H_
33 static const uint64_t
kAllBits64 = uint64_t{0xFFFFFFFFFFFFFFFF};
38 inline uint64_t
OneBit64(
int pos) {
return uint64_t{1} << pos; }
39 inline uint32_t
OneBit32(
int pos) {
return 1U << pos; }
43 const uint64_t m1 = uint64_t{0x5555555555555555};
44 const uint64_t m2 = uint64_t{0x3333333333333333};
45 const uint64_t m4 = uint64_t{0x0F0F0F0F0F0F0F0F};
46 const uint64_t h01 = uint64_t{0x0101010101010101};
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
71 #if defined(__GNUC__) || defined(__llvm__)
72 #define USE_FAST_LEAST_SIGNIFICANT_BIT true
75 #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
76 inline int LeastSignificantBitPosition64Fast(uint64_t n) {
77 return n == 0 ? 0 : __builtin_ctzll(n);
82 static const uint64_t kSeq = uint64_t{0x0218a392dd5fb34f};
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_t n) {
140 return n == 0 ? 0 : __builtin_ctzl(n);
145 static const uint32_t 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_t 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_t 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
330 inline uint32_t
BitPos64(uint64_t pos) {
return (pos & 63); }
331 inline uint32_t
BitPos32(uint32_t pos) {
return (pos & 31); }
338 inline uint64_t
BitLength64(uint64_t size) {
return ((size + 63) >> 6); }
339 inline uint32_t
BitLength32(uint32_t size) {
return ((size + 31) >> 5); }
346 inline bool IsBitSet64(
const uint64_t*
const bitset, uint64_t pos) {
349 inline bool IsBitSet32(
const uint32_t*
const bitset, uint32_t pos) {
354 inline void SetBit64(uint64_t*
const bitset, uint64_t pos) {
357 inline void SetBit32(uint32_t*
const bitset, uint32_t pos) {
362 inline void ClearBit64(uint64_t*
const bitset, uint64_t pos) {
365 inline void ClearBit32(uint32_t*
const bitset, uint32_t pos) {
381 uint64_t start, uint64_t end);
387 uint64_t start, uint64_t end);
394 uint64_t start, uint64_t end);
396 uint32_t start, uint32_t end);
399 uint64_t start, uint64_t end);
401 uint32_t start, uint32_t end);
405 return uint64_t{3} << (pos & 62);
413 template <
typename IndexType =
int64_t>
416 Bitset64() : size_(), data_(), end_(*this, true) {}
418 : size_(Value(
size) > 0 ?
size : IndexType(0)),
423 IndexType
size()
const {
return size_; }
435 size_ = Value(
size) > 0 ?
size : IndexType(0);
442 size_ = Value(
size) > 0 ?
size : IndexType(0);
447 const size_t bit_length =
static_cast<size_t>(
BitLength64(Value(size_)));
448 const size_t to_clear =
std::min(data_.size(), bit_length);
449 data_.resize(bit_length, 0);
450 memset(data_.data(), 0, to_clear *
sizeof(int64_t));
454 void ClearAll() { memset(data_.data(), 0, data_.size() *
sizeof(int64_t)); }
513 data_[offset] = other.data_[offset];
519 template <
typename OtherIndexType>
521 const int64_t min_size =
std::min(data_.size(), other.data_.size());
522 if (min_size == 0)
return;
523 const uint64_t last_common_bucket = data_[min_size - 1];
524 memcpy(data_.data(), other.data_.data(), min_size *
sizeof(uint64_t));
525 if (data_.size() >= other.data_.size()) {
528 data_[min_size - 1] &= ~bitmask;
529 data_[min_size - 1] |= (bitmask & last_common_bucket);
534 template <
typename OtherIndexType>
537 memcpy(data_.data(), other.data_.data(), data_.size() *
sizeof(uint64_t));
544 const int min_size =
std::min(data_.size(), other.data_.size());
545 for (
int i = 0; i < min_size; ++i) {
546 data_[i] &= other.data_[i];
548 for (
int i = min_size; i < data_.size(); ++i) {
557 const int min_size =
std::min(data_.size(), other.data_.size());
558 for (
int i = 0; i < min_size; ++i) {
559 data_[i] |= other.data_[i];
570 : bitset_(data_), index_(0), base_index_(0), current_(0) {
571 if (bitset_.data_.empty()) {
574 current_ = bitset_.data_[0];
580 bool Ok()
const {
return index_ != -1; }
585 return IndexType(index_);
593 const int size = bitset_.data_.size();
596 }
while (bucket <
size && bitset_.data_[bucket] == 0);
597 if (bucket ==
size) {
601 current_ = bitset_.data_[bucket];
607 current_ &= current_ - 1;
612 : bitset_(data_), index_(0), base_index_(0), current_(0) {
613 if (at_end || bitset_.data_.empty()) {
616 current_ = bitset_.data_[0];
621 return index_ != other.index_;
623 IndexType
operator*()
const {
return IndexType(index_); }
647 DCHECK_EQ(set1.data_.size(), set1.data_.size());
648 DCHECK(use1 == 0 || use1 == 1);
649 DCHECK(use2 == 0 || use2 == 1);
652 return ((use1 << pos) & set1.data_[bucket]) ^
653 ((use2 << pos) & set2.data_[bucket]);
659 for (IndexType i(0); i <
size(); ++i) {
660 output +=
IsSet(i) ?
"1" :
"0";
668 static int64_t Value(IndexType
input);
671 std::vector<uint64_t> data_;
677 template <
class OtherIndexType>
688 : size_(size), top_(-1), data_(
BitLength64(size), 0) {}
714 int bucket_index =
static_cast<int>(
BitOffset64(i));
716 for (--bucket_index; bucket_index >= 0; --bucket_index) {
722 int Top()
const {
return top_; }
727 int bucket_index =
static_cast<int>(
BitOffset64(top_));
730 if (bucket_index == 0) {
734 bucket = data_[--bucket_index];
740 top_ =
static_cast<int>(
BitShift64(bucket_index) +
747 std::vector<uint64_t> data_;
752 template <
typename IntType>
753 inline int64_t Bitset64<IntType>::Value(IntType
input) {
755 return input.value();
758 inline int64_t Bitset64<int64_t>::Value(int64_t
input) {
765 template <
typename IntegerType =
int64_t>
770 IntegerType
size()
const {
return bitset_.size(); }
772 for (
const IntegerType i : to_clear_) bitset_.ClearBucket(i);
781 const int kSparseThreshold = 300;
782 if (to_clear_.size() * kSparseThreshold < size) {
784 bitset_.Resize(size);
786 bitset_.ClearAndResize(size);
791 if (size < bitset_.size()) {
793 for (IntegerType
index : to_clear_) {
795 to_clear_[new_index] =
index;
799 to_clear_.resize(new_index);
801 bitset_.Resize(size);
805 if (!bitset_[
index]) {
807 to_clear_.push_back(
index);
812 return to_clear_.size();
833 std::vector<IntegerType> to_clear_;
#define DCHECK_LE(val1, val2)
#define DCHECK_NE(val1, val2)
#define CHECK_GE(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK_LT(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
void IncreaseSize(int size)
void ClearAndResize(int size)
Iterator(const Bitset64 &data_)
Iterator(const Bitset64 &data_, bool at_end)
bool operator!=(const Iterator &other) const
IndexType operator*() const
void ClearAndResize(IndexType size)
void ClearBucket(IndexType i)
void Set(IndexType i, bool value)
void SetContentFromBitsetOfSameSize(const Bitset64< OtherIndexType > &other)
void Union(const Bitset64< IndexType > &other)
std::string DebugString() const
void SetContentFromBitset(const Bitset64< OtherIndexType > &other)
void Intersection(const Bitset64< IndexType > &other)
void Resize(IndexType size)
bool IsSet(IndexType i) const
void ClearTwoBits(IndexType i)
void CopyBucket(const Bitset64< IndexType > &other, IndexType i)
bool operator[](IndexType i) const
static uint64_t ConditionalXorOfTwoBits(IndexType i, uint64_t use1, const Bitset64< IndexType > &set1, uint64_t use2, const Bitset64< IndexType > &set2)
bool AreOneOfTwoBitsSet(IndexType i) const
void PushBack(bool value)
SparseBitset(IntegerType size)
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
void Set(IntegerType index)
int NumberOfSetCallsWithDifferentArguments() const
void Clear(IntegerType index)
void Resize(IntegerType size)
bool operator[](IntegerType index) const
void ClearAndResize(IntegerType size)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Collection of objects used to extend the Constraint Solver library.
uint32_t IntervalDown32(uint32_t s)
static const uint64_t kAllBits64
bool IsEmptyRange32(const uint32_t *const bitset, uint32_t start, uint32_t end)
int LeastSignificantBitPosition32Default(uint32_t n)
uint32_t BitCountRange32(const uint32_t *const bitset, uint32_t start, uint32_t end)
void SetBit32(uint32_t *const bitset, uint32_t pos)
uint32_t BitLength32(uint32_t size)
uint32_t BitCount32(uint32_t n)
int64_t UnsafeMostSignificantBitPosition64(const uint64_t *const bitset, uint64_t start, uint64_t end)
int LeastSignificantBitPosition64DeBruijn(uint64_t n)
uint64_t BitCountRange64(const uint64_t *const bitset, uint64_t start, uint64_t end)
int MostSignificantBitPosition32Default(uint32_t n)
int LeastSignificantBitPosition64Default(uint64_t n)
bool IsBitSet32(const uint32_t *const bitset, uint32_t pos)
uint32_t BitPos32(uint32_t pos)
uint64_t BitShift64(uint64_t v)
static const uint64_t kAllBitsButLsb64
int32_t UnsafeLeastSignificantBitPosition32(const uint32_t *const bitset, uint32_t start, uint32_t end)
uint32_t BitOffset32(uint32_t pos)
uint32_t LeastSignificantBitWord32(uint32_t n)
uint64_t IntervalDown64(uint64_t s)
uint32_t IntervalUp32(uint32_t s)
void ClearBit32(uint32_t *const bitset, uint32_t pos)
int64_t UnsafeLeastSignificantBitPosition64(const uint64_t *const bitset, uint64_t start, uint64_t end)
int LeastSignificantBitPosition32DeBruijn(uint32_t n)
void ClearBit64(uint64_t *const bitset, uint64_t pos)
uint32_t OneBit32(int pos)
uint64_t OneRange64(uint64_t s, uint64_t e)
uint32_t BitShift32(uint32_t v)
uint32_t BitPos64(uint64_t pos)
bool IsEmptyRange64(const uint64_t *const bitset, uint64_t start, uint64_t end)
uint64_t BitCount64(uint64_t n)
int MostSignificantBitPosition32(uint32_t n)
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
uint64_t OneBit64(int pos)
uint32_t OneRange32(uint32_t s, uint32_t e)
uint64_t BitOffset64(uint64_t pos)
uint64_t BitLength64(uint64_t size)
int LeastSignificantBitPosition64(uint64_t n)
int MostSignificantBitPosition64Default(uint64_t n)
int LeastSignificantBitPosition32(uint32_t n)
void SetBit64(uint64_t *const bitset, uint64_t pos)
uint64_t LeastSignificantBitWord64(uint64_t n)
int32_t UnsafeMostSignificantBitPosition32(const uint32_t *const bitset, uint32_t start, uint32_t end)
uint64_t TwoBitsFromPos64(uint64_t pos)
static const uint32_t kAllBits32
int MostSignificantBitPosition64(uint64_t n)
uint64_t IntervalUp64(uint64_t s)
static int input(yyscan_t yyscanner)