NDEVR
API Documentation
BitAlignedBuffer.h
1#pragma once
2#include <NDEVR/Buffer.h>
3namespace NDEVR
4{
14 {
15 public:
20 BitAlignedBuffer(uint04 bits_per_element)
21 : m_bits_per_element(bits_per_element)
22 {
23 lib_assert(bits_per_element != 0 && bits_per_element < 64, "Bad Bit Alignment");
24 }
25
30 {
32 m_size = size;
33 }
34
39 void loadFromBytes(const uint8_t* data, uint04 byteCount)
40 {
41 lib_assert(data && byteCount > 0, "Invalid input data");
42
43 // Resize storage to hold the incoming bytes
44 uint04 word_count = (byteCount + 7) / 8;
45 storage.setSize(word_count, 0);
46
47 // Copy bytes into storage
48 for (uint04 i = 0; i < byteCount; ++i)
49 {
50 uint04 wordIndex = i / 8;
51 uint04 byte_offset = i % 8;
52 storage[wordIndex] |= static_cast<uint08>(data[i]) << (byte_offset * 8);
53 }
54
55 // Compute new size (number of elements)
56 uint04 total_bits = byteCount * 8;
57 m_size = total_bits / m_bits_per_element;;
58 }
59
63 void add(uint08 value)
64 {
65 lib_assert(value < (1ULL << m_bits_per_element), "value too large");
66 ensureCapacity(m_size + 1);
67
68 uint04 bitPos = m_size * m_bits_per_element;
69 uint04 wordIndex = bitPos / 64;
70 uint04 bitOffset = bitPos % 64;
71
72 // Clear destination bits
73 storage[wordIndex] &= ~(((1ULL << m_bits_per_element) - 1) << bitOffset);
74 // Write the value
75 storage[wordIndex] |= (value << bitOffset);
76
77 // Handle spillover to next word
78 if (bitOffset + m_bits_per_element > 64) {
79 uint08 spillBits = (bitOffset + m_bits_per_element) - 64;
80 storage[wordIndex + 1] &= ~((1ULL << spillBits) - 1);
81 storage[wordIndex + 1] |= (value >> (m_bits_per_element - spillBits));
82 }
83
84 ++m_size;
85 }
86
92 {
93 lib_assert(bit_pos < m_size * m_bits_per_element, "Index out of range");
94 uint04 word_index = bit_pos / 64;
95 uint04 bit_offset = bit_pos % 64;
96 uint04 and_value = ((1ULL << m_bits_per_element) - 1);
97 uint08 value = (storage[word_index] >> bit_offset) & and_value;
98
99 // Handle spillover to next word
100 if (bit_offset + m_bits_per_element > 64)
101 {
102 uint08 spillBits = (bit_offset + m_bits_per_element) - 64;
103 uint08 nextBits = storage[word_index + 1] & ((1ULL << spillBits) - 1);
104 value |= (nextBits << (m_bits_per_element - spillBits));
105 }
106
107 return value;
108 }
109
112 void clear()
113 {
114 storage.clear();
115 m_size = 0;
116 }
117
123 {
124 lib_assert(index < m_size, "Index out of range");
125 return getValueAtBitOffset(index * m_bits_per_element);
126 }
127
133 void set(uint04 index, uint08 value)
134 {
135 lib_assert(index < m_size, "Index out of range");
136 lib_assert(value < (1ULL << m_bits_per_element), "Value exceeds bit limit");
137
138 uint04 bitPos = index * m_bits_per_element;
139 uint04 wordIndex = bitPos / 64;
140 uint04 bitOffset = bitPos % 64;
141
142 // Clear destination bits
143 storage[wordIndex] &= ~(((1ULL << m_bits_per_element) - 1) << bitOffset);
144 // Write value
145 storage[wordIndex] |= (value << bitOffset);
146
147 // Handle spillover
148 if (bitOffset + m_bits_per_element > 64) {
149 uint08 spillBits = (bitOffset + m_bits_per_element) - 64;
150 storage[wordIndex + 1] &= ~((1ULL << spillBits) - 1);
151 storage[wordIndex + 1] |= (value >> (m_bits_per_element - spillBits));
152 }
153 }
154
159 {
160 return m_bits_per_element;
161 }
162
166 uint04 size() const
167 {
168 return m_size;
169 }
170
174 void ensureCapacity(uint04 newSize)
175 {
176 uint04 totalBits = newSize * m_bits_per_element;
177 uint04 requiredWords = (totalBits + 63) / 64;
178 if (storage.size() < requiredWords)
179 {
180 storage.setSize(requiredWords, 0U);
181 }
182 }
183 private:
184 uint04 m_bits_per_element;
185 uint04 m_size = 0;
186 Buffer<uint08> storage;
187 };
188
189}
uint08 operator[](uint04 index) const
Accesses the element at the given index (read-only).
uint04 size() const
Returns the number of elements currently stored in the buffer.
uint08 getValueAtBitOffset(uint04 bit_pos) const
Retrieves the value stored at a specific bit offset within the buffer.
void loadFromBytes(const uint8_t *data, uint04 byteCount)
Loads raw byte data into the buffer, replacing existing contents.
uint04 bitSize() const
Returns the number of bits used per element.
void clear()
Removes all elements and frees storage.
void ensureCapacity(uint04 newSize)
Ensures the internal storage can hold at least the specified number of elements.
void add(uint08 value)
Appends a value to the end of the buffer.
void set(uint04 index, uint08 value)
Sets the value of the element at the given index.
BitAlignedBuffer(uint04 bits_per_element)
Constructs a BitAlignedBuffer with the specified number of bits per element.
void setSize(uint04 size)
Sets the number of elements in the buffer, allocating storage as needed.
The equivelent of std::vector but with a bit more control.
Definition Buffer.hpp:58
The primary namespace for the NDEVR SDK.
uint64_t uint08
-Defines an alias representing an 8 byte, unsigned integer
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...