Bitcoin Core 28.99.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
34namespace bitset_detail {
35
37template<typename I>
38unsigned 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
61template<typename I>
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;
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 };
82 {
83 friend class IntBitSet;
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
117public:
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 {
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
227template<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 };
252 {
253 friend class MultiIntBitSet;
254 const std::array<I, N>* m_ptr;
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
309public:
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 {
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 {
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 {
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 {
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 {
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.
522template<unsigned BITS>
523using 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
int ret
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
#define Assume(val)
Assume is the identity function.
Definition: check.h:97
Dummy type to return using end().
Definition: bitset.h:74
constexpr IteratorEnd(const IteratorEnd &)=default
Iterator type returned by begin(), which efficiently iterates all 1 positions.
Definition: bitset.h:82
Iterator()=delete
Do not allow external code to construct an Iterator.
I m_val
The original integer's remaining bits.
Definition: bitset.h:84
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 unsigned operator*() const noexcept
Get the current bit position (only if != IteratorEnd).
Definition: bitset.h:110
constexpr Iterator(const Iterator &) noexcept=default
constexpr Iterator & operator++() noexcept
Progress to the next 1 bit (only if != IteratorEnd).
Definition: bitset.h:102
constexpr Iterator(I val) noexcept
Last reported 1 position (if m_pos != 0).
Definition: bitset.h:86
constexpr Iterator & operator=(const Iterator &) noexcept=default
A bitset implementation backed by a single integer of type I.
Definition: bitset.h:63
constexpr void Reset(unsigned pos) noexcept
Set a bit to 0.
Definition: bitset.h:163
IntBitSet(I val) noexcept
Internal constructor with a given integer as contents.
Definition: bitset.h:71
constexpr IteratorEnd end() const noexcept
Return a dummy object to compare Iterators with.
Definition: bitset.h:185
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
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
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
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
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
static constexpr IntBitSet Fill(unsigned count) noexcept
Construct a bitset with bits 0..count-1 (inclusive) set to 1.
Definition: bitset.h:143
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.
Definition: bitset.h:203
constexpr unsigned First() const noexcept
Find the first element (requires Any()).
Definition: bitset.h:187
constexpr bool Any() const noexcept
Check if any bits are 1.
Definition: bitset.h:181
constexpr IntBitSet(const IntBitSet &) noexcept=default
Copy construct a bitset.
friend constexpr void swap(IntBitSet &a, IntBitSet &b) noexcept
Swap two bitsets.
Definition: bitset.h:223
constexpr IntBitSet & operator|=(const IntBitSet &a) noexcept
Set this object's bits to be the binary AND between respective bits from this and a.
Definition: bitset.h:199
constexpr bool None() const noexcept
Check if all bits are 0.
Definition: bitset.h:179
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 IntBitSet & operator^=(const IntBitSet &a) noexcept
Set this object's bits to be the binary XOR between respective bits from this as a.
Definition: bitset.h:205
static constexpr unsigned MAX_SIZE
The maximum number of bits this bitset supports.
Definition: bitset.h:67
constexpr unsigned Last() const noexcept
Find the last element (requires Any()).
Definition: bitset.h:193
static constexpr unsigned Size() noexcept
Return the number of bits that this object holds.
Definition: bitset.h:177
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 void Set(unsigned pos) noexcept
Set a bit to 1.
Definition: bitset.h:151
constexpr IntBitSet() noexcept
Construct an all-zero bitset.
Definition: bitset.h:119
constexpr bool Overlaps(const IntBitSet &a) const noexcept
Check if the intersection between two sets is non-empty.
Definition: bitset.h:207
constexpr unsigned Count() const noexcept
Compute the number of 1 bits in the bitset.
Definition: bitset.h:175
friend constexpr bool operator==(const IntBitSet &a, const IntBitSet &b) noexcept=default
Check if bitset a and bitset b are identical.
constexpr IntBitSet & operator=(const IntBitSet &) noexcept=default
Copy assign a bitset.
constexpr Iterator begin() const noexcept
Return an object that iterates over all 1 bits (++ and * only allowed when != end()).
Definition: bitset.h:183
static constexpr IntBitSet Singleton(unsigned i) noexcept
Construct a bitset with the singleton i.
Definition: bitset.h:137
constexpr bool operator[](unsigned pos) const noexcept
Retrieve a bit at the given position.
Definition: bitset.h:169
I m_val
Integer whose bits represent this bitset.
Definition: bitset.h:69
constexpr IntBitSet & operator&=(const IntBitSet &a) noexcept
Set this object's bits to be the binary OR between respective bits from this and a.
Definition: bitset.h:201
constexpr void Set(unsigned pos, bool val) noexcept
Set a bit to the specified value.
Definition: bitset.h:157
constexpr IntBitSet(std::initializer_list< unsigned > ilist) noexcept
Construct from a list of values.
Definition: bitset.h:123
Dummy type to return using end().
Definition: bitset.h:244
constexpr IteratorEnd(const IteratorEnd &)=default
Iterator type returned by begin(), which efficiently iterates all 1 positions.
Definition: bitset.h:252
constexpr Iterator(const std::array< I, N > &ref) noexcept
Definition: bitset.h:258
I m_val
The remaining bits of (*m_ptr)[m_idx].
Definition: bitset.h:255
constexpr Iterator(const Iterator &) noexcept=default
constexpr unsigned operator*() const noexcept
Get the current bit position (only if != IteratorEnd).
Definition: bitset.h:302
constexpr Iterator & operator=(const Iterator &) noexcept=default
const std::array< I, N > * m_ptr
Pointer to array to fetch bits from.
Definition: bitset.h:254
unsigned m_pos
The last reported position.
Definition: bitset.h:256
Iterator()=delete
Do not allow external code to construct an Iterator.
unsigned m_idx
The index in *m_ptr currently being iterated over.
Definition: bitset.h:257
friend constexpr bool operator==(const Iterator &a, const IteratorEnd &) noexcept
Test whether we are done (can only compare with IteratorEnd).
Definition: bitset.h:277
constexpr Iterator & operator++() noexcept
Progress to the next 1 bit (only if != IteratorEnd).
Definition: bitset.h:282
A bitset implementation backed by N integers of type I.
Definition: bitset.h:229
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
bool constexpr None() const noexcept
Check if all bits are 0.
Definition: bitset.h:386
Iterator constexpr begin() const noexcept
Return an object that iterates over all 1 bits (++ and * only allowed when != end()).
Definition: bitset.h:396
std::array< I, N > m_val
Array whose member integers store the bits of the set.
Definition: bitset.h:241
IteratorEnd constexpr end() const noexcept
Return a dummy object to compare Iterators with.
Definition: bitset.h:398
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 MultiIntBitSet Fill(unsigned count) noexcept
Construct a bitset with bits 0..count-1 (inclusive) set to 1.
Definition: bitset.h:362
void constexpr Set(unsigned pos) noexcept
Set a bit to 1.
Definition: bitset.h:317
unsigned constexpr First() const noexcept
Find the first element (requires Any()).
Definition: bitset.h:400
unsigned constexpr Count() const noexcept
Compute the number of 1 bits in the bitset.
Definition: bitset.h:379
void constexpr Set(unsigned pos, bool val) noexcept
Set a bit to the specified value.
Definition: bitset.h:323
static constexpr unsigned Size() noexcept
Return the number of bits that this object holds.
Definition: bitset.h:377
unsigned constexpr Last() const noexcept
Find the last element (requires Any()).
Definition: bitset.h:410
constexpr MultiIntBitSet(const MultiIntBitSet &) noexcept=default
Copy construct a bitset.
constexpr MultiIntBitSet() noexcept
Construct an all-zero bitset.
Definition: bitset.h:311
constexpr MultiIntBitSet & operator|=(const MultiIntBitSet &a) noexcept
Set this object's bits to be the binary OR between respective bits from this and a.
Definition: bitset.h:420
bool constexpr operator[](unsigned pos) const noexcept
Retrieve a bit at the given position.
Definition: bitset.h:348
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
static constexpr unsigned MAX_SIZE
Number of elements this set type supports.
Definition: bitset.h:237
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 void swap(MultiIntBitSet &a, MultiIntBitSet &b) noexcept
Swap two bitsets.
Definition: bitset.h:514
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 bool Overlaps(const MultiIntBitSet &a) const noexcept
Check whether the intersection between two sets is non-empty.
Definition: bitset.h:452
constexpr MultiIntBitSet & operator=(const MultiIntBitSet &) noexcept=default
Copy assign a bitset.
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.
Definition: bitset.h:436
constexpr MultiIntBitSet & operator^=(const MultiIntBitSet &a) noexcept
Set this object's bits to be the binary XOR between respective bits from this and a.
Definition: bitset.h:444
friend constexpr bool operator==(const MultiIntBitSet &a, const MultiIntBitSet &b) noexcept=default
Check if bitset a and bitset b are identical.
constexpr MultiIntBitSet & operator&=(const MultiIntBitSet &a) noexcept
Set this object's bits to be the binary AND between respective bits from this and a.
Definition: bitset.h:428
constexpr MultiIntBitSet & operator=(std::initializer_list< unsigned > ilist) noexcept
Set a bitset to a list of values.
Definition: bitset.h:335
constexpr MultiIntBitSet(std::initializer_list< unsigned > ilist) noexcept
Construct a bitset from a list of values.
Definition: bitset.h:330
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
static constexpr MultiIntBitSet Singleton(unsigned pos) noexcept
Construct a bitset with the singleton pos.
Definition: bitset.h:354
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
bool constexpr Any() const noexcept
Check if any bits are 1.
Definition: bitset.h:394
unsigned constexpr PopCount(I v)
Count the number of bits set in an unsigned integer type.
Definition: bitset.h:38
static int count