Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
bit_utils.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstdint>
5
6#include "gaia/core/span.h"
7
8namespace gaia {
9 namespace core {
10 template <uint32_t BlockBits>
11 struct bit_view {
12 static constexpr uint32_t MaxValue = (1 << BlockBits) - 1;
13
14 std::span<uint8_t> m_data;
15
16 void set(uint32_t bitPosition, uint8_t value) noexcept {
17 GAIA_ASSERT(bitPosition < (m_data.size() * 8));
18 GAIA_ASSERT(value <= MaxValue);
19
20 const uint32_t idxByte = bitPosition / 8;
21 const uint32_t idxBit = bitPosition % 8;
22
23 const uint32_t mask = ~(MaxValue << idxBit);
24 m_data[idxByte] = (uint8_t)(((uint32_t)m_data[idxByte] & mask) | ((uint32_t)value << idxBit));
25
26 const bool overlaps = idxBit + BlockBits > 8;
27 if (overlaps) {
28 // Value spans over two bytes
29 const uint32_t shift2 = 8U - idxBit;
30 const uint32_t mask2 = ~(MaxValue >> shift2);
31 m_data[idxByte + 1] = (uint8_t)(((uint32_t)m_data[idxByte + 1] & mask2) | ((uint32_t)value >> shift2));
32 }
33 }
34
35 uint8_t get(uint32_t bitPosition) const noexcept {
36 GAIA_ASSERT(bitPosition < (m_data.size() * 8));
37
38 const uint32_t idxByte = bitPosition / 8;
39 const uint32_t idxBit = bitPosition % 8;
40
41 const uint8_t byte1 = (m_data[idxByte] >> idxBit) & MaxValue;
42
43 const bool overlaps = idxBit + BlockBits > 8;
44 if (overlaps) {
45 // Value spans over two bytes
46 const uint32_t shift2 = uint8_t(8U - idxBit);
47 const uint32_t mask2 = MaxValue >> shift2;
48 const uint8_t byte2 = uint8_t(((uint32_t)m_data[idxByte + 1] & mask2) << shift2);
49 return byte1 | byte2;
50 }
51
52 return byte1;
53 }
54 };
55
56 template <typename T>
57 inline auto swap_bits(T& mask, uint32_t left, uint32_t right) {
58 // Swap the bits in the read-write mask
59 const uint32_t b0 = (mask >> left) & 1U;
60 const uint32_t b1 = (mask >> right) & 1U;
61 // XOR the two bits
62 const uint32_t bxor = b0 ^ b1;
63 // Put the XOR bits back to their original positions
64 const uint32_t m = (bxor << left) | (bxor << right);
65 // XOR mask with the original one effectively swapping the bits
66 mask = mask ^ (uint8_t)m;
67 }
68 } // namespace core
69} // namespace gaia
Definition span_impl.h:99
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition bit_utils.h:11