I have implemented a simple bit vector class. However, I have some problems with understanding, how to push data to it.
In a standard vector, push_back inserts new element et the end. A similar logic can be implemented for single bit.
However, I want to append number with a given precision. For example:
13 => 4bits (1101)
54 => 6bits (11 0110)
522 => 10bits (10 0000 1010)
Starting with a bit vector with bits:
x x x
I can append it from highest bit (left to right), so for eg. 54@6bits I got
x x x 11 0110
or I can append it from lowest bit (right to left), so for eg. 54@6bits I got
x x x 0110 11
For me, the first option seems more logical.
However, when I add aligned numbers 522@16bits I end up with for left to right
x x x 0000 0010 0000 1010
or from right to left
x x x 0101 0000 0100 0000
However, in this case (right to left), when I later wants to read data to memory, they are incorrect because of Endian. How to solve this logic?
I want to be able to append numbers with selected bits precision, and later copy them from memory to variables.
Currently, I have solved this as:
template <typename T>
void BitVector::Append(T number, Endian e){
if (e == BitVector::Endian::Big){
this->Append(number, sizeof(T));
}
else {
uint8_t tmp[sizeof(T)];
memcpy(tmp, &number, sizeof(T));
for (size_t i = 0; i < sizeof(T); i++){
this->Append(tmp[i], 8);
}
}
}
and
void BitVector::Append(uint64_t number, uint32_t bitSize){
for (long i = long(bitSize - 1); i >= 0; i--){
this->push_back((number >> i) & 1);
}
}
Templated Append with Little endian should correspond to setting elements of array.
BitVector bb;
bb.Append<uint16_t>(160, BitVector::Endian::Little);
bb.Append<uint16_t>(39, BitVector::Endian::Little);
uint16_t tmp[2];
tmp[0] = 160;
tmp[1] = 39;
uint8_t res[4];
memcpy(res, tmp, 4);
res
and internal data of bit vector now contains the same data.
However, I am not sure if this is the most readable way.