14template <u
int32_t N = 256>
76 for (
size_t i = 0; i < n; ++i) {
112 return (
_blocks[idx] >> off) & 1;
125 cnt += __builtin_popcountll(
_blocks[i]);
142 cnt += __builtin_popcountll(last_block);
151 bool all() const noexcept {
183 _blocks[i] &= other._blocks[i];
190 _blocks[i] |= other._blocks[i];
197 _blocks[i] ^= other._blocks[i];
203 constexpr uint32_t
size() const noexcept {
return N; }
224template <u
int32_t N = 256>
260 if (
this != &other) {
266 if (
this != &other) {
274 if (
_storage.template is<fixed_bitset>()) {
275 _storage.template ptr<fixed_bitset>()->reset();
277 _storage.template ptr<bitset_dynamic>()->reset();
283 if (
_storage.template is<fixed_bitset>()) {
284 _storage.template ptr<fixed_bitset>()->assign(n, value);
286 _storage.template ptr<bitset_dynamic>()->assign(n, value);
294 if (
_storage.template is<bitset_dynamic>()) {
298 _storage.template ptr<bitset_dynamic>();
301 for (uint32_t i = 0; i < N && i < dynamic->
size(); ++i) {
302 if (dynamic->
test(i)) {
311 if (
_storage.template is<fixed_bitset>()) {
317 for (uint32_t i = 0; i < N; ++i) {
318 if (fixed->
test(i)) {
326 _storage.template ptr<bitset_dynamic>()->resize(new_size);
333 if (
pos >= N &&
_storage.template is<fixed_bitset>()) {
337 if (
_storage.template is<fixed_bitset>()) {
339 _storage.template ptr<fixed_bitset>()->set(
pos, value);
342 if (
pos >=
_storage.template ptr<bitset_dynamic>()->size()) {
343 _storage.template ptr<bitset_dynamic>()->resize(
pos + 1);
345 _storage.template ptr<bitset_dynamic>()->set(
pos, value);
355 if (
pos >= N &&
_storage.template is<fixed_bitset>()) {
359 if (
_storage.template is<fixed_bitset>()) {
364 if (
pos >=
_storage.template ptr<bitset_dynamic>()->size()) {
365 _storage.template ptr<bitset_dynamic>()->resize(
pos + 1);
367 _storage.template ptr<bitset_dynamic>()->flip(
pos);
374 if (
_storage.template is<fixed_bitset>()) {
375 _storage.template ptr<fixed_bitset>()->flip();
377 _storage.template ptr<bitset_dynamic>()->flip();
384 if (
_storage.template is<fixed_bitset>()) {
388 return _storage.template ptr<bitset_dynamic>()->test(
pos);
397 if (
_storage.template is<fixed_bitset>()) {
398 return _storage.template ptr<fixed_bitset>()->count();
400 return _storage.template ptr<bitset_dynamic>()->count();
405 bool any() const noexcept {
406 if (
_storage.template is<fixed_bitset>()) {
407 return _storage.template ptr<fixed_bitset>()->any();
409 return _storage.template ptr<bitset_dynamic>()->any();
414 if (
_storage.template is<fixed_bitset>()) {
415 return _storage.template ptr<fixed_bitset>()->none();
417 return _storage.template ptr<bitset_dynamic>()->none();
421 bool all() const noexcept {
422 if (
_storage.template is<fixed_bitset>()) {
423 return _storage.template ptr<fixed_bitset>()->all();
425 return _storage.template ptr<bitset_dynamic>()->all();
430 uint32_t
size() const noexcept {
431 if (
_storage.template is<fixed_bitset>()) {
434 return _storage.template ptr<bitset_dynamic>()->size();
449 if (result.
_storage.template is<fixed_bitset>() &&
450 rhs._storage.template is<fixed_bitset>()) {
452 *result.
_storage.template ptr<fixed_bitset>() &=
453 *rhs._storage.template ptr<fixed_bitset>();
457 result.
size() < rhs.size() ? result.
size() : rhs.size();
458 for (uint32_t i = 0; i < min_size; ++i) {
459 result.
set(i, result.
test(i) && rhs.test(i));
462 for (uint32_t i = min_size; i < result.
size(); ++i) {
474 if (result.
_storage.template is<fixed_bitset>() &&
475 rhs._storage.template is<fixed_bitset>()) {
477 *result.
_storage.template ptr<fixed_bitset>() |=
478 *rhs._storage.template ptr<fixed_bitset>();
482 result.
size() > rhs.size() ? result.
size() : rhs.size();
490 for (uint32_t i = 0; i < rhs.size(); ++i) {
504 if (result.
_storage.template is<fixed_bitset>() &&
505 rhs._storage.template is<fixed_bitset>()) {
507 *result.
_storage.template ptr<fixed_bitset>() ^=
508 *rhs._storage.template ptr<fixed_bitset>();
512 result.
size() > rhs.size() ? result.
size() : rhs.size();
520 for (uint32_t i = 0; i < rhs.size(); ++i) {
521 result.
set(i, result.
test(i) != rhs.test(i));
static constexpr uint32_t block_count
constexpr BitsetFixed() noexcept
Constructs a BitsetFixed with all bits reset.
friend BitsetFixed operator~(BitsetFixed bs) noexcept
BitsetFixed & operator|=(const BitsetFixed &other) noexcept
Bitwise OR.
bool any() const noexcept
Queries.
block_type _blocks[block_count]
BitsetFixed & flip(uint32_t pos)
Flips (toggles) the bit at position pos.
bool operator[](uint32_t pos) const noexcept
Returns the value of the bit at position pos.
BitsetFixed & operator&=(const BitsetFixed &other) noexcept
Bitwise AND.
bool none() const noexcept
void reset() noexcept
Resets all bits to zero.
BitsetFixed & reset(uint32_t pos)
Clears the bit at position pos.
friend BitsetFixed operator&(BitsetFixed lhs, const BitsetFixed &rhs) noexcept
Friend operators for convenience.
constexpr uint32_t size() const noexcept
Size of the BitsetFixed (number of bits).
BitsetFixed & set(uint32_t pos, bool value=true)
Sets or clears the bit at position pos.
uint32_t count() const noexcept
Returns the number of set bits.
BitsetFixed & operator^=(const BitsetFixed &other) noexcept
Bitwise XOR.
void assign(size_t n, bool value)
Proxy operator[](uint32_t pos)
friend BitsetFixed operator|(BitsetFixed lhs, const BitsetFixed &rhs) noexcept
bool test(uint32_t pos) const noexcept
Tests whether the bit at position pos is set.
static constexpr uint32_t bits_per_block
bool all() const noexcept
friend BitsetFixed operator^(BitsetFixed lhs, const BitsetFixed &rhs) noexcept
BitsetFixed & flip() noexcept
Flips all bits.
A simple fixed-size Bitset implementation similar to std::Bitset.
void reset() noexcept
Resets all bits to zero.
friend BitsetInlined operator&(const BitsetInlined &lhs, const BitsetInlined &rhs) noexcept
BitsetInlined(const BitsetInlined &other)
bool test(uint32_t pos) const noexcept
Tests whether the bit at position pos is set.
bool operator[](uint32_t pos) const noexcept
Returns the value of the bit at position pos.
BitsetInlined & set(uint32_t pos, bool value=true)
Sets or clears the bit at position pos.
bool none() const noexcept
BitsetInlined(BitsetInlined &&other) noexcept
BitsetInlined()
Constructs a Bitset with all bits reset.
BitsetInlined & operator=(BitsetInlined &&other) noexcept
Proxy operator[](uint32_t pos)
uint32_t count() const noexcept
Returns the number of set bits.
BitsetInlined(size_t size)
bool any() const noexcept
Queries.
BitsetFixed< N > fixed_bitset
friend BitsetInlined operator^(const BitsetInlined &lhs, const BitsetInlined &rhs) noexcept
uint32_t size() const noexcept
BitsetInlined & operator=(const BitsetInlined &other)
void resize(uint32_t new_size)
Resizes the Bitset if needed.
bool all() const noexcept
void assign(size_t n, bool value)
BitsetInlined & reset(uint32_t pos)
Clears the bit at position pos.
friend BitsetInlined operator|(const BitsetInlined &lhs, const BitsetInlined &rhs) noexcept
Variant< fixed_bitset, bitset_dynamic > _storage
friend BitsetInlined operator~(const BitsetInlined &bs) noexcept
Bitwise operators.
BitsetInlined & flip() noexcept
Flips all bits.
BitsetInlined & flip(uint32_t pos)
Flips (toggles) the bit at position pos.
A Bitset implementation with inline storage that can grow if needed.
uint32_t size() const noexcept
bool test(uint32_t pos) const noexcept
void set(uint32_t pos) noexcept
A dynamic bitset implementation that can be resized at runtime.
BitsetInlined< N > bitset
constexpr remove_reference< T >::type && move(T &&t) noexcept
BitsetFixed< N > bitset_fixed
Implements a simple red square effect for 2D LED grids.
Proxy & operator=(bool value)
Proxy(BitsetFixed &bitset, uint32_t pos)
Proxy(BitsetInlined &bitset, uint32_t pos)
Proxy & operator=(bool value)