2#include "gaia/config/config.h"
6#include "gaia/core/span.h"
12 template <u
int32_t BlockBits>
15 static constexpr uint32_t
MaxValue = (1 << BlockBits) - 1;
23 void set(uint32_t bitPosition, uint8_t value)
noexcept {
24 GAIA_ASSERT(bitPosition < (
m_data.size() * 8));
27 const uint32_t idxByte = bitPosition / 8;
28 const uint32_t idxBit = bitPosition % 8;
30 const uint32_t mask = ~(
MaxValue << idxBit);
31 m_data[idxByte] = (uint8_t)(((uint32_t)
m_data[idxByte] & mask) | ((uint32_t)value << idxBit));
33 const bool overlaps = idxBit + BlockBits > 8;
36 const uint32_t shift2 = 8U - idxBit;
37 const uint32_t mask2 = ~(
MaxValue >> shift2);
38 m_data[idxByte + 1] = (uint8_t)(((uint32_t)
m_data[idxByte + 1] & mask2) | ((uint32_t)value >> shift2));
45 uint8_t
get(uint32_t bitPosition)
const noexcept {
46 GAIA_ASSERT(bitPosition < (
m_data.size() * 8));
48 const uint32_t idxByte = bitPosition / 8;
49 const uint32_t idxBit = bitPosition % 8;
53 const bool overlaps = idxBit + BlockBits > 8;
56 const uint32_t shift2 = uint8_t(8U - idxBit);
57 const uint32_t mask2 =
MaxValue >> shift2;
58 const uint8_t byte2 = uint8_t(((uint32_t)
m_data[idxByte + 1] & mask2) << shift2);
73 inline auto swap_bits(T& mask, uint32_t left, uint32_t right) {
75 const uint32_t b0 = (mask >> left) & 1U;
76 const uint32_t b1 = (mask >> right) & 1U;
78 const uint32_t bxor = b0 ^ b1;
80 const uint32_t m = (bxor << left) | (bxor << right);
82 mask = mask ^ (uint8_t)m;
Provides packed access to fixed-width unsigned values stored in a byte span.
Definition bit_utils.h:13
uint8_t get(uint32_t bitPosition) const noexcept
Reads a packed value from the specified bit position.
Definition bit_utils.h:45
std::span< uint8_t > m_data
Bytes containing the packed values.
Definition bit_utils.h:18
void set(uint32_t bitPosition, uint8_t value) noexcept
Stores a packed value at the specified bit position.
Definition bit_utils.h:23
static constexpr uint32_t MaxValue
Largest value representable by one packed block.
Definition bit_utils.h:15