22 static constexpr uint32_t bitsPerWord = (CHAR_BIT *
sizeof(WordType));
23 static constexpr uint32_t wordCount = ((bitCount + bitsPerWord - 1) / bitsPerWord);
24 static constexpr uint32_t totalBitCount = wordCount * bitsPerWord;
25 static constexpr uint32_t lastWordbitCount = bitCount % bitsPerWord;
26 static constexpr uint32_t lastWordMask = (lastWordbitCount == 0)
28 : ((1 << lastWordbitCount) - 1);
31 for (
size_t i = 0; i < wordCount; ++i) {
36 Bitset(
const Bitset& other) {
37 for (
size_t i = 0; i < wordCount; ++i) {
38 contents[i] = other.contents[i];
42 Bitset(Bitset&& other)
noexcept {
43 for (
size_t i = 0; i < wordCount; ++i) {
44 contents[i] = other.contents[i];
48 Bitset& operator=(
const Bitset& other) {
49 for (
size_t i = 0; i < wordCount; ++i) {
50 contents[i] = other.contents[i];
55 Bitset& operator=(Bitset&& other) {
56 for (
size_t i = 0; i < wordCount; ++i) {
57 contents[i] = other.contents[i];
63 for (WordType& w : contents) {
68 contents[wordCount - 1] &= lastWordMask;
71 void Set(uint32_t bitIndex,
bool value =
true) {
72 size_t wordIndex = bitIndex / bitsPerWord;
73 size_t bitInWord = bitIndex % bitsPerWord;
76 contents[wordIndex] |= (1 << bitInWord);
79 contents[wordIndex] &= ~(1 << bitInWord);
84 for (WordType& w : contents) {
89 void Unset(uint32_t index) {
90 contents[index / bitsPerWord] &= ~(1 << (index % bitsPerWord));
94 for (WordType& w : contents) {
99 contents[wordCount - 1] &= lastWordMask;
102 void Flip(uint32_t index) {
103 contents[index / bitsPerWord] ^= (1 << (index % bitsPerWord));
106 bool Test(uint32_t index)
const {
107 return (contents[index / bitsPerWord] >> (index % bitsPerWord)) & 1;
110 WordType GetWord(uint32_t index)
const {
111 return contents[index];
115 for (
size_t i = 0; i < wordCount - 1; ++i) {
116 if (contents[i] != WordType(~0)) {
125 for (WordType w : contents) {
135 for (WordType w : contents) {
144 constexpr uint32_t GetTrueBitCount()
const {
146 for (uint32_t w : contents) {
147 total += Popcount(w);
153 constexpr uint32_t GetFalseBitCount()
const {
154 return bitCount - GetTrueBitCount();
157 static constexpr uint32_t GetBitCount() {
161 static constexpr uint32_t GetBitCapacity() {
162 return totalBitCount;
165 static constexpr uint32_t GetWordCount() {
169 Bitset operator&=(
const Bitset& other)
const {
170 for (
size_t i = 0; i < wordCount; ++i) {
171 contents[i] &= other.contents[i];
177 Bitset operator|=(
const Bitset& other)
const {
178 for (
size_t i = 0; i < wordCount; ++i) {
179 contents[i] |= other.contents[i];
185 Bitset operator^=(
const Bitset& other)
const {
186 for (
size_t i = 0; i < wordCount; ++i) {
187 contents[i] ^= other.contents[i];
193 Bitset operator&(
const Bitset& other)
const {
195 for (
size_t i = 0; i < wordCount; ++i) {
196 result.contents[i] = contents[i] & other.contents[i];
202 Bitset operator|(
const Bitset& other)
const {
204 for (
size_t i = 0; i < wordCount; ++i) {
205 result.contents[i] = contents[i] | other.contents[i];
211 Bitset operator^(
const Bitset& other)
const {
213 for (
size_t i = 0; i < wordCount; ++i) {
214 result.contents[i] = contents[i] ^ other.contents[i];
220 friend Bitset operator~(
const Bitset& obj) {
226 bool operator[](uint32_t index)
const {
227 return (contents[index / bitsPerWord] >> index % bitsPerWord) & 1;
230 bool operator==(
const Bitset& other)
const {
231 for (
size_t i = 0; i < wordCount; ++i) {
232 if (contents[i] != other.contents[i]) {
240 bool operator!=(
const Bitset& other)
const {
241 return *
this != other;
245 WordType contents[wordCount];
333 using UnderlyingType = std::underlying_type_t<Enum>;
335 static constexpr uint32_t bitsPerWord = (CHAR_BIT *
sizeof(UnderlyingType));
336 static constexpr uint32_t enumBitCount = Traits::size;
337 static_assert(std::is_enum_v<Enum>,
"BitsetFlags requires an enum type");
339 BitsetFlags() =
default;
340 BitsetFlags(
const BitsetFlags&) =
default;
341 BitsetFlags(BitsetFlags&&) =
default;
342 BitsetFlags(Enum enumValue) : value(
static_cast<UnderlingType
>(enumValue)) {}
344 BitsetFlags& operator=(
const BitsetFlags& other) {
349 BitsetFlags& operator=(BitsetFlags&& other) {
354 BitsetFlags& operator=(Enum enumValue) {
355 value =
static_cast<UnderlyingType
>(enumValue);
360 value = ~UnderlyingType(0);
363 void Set(uint32_t bitIndex) {
364 value |= (1 << bitIndex);
368 value |=
static_cast<UnderlyingType
>(e);
371 void Set(uint32_t bitIndex,
bool shouldSet) {
373 value |= (1 << bitIndex);
376 value &= ~(1 << bitIndex);
380 void Set(Enum e,
bool shouldSet) {
382 value |=
static_cast<UnderlyingType
>(e);
385 value &= ~static_cast<UnderlyingType>(e);
393 void Unset(uint32_t index) {
394 value &= ~(1 << index);
398 value &= ~static_cast<UnderlyingType>(e);
405 void Flip(uint32_t index) {
406 value ^= (1 << index);
410 value ^=
static_cast<UnderlyingType
>(e);
413 bool Test(uint32_t index)
const {
414 return (value >> index) & 1;
417 bool Test(Enum e)
const {
418 return value &
static_cast<UnderlyingType
>(e);
421 static constexpr uint32_t GetBitCount() {
425 static constexpr const char* GetFlagNameByIndex(uint32_t index) {
426 return Traits::names[index];
429 static constexpr const char* GetFlagName(Enum e) {
430 uint32_t index =
static_cast<uint32_t
>(std::log2(
static_cast<uint32_t
>(e)));
431 return Traits::names[index];
434 Enum GetValueEnum()
const {
435 return static_cast<Enum
>(value);
438 UnderlyingType GetValueUnderlying()
const {
450 BitsetFlags& operator&=(
const BitsetFlags& other)
const {
451 value &= other.value;
455 BitsetFlags& operator|=(
const BitsetFlags& other)
const {
456 value |= other.value;
460 BitsetFlags& operator^=(
const BitsetFlags& other)
const {
461 value ^= other.value;
465 BitsetFlags operator&(
const BitsetFlags& other)
const {
466 return value & other.value;
469 BitsetFlags operator|(
const BitsetFlags& other)
const {
470 return value | other.value;
473 BitsetFlags operator^(
const BitsetFlags& other)
const {
474 return value ^ other.value;
477 BitsetFlags operator~()
const {
481 bool operator[](uint32_t index)
const {
482 return (value >> index) & 1;
485 bool operator[](Enum e)
const {
486 return value &
static_cast<UnderlyingType
>(e);
489 bool operator==(
const BitsetFlags& other)
const {
490 return value == other.value;
493 bool operator!=(
const BitsetFlags& other)
const {
494 return value != other.value;
499 const BitsetFlags* bitset;
501 bool operator!=(
const Iterator& other)
const {
return i != other.i; }
502 void operator++() { ++i; }
503 Enum operator*()
const {
return static_cast<Enum
>(i); }
506 Iterator begin()
const {
return { 0,
this }; }
507 Iterator end()
const {
return { EnumTraits<Enum>::size,
this }; }
510 UnderlyingType value = 0;