2#include "gaia/config/config.h"
7#include "gaia/cnt/bitset_iterator.h"
8#include "gaia/core/utility.h"
9#include "gaia/mem/mem_alloc.h"
10#include "gaia/mem/mem_utils.h"
16 template <
typename Allocator = mem::DefaultAllocatorAdaptor>
19 struct size_type_selector {
20 static constexpr bool Use32Bit =
sizeof(
size_t) == 4;
21 using type = std::conditional_t<Use32Bit, uint32_t, uint64_t>;
24 using difference_type =
typename size_type_selector::type;
25 using size_type =
typename size_type_selector::type;
26 using value_type = size_type;
27 using reference = size_type&;
28 using const_reference =
const size_type&;
29 using pointer = size_type*;
30 using const_pointer =
const size_type*;
32 static constexpr uint32_t BitsPerItem =
sizeof(
typename size_type_selector::type) * 8;
34 pointer m_pData =
nullptr;
39 return (m_cnt + BitsPerItem - 1) / BitsPerItem;
42 bool has_trailing_bits()
const {
43 return (m_cnt % BitsPerItem) != 0;
46 size_type last_item_mask()
const {
47 return ((size_type)1 << (m_cnt % BitsPerItem)) - 1;
64 m_pData = mem::AllocHelper::alloc<size_type, Allocator>(
itemsNew);
75 mem::AllocHelper::free<Allocator>((
void*)
pDataOld);
114 mem::AllocHelper::free<Allocator>((
void*)m_pData);
121 mem::copy_elements<size_type, false>((
uint8_t*)m_pData, (
const uint8_t*)other.m_pData, other.items(), 0, 0, 0);
128 GAIA_ASSERT(core::addressof(other) !=
this);
131 mem::copy_elements<size_type, false>((
uint8_t*)m_pData, (
const uint8_t*)other.m_pData, other.items(), 0, 0, 0);
138 m_pData = other.m_pData;
142 other.m_pData =
nullptr;
151 GAIA_ASSERT(core::addressof(other) !=
this);
153 m_pData = other.m_pData;
157 other.m_pData =
nullptr;
178 m_pData = mem::AllocHelper::alloc<size_type, Allocator>(
itemsNew);
190 mem::AllocHelper::free<Allocator>(
pDataOld);
212 m_pData = mem::AllocHelper::alloc<size_type, Allocator>(
itemsNew);
227 mem::AllocHelper::free<Allocator>((
void*)
pDataOld);
239 return iter(*
this, 0,
true);
295 const uint32_t item_count = items();
296 GAIA_FOR(item_count) {
297 if (m_pData[
i] != other.m_pData[
i])
307 const uint32_t item_count = items();
308 GAIA_FOR(item_count) {
309 if (m_pData[
i] == other.m_pData[
i])
317 if GAIA_UNLIKELY (
size() == 0)
320 const auto item_count = items();
324 GAIA_FOR(item_count - 1) m_pData[
i] = (size_type)-1;
327 GAIA_FOR(item_count) m_pData[
i] = (size_type)-1;
338 m_pData[
pos / BitsPerItem] |= ((size_type)1 << (
pos % BitsPerItem));
340 m_pData[
pos / BitsPerItem] &= ~((size_type)1 << (
pos % BitsPerItem));
345 if GAIA_UNLIKELY (
size() == 0)
348 const auto item_count = items();
352 GAIA_FOR(item_count - 1) m_pData[
i] = ~m_pData[
i];
353 m_pData[item_count - 1] = (~m_pData[item_count - 1]) &
lastItemMask;
355 GAIA_FOR(item_count + 1) m_pData[
i] = ~m_pData[
i];
363 m_pData[
pos / BitsPerItem] ^= ((size_type)1 << (
pos % BitsPerItem));
374 if GAIA_UNLIKELY (
size() == 0)
381 const auto diff = to - from;
383 if (
diff == BitsPerItem - 1)
384 return (size_type)-1;
386 return ((size_type(1) << (
diff + 1)) - 1) << from;
405 const auto item_count = items();
406 GAIA_FOR(item_count) m_pData[
i] = 0;
413 m_pData[
pos / BitsPerItem] &= ~((size_type)1 << (
pos % BitsPerItem));
421 return (m_pData[
pos / BitsPerItem] & ((size_type)1 << (
pos % BitsPerItem))) != 0;
426 GAIA_NODISCARD
bool all()
const {
427 const auto item_count = items() - 1;
430 GAIA_FOR(item_count) {
431 if (m_pData[
i] != (size_type)-1)
435 if (has_trailing_bits())
438 return m_pData[item_count] == (size_type)-1;
443 GAIA_NODISCARD
bool any()
const {
444 const auto item_count = items();
445 GAIA_FOR(item_count) {
454 GAIA_NODISCARD
bool none()
const {
455 const auto item_count = items();
456 GAIA_FOR(item_count) {
468 const auto item_count = items();
470 GAIA_MSVC_WARNING_PUSH()
471 GAIA_MSVC_WARNING_DISABLE(4244)
472 if constexpr (
sizeof(size_type) == 4) {
473 GAIA_FOR(item_count)
total += GAIA_POPCNT(m_pData[
i]);
475 GAIA_FOR(item_count)
total += GAIA_POPCNT64(m_pData[
i]);
477 GAIA_MSVC_WARNING_POP()
Array with variable size of elements of type.
Definition darray_impl.h:27
Dynamically sized bit set.
Definition dbitset.h:17
GAIA_NODISCARD bool none() const
Checks if all bits are reset.
Definition dbitset.h:454
dbitset(uint32_t reserveBits)
Constructs a bit set with requested initial capacity and a size of one bit.
Definition dbitset.h:109
void reset()
Unsets all bits.
Definition dbitset.h:404
dbitset()
Constructs a bit set with capacity for at least 128 bits and an initial size of one bit.
Definition dbitset.h:102
const_iterator< dbitset > iter
Forward iterator over set bit indices.
Definition dbitset.h:86
void set(uint32_t pos, bool value=true)
Sets one bit, growing the bit set when needed.
Definition dbitset.h:334
const_iterator_inverse< dbitset > iter_inv
Forward iterator over unset bit indices.
Definition dbitset.h:88
GAIA_NODISCARD uint32_t count() const
Returns the number of set bits.
Definition dbitset.h:465
GAIA_NODISCARD constexpr uint32_t capacity() const
Returns the number of bits the dbitset can hold.
Definition dbitset.h:490
const_reverse_inverse_iterator< dbitset > iter_rev_inv
Reverse iterator over unset bit indices.
Definition dbitset.h:92
iter_inv ibegin() const
Returns an iterator to the first unset bit.
Definition dbitset.h:262
iter_rev_inv ribegin() const
Returns an iterator to the last unset bit.
Definition dbitset.h:274
GAIA_NODISCARD bool operator==(const dbitset &other) const
Compares two bit sets for equality.
Definition dbitset.h:294
dbitset(dbitset &&other) noexcept
Move-constructs a bit set and leaves the source empty.
Definition dbitset.h:137
iter_rev rend() const
Returns the reverse set-bit sentinel.
Definition dbitset.h:256
GAIA_NODISCARD constexpr uint32_t size() const
Returns the number of bits the dbitset holds.
Definition dbitset.h:484
iter_rev rbegin() const
Returns an iterator to the last set bit.
Definition dbitset.h:250
dbitset & operator=(const dbitset &other)
Copy-assigns a bit set.
Definition dbitset.h:127
iter end() const
Returns the forward set-bit sentinel.
Definition dbitset.h:244
GAIA_NODISCARD bool operator[](uint32_t pos) const
Tests a bit.
Definition dbitset.h:287
GAIA_NODISCARD bool all() const
Checks if all bits are set.
Definition dbitset.h:426
void flip(uint32_t pos)
Flips one bit.
Definition dbitset.h:361
GAIA_NODISCARD bool test(uint32_t pos) const
Returns the value of one bit.
Definition dbitset.h:419
iter_rev_inv riend() const
Returns the reverse unset-bit sentinel.
Definition dbitset.h:280
GAIA_NODISCARD bool operator!=(const dbitset &other) const
Compares two bit sets for inequality.
Definition dbitset.h:306
void flip()
Flips all bits.
Definition dbitset.h:344
dbitset(const dbitset &other)
Copy-constructs a bit set.
Definition dbitset.h:119
void reserve(uint32_t bitsWanted)
Reserves storage without changing the current bit count.
Definition dbitset.h:165
void resize(uint32_t bitsWanted)
Changes the number of addressable bits.
Definition dbitset.h:199
const_reverse_iterator< dbitset > iter_rev
Reverse iterator over set bit indices.
Definition dbitset.h:90
iter_inv iend() const
Returns the forward unset-bit sentinel.
Definition dbitset.h:268
dbitset & operator=(dbitset &&other) noexcept
Move-assigns a bit set and leaves the source empty.
Definition dbitset.h:150
void set()
Sets all bits.
Definition dbitset.h:316
GAIA_NODISCARD bool any() const
Checks if any bit is set.
Definition dbitset.h:443
iter begin() const
Returns an iterator to the first set bit.
Definition dbitset.h:238
void reset(uint32_t pos)
Unsets one bit.
Definition dbitset.h:411
dbitset & flip(uint32_t bitFrom, uint32_t bitTo)
Flips an inclusive range of bits.
Definition dbitset.h:370