3template <
class Container>
6 return (uiBitIndex >> 5);
9template <
class Container>
12 return 1 << (uiBitIndex & 0x1F);
15template <
class Container>
21template <
class Container>
25 const plUInt32 uiInts = (uiBitCount + 31) >> 5;
28 m_uiCount = uiBitCount;
31template <
class Container>
34 if (m_uiCount == uiBitCount)
37 const plUInt32 uiOldBits = m_uiCount;
39 SetCountUninitialized(uiBitCount);
42 if (uiBitCount > uiOldBits)
45 SetBitRange(uiOldBits, uiBitCount - uiOldBits);
47 ClearBitRange(uiOldBits, uiBitCount - uiOldBits);
51template <
class Container>
54 return m_uiCount == 0;
57template <
class Container>
60 if (m_uiCount == 0 || uiNumBits == 0)
63 PL_ASSERT_DEBUG(uiFirstBit < m_uiCount,
"Cannot access bit {0}, the bitfield only has {1} bits.", uiFirstBit, m_uiCount);
67 const plUInt32 uiFirstInt = GetBitInt(uiFirstBit);
68 const plUInt32 uiLastInt = GetBitInt(uiLastBit);
71 if (uiFirstInt == uiLastInt)
73 for (plUInt32 i = uiFirstBit; i <= uiLastBit; ++i)
81 const plUInt32 uiNextIntBit = (uiFirstInt + 1) * 32;
82 const plUInt32 uiPrevIntBit = uiLastInt * 32;
85 for (plUInt32 i = uiFirstBit; i < uiNextIntBit; ++i)
92 for (plUInt32 i = uiFirstInt + 1; i < uiLastInt; ++i)
94 if ((m_Container[i] & 0xFFFFFFFF) != 0)
99 for (plUInt32 i = uiPrevIntBit; i <= uiLastBit; ++i)
109template <
class Container>
112 return !IsAnyBitSet(uiFirstBit, uiLastBit);
115template <
class Container>
118 if (m_uiCount == 0 || uiNumBits == 0)
121 PL_ASSERT_DEBUG(uiFirstBit < m_uiCount,
"Cannot access bit {0}, the bitfield only has {1} bits.", uiFirstBit, m_uiCount);
125 const plUInt32 uiFirstInt = GetBitInt(uiFirstBit);
126 const plUInt32 uiLastInt = GetBitInt(uiLastBit);
129 if (uiFirstInt == uiLastInt)
131 for (plUInt32 i = uiFirstBit; i <= uiLastBit; ++i)
139 const plUInt32 uiNextIntBit = (uiFirstInt + 1) * 32;
140 const plUInt32 uiPrevIntBit = uiLastInt * 32;
143 for (plUInt32 i = uiFirstBit; i < uiNextIntBit; ++i)
150 for (plUInt32 i = uiFirstInt + 1; i < uiLastInt; ++i)
152 if (m_Container[i] != 0xFFFFFFFF)
157 for (plUInt32 i = uiPrevIntBit; i <= uiLastBit; ++i)
167template <
class Container>
174template <
class Container>
177 PL_ASSERT_DEBUG(uiBit < m_uiCount,
"Cannot access bit {0}, the bitfield only has {1} bits.", uiBit, m_uiCount);
179 m_Container[GetBitInt(uiBit)] |= GetBitMask(uiBit);
182template <
class Container>
185 PL_ASSERT_DEBUG(uiBit < m_uiCount,
"Cannot access bit {0}, the bitfield only has {1} bits.", uiBit, m_uiCount);
187 m_Container[GetBitInt(uiBit)] &= ~GetBitMask(uiBit);
190template <
class Container>
203template <
class Container>
206 PL_ASSERT_DEBUG(uiBit < m_uiCount,
"Cannot access bit {0}, the bitfield only has {1} bits.", uiBit, m_uiCount);
208 return (m_Container[GetBitInt(uiBit)] & GetBitMask(uiBit)) != 0;
211template <
class Container>
214 for (plUInt32 i = 0; i < m_Container.GetCount(); ++i)
218template <
class Container>
221 for (plUInt32 i = 0; i < m_Container.GetCount(); ++i)
222 m_Container[i] = 0xFFFFFFFF;
225template <
class Container>
228 if (m_uiCount == 0 || uiNumBits == 0)
231 PL_ASSERT_DEBUG(uiFirstBit < m_uiCount,
"Cannot access bit {0}, the bitfield only has {1} bits.", uiFirstBit, m_uiCount);
233 const plUInt32 uiLastBit = uiFirstBit + uiNumBits - 1;
235 const plUInt32 uiFirstInt = GetBitInt(uiFirstBit);
236 const plUInt32 uiLastInt = GetBitInt(uiLastBit);
239 if (uiFirstInt == uiLastInt)
241 for (plUInt32 i = uiFirstBit; i <= uiLastBit; ++i)
247 const plUInt32 uiNextIntBit = (uiFirstInt + 1) * 32;
248 const plUInt32 uiPrevIntBit = uiLastInt * 32;
251 for (plUInt32 i = uiFirstBit; i < uiNextIntBit; ++i)
255 for (plUInt32 i = uiFirstInt + 1; i < uiLastInt; ++i)
256 m_Container[i] = 0xFFFFFFFF;
259 for (plUInt32 i = uiPrevIntBit; i <= uiLastBit; ++i)
263template <
class Container>
266 if (m_uiCount == 0 || uiNumBits == 0)
269 PL_ASSERT_DEBUG(uiFirstBit < m_uiCount,
"Cannot access bit {0}, the bitfield only has {1} bits.", uiFirstBit, m_uiCount);
271 const plUInt32 uiLastBit = uiFirstBit + uiNumBits - 1;
273 const plUInt32 uiFirstInt = GetBitInt(uiFirstBit);
274 const plUInt32 uiLastInt = GetBitInt(uiLastBit);
277 if (uiFirstInt == uiLastInt)
279 for (plUInt32 i = uiFirstBit; i <= uiLastBit; ++i)
285 const plUInt32 uiNextIntBit = (uiFirstInt + 1) * 32;
286 const plUInt32 uiPrevIntBit = uiLastInt * 32;
289 for (plUInt32 i = uiFirstBit; i < uiNextIntBit; ++i)
293 for (plUInt32 i = uiFirstInt + 1; i < uiLastInt; ++i)
297 for (plUInt32 i = uiPrevIntBit; i <= uiLastBit; ++i)
301template <
class Container>
305 m_Container.Swap(other.m_Container);
308template <
class Container>
314template <
class Container>
323template <
class Container>
326 m_pBitfield = &bitfield;
330template <
class Container>
333 return m_pBitfield !=
nullptr;
336template <
class Container>
339 return *m_Iterator + (m_uiChunk << 5);
342template <
class Container>
346 if (!m_Iterator.IsValid())
348 FindNextChunk(m_uiChunk + 1);
352template <
class Container>
355 return m_pBitfield == other.m_pBitfield && m_Iterator == other.m_Iterator && m_uiChunk == other.m_uiChunk;
358template <
class Container>
361 return m_pBitfield != other.m_pBitfield || m_Iterator != other.m_Iterator || m_uiChunk != other.m_uiChunk;
364template <
class Container>
370template <
class Container>
376template <
class Container>
379 if (uiStartChunk < m_pBitfield->m_Container.GetCount())
381 const plUInt32 uiLastChunk = m_pBitfield->m_Container.GetCount() - 1;
382 for (plUInt32 i = uiStartChunk; i < uiLastChunk; ++i)
384 if (m_pBitfield->m_Container[i] != 0)
387 m_Iterator = sub_iterator(m_pBitfield->m_Container[i]);
392 const plUInt32 uiMask = 0xFFFFFFFF >> (32 - (m_pBitfield->m_uiCount - (uiLastChunk << 5)));
393 if ((m_pBitfield->m_Container[uiLastChunk] & uiMask) != 0)
395 m_uiChunk = uiLastChunk;
396 m_Iterator = sub_iterator(m_pBitfield->m_Container[uiLastChunk] & uiMask);
402 m_pBitfield =
nullptr;
404 m_Iterator = sub_iterator();
414 static_assert(std::is_unsigned<T>::value,
"Storage type must be unsigned");
426 return m_Storage != 0;
432 return m_Storage == 0;
438 const T inv = ~m_Storage;
445 PL_ASSERT_DEBUG(uiFirstBit < GetStorageTypeBitCount(),
"Cannot access first bit {0}, the bitfield only has {1} bits.", uiFirstBit, GetStorageTypeBitCount());
447 T mask = (uiNumBits / 8 >=
sizeof(T)) ? (~static_cast<T>(0)) : ((
static_cast<T
>(1) << uiNumBits) - 1);
456 PL_ASSERT_DEBUG(uiFirstBit < GetStorageTypeBitCount(),
"Cannot access first bit {0}, the bitfield only has {1} bits.", uiFirstBit, GetStorageTypeBitCount());
458 T mask = (uiNumBits / 8 >=
sizeof(T)) ? (~static_cast<T>(0)) : ((
static_cast<T
>(1) << uiNumBits) - 1);
496 PL_ASSERT_DEBUG(uiBit < GetStorageTypeBitCount(),
"Cannot access bit {0}, the bitfield only has {1} bits.", uiBit, GetStorageTypeBitCount());
498 return (m_Storage & (
static_cast<T
>(1u) << uiBit)) != 0;
504 PL_ASSERT_DEBUG(uiBit < GetStorageTypeBitCount(),
"Cannot access bit {0}, the bitfield only has {1} bits.", uiBit, GetStorageTypeBitCount());
506 m_Storage &= ~(
static_cast<T
>(1u) << uiBit);
525 PL_ASSERT_DEBUG(uiBit < GetStorageTypeBitCount(),
"Cannot access bit {0}, the bitfield only has {1} bits.", uiBit, GetStorageTypeBitCount());
527 m_Storage |=
static_cast<T
>(1u) << uiBit;
A template interface, that turns any array class into a bitfield.
Definition Bitfield.h:17
bool IsEmpty() const
Returns true, if the bitfield does not store any bits.
Definition Bitfield_inl.h:52
void SetBitValue(plUInt32 uiBit, bool bValue)
Sets the given bit to 1 or 0 depending on the given value.
Definition Bitfield_inl.h:191
void SetCount(plUInt32 uiBitCount, bool bSetNew=false)
Resizes the Bitfield to hold the given number of bits. If bSetNew is true, new bits are set to 1,...
Definition Bitfield_inl.h:32
bool IsNoBitSet(plUInt32 uiFirstBit=0, plUInt32 uiNumBits=0xFFFFFFFF) const
Returns true, if the bitfield is empty or all bits are set to zero.
Definition Bitfield_inl.h:110
void ClearBit(plUInt32 uiBit)
Clears the given bit to 0.
Definition Bitfield_inl.h:183
ConstIterator GetIterator() const
Returns a constant iterator to the very first set bit. Note that due to the way iterating through bit...
Definition Bitfield_inl.h:309
bool IsBitSet(plUInt32 uiBit) const
Returns true, if the given bit is set to 1.
Definition Bitfield_inl.h:204
plUInt32 GetCount() const
Returns the number of bits that this bitfield stores.
Definition Bitfield_inl.h:16
void SetCountUninitialized(plUInt32 uiBitCount)
Resizes the Bitfield to hold the given number of bits. This version does NOT initialize new bits!
Definition Bitfield_inl.h:23
bool AreAllBitsSet(plUInt32 uiFirstBit=0, plUInt32 uiNumBits=0xFFFFFFFF) const
Returns true, if the bitfield is not empty and all bits are set to one.
Definition Bitfield_inl.h:116
void ClearBitRange(plUInt32 uiFirstBit, plUInt32 uiNumBits)
Clears the range starting at uiFirstBit up to (and including) uiLastBit to 0.
Definition Bitfield_inl.h:264
void SetBit(plUInt32 uiBit)
Sets the given bit to 1.
Definition Bitfield_inl.h:175
void SetBitRange(plUInt32 uiFirstBit, plUInt32 uiNumBits)
Sets the range starting at uiFirstBit up to (and including) uiLastBit to 1.
Definition Bitfield_inl.h:226
void Clear()
Discards all bits and sets count to zero.
Definition Bitfield_inl.h:168
void SetAllBits()
Sets all bits to 1.
Definition Bitfield_inl.h:219
ConstIterator GetEndIterator() const
Returns an invalid iterator. Needed to support range based for loops.
Definition Bitfield_inl.h:315
void Swap(plBitfield< Container > &other)
Swaps two bitfields.
Definition Bitfield_inl.h:302
void ClearAllBits()
Clears all bits to 0.
Definition Bitfield_inl.h:212
bool IsAnyBitSet(plUInt32 uiFirstBit=0, plUInt32 uiNumBits=0xFFFFFFFF) const
Returns true, if the bitfield is not empty and any bit is 1.
Definition Bitfield_inl.h:58
Definition Bitfield.h:167
void Swap(plStaticBitfield< T > &other)
Swaps two bitfields.
Definition Bitfield_inl.h:543
plUInt32 GetLowestBitSet() const
Returns the index of the lowest bit that is set. Returns the max index+1 in case no bit is set,...
Definition Bitfield_inl.h:476
bool IsBitSet(plUInt32 uiBit) const
Returns true, if the given bit is set to 1.
Definition Bitfield_inl.h:494
void ClearBit(plUInt32 uiBit)
Clears the given bit to 0.
Definition Bitfield_inl.h:502
bool IsAnyBitSet() const
Returns true, if the bitfield is not zero.
Definition Bitfield_inl.h:424
void ClearBitRange(plUInt32 uiFirstBit, plUInt32 uiNumBits)
Clears the range starting at uiFirstBit up to (and including) uiLastBit to 0.
Definition Bitfield_inl.h:443
bool AreAllBitsSet() const
Returns true, if the bitfield is not empty and all bits are set to one.
Definition Bitfield_inl.h:436
void SetAllBits()
Sets all bits to 1.
Definition Bitfield_inl.h:482
void SetValue(T value)
Sets the raw uint that stores all bits.
Definition Bitfield_inl.h:531
plStaticBitfield()
Initializes the bitfield to all zero.
Definition Bitfield_inl.h:412
bool IsNoBitSet() const
Returns true, if the bitfield is all zero.
Definition Bitfield_inl.h:430
plUInt32 GetNumBitsSet() const
Returns the count of how many bits are set in total.
Definition Bitfield_inl.h:464
void ClearAllBits()
Clears all bits to 0. Same as Clear().
Definition Bitfield_inl.h:488
T GetValue() const
Returns the raw uint that stores all bits.
Definition Bitfield_inl.h:537
void SetBitValue(plUInt32 uiBit, bool bValue)
Sets the given bit to 1 or 0 depending on the given value.
Definition Bitfield_inl.h:510
void SetBitRange(plUInt32 uiFirstBit, plUInt32 uiNumBits)
Sets the range starting at uiFirstBit up to (and including) uiLastBit to 1.
Definition Bitfield_inl.h:454
void SetBit(plUInt32 uiBit)
Sets the given bit to 1.
Definition Bitfield_inl.h:523
plUInt32 GetHighestBitSet() const
Returns the index of the highest bit that is set. Returns the max index+1 in case no bit is set,...
Definition Bitfield_inl.h:470
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
PL_ALWAYS_INLINE plUInt32 FirstBitHigh(plUInt32 value)
Returns the index of the most significant bit set.
Definition Math_inl.h:119
constexpr TYPE MaxValue()
Returns the largest possible positive value (that is not infinity).
PL_ALWAYS_INLINE plUInt32 FirstBitLow(plUInt32 value)
Returns the index of the least significant bit set.
Definition Math_inl.h:70
PL_ALWAYS_INLINE plUInt32 CountBits(plUInt32 value)
Returns the number of bits set.
Definition Math_inl.h:186
PL_ALWAYS_INLINE void Swap(T &ref_f1, T &ref_f2)
Swaps the values in the two variables f1 and f2.
Definition Math_inl.h:224
void operator++()
Shorthand for 'Next'.
Definition Bitfield_inl.h:371
plUInt32 Value() const
Returns the 'value' of the element that this iterator points to.
Definition Bitfield_inl.h:337
bool IsValid() const
Checks whether this iterator points to a valid element.
Definition Bitfield_inl.h:331
plUInt32 operator*() const
Returns 'Value()' to enable foreach.
Definition Bitfield_inl.h:365
void Next()
Advances the iterator to the next element in the map. The iterator will not be valid anymore,...
Definition Bitfield_inl.h:343