5 #ifndef BITCOIN_UTIL_BITSET_H 6 #define BITCOIN_UTIL_BITSET_H 14 #include <type_traits> 40 static_assert(std::is_integral_v<I> && std::is_unsigned_v<I> && std::numeric_limits<I>::radix == 2);
41 constexpr
auto BITS = std::numeric_limits<I>::digits;
44 if constexpr (BITS <= 32) {
45 v -= (v >> 1) & 0x55555555;
46 v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
47 v = (v + (v >> 4)) & 0x0f0f0f0f;
48 if constexpr (BITS > 8) v += v >> 8;
49 if constexpr (BITS > 16) v += v >> 16;
52 static_assert(BITS <= 64);
53 v -= (v >> 1) & 0x5555555555555555;
54 v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333);
55 v = (v + (v >> 4)) & 0x0f0f0f0f0f0f0f0f;
56 return (v * uint64_t{0x0101010101010101}) >> 56;
65 static_assert(std::is_integral_v<I> && std::is_unsigned_v<I> && std::numeric_limits<I>::radix == 2);
67 static constexpr
unsigned MAX_SIZE = std::numeric_limits<I>::digits;
125 for (
auto pos : ilist)
Set(pos);
133 for (
auto pos : ilist)
Set(pos);
151 constexpr
void Set(
unsigned pos) noexcept
154 m_val |= I{1U} << pos;
157 constexpr
void Set(
unsigned pos,
bool val) noexcept
160 m_val = (
m_val & ~I(I{1U} << pos)) | (I(val) << pos);
163 constexpr
void Reset(
unsigned pos) noexcept
166 m_val &= ~I(I{1U} << pos);
172 return (
m_val >> pos) & 1U;
179 constexpr
bool None() const noexcept {
return m_val == 0; }
181 constexpr
bool Any() const noexcept {
return !
None(); }
187 constexpr
unsigned First() const noexcept
190 return std::countr_zero(
m_val);
193 constexpr
unsigned Last() const noexcept
196 return std::bit_width(
m_val) - 1;
227 template<
typename I,
unsigned N>
231 static_assert(std::is_integral_v<I> && std::is_unsigned_v<I> && std::numeric_limits<I>::radix == 2);
233 static_assert(N > 0);
235 static constexpr
unsigned LIMB_BITS = std::numeric_limits<I>::digits;
241 std::array<I, N>
m_val;
289 if (
m_idx == N)
break;
317 void constexpr
Set(
unsigned pos) noexcept
323 void constexpr
Set(
unsigned pos,
bool val) noexcept
332 for (
auto pos : ilist)
Set(pos);
338 for (
auto pos : ilist)
Set(pos);
342 void constexpr
Reset(
unsigned pos) noexcept
369 ret.m_val[i++] = I(~I{0});
379 unsigned constexpr
Count() const noexcept
386 bool constexpr
None() const noexcept
388 for (
auto v :
m_val) {
389 if (v != 0)
return false;
394 bool constexpr
Any() const noexcept {
return !
None(); }
400 unsigned constexpr
First() const noexcept
403 while (
m_val[p] == 0) {
410 unsigned constexpr
Last() const noexcept
413 while (
m_val[p] == 0) {
422 for (
unsigned i = 0; i < N; ++i) {
423 m_val[i] |= a.m_val[i];
430 for (
unsigned i = 0; i < N; ++i) {
431 m_val[i] &= a.m_val[i];
438 for (
unsigned i = 0; i < N; ++i) {
439 m_val[i] &= ~a.m_val[i];
446 for (
unsigned i = 0; i < N; ++i) {
447 m_val[i] ^= a.m_val[i];
454 for (
unsigned i = 0; i < N; ++i) {
455 if (
m_val[i] & a.m_val[i])
return true;
463 for (
unsigned i = 0; i < N; ++i) {
464 r.
m_val[i] = a.m_val[i] & b.m_val[i];
472 for (
unsigned i = 0; i < N; ++i) {
473 r.
m_val[i] = a.m_val[i] | b.m_val[i];
481 for (
unsigned i = 0; i < N; ++i) {
482 r.
m_val[i] = a.m_val[i] & ~b.m_val[i];
490 for (
unsigned i = 0; i < N; ++i) {
491 r.
m_val[i] = a.m_val[i] ^ b.m_val[i];
498 for (
unsigned i = 0; i < N; ++i) {
499 if (a.m_val[i] & ~
m_val[i])
return false;
506 for (
unsigned i = 0; i < N; ++i) {
507 if (
m_val[i] & ~a.m_val[i])
return false;
522 template<
unsigned BITS>
523 using BitSet = std::conditional_t<(BITS <= 32), bitset_detail::IntBitSet<uint32_t>,
527 #endif // BITCOIN_UTIL_BITSET_H constexpr IntBitSet & operator=(const IntBitSet &) noexcept=default
Copy assign a bitset.
static constexpr MultiIntBitSet Singleton(unsigned pos) noexcept
Construct a bitset with the singleton pos.
constexpr MultiIntBitSet & operator &=(const MultiIntBitSet &a) noexcept
Set this object's bits to be the binary AND between respective bits from this and a...
friend constexpr bool operator==(const IntBitSet &a, const IntBitSet &b) noexcept=default
Check if bitset a and bitset b are identical.
Iterator constexpr begin() const noexcept
Return an object that iterates over all 1 bits (++ and * only allowed when != end()).
constexpr IntBitSet() noexcept
Construct an all-zero bitset.
Iterator()=delete
Do not allow external code to construct an Iterator.
void constexpr Set(unsigned pos, bool val) noexcept
Set a bit to the specified value.
unsigned constexpr First() const noexcept
Find the first element (requires Any()).
constexpr bool None() const noexcept
Check if all bits are 0.
constexpr bool Overlaps(const IntBitSet &a) const noexcept
Check if the intersection between two sets is non-empty.
bool constexpr Any() const noexcept
Check if any bits are 1.
friend constexpr void swap(MultiIntBitSet &a, MultiIntBitSet &b) noexcept
Swap two bitsets.
constexpr bool operator[](unsigned pos) const noexcept
Retrieve a bit at the given position.
constexpr MultiIntBitSet & operator^=(const MultiIntBitSet &a) noexcept
Set this object's bits to be the binary XOR between respective bits from this and a...
void constexpr Set(unsigned pos) noexcept
Set a bit to 1.
unsigned constexpr Last() const noexcept
Find the last element (requires Any()).
constexpr void Set(unsigned pos) noexcept
Set a bit to 1.
constexpr MultiIntBitSet() noexcept
Construct an all-zero bitset.
friend constexpr MultiIntBitSet operator &(const MultiIntBitSet &a, const MultiIntBitSet &b) noexcept
Return an object with the binary AND between respective bits from a and b.
friend constexpr IntBitSet operator-(const IntBitSet &a, const IntBitSet &b) noexcept
Return an object with the binary AND NOT between respective bits from a and b.
static constexpr IntBitSet Singleton(unsigned i) noexcept
Construct a bitset with the singleton i.
Iterator type returned by begin(), which efficiently iterates all 1 positions.
const std::array< I, N > * m_ptr
Pointer to array to fetch bits from.
constexpr IteratorEnd()=default
constexpr unsigned operator*() const noexcept
Get the current bit position (only if != IteratorEnd).
constexpr unsigned First() const noexcept
Find the first element (requires Any()).
constexpr Iterator & operator++() noexcept
Progress to the next 1 bit (only if != IteratorEnd).
constexpr IntBitSet(std::initializer_list< unsigned > ilist) noexcept
Construct from a list of values.
A bitset implementation backed by N integers of type I.
I m_val
Integer whose bits represent this bitset.
constexpr unsigned Count() const noexcept
Compute the number of 1 bits in the bitset.
unsigned m_pos
The last reported position.
unsigned constexpr PopCount(I v)
Count the number of bits set in an unsigned integer type.
Dummy type to return using end().
constexpr IntBitSet & operator-=(const IntBitSet &a) noexcept
Set this object's bits to be the binary AND NOT between respective bits from this and a...
friend constexpr MultiIntBitSet operator^(const MultiIntBitSet &a, const MultiIntBitSet &b) noexcept
Return an object with the binary XOR between respective bits from a and b.
constexpr void Reset(unsigned pos) noexcept
Set a bit to 0.
static constexpr MultiIntBitSet Fill(unsigned count) noexcept
Construct a bitset with bits 0..count-1 (inclusive) set to 1.
constexpr void Set(unsigned pos, bool val) noexcept
Set a bit to the specified value.
friend constexpr IntBitSet operator^(const IntBitSet &a, const IntBitSet &b) noexcept
Return an object with the binary XOR between respective bits from a and b.
constexpr bool IsSupersetOf(const MultiIntBitSet &a) const noexcept
Check if bitset a is a superset of bitset b (= every 1 bit in b is also in a).
static constexpr unsigned Size() noexcept
Return the number of bits that this object holds.
constexpr bool Any() const noexcept
Check if any bits are 1.
std::array< I, N > m_val
Array whose member integers store the bits of the set.
constexpr MultiIntBitSet(std::initializer_list< unsigned > ilist) noexcept
Construct a bitset from a list of values.
constexpr friend bool operator==(const Iterator &a, const IteratorEnd &) noexcept
Test whether we are done (can only compare with IteratorEnd).
constexpr IteratorEnd end() const noexcept
Return a dummy object to compare Iterators with.
constexpr MultiIntBitSet & operator-=(const MultiIntBitSet &a) noexcept
Set this object's bits to be the binary AND NOT between respective bits from this and a...
static constexpr unsigned MAX_SIZE
The maximum number of bits this bitset supports.
constexpr Iterator(const std::array< I, N > &ref) noexcept
friend constexpr IntBitSet operator &(const IntBitSet &a, const IntBitSet &b) noexcept
Return an object with the binary AND between respective bits from a and b.
constexpr IteratorEnd()=default
friend constexpr bool operator==(const Iterator &a, const IteratorEnd &) noexcept
Test whether we are done (can only compare with IteratorEnd).
IteratorEnd constexpr end() const noexcept
Return a dummy object to compare Iterators with.
constexpr IntBitSet & operator|=(const IntBitSet &a) noexcept
Set this object's bits to be the binary AND between respective bits from this and a...
constexpr MultiIntBitSet & operator=(std::initializer_list< unsigned > ilist) noexcept
Set a bitset to a list of values.
constexpr IntBitSet & operator=(std::initializer_list< unsigned > ilist) noexcept
Assign from a list of positions (which will be made true, all others false).
I m_val
The original integer's remaining bits.
static constexpr IntBitSet Fill(unsigned count) noexcept
Construct a bitset with bits 0..count-1 (inclusive) set to 1.
friend constexpr MultiIntBitSet operator|(const MultiIntBitSet &a, const MultiIntBitSet &b) noexcept
Return an object with the binary OR between respective bits from a and b.
constexpr MultiIntBitSet & operator=(const MultiIntBitSet &) noexcept=default
Copy assign a bitset.
unsigned constexpr Count() const noexcept
Compute the number of 1 bits in the bitset.
friend constexpr MultiIntBitSet operator-(const MultiIntBitSet &a, const MultiIntBitSet &b) noexcept
Return an object with the binary AND NOT between respective bits from a and b.
IntBitSet(I val) noexcept
Internal constructor with a given integer as contents.
#define Assume(val)
Assume is the identity function.
constexpr unsigned Last() const noexcept
Find the last element (requires Any()).
friend constexpr IntBitSet operator|(const IntBitSet &a, const IntBitSet &b) noexcept
Return an object with the binary OR between respective bits from a and b.
I m_val
The remaining bits of (*m_ptr)[m_idx].
std::conditional_t<(BITS<=32), bitset_detail::IntBitSet< uint32_t >, std::conditional_t<(BITS<=std::numeric_limits< size_t >::digits), bitset_detail::IntBitSet< size_t >, bitset_detail::MultiIntBitSet< size_t,(BITS+std::numeric_limits< size_t >::digits - 1)/std::numeric_limits< size_t >::digits > >> BitSet
constexpr IntBitSet & operator^=(const IntBitSet &a) noexcept
Set this object's bits to be the binary XOR between respective bits from this as a.
constexpr bool IsSubsetOf(const IntBitSet &a) const noexcept
Check if bitset a is a subset of bitset b (= every 1 bit in a is also in b).
constexpr MultiIntBitSet & operator|=(const MultiIntBitSet &a) noexcept
Set this object's bits to be the binary OR between respective bits from this and a.
constexpr Iterator(I val) noexcept
Last reported 1 position (if m_pos != 0).
Dummy type to return using end().
bool constexpr None() const noexcept
Check if all bits are 0.
constexpr bool Overlaps(const MultiIntBitSet &a) const noexcept
Check whether the intersection between two sets is non-empty.
constexpr Iterator begin() const noexcept
Return an object that iterates over all 1 bits (++ and * only allowed when != end()).
constexpr unsigned operator*() const noexcept
Get the current bit position (only if != IteratorEnd).
constexpr bool IsSupersetOf(const IntBitSet &a) const noexcept
Check if bitset a is a superset of bitset b (= every 1 bit in b is also in a).
constexpr Iterator & operator++() noexcept
Progress to the next 1 bit (only if != IteratorEnd).
static constexpr unsigned MAX_SIZE
Number of elements this set type supports.
static constexpr unsigned Size() noexcept
Return the number of bits that this object holds.
constexpr Iterator & operator=(const Iterator &) noexcept=default
constexpr Iterator & operator=(const Iterator &) noexcept=default
constexpr bool IsSubsetOf(const MultiIntBitSet &a) const noexcept
Check if bitset a is a subset of bitset b (= every 1 bit in a is also in b).
A bitset implementation backed by a single integer of type I.
void constexpr Reset(unsigned pos) noexcept
Set a bit to 0.
static constexpr unsigned LIMB_BITS
The number of bits per integer.
unsigned m_idx
The index in *m_ptr currently being iterated over.
constexpr IntBitSet & operator &=(const IntBitSet &a) noexcept
Set this object's bits to be the binary OR between respective bits from this and a.
friend constexpr void swap(IntBitSet &a, IntBitSet &b) noexcept
Swap two bitsets.
Iterator type returned by begin(), which efficiently iterates all 1 positions.
friend constexpr bool operator==(const MultiIntBitSet &a, const MultiIntBitSet &b) noexcept=default
Check if bitset a and bitset b are identical.
Iterator()=delete
Do not allow external code to construct an Iterator.
bool constexpr operator[](unsigned pos) const noexcept
Retrieve a bit at the given position.