convert vector of uint8_t to bitset

3.6k views Asked by At

In the following code I've a uint8_t vector filled from some binary file which contains information in some_size number of bytes -

std::ifstream db(path.c_str(), std::ios::binary);
std::vector <uint8_t> buffer(some_size, 0);
db.read(reinterpret_cast<char *>(&buffer.front()), some_size);
db.close();

Now I know from some index say 20, there exists 37 bytes of either 1 or 0 which I need to fill into a bitset. The bitset looks like std::bitset<37> booleans; and is initialized to all 0s initially. Now if initial index is 20, so I need to fill booleans with 37 boolean values that are present in bytes which will range from buffer[20] to buffer[56].

Apart from looping over the vector and manually setting 1 or 0 on each bit in bitset, is there any other way to convert those bytes to this bitset?

2

There are 2 answers

2
PaulMcKenzie On BEST ANSWER

Since you don't want to write a hand-coded loop, you can use std::for_each:

#include <bitset>
#include <cstdint>
#include <vector>
#include <algorithm>

int main()
{
    std::vector <uint8_t> buffer(100, 0);
    std::bitset<37> b;
    std::size_t i = 0;
    std::for_each(buffer.begin() + 20, buffer.begin() + 57, [&](uint8_t val)
    { b[i] = val; ++i; });
}

The underlying issue is that std::bitset doesn't have iterators, so the familiar STL algorithm functions such as std::copy, std::copy_n, std::transform, etc. that require iterators are difficult, if not impossible to be used if std::bitset is a source (or target) in the algorithm function. Thus it seems that std::for_each with a lambda that increments an index will work.

1
Andrei On

You can do something like this:

std::vector<uint8_t> sourceVec{1,0,1,1,0};
std::stringstream strStream;
std::copy(sourceVec.begin(), sourceVec.end(), std::ostream_iterator<int>(strStream));
std::bitset<5> bitsetVar(strStream.str());