Can I initialize a std::vector<bool> from uint8_t (or std::byte) range so that every bit in input is treated as a boolean?

std::vector<bool> is a poor choice here, because you are thinking about it in terms of its implementation rather than its behavior.... just avoid vector<bool>.

Use a boost::dynamic_bitset instead. Anecdotally I have personally found it to be far more performant anyway:

std::array<std::uint8_t, 2> data {7,32};
boost::dynamic_bitset<std::uint8_t> vb(rbegin(data), rend(data));
std::cout << vb; // 0000011100100000

Live Demo

We have to reverse the input range because boost's dynamic bitset appends to the end where the most significant bit is (typically the left side), rather than the right side.


Using a boost container is most certainly the best way to go - but if that's not an option, you could create an iterator type to populate your vector<bool> directly on construction.

Example:

struct biterator {
    using value_type = bool;
    using reference = bool;
    using difference_type = std::ptrdiff_t;
    using pointer = uint8_t*;
    using iterator_category = std::forward_iterator_tag;

    biterator(const uint8_t* c) : curr(c), bit(1U<<7) {}
    biterator& operator++() { if(!(bit >>= 1)) { ++curr; bit = 1U<<7; } return *this; }
    bool operator*() const { return *curr & bit; }
    bool operator!=(const biterator& rhs) const { return curr != rhs.curr; }

private:
    const uint8_t* curr;
    uint8_t bit;
};

Usage:

uint8_t data [] = {7, 32};
    
std::vector<bool> vb(biterator(std::begin(data)), biterator(std::end(data)));

Demo


The proposal for this is P0237 Wording for fundamental bit manipulation utilities:

#include <bit>
#include <cstdint>
std::uint8_t data [] = {7,32};
std::vector<bool> vb(
    std::bit_iterator(std::begin(data), 0)),
    std::bit_iterator(std::end(data), 0)));

There is an implementation of P0237 (and N2050) called itsy.

Tags:

C++

Stdvector