2#include "gaia/config/config.h"
7#include "gaia/cnt/bitset_iterator.h"
11 template <u
int32_t NBits>
14 static constexpr uint32_t BitCount = NBits;
15 static_assert(NBits > 0);
18 template <
bool Use32Bit>
19 struct size_type_selector {
20 using type = std::conditional_t<Use32Bit, uint32_t, uint64_t>;
24 static constexpr uint32_t BitsPerItem = (NBits / 64) > 0 ? 64 : 32;
25 static constexpr uint32_t Items = (NBits + BitsPerItem - 1) / BitsPerItem;
27 using size_type =
typename size_type_selector<BitsPerItem == 32>::type;
30 static constexpr bool HasTrailingBits = (NBits % BitsPerItem) != 0;
31 static constexpr size_type LastItemMask = ((size_type)1 << (NBits % BitsPerItem)) - 1;
33 size_type m_data[Items]{};
36 size_type data(uint32_t wordIdx)
const {
37 return m_data[wordIdx];
50 constexpr size_type* data() {
54 constexpr const size_type* data()
const {
59 GAIA_NODISCARD
constexpr uint32_t
items()
const {
63 constexpr iter begin()
const {
64 return iter(*
this, 0,
true);
67 constexpr iter end()
const {
68 return iter(*
this, NBits,
false);
71 constexpr iter_rev rbegin()
const {
72 return iter_rev(*
this, NBits,
false);
75 constexpr iter_rev rend()
const {
76 return iter_rev(*
this, 0,
true);
79 constexpr iter_inv ibegin()
const {
80 return iter_inv(*
this, 0,
true);
83 constexpr iter_inv iend()
const {
84 return iter_inv(*
this, NBits,
false);
87 constexpr iter_rev_inv ribegin()
const {
88 return iter_rev_inv(*
this, NBits,
false);
91 constexpr iter_rev_inv riend()
const {
92 return iter_rev_inv(*
this, 0,
true);
95 GAIA_NODISCARD
constexpr bool operator[](uint32_t pos)
const {
99 GAIA_NODISCARD
constexpr bool operator==(
const bitset& other)
const {
101 if (m_data[i] != other.m_data[i])
107 GAIA_NODISCARD
constexpr bool operator!=(
const bitset& other)
const {
109 if (m_data[i] == other.m_data[i])
117 if constexpr (HasTrailingBits) {
118 GAIA_FOR(Items - 1) m_data[i] = (size_type)-1;
119 m_data[Items - 1] = LastItemMask;
121 GAIA_FOR(Items) m_data[i] = (size_type)-1;
128 constexpr void set(uint32_t pos,
bool value =
true) {
129 GAIA_ASSERT(pos < NBits);
131 m_data[pos / BitsPerItem] |= ((size_type)1 << (pos % BitsPerItem));
133 m_data[pos / BitsPerItem] &= ~((size_type)1 << (pos % BitsPerItem));
138 if constexpr (HasTrailingBits) {
139 GAIA_FOR(Items - 1) m_data[i] = ~m_data[i];
140 m_data[Items - 1] = (~m_data[Items - 1]) & LastItemMask;
142 GAIA_FOR(Items) m_data[i] = ~m_data[i];
148 constexpr void flip(uint32_t pos) {
149 GAIA_ASSERT(pos < NBits);
150 const auto wordIdx = pos / BitsPerItem;
151 const auto bitIdx = pos % BitsPerItem;
152 m_data[wordIdx] ^= ((size_type)1 << bitIdx);
157 GAIA_ASSERT(bitFrom <= bitTo);
158 GAIA_ASSERT(bitTo <
size());
164 const uint32_t wordIdxFrom = bitFrom / BitsPerItem;
165 const uint32_t wordIdxTo = bitTo / BitsPerItem;
167 auto getMask = [](uint32_t from, uint32_t to) -> size_type {
168 const auto diff = to - from;
170 if (diff == BitsPerItem - 1)
171 return (size_type)-1;
173 return ((size_type(1) << (diff + 1)) - 1) << from;
176 if (wordIdxFrom == wordIdxTo) {
177 m_data[wordIdxTo] ^= getMask(bitFrom % BitsPerItem, bitTo % BitsPerItem);
180 m_data[wordIdxFrom] ^= getMask(bitFrom % BitsPerItem, BitsPerItem - 1);
182 GAIA_FOR2(wordIdxFrom + 1, wordIdxTo) m_data[i] = ~m_data[i];
184 m_data[wordIdxTo] ^= getMask(0, bitTo % BitsPerItem);
192 GAIA_FOR(Items) m_data[i] = 0;
196 constexpr void reset(uint32_t pos) {
197 GAIA_ASSERT(pos < NBits);
198 m_data[pos / BitsPerItem] &= ~((size_type)1 << (pos % BitsPerItem));
202 GAIA_NODISCARD
constexpr bool test(uint32_t pos)
const {
203 GAIA_ASSERT(pos < NBits);
204 return (m_data[pos / BitsPerItem] & ((size_type)1 << (pos % BitsPerItem))) != 0;
208 GAIA_NODISCARD
constexpr bool all()
const {
209 if constexpr (HasTrailingBits) {
210 GAIA_FOR(Items - 1) {
211 if (m_data[i] != (size_type)-1)
214 return (m_data[Items - 1] & LastItemMask) == LastItemMask;
217 if (m_data[i] != (size_type)-1)
225 GAIA_NODISCARD
constexpr bool any()
const {
234 GAIA_NODISCARD
constexpr bool none()
const {
243 GAIA_NODISCARD uint32_t
count()
const {
246 GAIA_MSVC_WARNING_PUSH()
247 GAIA_MSVC_WARNING_DISABLE(4244)
248 if constexpr (
sizeof(size_type) == 4) {
249 GAIA_FOR(Items) total += GAIA_POPCNT(m_data[i]);
251 GAIA_FOR(Items) total += GAIA_POPCNT64(m_data[i]);
253 GAIA_MSVC_WARNING_POP()
259 GAIA_NODISCARD
constexpr uint32_t
size()
const {
Bitset iterator.
Definition bitset_iterator.h:14
GAIA_NODISCARD constexpr bool all() const
Checks if all bits are set.
Definition bitset.h:208
constexpr void reset()
Unsets all bits.
Definition bitset.h:191
GAIA_NODISCARD constexpr bool none() const
Checks if all bits are reset.
Definition bitset.h:234
GAIA_NODISCARD constexpr bool test(uint32_t pos) const
Returns the value of the bit at the position.
Definition bitset.h:202
GAIA_NODISCARD uint32_t count() const
Returns the number of set bits.
Definition bitset.h:243
constexpr void reset(uint32_t pos)
Unsets the bit at the postion.
Definition bitset.h:196
constexpr void set(uint32_t pos, bool value=true)
Sets the bit at the given position.
Definition bitset.h:128
constexpr bitset & flip(uint32_t bitFrom, uint32_t bitTo)
Flips all bits from.
Definition bitset.h:156
GAIA_NODISCARD constexpr uint32_t size() const
Returns the number of bits the bitset can hold.
Definition bitset.h:259
GAIA_NODISCARD constexpr bool any() const
Checks if any bit is set.
Definition bitset.h:225
constexpr void set()
Sets all bits.
Definition bitset.h:116
GAIA_NODISCARD constexpr uint32_t items() const
Returns the number of words used by the bitset internally.
Definition bitset.h:59
constexpr bitset & flip()
Flips all bits.
Definition bitset.h:137
constexpr void flip(uint32_t pos)
Flips the bit at the postion.
Definition bitset.h:148
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9