17 struct size_type_selector {
18 static constexpr bool Use32Bit =
sizeof(
size_t) == 4;
19 using type = std::conditional_t<Use32Bit, uint32_t, uint64_t>;
22 using difference_type =
typename size_type_selector::type;
23 using size_type =
typename size_type_selector::type;
24 using value_type = size_type;
25 using reference = size_type&;
26 using const_reference =
const size_type&;
27 using pointer = size_type*;
28 using const_pointer =
const size_type*;
30 static constexpr uint32_t BitsPerItem =
sizeof(
typename size_type_selector::type) * 8;
32 pointer m_pData =
nullptr;
37 return (m_cnt + BitsPerItem - 1) / BitsPerItem;
40 bool has_trailing_bits()
const {
41 return (m_cnt % BitsPerItem) != 0;
44 size_type last_item_mask()
const {
45 return ((size_type)1 << (m_cnt % BitsPerItem)) - 1;
62 m_pData = mem::AllocHelper::alloc<size_type, Allocator>(
itemsNew);
73 mem::AllocHelper::free<Allocator>((
void*)
pDataOld);
103 mem::AllocHelper::free<Allocator>((
void*)m_pData);
108 mem::copy_elements<size_type, false>((
uint8_t*)m_pData, (
const uint8_t*)other.m_pData, other.items(), 0, 0, 0);
112 GAIA_ASSERT(core::addressof(other) !=
this);
115 mem::copy_elements<size_type, false>((
uint8_t*)m_pData, (
const uint8_t*)other.m_pData, other.items(), 0, 0, 0);
120 m_pData = other.m_pData;
124 other.m_pData =
nullptr;
130 GAIA_ASSERT(core::addressof(other) !=
this);
132 m_pData = other.m_pData;
136 other.m_pData =
nullptr;
155 m_pData = mem::AllocHelper::alloc<size_type, Allocator>(
itemsNew);
167 mem::AllocHelper::free<Allocator>(
pDataOld);
187 m_pData = mem::AllocHelper::alloc<size_type, Allocator>(
itemsNew);
201 mem::AllocHelper::free<Allocator>((
void*)
pDataOld);
211 return iter(*
this, 0,
true);
242 GAIA_NODISCARD
bool operator[](
uint32_t pos)
const {
246 GAIA_NODISCARD
bool operator==(
const dbitset& other)
const {
247 const uint32_t item_count = items();
248 GAIA_FOR(item_count) {
249 if (m_pData[
i] != other.m_pData[
i])
255 GAIA_NODISCARD
bool operator!=(
const dbitset& other)
const {
256 const uint32_t item_count = items();
257 GAIA_FOR(item_count) {
258 if (m_pData[
i] == other.m_pData[
i])
266 if GAIA_UNLIKELY (
size() == 0)
269 const auto item_count = items();
273 GAIA_FOR(item_count - 1) m_pData[
i] = (size_type)-1;
276 GAIA_FOR(item_count) m_pData[
i] = (size_type)-1;
285 m_pData[pos / BitsPerItem] |= ((size_type)1 << (pos % BitsPerItem));
287 m_pData[pos / BitsPerItem] &= ~((size_type)1 << (pos % BitsPerItem));
292 if GAIA_UNLIKELY (
size() == 0)
295 const auto item_count = items();
299 GAIA_FOR(item_count - 1) m_pData[
i] = ~m_pData[
i];
300 m_pData[item_count - 1] = (~m_pData[item_count - 1]) &
lastItemMask;
302 GAIA_FOR(item_count + 1) m_pData[
i] = ~m_pData[
i];
308 GAIA_ASSERT(pos <
size());
309 m_pData[pos / BitsPerItem] ^= ((size_type)1 << (pos % BitsPerItem));
317 if GAIA_UNLIKELY (
size() == 0)
324 const auto diff = to - from;
326 if (
diff == BitsPerItem - 1)
327 return (size_type)-1;
329 return ((size_type(1) << (
diff + 1)) - 1) << from;
348 const auto item_count = items();
349 GAIA_FOR(item_count) m_pData[
i] = 0;
354 GAIA_ASSERT(pos <
size());
355 m_pData[pos / BitsPerItem] &= ~((size_type)1 << (pos % BitsPerItem));
360 GAIA_ASSERT(pos <
size());
361 return (m_pData[pos / BitsPerItem] & ((size_type)1 << (pos % BitsPerItem))) != 0;
365 GAIA_NODISCARD
bool all()
const {
366 const auto item_count = items() - 1;
369 GAIA_FOR(item_count) {
370 if (m_pData[
i] != (size_type)-1)
374 if (has_trailing_bits())
377 return m_pData[item_count] == (size_type)-1;
381 GAIA_NODISCARD
bool any()
const {
382 const auto item_count = items();
383 GAIA_FOR(item_count) {
391 GAIA_NODISCARD
bool none()
const {
392 const auto item_count = items();
393 GAIA_FOR(item_count) {
404 const auto item_count = items();
406 GAIA_MSVC_WARNING_PUSH()
407 GAIA_MSVC_WARNING_DISABLE(4244)
408 if constexpr (
sizeof(size_type) == 4) {
409 GAIA_FOR(item_count)
total += GAIA_POPCNT(m_pData[
i]);
411 GAIA_FOR(item_count)
total += GAIA_POPCNT64(m_pData[
i]);
413 GAIA_MSVC_WARNING_POP()