21 uint64_t mask = 1_u64 << index();
28 operator bool()
const {
return word() & (1_u64 << index()); }
31 const uint64_t& word()
const {
return *word_; }
32 uint64_t& word() {
return *word_; }
33 uint64_t index()
const {
return index_; }
48 ensure_capacity(other.num_bits() - 1);
49 std::copy_n(other.words(), other.num_words(), words());
62 bool test(
size_t i)
const {
63 if ((i / 64_s) >= num_words())
return false;
64 return *(words() + i / 64_s) & (1_u64 << i % 64_u64);
68 BitSet&
set (
size_t i) { ensure_capacity(i); *(words() + i/64_s) |= (1_u64 << i%64_u64);
return *
this; }
69 BitSet&
toggle(
size_t i) { ensure_capacity(i); *(words() + i/64_s) ^= (1_u64 << i%64_u64);
return *
this; }
70 BitSet&
clear (
size_t i) { ensure_capacity(i); *(words() + i/64_s) &= ~(1_u64 << i%64_u64);
return *
this; }
81 return reference(words() + i / 64_s, i % 64_u64);
96 bool any_range(
const size_t begin,
const size_t end)
const;
139 size_t count()
const;
144 swap(b1.num_words_, b2.num_words_);
145 swap(b1.words_, b2.words_);
146 swap(b1.padding, b2.padding);
151 void ensure_capacity(
size_t num_bits)
const;
152 template<
class F>
BitSet& op_assign(
const BitSet& other) {
153 if (this->num_words() < other.num_words()) this->ensure_capacity(other.num_bits() - 1);
154 auto this_words = this->words();
155 auto other_words = other.words();
156 for (
size_t i = 0, e = other.num_words(); i != e; ++i) this_words[i] = F()(this_words[i], other_words[i]);
160 void dealloc()
const;
161 const uint64_t* words()
const {
return num_words_ == 1 ? &word_ : words_; }
162 uint64_t* words() {
return num_words_ == 1 ? &word_ : words_; }
163 size_t num_words()
const {
return num_words_; }
164 size_t num_bits()
const {
return num_words_ * 64_s; }
167 mutable uint64_t* words_;
170 mutable uint32_t num_words_;
176static_assert(
sizeof(
BitSet) == 16);
reference operator=(bool b) noexcept
void friend swap(BitSet &b1, BitSet &b2) noexcept
BitSet & operator>>=(uint64_t shift)
bool any_end(const size_t end) const
Is any bit in [0, end[ set?
bool none_range(const size_t begin, const size_t end) const
BitSet operator^(BitSet b) const
BitSet & toggle(size_t i)
BitSet operator&(BitSet b) const
bool any_begin(const size_t begin) const
Is any bit in [begin, ∞[ set?
BitSet operator|(BitSet b) const
BitSet(BitSet &&other) noexcept
bool none_end(const size_t end) const
Is no bit in [0, end[ set?
bool operator[](size_t i) const
BitSet & operator|=(const BitSet &other)
bool test(size_t i) const
bool operator==(const BitSet &) const
void clear()
clears all bits
BitSet operator>>(uint64_t shift) const
uint32_t padding
Unused; do whatever you want with this.
BitSet & operator=(BitSet other) noexcept
reference operator[](size_t i)
bool none_begin(const size_t begin) const
Is no bit in [begin, ∞[ set?
bool any_range(const size_t begin, const size_t end) const
bool operator!=(const BitSet &other) const
BitSet(const BitSet &other)
BitSet & operator^=(const BitSet &other)
size_t count() const
number of bits set
BitSet & operator&=(const BitSet &other)