16 using value_type = uint32_t;
17 using size_type =
typename TBitset::size_type;
20 const TBitset* m_bitset =
nullptr;
23 GAIA_NODISCARD size_type item(uint32_t wordIdx)
const noexcept {
24 if constexpr (IsInverse)
25 return ~m_bitset->data(wordIdx);
27 return m_bitset->data(wordIdx);
30 GAIA_NODISCARD
bool check_bit(uint32_t pos)
const noexcept {
31 if constexpr (IsInverse)
32 return !m_bitset->test(pos);
34 return m_bitset->test(pos);
37 GAIA_NODISCARD uint32_t find_next_set_bit(uint32_t pos)
const noexcept {
38 value_type wordIndex = pos / TBitset::BitsPerItem;
39 const auto item_count = m_bitset->items();
40 GAIA_ASSERT(wordIndex < item_count);
43 const size_type posInWord = pos % TBitset::BitsPerItem + 1;
44 if GAIA_LIKELY (posInWord < TBitset::BitsPerItem) {
45 const size_type mask = (size_type(1) << posInWord) - 1;
46 word = item(wordIndex) & (~mask);
49 GAIA_MSVC_WARNING_PUSH()
50 GAIA_MSVC_WARNING_DISABLE(4244)
53 if constexpr (TBitset::BitsPerItem == 32)
54 return wordIndex * TBitset::BitsPerItem + GAIA_FFS(word) - 1;
56 return wordIndex * TBitset::BitsPerItem + GAIA_FFS64(word) - 1;
60 if (++wordIndex >= item_count)
63 word = item(wordIndex);
65 GAIA_MSVC_WARNING_POP()
68 GAIA_NODISCARD uint32_t find_prev_set_bit(uint32_t pos)
const noexcept {
69 value_type wordIndex = pos / TBitset::BitsPerItem;
70 GAIA_ASSERT(wordIndex < m_bitset->items());
72 const size_type posInWord = pos % TBitset::BitsPerItem;
73 const size_type mask = (size_type(1) << posInWord) - 1;
74 size_type word = item(wordIndex) & mask;
76 GAIA_MSVC_WARNING_PUSH()
77 GAIA_MSVC_WARNING_DISABLE(4244)
80 if constexpr (TBitset::BitsPerItem == 32)
81 return TBitset::BitsPerItem * (wordIndex + 1) - GAIA_CTZ(word) - 1;
83 return TBitset::BitsPerItem * (wordIndex + 1) - GAIA_CTZ64(word) - 1;
90 word = item(--wordIndex);
92 GAIA_MSVC_WARNING_POP()
99 if constexpr (!IsFwd) {
101 if (pos != 0 || !check_bit(0)) {
102 pos = find_next_set_bit(m_pos);
105 pos = (value_type)-1;
112 if (pos != 0 || !check_bit(0)) {
113 pos = find_next_set_bit(m_pos);
122 const auto lastBit = bitsetSize - 1;
125 if (pos >= bitsetSize)
126 pos = bitsetSize - 1;
128 if constexpr (!IsFwd) {
130 if (pos != lastBit || !check_bit(pos)) {
131 const auto newPos = find_prev_set_bit(pos);
133 pos = (newPos == pos) ? bitsetSize - 1 : newPos;
137 if (pos != lastBit || !check_bit(pos)) {
138 const auto newPos = find_prev_set_bit(pos);
140 pos = (newPos == pos) ? bitsetSize : newPos + 1;
151 GAIA_NODISCARD value_type operator*()
const {
155 GAIA_NODISCARD value_type operator->()
const {
159 GAIA_NODISCARD value_type index()
const {
164 if constexpr (!IsFwd) {
165 if (m_pos == (value_type)-1)
168 auto newPos = find_prev_set_bit(m_pos);
174 auto newPos = find_next_set_bit(m_pos);
191 return m_pos == other.m_pos;
195 return m_pos != other.m_pos;