Reputation: 30006
I know that std::vector<bool>
is bad, but I have a really nice use case for it.
I would like to do something like this:
uint8_t data [] = {7,32};
std::vector<bool> vb/*...*/ ;
// now vb is size of 8 vector with this values:
// false, false, false, false, false, true, true, true, (7)
// false, false, true, false, false, false, false, false (32)
Note: I know I can manually disect every byte of input and make 8 inserts, but I am looking for something prebuilt in the standard
Upvotes: 7
Views: 1112
Reputation: 117288
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)));
Upvotes: 4
Reputation: 157324
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.
Upvotes: 3
Reputation: 41092
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
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.
Upvotes: 6