5#ifndef __NBFS_BIT_LIST_H
6#define __NBFS_BIT_LIST_H
10#define __bit_list_words(__n) \
11 (((uint8_t)((__n) >> 5)) + ((uint8_t)((((__n) & 0x1f) == 0) ? 0 : 1)))
13#define do_forall(x,n,...) for (uint8_t x = 0; x < __bit_list_words((n)); x++) {__VA_ARGS__}
15template <u
int16_t _nbits>
18 uint32_t bits[__bit_list_words(_nbits)];
20 static constexpr uint32_t
21 _whichword(uint8_t idx)
24 static constexpr uint32_t
25 _whichbit(uint8_t idx)
26 {
return idx & 0x1F; }
28 static constexpr uint32_t
30 {
return ((uint32_t)1UL) << _whichbit(idx); }
34 {
return bits[_whichword(idx)]; }
37 _getword(uint8_t idx)
const
38 {
return bits[_whichword(idx)]; }
40 void _xor(
const bit_list<_nbits>& rhs)
41 { do_forall(i, _nbits, bits[i] ^= rhs.bits[i];) }
43 void _and(
const bit_list<_nbits>& rhs)
44 { do_forall(i, _nbits, bits[i] &= rhs.bits[i];) }
46 void _or(
const bit_list<_nbits>& rhs)
47 { do_forall(i, _nbits, bits[i] |= rhs.bits[i];) }
49 bool _isequal(
const bit_list<_nbits>& rhs)
50 { do_forall(i, _nbits,
if (bits[i] != rhs.bit[i])
return false;) }
57 bit_t(bit_list &list, uint8_t idx)
58 : _stor(list.bits[_whichword(idx)]), pos(_whichbit(idx))
60 bit_t(uint32_t &word, uint8_t bitPos)
61 : _stor(word), pos(bitPos)
64 operator bool() {
return _stor & bit_list::_maskbit(pos); }
66 bit_t& operator=(
bool rhs)
68 if (rhs) { _stor |= bit_list::_maskbit(pos); }
69 else { _stor &= ~bit_list::_maskbit(pos); }
74 bit_t& operator=(
const bit_t& rhs)
76 if ((rhs._stor) & bit_list::_maskbit(rhs.pos))
77 _stor |= bit_list::_maskbit(pos);
79 _stor &= ~bit_list::_maskbit(pos);
83 friend class bit_list;
99 : list(NULL), _wordIdx(__bit_list_words(_nbits)), _bitPos(0)
102 iterator(
const bit_list *_list)
103 : list(_list), _wordIdx(0), _bitPos(0)
104 {
if (!(list->bits[_wordIdx] & 0x1)) operator++(); }
106 iterator(
const bit_list *_list, uint8_t word, uint8_t bitPos)
107 : list(_list), _wordIdx(word), _bitPos(bitPos)
109 iterator(
const iterator &it)
110 : list(it.list), _wordIdx(it._wordIdx), _bitPos(it._bitPos)
113 iterator & operator=(
const iterator& rhs)
114 { list = rhs.list; _wordIdx = rhs._wordIdx; _bitPos = rhs._bitPos;
return *
this; }
116 iterator& operator++()
118 uint32_t wordVal, searchMask;
120 while ((_wordIdx + (_bitPos==31)) < __bit_list_words(_nbits))
124 searchMask = ~((0x2 << _bitPos) - 1);
125 wordVal = list->bits[_wordIdx] & searchMask;
130 wordVal = list->bits[_wordIdx];
134 _bitPos = __builtin_ctz(wordVal);
139 _wordIdx = __bit_list_words(_nbits);
146 iterator& operator--()
148 uint32_t wordVal, searchMask;
149 if (!(_wordIdx || _bitPos))
155 wordVal = list->bits[_wordIdx - 1] & 0xFFFFFFFF;
159 _bitPos = (31-__builtin_clz(wordVal));
165 searchMask = ((0x1 << _bitPos) - 1);
166 wordVal = list->bits[_wordIdx] & searchMask;
169 _bitPos = (31-__builtin_clz(wordVal));
176 }
while (_wordIdx--);
179 _wordIdx = __bit_list_words(_nbits);
183 iterator operator++(
int) { iterator tmp(*
this); operator++();
return tmp; }
184 iterator operator--(
int) { iterator tmp(*
this); operator--();
return tmp; }
187 bool operator==(
const iterator &rhs)
const
189 return ((list == rhs.list)
190 && (_wordIdx == rhs._wordIdx)
191 && (_bitPos == rhs._bitPos));
194 bool operator!=(
const iterator &rhs)
const
196 return !((list == rhs.list)
197 && (_wordIdx == rhs._wordIdx)
198 && (_bitPos == rhs._bitPos));
201 uint8_t operator*() {
return (_wordIdx << 5) + _bitPos; }
203 friend class bit_list;
205 friend class iterator;
207 inline void clr_all()
209 for (
int i = 0; i < __bit_list_words(_nbits); i++)
212 inline void set_all()
214 for (
int i = 0; i < __bit_list_words(_nbits); i++)
215 bits[i] = 0xffffffff;
217 bool set(uint8_t bit,
bool val =
true)
219 uint32_t msk = 1 << (bit & 0x1f);
220 uint32_t *w = bits + (bit >> 5);
222 *w = (*w & ~msk) | (-val & msk);
226 bool clr(uint8_t bit)
227 {
return set(bit,
false); }
229 bool test(uint8_t bit)
const
230 {
return bits[_whichword(bit)] & _maskbit(bit); }
232 bit_list<_nbits> flip()
233 { do_forall(i, _nbits, bits[i] = ~bits[i];)
return *
this; }
235 uint16_t count()
const
239 _ret += __builtin_popcount(bits[i]);
241 return (uint16_t) _ret;
245 { do_forall(i, _nbits,
if (bits[i] != 0xFFFFFFFF)
return false;)
return true; }
248 { do_forall(i, _nbits,
if (bits[i])
return true;)
return false; }
256 {
return bit_list<_nbits>(*this).flip(); }
258 operator bool()
const
263 operator ^=(
const bit_list<_nbits>& rhs)
270 operator &=(
const bit_list<_nbits>& rhs)
277 operator |=(
const bit_list<_nbits>& rhs)
285 operator==(
const bit_list<_nbits>& rhs)
const
286 {
return isequal(rhs); }
289 operator!=(
const bit_list<_nbits>& rhs)
const
290 {
return !isequal(rhs); }
292 inline bit_t operator[](uint8_t bit)
293 {
return bit_t(_getword(bit), _whichbit(bit)); }
295 inline bool operator[](uint8_t bit)
const
296 {
return test(bit); }
298 iterator begin()
const
299 {
return iterator(
this); }
302 {
return iterator(
this, __bit_list_words(_nbits), 0); }
304 iterator last()
const
310 bit_list<_nbits>() { clr_all(); }
312 bit_list(
const bit_list& rhs)
313 { do_forall(i, _nbits, bits[i] = rhs.bits[i];) }
315 bit_list(uint32_t pattern)
316 { do_forall(i, _nbits, bits[i] = pattern;) }