16 #ifndef OR_TOOLS_UTIL_BITSET_H_
17 #define OR_TOOLS_UTIL_BITSET_H_
34 static const uint64_t
kAllBits64 = uint64_t{0xFFFFFFFFFFFFFFFF};
39 inline uint64_t
OneBit64(
int pos) {
return uint64_t{1} << pos; }
40 inline uint32_t
OneBit32(
int pos) {
return 1U << pos; }
44 const uint64_t m1 = uint64_t{0x5555555555555555};
45 const uint64_t m2 = uint64_t{0x3333333333333333};
46 const uint64_t m4 = uint64_t{0x0F0F0F0F0F0F0F0F};
47 const uint64_t h01 = uint64_t{0x0101010101010101};
49 n = (n & m2) + ((n >> 2) & m2);
50 n = (n + (n >> 4)) & m4;
55 n -= (n >> 1) & 0x55555555UL;
56 n = (n & 0x33333333) + ((n >> 2) & 0x33333333UL);
57 n = (n + (n >> 4)) & 0x0F0F0F0FUL;
60 return n & 0x0000003FUL;
71 #define USE_DEBRUIJN true
72 #if defined(__GNUC__) || defined(__llvm__)
73 #define USE_FAST_LEAST_SIGNIFICANT_BIT true
76 #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
77 inline int LeastSignificantBitPosition64Fast(uint64_t n) {
78 return __builtin_ctzll(n);
83 static const uint64_t kSeq = uint64_t{0x0218a392dd5fb34f};
84 static const int kTab[64] = {
86 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 52, 20, 58,
87 5, 17, 26, 56, 15, 38, 29, 40, 10, 49, 53, 31, 21, 34, 59, 42,
88 63, 6, 12, 18, 24, 27, 51, 57, 16, 55, 37, 39, 48, 30, 33, 41,
89 62, 11, 23, 50, 54, 36, 47, 32, 61, 22, 35, 46, 60, 45, 44, 43,
91 return kTab[((n & (~n + 1)) * kSeq) >> 58];
97 if (n & 0x00000000FFFFFFFFLL) {
102 if (n & 0x000000000000FFFFLL) {
107 if (n & 0x00000000000000FFLL) {
112 if (n & 0x000000000000000FLL) {
117 if (n & 0x0000000000000003LL) {
122 if (n & 0x0000000000000001LL) {
130 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
131 return LeastSignificantBitPosition64Fast(n);
132 #elif defined(USE_DEBRUIJN)
139 #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
140 inline int LeastSignificantBitPosition32Fast(uint32_t n) {
141 return __builtin_ctzl(n);
146 static const uint32_t kSeq = 0x077CB531U;
147 static const int kTab[32] = {
148 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20,
149 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19,
150 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
151 return kTab[((n & (~n + 1)) * kSeq) >> 27];
157 if (n & 0x0000FFFFL) {
162 if (n & 0x000000FFL) {
167 if (n & 0x0000000FL) {
172 if (n & 0x00000003L) {
177 if (n & 0x00000001L) {
185 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
186 return LeastSignificantBitPosition32Fast(n);
187 #elif defined(USE_DEBRUIJN)
195 #if USE_FAST_LEAST_SIGNIFICANT_BIT
196 inline int MostSignificantBitPosition64Fast(uint64_t n) {
199 const int offset = __builtin_clzll(1);
200 return n == 0 ? 0 : (offset - __builtin_clzll(n));
233 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
234 return MostSignificantBitPosition64Fast(n);
240 #if USE_FAST_LEAST_SIGNIFICANT_BIT
241 inline int MostSignificantBitPosition32Fast(uint32_t n) {
245 const int offset = __builtin_clzl(1);
246 return n == 0 ? 0 : (offset - __builtin_clzl(n));
275 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
276 return MostSignificantBitPosition32Fast(n);
283 #undef USE_FAST_LEAST_SIGNIFICANT_BIT
331 inline uint32_t
BitPos64(uint64_t pos) {
return (pos & 63); }
332 inline uint32_t
BitPos32(uint32_t pos) {
return (pos & 31); }
339 inline uint64_t
BitLength64(uint64_t size) {
return ((size + 63) >> 6); }
340 inline uint32_t
BitLength32(uint32_t size) {
return ((size + 31) >> 5); }
347 inline bool IsBitSet64(
const uint64_t*
const bitset, uint64_t pos) {
350 inline bool IsBitSet32(
const uint32_t*
const bitset, uint32_t pos) {
355 inline void SetBit64(uint64_t*
const bitset, uint64_t pos) {
358 inline void SetBit32(uint32_t*
const bitset, uint32_t pos) {
363 inline void ClearBit64(uint64_t*
const bitset, uint64_t pos) {
366 inline void ClearBit32(uint32_t*
const bitset, uint32_t pos) {
406 return uint64_t{3} << (pos & 62);
414 template <
typename IndexType =
int64_t>
427 const uint64_t*
data()
const {
return data_; }
430 const uint64_t*
const data_;
435 : size_(Value(
size) > 0 ?
size : IndexType(0)),
441 IndexType
size()
const {
return size_; }
453 DCHECK_GE(Value(
size), 0);
454 size_ = Value(
size) > 0 ?
size : IndexType(0);
460 DCHECK_GE(Value(
size), 0);
461 size_ = Value(
size) > 0 ?
size : IndexType(0);
466 const size_t bit_length =
static_cast<size_t>(
BitLength64(Value(size_)));
467 const size_t to_clear =
std::min(data_.size(), bit_length);
468 data_.resize(bit_length, 0);
469 memset(data_.data(), 0, to_clear *
sizeof(int64_t));
473 void ClearAll() { memset(data_.data(), 0, data_.size() *
sizeof(int64_t)); }
477 DCHECK_GE(Value(i), 0);
478 DCHECK_LT(Value(i), Value(size_));
484 DCHECK_GE(Value(i), 0);
485 DCHECK_LT(Value(i), Value(size_));
491 DCHECK_GE(Value(i), 0);
492 DCHECK_LT(Value(i), Value(size_));
498 DCHECK_GE(Value(i), 0);
499 DCHECK_LT(Value(i), Value(size_));
505 DCHECK_GE(Value(i), 0);
506 DCHECK_LT(Value(i), Value(size_));
515 DCHECK_GE(Value(i), 0);
516 DCHECK_LT(Value(i), size_);
532 data_[offset] = other.data_[offset];
538 template <
typename OtherIndexType>
540 const int64_t min_size =
std::min(data_.size(), other.data_.size());
541 if (min_size == 0)
return;
542 const uint64_t last_common_bucket = data_[min_size - 1];
543 memcpy(data_.data(), other.data_.data(), min_size *
sizeof(uint64_t));
544 if (data_.size() >= other.data_.size()) {
547 data_[min_size - 1] &= ~bitmask;
548 data_[min_size - 1] |= (bitmask & last_common_bucket);
553 template <
typename OtherIndexType>
555 DCHECK_EQ(Value(
size()), other.Value(other.
size()));
556 memcpy(data_.data(), other.data_.data(), data_.size() *
sizeof(uint64_t));
563 const int min_size =
std::min(data_.size(), other.data_.size());
564 for (
int i = 0; i < min_size; ++i) {
565 data_[i] &= other.data_[i];
567 for (
int i = min_size; i < data_.size(); ++i) {
576 const int min_size =
std::min(data_.size(), other.data_.size());
577 for (
int i = 0; i < min_size; ++i) {
578 data_[i] |= other.data_[i];
590 : data_(bitset.data_.data()), size_(bitset.data_.
size()) {
591 if (!bitset.data_.empty()) {
599 IndexType
operator*()
const {
return IndexType(index_); }
603 while (current_ == 0) {
605 if (bucket == size_) {
609 current_ = data_[bucket];
614 current_ &= current_ - 1;
618 const uint64_t*
const data_;
621 uint64_t current_ = 0;
635 DCHECK(use1 == 0 || use1 == 1);
636 DCHECK(use2 == 0 || use2 == 1);
639 return ((use1 << pos) & set1.data_[bucket]) ^
640 ((use2 << pos) & set2.data_[bucket]);
646 for (IndexType i(0); i <
size(); ++i) {
647 output +=
IsSet(i) ?
"1" :
"0";
655 static int Value(IndexType
input);
658 std::vector<uint64_t> data_;
660 template <
class OtherIndexType>
671 : size_(size), top_(-1), data_(
BitLength64(size), 0) {}
674 CHECK_GE(size, size_);
697 int bucket_index =
static_cast<int>(
BitOffset64(i));
699 for (--bucket_index; bucket_index >= 0; --bucket_index) {
705 int Top()
const {
return top_; }
710 int bucket_index =
static_cast<int>(
BitOffset64(top_));
713 if (bucket_index == 0) {
717 bucket = data_[--bucket_index];
723 top_ =
static_cast<int>(
BitShift64(bucket_index) +
730 std::vector<uint64_t> data_;
735 template <
typename IntType>
736 inline int Bitset64<IntType>::Value(IntType
input) {
737 DCHECK_GE(
input.value(), 0);
738 return input.value();
741 inline int Bitset64<int>::Value(
int input) {
746 inline int Bitset64<int64_t>::Value(int64_t
input) {
753 template <
typename IntegerType =
int64_t>
758 IntegerType
size()
const {
return bitset_.size(); }
760 for (
const IntegerType i : to_clear_) bitset_.ClearBucket(i);
769 const int kSparseThreshold = 300;
770 if (to_clear_.size() * kSparseThreshold < size) {
772 bitset_.Resize(size);
774 bitset_.ClearAndResize(size);
779 if (size < bitset_.size()) {
781 for (IntegerType
index : to_clear_) {
783 to_clear_[new_index] =
index;
787 to_clear_.resize(new_index);
789 bitset_.Resize(size);
793 if (!bitset_[
index]) {
795 to_clear_.push_back(
index);
800 to_clear_.push_back(
index);
804 return to_clear_.size();
818 for (IntegerType
index : to_clear_) CHECK(!bitset_[
index]);
824 return bitset_.const_view();
829 std::vector<IntegerType> to_clear_;
void IncreaseSize(int size)
void ClearAndResize(int size)
const uint64_t * data() const
bool operator[](IndexType i) const
ConstView(const Bitset64 *bitset)
Iterator(const Bitset64 &bitset)
IndexType operator*() const
bool operator!=(const EndIterator &) 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)
ConstView const_view() const
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)
void SetUnsafe(IntegerType index)
Bitset64< IntegerType >::ConstView const_view() const
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)
std::optional< int64_t > end