Bitcoin Core  29.1.0
P2P Digital Currency
bitset.h
Go to the documentation of this file.
1 // Copyright (c) The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_UTIL_BITSET_H
6 #define BITCOIN_UTIL_BITSET_H
7 
8 #include <util/check.h>
9 
10 #include <array>
11 #include <bit>
12 #include <cstdint>
13 #include <limits>
14 #include <type_traits>
15 
16 /* This file provides data types similar to std::bitset, but adds the following functionality:
17  *
18  * - Efficient iteration over all set bits (compatible with range-based for loops).
19  * - Efficient search for the first and last set bit (First() and Last()).
20  * - Efficient set subtraction: (a - b) implements "a and not b".
21  * - Efficient non-strict subset/superset testing: IsSubsetOf() and IsSupersetOf().
22  * - Efficient set overlap testing: a.Overlaps(b)
23  * - Efficient construction of set containing 0..N-1 (S::Fill).
24  * - Efficient construction of a single set (S::Singleton).
25  * - Construction from initializer lists.
26  *
27  * Other differences:
28  * - BitSet<N> is a bitset that supports at least N elements, but may support more (Size() reports
29  * the actual number). Because the actual number is unpredictable, there are no operations that
30  * affect all positions (like std::bitset's operator~, flip(), or all()).
31  * - Various other unimplemented features.
32  */
33 
34 namespace bitset_detail {
35 
37 template<typename I>
38 unsigned inline constexpr PopCount(I v)
39 {
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;
42  // Algorithms from https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation.
43  // These seem to be faster than std::popcount when compiling for non-SSE4 on x86_64.
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;
50  return v & 0x3f;
51  } else {
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;
57  }
58 }
59 
61 template<typename I>
62 class IntBitSet
63 {
64  // Only binary, unsigned, integer, types allowed.
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;
69  I m_val;
71  IntBitSet(I val) noexcept : m_val{val} {}
74  {
75  friend class IntBitSet;
76  constexpr IteratorEnd() = default;
77  public:
78  constexpr IteratorEnd(const IteratorEnd&) = default;
79  };
81  class Iterator
82  {
83  friend class IntBitSet;
84  I m_val;
85  unsigned m_pos;
86  constexpr Iterator(I val) noexcept : m_val(val), m_pos(0)
87  {
88  if (m_val != 0) m_pos = std::countr_zero(m_val);
89  }
90  public:
92  Iterator() = delete;
93  // Copying is allowed.
94  constexpr Iterator(const Iterator&) noexcept = default;
95  constexpr Iterator& operator=(const Iterator&) noexcept = default;
97  constexpr friend bool operator==(const Iterator& a, const IteratorEnd&) noexcept
98  {
99  return a.m_val == 0;
100  }
102  constexpr Iterator& operator++() noexcept
103  {
104  Assume(m_val != 0);
105  m_val &= m_val - I{1U};
106  if (m_val != 0) m_pos = std::countr_zero(m_val);
107  return *this;
108  }
110  constexpr unsigned operator*() const noexcept
111  {
112  Assume(m_val != 0);
113  return m_pos;
114  }
115  };
116 
117 public:
119  constexpr IntBitSet() noexcept : m_val{0} {}
121  constexpr IntBitSet(const IntBitSet&) noexcept = default;
123  constexpr IntBitSet(std::initializer_list<unsigned> ilist) noexcept : m_val(0)
124  {
125  for (auto pos : ilist) Set(pos);
126  }
128  constexpr IntBitSet& operator=(const IntBitSet&) noexcept = default;
130  constexpr IntBitSet& operator=(std::initializer_list<unsigned> ilist) noexcept
131  {
132  m_val = 0;
133  for (auto pos : ilist) Set(pos);
134  return *this;
135  }
137  static constexpr IntBitSet Singleton(unsigned i) noexcept
138  {
139  Assume(i < MAX_SIZE);
140  return IntBitSet(I(1U) << i);
141  }
143  static constexpr IntBitSet Fill(unsigned count) noexcept
144  {
145  IntBitSet ret;
146  Assume(count <= MAX_SIZE);
147  if (count) ret.m_val = I(~I{0}) >> (MAX_SIZE - count);
148  return ret;
149  }
151  constexpr void Set(unsigned pos) noexcept
152  {
153  Assume(pos < MAX_SIZE);
154  m_val |= I{1U} << pos;
155  }
157  constexpr void Set(unsigned pos, bool val) noexcept
158  {
159  Assume(pos < MAX_SIZE);
160  m_val = (m_val & ~I(I{1U} << pos)) | (I(val) << pos);
161  }
163  constexpr void Reset(unsigned pos) noexcept
164  {
165  Assume(pos < MAX_SIZE);
166  m_val &= ~I(I{1U} << pos);
167  }
169  constexpr bool operator[](unsigned pos) const noexcept
170  {
171  Assume(pos < MAX_SIZE);
172  return (m_val >> pos) & 1U;
173  }
175  constexpr unsigned Count() const noexcept { return PopCount(m_val); }
177  static constexpr unsigned Size() noexcept { return MAX_SIZE; }
179  constexpr bool None() const noexcept { return m_val == 0; }
181  constexpr bool Any() const noexcept { return !None(); }
183  constexpr Iterator begin() const noexcept { return Iterator(m_val); }
185  constexpr IteratorEnd end() const noexcept { return IteratorEnd(); }
187  constexpr unsigned First() const noexcept
188  {
189  Assume(m_val != 0);
190  return std::countr_zero(m_val);
191  }
193  constexpr unsigned Last() const noexcept
194  {
195  Assume(m_val != 0);
196  return std::bit_width(m_val) - 1;
197  }
199  constexpr IntBitSet& operator|=(const IntBitSet& a) noexcept { m_val |= a.m_val; return *this; }
201  constexpr IntBitSet& operator&=(const IntBitSet& a) noexcept { m_val &= a.m_val; return *this; }
203  constexpr IntBitSet& operator-=(const IntBitSet& a) noexcept { m_val &= ~a.m_val; return *this; }
205  constexpr IntBitSet& operator^=(const IntBitSet& a) noexcept { m_val ^= a.m_val; return *this; }
207  constexpr bool Overlaps(const IntBitSet& a) const noexcept { return m_val & a.m_val; }
209  friend constexpr IntBitSet operator&(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val & b.m_val); }
211  friend constexpr IntBitSet operator|(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val | b.m_val); }
213  friend constexpr IntBitSet operator-(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val & ~b.m_val); }
215  friend constexpr IntBitSet operator^(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val ^ b.m_val); }
217  friend constexpr bool operator==(const IntBitSet& a, const IntBitSet& b) noexcept = default;
219  constexpr bool IsSupersetOf(const IntBitSet& a) const noexcept { return (a.m_val & ~m_val) == 0; }
221  constexpr bool IsSubsetOf(const IntBitSet& a) const noexcept { return (m_val & ~a.m_val) == 0; }
223  friend constexpr void swap(IntBitSet& a, IntBitSet& b) noexcept { std::swap(a.m_val, b.m_val); }
224 };
225 
227 template<typename I, unsigned N>
229 {
230  // Only binary, unsigned, integer, types allowed.
231  static_assert(std::is_integral_v<I> && std::is_unsigned_v<I> && std::numeric_limits<I>::radix == 2);
232  // Cannot be empty.
233  static_assert(N > 0);
235  static constexpr unsigned LIMB_BITS = std::numeric_limits<I>::digits;
237  static constexpr unsigned MAX_SIZE = LIMB_BITS * N;
238  // No overflow allowed here.
239  static_assert(MAX_SIZE / LIMB_BITS == N);
241  std::array<I, N> m_val;
244  {
245  friend class MultiIntBitSet;
246  constexpr IteratorEnd() = default;
247  public:
248  constexpr IteratorEnd(const IteratorEnd&) = default;
249  };
251  class Iterator
252  {
253  friend class MultiIntBitSet;
254  const std::array<I, N>* m_ptr;
255  I m_val;
256  unsigned m_pos;
257  unsigned m_idx;
258  constexpr Iterator(const std::array<I, N>& ref) noexcept : m_ptr(&ref), m_idx(0)
259  {
260  do {
261  m_val = (*m_ptr)[m_idx];
262  if (m_val) {
263  m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS;
264  break;
265  }
266  ++m_idx;
267  } while(m_idx < N);
268  }
269 
270  public:
272  Iterator() = delete;
273  // Copying is allowed.
274  constexpr Iterator(const Iterator&) noexcept = default;
275  constexpr Iterator& operator=(const Iterator&) noexcept = default;
277  friend constexpr bool operator==(const Iterator& a, const IteratorEnd&) noexcept
278  {
279  return a.m_idx == N;
280  }
282  constexpr Iterator& operator++() noexcept
283  {
284  Assume(m_idx < N);
285  m_val &= m_val - I{1U};
286  if (m_val == 0) {
287  while (true) {
288  ++m_idx;
289  if (m_idx == N) break;
290  m_val = (*m_ptr)[m_idx];
291  if (m_val) {
292  m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS;
293  break;
294  }
295  }
296  } else {
297  m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS;
298  }
299  return *this;
300  }
302  constexpr unsigned operator*() const noexcept
303  {
304  Assume(m_idx < N);
305  return m_pos;
306  }
307  };
308 
309 public:
311  constexpr MultiIntBitSet() noexcept : m_val{} {}
313  constexpr MultiIntBitSet(const MultiIntBitSet&) noexcept = default;
315  constexpr MultiIntBitSet& operator=(const MultiIntBitSet&) noexcept = default;
317  void constexpr Set(unsigned pos) noexcept
318  {
319  Assume(pos < MAX_SIZE);
320  m_val[pos / LIMB_BITS] |= I{1U} << (pos % LIMB_BITS);
321  }
323  void constexpr Set(unsigned pos, bool val) noexcept
324  {
325  Assume(pos < MAX_SIZE);
326  m_val[pos / LIMB_BITS] = (m_val[pos / LIMB_BITS] & ~I(I{1U} << (pos % LIMB_BITS))) |
327  (I{val} << (pos % LIMB_BITS));
328  }
330  constexpr MultiIntBitSet(std::initializer_list<unsigned> ilist) noexcept : m_val{}
331  {
332  for (auto pos : ilist) Set(pos);
333  }
335  constexpr MultiIntBitSet& operator=(std::initializer_list<unsigned> ilist) noexcept
336  {
337  m_val.fill(0);
338  for (auto pos : ilist) Set(pos);
339  return *this;
340  }
342  void constexpr Reset(unsigned pos) noexcept
343  {
344  Assume(pos < MAX_SIZE);
345  m_val[pos / LIMB_BITS] &= ~I(I{1U} << (pos % LIMB_BITS));
346  }
348  bool constexpr operator[](unsigned pos) const noexcept
349  {
350  Assume(pos < MAX_SIZE);
351  return (m_val[pos / LIMB_BITS] >> (pos % LIMB_BITS)) & 1U;
352  }
354  static constexpr MultiIntBitSet Singleton(unsigned pos) noexcept
355  {
356  Assume(pos < MAX_SIZE);
358  ret.m_val[pos / LIMB_BITS] = I{1U} << (pos % LIMB_BITS);
359  return ret;
360  }
362  static constexpr MultiIntBitSet Fill(unsigned count) noexcept
363  {
364  Assume(count <= MAX_SIZE);
366  if (count) {
367  unsigned i = 0;
368  while (count > LIMB_BITS) {
369  ret.m_val[i++] = I(~I{0});
370  count -= LIMB_BITS;
371  }
372  ret.m_val[i] = I(~I{0}) >> (LIMB_BITS - count);
373  }
374  return ret;
375  }
377  static constexpr unsigned Size() noexcept { return MAX_SIZE; }
379  unsigned constexpr Count() const noexcept
380  {
381  unsigned ret{0};
382  for (I v : m_val) ret += PopCount(v);
383  return ret;
384  }
386  bool constexpr None() const noexcept
387  {
388  for (auto v : m_val) {
389  if (v != 0) return false;
390  }
391  return true;
392  }
394  bool constexpr Any() const noexcept { return !None(); }
396  Iterator constexpr begin() const noexcept { return Iterator(m_val); }
398  IteratorEnd constexpr end() const noexcept { return IteratorEnd(); }
400  unsigned constexpr First() const noexcept
401  {
402  unsigned p = 0;
403  while (m_val[p] == 0) {
404  ++p;
405  Assume(p < N);
406  }
407  return std::countr_zero(m_val[p]) + p * LIMB_BITS;
408  }
410  unsigned constexpr Last() const noexcept
411  {
412  unsigned p = N - 1;
413  while (m_val[p] == 0) {
414  Assume(p > 0);
415  --p;
416  }
417  return std::bit_width(m_val[p]) - 1 + p * LIMB_BITS;
418  }
420  constexpr MultiIntBitSet& operator|=(const MultiIntBitSet& a) noexcept
421  {
422  for (unsigned i = 0; i < N; ++i) {
423  m_val[i] |= a.m_val[i];
424  }
425  return *this;
426  }
428  constexpr MultiIntBitSet& operator&=(const MultiIntBitSet& a) noexcept
429  {
430  for (unsigned i = 0; i < N; ++i) {
431  m_val[i] &= a.m_val[i];
432  }
433  return *this;
434  }
436  constexpr MultiIntBitSet& operator-=(const MultiIntBitSet& a) noexcept
437  {
438  for (unsigned i = 0; i < N; ++i) {
439  m_val[i] &= ~a.m_val[i];
440  }
441  return *this;
442  }
444  constexpr MultiIntBitSet& operator^=(const MultiIntBitSet& a) noexcept
445  {
446  for (unsigned i = 0; i < N; ++i) {
447  m_val[i] ^= a.m_val[i];
448  }
449  return *this;
450  }
452  constexpr bool Overlaps(const MultiIntBitSet& a) const noexcept
453  {
454  for (unsigned i = 0; i < N; ++i) {
455  if (m_val[i] & a.m_val[i]) return true;
456  }
457  return false;
458  }
460  friend constexpr MultiIntBitSet operator&(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept
461  {
462  MultiIntBitSet r;
463  for (unsigned i = 0; i < N; ++i) {
464  r.m_val[i] = a.m_val[i] & b.m_val[i];
465  }
466  return r;
467  }
469  friend constexpr MultiIntBitSet operator|(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept
470  {
471  MultiIntBitSet r;
472  for (unsigned i = 0; i < N; ++i) {
473  r.m_val[i] = a.m_val[i] | b.m_val[i];
474  }
475  return r;
476  }
478  friend constexpr MultiIntBitSet operator-(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept
479  {
480  MultiIntBitSet r;
481  for (unsigned i = 0; i < N; ++i) {
482  r.m_val[i] = a.m_val[i] & ~b.m_val[i];
483  }
484  return r;
485  }
487  friend constexpr MultiIntBitSet operator^(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept
488  {
489  MultiIntBitSet r;
490  for (unsigned i = 0; i < N; ++i) {
491  r.m_val[i] = a.m_val[i] ^ b.m_val[i];
492  }
493  return r;
494  }
496  constexpr bool IsSupersetOf(const MultiIntBitSet& a) const noexcept
497  {
498  for (unsigned i = 0; i < N; ++i) {
499  if (a.m_val[i] & ~m_val[i]) return false;
500  }
501  return true;
502  }
504  constexpr bool IsSubsetOf(const MultiIntBitSet& a) const noexcept
505  {
506  for (unsigned i = 0; i < N; ++i) {
507  if (m_val[i] & ~a.m_val[i]) return false;
508  }
509  return true;
510  }
512  friend constexpr bool operator==(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept = default;
514  friend constexpr void swap(MultiIntBitSet& a, MultiIntBitSet& b) noexcept { std::swap(a.m_val, b.m_val); }
515 };
516 
517 } // namespace bitset_detail
518 
519 // BitSet dispatches to IntBitSet or MultiIntBitSet as appropriate for the requested minimum number
520 // of bits. Use IntBitSet up to 32-bit, or up to 64-bit on 64-bit platforms; above that, use a
521 // MultiIntBitSet of size_t.
522 template<unsigned BITS>
523 using BitSet = std::conditional_t<(BITS <= 32), bitset_detail::IntBitSet<uint32_t>,
524  std::conditional_t<(BITS <= std::numeric_limits<size_t>::digits), bitset_detail::IntBitSet<size_t>,
525  bitset_detail::MultiIntBitSet<size_t, (BITS + std::numeric_limits<size_t>::digits - 1) / std::numeric_limits<size_t>::digits>>>;
526 
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.
Definition: bitset.h:354
constexpr MultiIntBitSet & operator &=(const MultiIntBitSet &a) noexcept
Set this object&#39;s bits to be the binary AND between respective bits from this and a...
Definition: bitset.h:428
friend constexpr bool operator==(const IntBitSet &a, const IntBitSet &b) noexcept=default
Check if bitset a and bitset b are identical.
int ret
Iterator constexpr begin() const noexcept
Return an object that iterates over all 1 bits (++ and * only allowed when != end()).
Definition: bitset.h:396
constexpr IntBitSet() noexcept
Construct an all-zero bitset.
Definition: bitset.h:119
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.
Definition: bitset.h:323
unsigned constexpr First() const noexcept
Find the first element (requires Any()).
Definition: bitset.h:400
constexpr bool None() const noexcept
Check if all bits are 0.
Definition: bitset.h:179
constexpr bool Overlaps(const IntBitSet &a) const noexcept
Check if the intersection between two sets is non-empty.
Definition: bitset.h:207
bool constexpr Any() const noexcept
Check if any bits are 1.
Definition: bitset.h:394
friend constexpr void swap(MultiIntBitSet &a, MultiIntBitSet &b) noexcept
Swap two bitsets.
Definition: bitset.h:514
constexpr bool operator[](unsigned pos) const noexcept
Retrieve a bit at the given position.
Definition: bitset.h:169
constexpr MultiIntBitSet & operator^=(const MultiIntBitSet &a) noexcept
Set this object&#39;s bits to be the binary XOR between respective bits from this and a...
Definition: bitset.h:444
void constexpr Set(unsigned pos) noexcept
Set a bit to 1.
Definition: bitset.h:317
unsigned constexpr Last() const noexcept
Find the last element (requires Any()).
Definition: bitset.h:410
constexpr void Set(unsigned pos) noexcept
Set a bit to 1.
Definition: bitset.h:151
constexpr MultiIntBitSet() noexcept
Construct an all-zero bitset.
Definition: bitset.h:311
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.
Definition: bitset.h:460
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.
Definition: bitset.h:213
static constexpr IntBitSet Singleton(unsigned i) noexcept
Construct a bitset with the singleton i.
Definition: bitset.h:137
Iterator type returned by begin(), which efficiently iterates all 1 positions.
Definition: bitset.h:251
const std::array< I, N > * m_ptr
Pointer to array to fetch bits from.
Definition: bitset.h:254
constexpr unsigned operator*() const noexcept
Get the current bit position (only if != IteratorEnd).
Definition: bitset.h:302
constexpr unsigned First() const noexcept
Find the first element (requires Any()).
Definition: bitset.h:187
constexpr Iterator & operator++() noexcept
Progress to the next 1 bit (only if != IteratorEnd).
Definition: bitset.h:102
constexpr IntBitSet(std::initializer_list< unsigned > ilist) noexcept
Construct from a list of values.
Definition: bitset.h:123
A bitset implementation backed by N integers of type I.
Definition: bitset.h:228
I m_val
Integer whose bits represent this bitset.
Definition: bitset.h:69
constexpr unsigned Count() const noexcept
Compute the number of 1 bits in the bitset.
Definition: bitset.h:175
unsigned m_pos
The last reported position.
Definition: bitset.h:256
unsigned constexpr PopCount(I v)
Count the number of bits set in an unsigned integer type.
Definition: bitset.h:38
Dummy type to return using end().
Definition: bitset.h:73
constexpr IntBitSet & operator-=(const IntBitSet &a) noexcept
Set this object&#39;s bits to be the binary AND NOT between respective bits from this and a...
Definition: bitset.h:203
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.
Definition: bitset.h:487
constexpr void Reset(unsigned pos) noexcept
Set a bit to 0.
Definition: bitset.h:163
static constexpr MultiIntBitSet Fill(unsigned count) noexcept
Construct a bitset with bits 0..count-1 (inclusive) set to 1.
Definition: bitset.h:362
constexpr void Set(unsigned pos, bool val) noexcept
Set a bit to the specified value.
Definition: bitset.h:157
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.
Definition: bitset.h:215
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).
Definition: bitset.h:496
static constexpr unsigned Size() noexcept
Return the number of bits that this object holds.
Definition: bitset.h:377
constexpr bool Any() const noexcept
Check if any bits are 1.
Definition: bitset.h:181
std::array< I, N > m_val
Array whose member integers store the bits of the set.
Definition: bitset.h:239
constexpr MultiIntBitSet(std::initializer_list< unsigned > ilist) noexcept
Construct a bitset from a list of values.
Definition: bitset.h:330
constexpr friend bool operator==(const Iterator &a, const IteratorEnd &) noexcept
Test whether we are done (can only compare with IteratorEnd).
Definition: bitset.h:97
constexpr IteratorEnd end() const noexcept
Return a dummy object to compare Iterators with.
Definition: bitset.h:185
constexpr MultiIntBitSet & operator-=(const MultiIntBitSet &a) noexcept
Set this object&#39;s bits to be the binary AND NOT between respective bits from this and a...
Definition: bitset.h:436
static constexpr unsigned MAX_SIZE
The maximum number of bits this bitset supports.
Definition: bitset.h:67
constexpr Iterator(const std::array< I, N > &ref) noexcept
Definition: bitset.h:258
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.
Definition: bitset.h:209
friend constexpr bool operator==(const Iterator &a, const IteratorEnd &) noexcept
Test whether we are done (can only compare with IteratorEnd).
Definition: bitset.h:277
IteratorEnd constexpr end() const noexcept
Return a dummy object to compare Iterators with.
Definition: bitset.h:398
constexpr IntBitSet & operator|=(const IntBitSet &a) noexcept
Set this object&#39;s bits to be the binary AND between respective bits from this and a...
Definition: bitset.h:199
constexpr MultiIntBitSet & operator=(std::initializer_list< unsigned > ilist) noexcept
Set a bitset to a list of values.
Definition: bitset.h:335
constexpr IntBitSet & operator=(std::initializer_list< unsigned > ilist) noexcept
Assign from a list of positions (which will be made true, all others false).
Definition: bitset.h:130
I m_val
The original integer&#39;s remaining bits.
Definition: bitset.h:84
static constexpr IntBitSet Fill(unsigned count) noexcept
Construct a bitset with bits 0..count-1 (inclusive) set to 1.
Definition: bitset.h:143
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.
Definition: bitset.h:469
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.
Definition: bitset.h:379
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.
Definition: bitset.h:478
IntBitSet(I val) noexcept
Internal constructor with a given integer as contents.
Definition: bitset.h:71
#define Assume(val)
Assume is the identity function.
Definition: check.h:97
constexpr unsigned Last() const noexcept
Find the last element (requires Any()).
Definition: bitset.h:193
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.
Definition: bitset.h:211
I m_val
The remaining bits of (*m_ptr)[m_idx].
Definition: bitset.h:255
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
Definition: bitset.h:525
constexpr IntBitSet & operator^=(const IntBitSet &a) noexcept
Set this object&#39;s bits to be the binary XOR between respective bits from this as a.
Definition: bitset.h:205
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).
Definition: bitset.h:221
constexpr MultiIntBitSet & operator|=(const MultiIntBitSet &a) noexcept
Set this object&#39;s bits to be the binary OR between respective bits from this and a.
Definition: bitset.h:420
constexpr Iterator(I val) noexcept
Last reported 1 position (if m_pos != 0).
Definition: bitset.h:86
Dummy type to return using end().
Definition: bitset.h:243
bool constexpr None() const noexcept
Check if all bits are 0.
Definition: bitset.h:386
constexpr bool Overlaps(const MultiIntBitSet &a) const noexcept
Check whether the intersection between two sets is non-empty.
Definition: bitset.h:452
constexpr Iterator begin() const noexcept
Return an object that iterates over all 1 bits (++ and * only allowed when != end()).
Definition: bitset.h:183
constexpr unsigned operator*() const noexcept
Get the current bit position (only if != IteratorEnd).
Definition: bitset.h:110
static int count
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).
Definition: bitset.h:219
constexpr Iterator & operator++() noexcept
Progress to the next 1 bit (only if != IteratorEnd).
Definition: bitset.h:282
static constexpr unsigned MAX_SIZE
Number of elements this set type supports.
Definition: bitset.h:237
static constexpr unsigned Size() noexcept
Return the number of bits that this object holds.
Definition: bitset.h:177
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).
Definition: bitset.h:504
A bitset implementation backed by a single integer of type I.
Definition: bitset.h:62
void constexpr Reset(unsigned pos) noexcept
Set a bit to 0.
Definition: bitset.h:342
static constexpr unsigned LIMB_BITS
The number of bits per integer.
Definition: bitset.h:235
unsigned m_idx
The index in *m_ptr currently being iterated over.
Definition: bitset.h:257
constexpr IntBitSet & operator &=(const IntBitSet &a) noexcept
Set this object&#39;s bits to be the binary OR between respective bits from this and a.
Definition: bitset.h:201
friend constexpr void swap(IntBitSet &a, IntBitSet &b) noexcept
Swap two bitsets.
Definition: bitset.h:223
Iterator type returned by begin(), which efficiently iterates all 1 positions.
Definition: bitset.h:81
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.
Definition: bitset.h:348