16#ifndef OR_TOOLS_UTIL_BITSET_H_
17#define OR_TOOLS_UTIL_BITSET_H_
33static const uint64_t
kAllBits64 = uint64_t{0xFFFFFFFFFFFFFFFF};
38inline uint64_t
OneBit64(
int pos) {
return uint64_t{1} << pos; }
39inline 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)
76inline 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)
139inline 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
195inline 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
240inline 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
330inline uint32_t
BitPos64(uint64_t pos) {
return (pos & 63); }
331inline uint32_t
BitPos32(uint32_t pos) {
return (pos & 31); }
338inline uint64_t
BitLength64(uint64_t size) {
return ((size + 63) >> 6); }
339inline uint32_t
BitLength32(uint32_t size) {
return ((size + 31) >> 5); }
346inline bool IsBitSet64(
const uint64_t*
const bitset, uint64_t pos) {
349inline bool IsBitSet32(
const uint32_t*
const bitset, uint32_t pos) {
354inline void SetBit64(uint64_t*
const bitset, uint64_t pos) {
357inline void SetBit32(uint32_t*
const bitset, uint32_t pos) {
362inline void ClearBit64(uint64_t*
const bitset, uint64_t pos) {
365inline void ClearBit32(uint32_t*
const bitset, uint32_t pos) {
405 return uint64_t{3} << (pos & 62);
413template <
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)); }
474 data_[
BitOffset64(Value(i))] &= ~TwoBitsFromPos64(Value(i));
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 int 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_));
728 uint64_t bucket = data_[bucket_index] &= ~OneBit64(
BitPos64(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_;
752template <
typename IntType>
753inline int Bitset64<IntType>::Value(IntType
input) {
755 return input.value();
758inline int Bitset64<int>::Value(
int input) {
770template <
typename IntegerType =
int64_t>
775 IntegerType
size()
const {
return bitset_.size(); }
777 for (
const IntegerType i : to_clear_) bitset_.ClearBucket(i);
786 const int kSparseThreshold = 300;
787 if (to_clear_.size() * kSparseThreshold < size) {
789 bitset_.Resize(size);
791 bitset_.ClearAndResize(size);
796 if (size < bitset_.size()) {
798 for (IntegerType
index : to_clear_) {
800 to_clear_[new_index] =
index;
804 to_clear_.resize(new_index);
806 bitset_.Resize(size);
810 if (!bitset_[
index]) {
812 to_clear_.push_back(
index);
817 return to_clear_.size();
838 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)
void Set(IntegerType index)
const std::vector< IntegerType > & PositionsSetAtLeastOnce() 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)
std::function< int64_t(const Model &)> Value(IntegerVariable v)
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