16#ifndef OR_TOOLS_UTIL_BITSET_H_
17#define OR_TOOLS_UTIL_BITSET_H_
29#include "absl/log/check.h"
37static const uint64_t
kAllBits64 = uint64_t{0xFFFFFFFFFFFFFFFF};
42inline uint64_t
OneBit64(
int pos) {
return uint64_t{1} << pos; }
43inline uint32_t
OneBit32(
int pos) {
return 1U << pos; }
47 const uint64_t m1 = uint64_t{0x5555555555555555};
48 const uint64_t m2 = uint64_t{0x3333333333333333};
49 const uint64_t m4 = uint64_t{0x0F0F0F0F0F0F0F0F};
50 const uint64_t h01 = uint64_t{0x0101010101010101};
52 n = (n & m2) + ((n >> 2) & m2);
53 n = (n + (n >> 4)) & m4;
58 n -= (n >> 1) & 0x55555555UL;
59 n = (n & 0x33333333) + ((n >> 2) & 0x33333333UL);
60 n = (n + (n >> 4)) & 0x0F0F0F0FUL;
63 return n & 0x0000003FUL;
74#define USE_DEBRUIJN true
75#if defined(__GNUC__) || defined(__llvm__)
76#define USE_FAST_LEAST_SIGNIFICANT_BIT true
79#if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
80inline int LeastSignificantBitPosition64Fast(uint64_t n) {
81 return __builtin_ctzll(n);
86 static const uint64_t kSeq = uint64_t{0x0218a392dd5fb34f};
87 static const int kTab[64] = {
89 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 52, 20, 58,
90 5, 17, 26, 56, 15, 38, 29, 40, 10, 49, 53, 31, 21, 34, 59, 42,
91 63, 6, 12, 18, 24, 27, 51, 57, 16, 55, 37, 39, 48, 30, 33, 41,
92 62, 11, 23, 50, 54, 36, 47, 32, 61, 22, 35, 46, 60, 45, 44, 43,
94 return kTab[((n & (~n + 1)) * kSeq) >> 58];
100 if (n & 0x00000000FFFFFFFFLL) {
105 if (n & 0x000000000000FFFFLL) {
110 if (n & 0x00000000000000FFLL) {
115 if (n & 0x000000000000000FLL) {
120 if (n & 0x0000000000000003LL) {
125 if (n & 0x0000000000000001LL) {
133#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
134 return LeastSignificantBitPosition64Fast(n);
135#elif defined(USE_DEBRUIJN)
142#if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
143inline int LeastSignificantBitPosition32Fast(uint32_t n) {
144 return __builtin_ctzl(n);
149 static const uint32_t kSeq = 0x077CB531U;
150 static const int kTab[32] = {
151 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20,
152 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19,
153 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
154 return kTab[((n & (~n + 1)) * kSeq) >> 27];
160 if (n & 0x0000FFFFL) {
165 if (n & 0x000000FFL) {
170 if (n & 0x0000000FL) {
175 if (n & 0x00000003L) {
180 if (n & 0x00000001L) {
188#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
189 return LeastSignificantBitPosition32Fast(n);
190#elif defined(USE_DEBRUIJN)
198#if USE_FAST_LEAST_SIGNIFICANT_BIT
199inline int MostSignificantBitPosition64Fast(uint64_t n) {
202 const int offset = __builtin_clzll(1);
203 return n == 0 ? 0 : (offset - __builtin_clzll(n));
236#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
237 return MostSignificantBitPosition64Fast(n);
243#if USE_FAST_LEAST_SIGNIFICANT_BIT
244inline int MostSignificantBitPosition32Fast(uint32_t n) {
248 const int offset = __builtin_clzl(1);
249 return n == 0 ? 0 : (offset - __builtin_clzl(n));
278#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
279 return MostSignificantBitPosition32Fast(n);
286#undef USE_FAST_LEAST_SIGNIFICANT_BIT
334inline uint32_t
BitPos64(uint64_t pos) {
return (pos & 63); }
335inline uint32_t
BitPos32(uint32_t pos) {
return (pos & 31); }
342inline uint64_t
BitLength64(uint64_t size) {
return ((size + 63) >> 6); }
343inline uint32_t
BitLength32(uint32_t size) {
return ((size + 31) >> 5); }
350inline bool IsBitSet64(
const uint64_t*
const bitset, uint64_t pos) {
353inline bool IsBitSet32(
const uint32_t*
const bitset, uint32_t pos) {
358inline void SetBit64(uint64_t*
const bitset, uint64_t pos) {
361inline void SetBit32(uint32_t*
const bitset, uint32_t pos) {
366inline void ClearBit64(uint64_t*
const bitset, uint64_t pos) {
369inline void ClearBit32(uint32_t*
const bitset, uint32_t pos) {
396 uint64_t start, uint64_t end);
398 uint32_t start, uint32_t end);
401 uint64_t start, uint64_t end);
403 uint32_t start, uint32_t end);
407 return uint64_t{3} << (pos & 62);
415template <
typename IndexType =
int64_t>
429 const uint64_t*
data()
const {
return data_; }
432 const uint64_t*
const data_;
452 uint64_t*
const data_;
457 : size_(Value(
size) > 0 ?
size : IndexType(0)),
461 View
view() {
return View(
this); }
464 IndexType
size()
const {
return size_; }
470 Set(size_ - 1, value);
476 DCHECK_GE(Value(
size), 0);
477 IndexType new_size = Value(
size) > 0 ?
size : IndexType(0);
478 if (new_size < size_ && Value(new_size) > 0) {
479 const int64_t new_data_size =
BitLength64(Value(new_size));
482 data_[new_data_size - 1] &= ~bitmask;
490 DCHECK_GE(Value(
size), 0);
491 size_ = Value(
size) > 0 ?
size : IndexType(0);
496 const size_t bit_length =
static_cast<size_t>(
BitLength64(Value(size_)));
497 const size_t to_clear = std::min(data_.size(), bit_length);
498 data_.resize(bit_length, 0);
499 memset(data_.data(), 0, to_clear *
sizeof(int64_t));
503 void ClearAll() { memset(data_.data(), 0, data_.size() *
sizeof(int64_t)); }
507 DCHECK_GE(Value(i), 0);
508 DCHECK_LT(Value(i), Value(size_));
514 DCHECK_GE(Value(i), 0);
515 DCHECK_LT(Value(i), Value(size_));
521 DCHECK_GE(Value(i), 0);
522 DCHECK_LT(Value(i), Value(size_));
528 DCHECK_GE(Value(i), 0);
529 DCHECK_LT(Value(i), Value(size_));
535 DCHECK_GE(Value(i), 0);
536 DCHECK_LT(Value(i), Value(size_));
545 DCHECK_GE(Value(i), 0);
546 DCHECK_LT(Value(i), size_);
552 void Set(IndexType i,
bool value) {
563 data_[offset] = other.data_[offset];
569 template <
typename OtherIndexType>
571 const int64_t min_size = std::min(data_.size(), other.data_.size());
572 if (min_size == 0)
return;
573 const uint64_t last_common_bucket = data_[min_size - 1];
574 memcpy(data_.data(), other.data_.data(), min_size *
sizeof(uint64_t));
575 if (data_.size() >= other.data_.size()) {
578 data_[min_size - 1] &= ~bitmask;
579 data_[min_size - 1] |= (bitmask & last_common_bucket);
584 template <
typename OtherIndexType>
586 DCHECK_EQ(Value(
size()), other.Value(other.
size()));
587 memcpy(data_.data(), other.data_.data(), data_.size() *
sizeof(uint64_t));
594 const int min_size = std::min(data_.size(), other.data_.size());
595 uint64_t*
const d = data_.data();
596 const uint64_t*
const o = other.data_.data();
597 for (
int i = 0; i < min_size; ++i) {
600 for (
int i = min_size; i < data_.size(); ++i) {
608 DCHECK_EQ(a.
size(), b.size());
612 const int num_buckets = a.data_.size();
613 for (
int i = 0; i < num_buckets; ++i) {
614 data_[i] = a.data_[i] & b.data_[i];
622 const int min_size = std::min(data_.size(), other.data_.size());
623 for (
int i = 0; i < min_size; ++i) {
624 data_[i] |= other.data_[i];
648 : data_(bitset.data_.data()), size_(bitset.data_.
size()) {
649 if (!bitset.data_.empty()) {
656 return Iterator(bitset.data_.data());
661 if (other.size_ == 0) {
664 return std::tie(index_, current_) !=
665 std::tie(other.index_, other.current_);
668 IndexType
operator*()
const {
return IndexType(index_); }
678 while (current_ == 0) {
680 if (bucket == size_) {
684 current_ = data_[bucket];
689 current_ &= current_ - 1;
694 explicit Iterator(
const uint64_t* data) : data_(data), size_(0) {}
696 const uint64_t* data_;
699 uint64_t current_ = 0;
704 Iterator
begin()
const {
return Iterator(*
this); }
713 DCHECK(use1 == 0 || use1 == 1);
714 DCHECK(use2 == 0 || use2 == 1);
717 return ((use1 << pos) & set1.
data()[bucket]) ^
718 ((use2 << pos) & set2.
data()[bucket]);
724 for (IndexType i(0); i <
size(); ++i) {
725 output +=
IsSet(i) ?
"1" :
"0";
731 return std::all_of(data_.begin(), data_.end(),
732 [](uint64_t v) { return v == 0; });
738 static int Value(IndexType
input);
741 std::vector<uint64_t> data_;
743 template <
class OtherIndexType>
753 : size_(size), top_(-1), data_(
BitLength64(size), 0) {}
760 CHECK_GE(size, size_);
774 top_ = std::max(top_, i);
782 top_ = std::max(top_, i - 1);
783 int bucket_index =
static_cast<int>(
BitOffset64(i));
785 for (--bucket_index; bucket_index >= 0; --bucket_index) {
791 int Top()
const {
return top_; }
796 int bucket_index =
static_cast<int>(
BitOffset64(top_));
799 if (bucket_index == 0) {
803 bucket = data_[--bucket_index];
809 top_ =
static_cast<int>(
BitShift64(bucket_index) +
816 std::vector<uint64_t> data_;
820template <
typename IntType>
821inline int Bitset64<IntType>::Value(IntType
input) {
822 DCHECK_GE(
input.value(), 0);
823 return input.value();
826inline int Bitset64<int>::Value(
int input) {
831inline int Bitset64<int64_t>::Value(int64_t
input) {
836inline int Bitset64<size_t>::Value(
size_t input) {
842template <
typename IntegerType =
int64_t>
851 IntegerType
size()
const {
return bitset_.size(); }
853 for (
const IntegerType i : to_clear_) bitset_.ClearBucket(i);
862 const int kSparseThreshold = 300;
863 if (to_clear_.size() * kSparseThreshold <
size) {
865 bitset_.Resize(
size);
867 bitset_.ClearAndResize(
size);
872 if (
size < bitset_.size()) {
874 for (IntegerType index : to_clear_) {
876 to_clear_[new_index] = index;
880 to_clear_.resize(new_index);
882 bitset_.Resize(
size);
884 bool operator[](IntegerType index)
const {
return bitset_[index]; }
885 void Set(IntegerType index) {
886 if (!bitset_[index]) {
888 to_clear_.push_back(index);
896 to_clear_.push_back(index);
899 void Clear(IntegerType index) { bitset_.Clear(index); }
901 return to_clear_.size();
915 for (IntegerType index : to_clear_) CHECK(!bitset_[index]);
921 return bitset_.const_view();
926 std::vector<IntegerType> to_clear_;
int Top() const
Returns the position of the highest bit set in O(1) or -1 if no bit is set.
void ClearAndResize(int size)
void ClearTop()
Clears the Top() bit and recomputes the position of the next Top().
BitQueue64(const BitQueue64 &)=delete
This type is neither copyable nor movable.
void IncreaseSize(int size)
BitQueue64 & operator=(const BitQueue64 &)=delete
void SetAllBefore(int i)
Sets all the bits from 0 up to i-1 to 1.
When speed matter, caching the base pointer helps.
const uint64_t * data() const
bool operator[](IndexType i) const
ConstView(const Bitset64 *bitset)
Iterator(const Iterator &other)=default
bool operator==(const Iterator &other) const
bool operator!=(const Iterator &other) const
std::forward_iterator_tag iterator_category
Iterator(Iterator &&other)=default
Iterator & operator=(const Iterator &other)=default
std::ptrdiff_t difference_type
IndexType operator*() const
static Iterator EndIterator(const Bitset64 &bitset)
Iterator(const Bitset64 &bitset)
bool operator[](IndexType i) const
void CopyBucket(const Bitset64< IndexType > &other, IndexType i)
Copies bucket containing bit i from "other" to "this".
void ClearAll()
Sets all bits to 0.
void ClearBucket(IndexType i)
Sets bucket containing bit i to 0.
void SetContentFromBitset(const Bitset64< OtherIndexType > &other)
bool IsSet(IndexType i) const
Returns true if the bit at position i is set.
void Clear(IndexType i)
Sets the bit at position i to 0.
void Set(IndexType i, bool value)
If value is true, sets the bit at position i to 1, sets it to 0 otherwise.
void Union(const Bitset64< IndexType > &other)
void Intersection(const Bitset64< IndexType > &other)
void resize(int size)
Resizes the Bitset64 to the given number of bits. New bits are sets to 0.
std::string DebugString() const
Returns a 0/1 string representing the bitset.
static uint64_t ConditionalXorOfTwoBits(IndexType i, uint64_t use1, Bitset64< IndexType >::ConstView set1, uint64_t use2, Bitset64< IndexType >::ConstView set2)
void ClearTwoBits(IndexType i)
Clears the bits at position i and i ^ 1.
void Resize(IndexType size)
bool AreOneOfTwoBitsSet(IndexType i) const
Returns true if the bit at position i or the one at position i ^ 1 is set.
void SetToIntersectionOf(const Bitset64< IndexType > &a, const Bitset64< IndexType > &b)
This one assume both given bitset to be of the same size.
void ClearAndResize(IndexType size)
Changes the number of bits the Bitset64 can hold and set all of them to 0.
void PushBack(bool value)
Appends value at the end of the bitset.
bool operator[](IndexType i) const
Same as IsSet().
void SetContentFromBitsetOfSameSize(const Bitset64< OtherIndexType > &other)
Same as SetContentFromBitset where "this" and "other" have the same size.
ConstView const_view() const
void Set(IndexType i)
Sets the bit at position i to 1.
void ClearAndResize(IntegerType size)
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
void Clear(IntegerType index)
bool operator[](IntegerType index) const
SparseBitset & operator=(const SparseBitset &)=delete
Bitset64< IntegerType >::ConstView const_view() const
SparseBitset(IntegerType size)
void Set(IntegerType index)
Bitset64< IntegerType >::View BitsetView()
A bit hacky for really hot loop.
int NumberOfSetCallsWithDifferentArguments() const
SparseBitset(const SparseBitset &)=delete
This type is neither copyable nor movable.
void Resize(IntegerType size)
void SetUnsafe(typename Bitset64< IntegerType >::View view, IntegerType index)
In SWIG mode, we don't want anything besides these top-level includes.
uint32_t IntervalDown32(uint32_t s)
int64_t UnsafeMostSignificantBitPosition64(const uint64_t *bitset, uint64_t start, uint64_t end)
uint32_t BitCountRange32(const uint32_t *bitset, uint32_t start, uint32_t end)
int LeastSignificantBitPosition32Default(uint32_t n)
void SetBit32(uint32_t *const bitset, uint32_t pos)
int64_t UnsafeLeastSignificantBitPosition64(const uint64_t *bitset, uint64_t start, uint64_t end)
uint32_t BitLength32(uint32_t size)
static const uint32_t kAllBits32
bool IsEmptyRange32(const uint32_t *bitset, uint32_t start, uint32_t end)
uint32_t BitCount32(uint32_t n)
int32_t UnsafeLeastSignificantBitPosition32(const uint32_t *bitset, uint32_t start, uint32_t end)
int LeastSignificantBitPosition64DeBruijn(uint64_t n)
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)
Returns the bit number in the bitset of the first bit of word number v.
uint32_t BitOffset32(uint32_t pos)
uint32_t LeastSignificantBitWord32(uint32_t n)
uint64_t IntervalDown64(uint64_t s)
Returns a word with the s most significant bits unset.
uint32_t IntervalUp32(uint32_t s)
void ClearBit32(uint32_t *const bitset, uint32_t pos)
static const uint64_t kAllBits64
Basic bit operations.
int LeastSignificantBitPosition32DeBruijn(uint32_t n)
void ClearBit64(uint64_t *const bitset, uint64_t pos)
Sets the bit pos to false in bitset.
uint32_t OneBit32(int pos)
uint64_t OneRange64(uint64_t s, uint64_t e)
Returns a word with bits from s to e set.
static const uint64_t kAllBitsButLsb64
uint32_t BitShift32(uint32_t v)
uint32_t BitPos64(uint64_t pos)
Bit operators used to manipulates bitsets.
uint64_t BitCountRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
Returns the number of bits set in bitset between positions start and end.
uint64_t BitCount64(uint64_t n)
Returns the number of bits set in n.
int MostSignificantBitPosition32(uint32_t n)
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
Returns true if the bit pos is set in bitset.
uint64_t OneBit64(int pos)
Returns a word with only bit pos set.
uint32_t OneRange32(uint32_t s, uint32_t e)
uint64_t BitOffset64(uint64_t pos)
Returns the word number corresponding to bit number pos.
bool IsEmptyRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
Returns true if no bits are set in bitset between start and end.
uint64_t BitLength64(uint64_t size)
Returns the number of words needed to store size bits.
int LeastSignificantBitPosition64(uint64_t n)
int32_t UnsafeMostSignificantBitPosition32(const uint32_t *bitset, uint32_t start, uint32_t end)
int MostSignificantBitPosition64Default(uint64_t n)
Returns the most significant bit position in n.
int LeastSignificantBitPosition32(uint32_t n)
void SetBit64(uint64_t *const bitset, uint64_t pos)
Sets the bit pos to true in bitset.
uint64_t LeastSignificantBitWord64(uint64_t n)
Returns a word with only the least significant bit of n set.
uint64_t TwoBitsFromPos64(uint64_t pos)
Returns a mask with the bits pos % 64 and (pos ^ 1) % 64 sets.
int MostSignificantBitPosition64(uint64_t n)
uint64_t IntervalUp64(uint64_t s)
Returns a word with s least significant bits unset.
static int input(yyscan_t yyscanner)