Nebula
Loading...
Searching...
No Matches
bitfield.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
18#include "core/types.h"
19
20//------------------------------------------------------------------------------
21namespace Util
22{
23template <unsigned int NUMBITS> class BitField
24{
25 static_assert(NUMBITS > 0);
26
27public:
31 constexpr BitField(std::initializer_list<unsigned int> list);
33 BitField(const BitField<NUMBITS>& rhs) = default;
35 BitField(const uint64_t mask);
36
38 constexpr bool operator==(const BitField<NUMBITS>& rhs) const;
40 constexpr bool operator!=(const BitField<NUMBITS>& rhs) const;
41
43 constexpr bool IsSet(const uint64_t bitIndex) const;
45 template <uint64_t bitIndex> constexpr bool IsSet() const;
47 void Clear();
49 bool IsNull() const;
51 constexpr void SetBit(const uint64_t bitIndex);
53 constexpr void SetBitIf(const uint64_t bitIndex, uint64_t cond);
55 template <uint64_t bitIndex> constexpr void SetBit();
57 void ClearBit(const uint64_t bitIndex);
58
64 bool SectionIsNull(uint64_t section) const;
65
67 static constexpr BitField<NUMBITS> Or(const BitField<NUMBITS>& b0, const BitField<NUMBITS>& b1);
69 static constexpr BitField<NUMBITS> And(const BitField<NUMBITS>& b0, const BitField<NUMBITS>& b1);
70
71private:
72 static constexpr uint64_t BASE = NUMBITS > 32 ? 64 : NUMBITS > 16 ? 32 : NUMBITS > 8 ? 16 : 8;
73 static const int size = ((NUMBITS + BASE - 1) / BASE);
74
75 // Template magic to automatically use the smallest type possible
76 template <size_t S> struct BitType
77 {
78 using T = uint8_t;
79 };
80 template <> struct BitType<16>
81 {
82 using T = uint16_t;
83 };
84 template <> struct BitType<32>
85 {
86 using T = uint32_t;
87 };
88 template <> struct BitType<64>
89 {
90 using T = uint64_t;
91 };
92
93 using TYPE = typename BitType<BASE>::T;
94
96
97public:
98 BitType<BASE>::T GetBits(size_t index) const
99 {
100 n_assert(index < size);
101 return this->bits[index];
102 }
103
104 void SetBits(size_t index, BitType<BASE>::T value)
105 {
106 n_assert(index < size);
107 this->bits[index] = value;
108 }
109};
110
111//------------------------------------------------------------------------------
114template <unsigned int NUMBITS> BitField<NUMBITS>::BitField()
115{
116 IndexT i;
117 for (i = 0; i < size; i++)
118 {
119 this->bits[i] = 0;
120 }
121}
122
123//------------------------------------------------------------------------------
126template <unsigned int NUMBITS> constexpr BitField<NUMBITS>::BitField(std::initializer_list<unsigned int> list)
127{
128 for (IndexT i = 0; i < size; i++)
129 {
130 this->bits[i] = 0;
131 }
132
133 for (auto bit : list)
134 {
135 this->SetBit(bit);
136 }
137}
138
139//------------------------------------------------------------------------------
142template<unsigned int NUMBITS>
143inline BitField<NUMBITS>::BitField(const uint64_t mask)
144{
145 for (IndexT i = 0; i < NUMBITS; i++)
146 {
147 if (mask & (1ull << i))
148 {
149 this->SetBit(i);
150 }
151 }
152}
153
154//------------------------------------------------------------------------------
157template <unsigned int NUMBITS>
158constexpr bool
160{
161 for (IndexT i = 0; i < size; i++)
162 {
163 if (this->bits[i] != rhs.bits[i])
164 {
165 return false;
166 }
167 }
168 return true;
169}
170
171//------------------------------------------------------------------------------
174template <unsigned int NUMBITS>
175constexpr bool
177{
178 return !(*this == rhs);
179}
180
181//------------------------------------------------------------------------------
184template <unsigned int NUMBITS>
185constexpr bool
186BitField<NUMBITS>::IsSet(const uint64_t bitIndex) const
187{
188 n_assert(bitIndex < NUMBITS);
189 const TYPE i = (1ull << (bitIndex % BASE));
190 const TYPE index = bitIndex / BASE;
191 return (this->bits[index] & i) == i;
192}
193
194//------------------------------------------------------------------------------
197template <unsigned int NUMBITS>
198template <uint64_t bitIndex>
199constexpr bool
201{
202 static_assert(bitIndex < NUMBITS);
203 constexpr TYPE i = (1ull << (bitIndex % BASE));
204 constexpr TYPE index = bitIndex / BASE;
205 return (this->bits[index] & i) == i;
206}
207
208//------------------------------------------------------------------------------
211template <unsigned int NUMBITS>
212void
214{
215 IndexT i;
216 for (i = 0; i < size; i++)
217 {
218 this->bits[i] = 0;
219 }
220}
221
222//------------------------------------------------------------------------------
225template <unsigned int NUMBITS>
226bool
228{
229 IndexT i;
230 for (i = 0; i < size; i++)
231 {
232 if (this->bits[i] != 0)
233 {
234 return false;
235 }
236 }
237 return true;
238}
239
240//------------------------------------------------------------------------------
243template <unsigned int NUMBITS>
244constexpr void
246{
247 n_assert(i < NUMBITS);
248 const TYPE index = i / BASE;
249 const TYPE bit = (1ull << (i % BASE));
250 this->bits[index] |= bit;
251}
252
253//------------------------------------------------------------------------------
256template <unsigned int NUMBITS>
257constexpr void
258BitField<NUMBITS>::SetBitIf(const uint64_t i, uint64_t cond)
259{
260 n_assert(i < NUMBITS);
261 const TYPE index = i / BASE;
262 const TYPE bit = (1ull << (i % BASE));
263 this->bits[index] |= bit * cond;
264}
265
266//------------------------------------------------------------------------------
269template <unsigned int NUMBITS>
270template <uint64_t i>
271constexpr void
273{
274 static_assert(i < NUMBITS);
275 constexpr TYPE index = i / BASE;
276 constexpr TYPE bit = (1ull << (i % BASE));
277 this->bits[index] |= bit;
278}
279
280//------------------------------------------------------------------------------
283template <unsigned int NUMBITS>
284void
286{
287 n_assert(i < NUMBITS);
288 const TYPE index = i / BASE;
289 const TYPE bit = ~(1ull << (i % BASE));
290 this->bits[index] &= bit;
291}
292
293//------------------------------------------------------------------------------
296template <unsigned int NUMBITS>
297bool
298BitField<NUMBITS>::SectionIsNull(uint64_t section) const
299{
300 n_assert(section < this->size);
301 return this->bits[section] == 0;
302}
303
304//------------------------------------------------------------------------------
307template <unsigned int NUMBITS>
308constexpr BitField<NUMBITS>
310{
312 for (IndexT i = 0; i < size; i++)
313 {
314 res.bits[i] = b0.bits[i] | b1.bits[i];
315 }
316 return res;
317}
318
319//------------------------------------------------------------------------------
322template <unsigned int NUMBITS>
323constexpr BitField<NUMBITS>
325{
327 for (IndexT i = 0; i < size; i++)
328 {
329 res.bits[i] = b0.bits[i] & b1.bits[i];
330 }
331 return res;
332}
333
334} // namespace Util
335//------------------------------------------------------------------------------
Implements large bit field.
Definition bitfield.h:24
constexpr bool operator==(const BitField< NUMBITS > &rhs) const
equality operator
Definition bitfield.h:159
static constexpr uint64_t BASE
Definition bitfield.h:72
void ClearBit(const uint64_t bitIndex)
clear a bit by index
Definition bitfield.h:285
constexpr bool operator!=(const BitField< NUMBITS > &rhs) const
inequality operator
Definition bitfield.h:176
BitType< BASE >::T GetBits(size_t index) const
Definition bitfield.h:98
BitField(const BitField< NUMBITS > &rhs)=default
copy constructor
bool IsNull() const
return true if all bits are 0
Definition bitfield.h:227
constexpr void SetBit()
set a bit by index
Definition bitfield.h:272
BitField(const uint64_t mask)
Construct from mask.
Definition bitfield.h:143
bool SectionIsNull(uint64_t section) const
Check if a section of the bitfield is set.
Definition bitfield.h:298
void SetBits(size_t index, BitType< BASE >::T value)
Definition bitfield.h:104
static constexpr BitField< NUMBITS > And(const BitField< NUMBITS > &b0, const BitField< NUMBITS > &b1)
set bitfield to AND combination
Definition bitfield.h:324
typename BitType< BASE >::T TYPE
Definition bitfield.h:93
constexpr void SetBitIf(const uint64_t bitIndex, uint64_t cond)
set a bit by index. Multiplies the bit with cond before OR-ing which means it won't set the bit if mu...
Definition bitfield.h:258
constexpr void SetBit(const uint64_t bitIndex)
set a bit by index
Definition bitfield.h:245
constexpr BitField(std::initializer_list< unsigned int > list)
constructs a bitfield based on multiple values
Definition bitfield.h:126
void Clear()
clear content
Definition bitfield.h:213
BitField()
constructor
Definition bitfield.h:114
constexpr bool IsSet(const uint64_t bitIndex) const
Check if single bit is set.
Definition bitfield.h:186
TYPE bits[size]
Definition bitfield.h:95
constexpr bool IsSet() const
Check if single bit is set.
Definition bitfield.h:200
static constexpr BitField< NUMBITS > Or(const BitField< NUMBITS > &b0, const BitField< NUMBITS > &b1)
set bitfield to OR combination
Definition bitfield.h:309
static const int size
Definition bitfield.h:73
#define n_assert(exp)
Definition debug.h:50
A pinned array is an array which manages its own virtual memory.
Definition String.cs:6
constexpr uint64_t SetBit(uint64_t mask, uint8_t bit)
Definition bit.h:21
uint16_t T
Definition bitfield.h:82
uint32_t T
Definition bitfield.h:86
uint64_t T
Definition bitfield.h:90
Definition bitfield.h:77
uint8_t T
Definition bitfield.h:78
int IndexT
Definition types.h:41