bit::vector — Exporting Bits

The bits from a bit-vector can be exported to fill various destinations — unsigned words, collections of unsigned words, or a std::bitset:

template<std::unsigned_integral Dst>
1constexpr void export_bits(Dst &dst) const;

template<typename Iter>
2constexpr void export_bits(Iter b, Iter e) const;

template<std::unsigned_integral Dst, std::size_t N>
3constexpr void export_bits(std::array<Dst, N> &dst) const;

template<std::unsigned_integral Dst>
4constexpr void export_bits(std::vector<Dst> &dst) const;

template<std::size_t N>
5constexpr void export_bits(std::bitset<N> &dst) const;
1
Initializes the word dst to zero and then fills it with as many bits as possible from the bit-vector.
2
Initializes an iteration of unsigned integers to zeros and fills them with as many bits as possible from the bit-vector.
3
Initializes an array of unsigned integers to zeros and fills it with as many bits as possible from the bit-vector.
4
Initializes a vector of unsigned integers to zeros and fills it with as many bits as possible from the bit-vector.
5
Sets all the bits in a std::bitset to zero and then fills it with as many bits as possible from the bit-vector.
These methods do not resize the destination. We start sourcing bits from the beginning of the bit-vector. We stop when we run out of source bits or have no more space to put the bits. Note that the destination gets initialized to all zeros. Thus, if the source bit-vector is empty, the destination will be returned filled with zeros.

In many applications, we use these export_bits functions to flip back and forth between bit-space and word-space.

In word-space, the sources and destinations are often a std::vector or a std::array, so we supply specializations for those collections — one could get by just using the versions of export_bits that take iterators.

Exporting ALL bits from a bit-vector

We also have a method that takes all the bits from a bit-vector and uses them to fill a vector of words of some unsigned type.

template<std::unsigned_integral Dst>
constexpr void export_all_bits(std::vector<Dst> &dst) const;

As the name suggests, this method first resizes the destination vector to accommodate all the bits in the source bit-vector and then copies them.

Template Parameters

Parameter Description
Dst Dst is the type of unsigned integer set from the bits in the source bit-vector. There is no requirement that Dst and Block are the same. For example, we can fill an array of 32-bit unsigned integers while the storage scheme for the bit-vector remains the default 64-bit type.
Iter An iterator — might be the type returned by any std::cbegin(collection) and std::cend(collection) Iter::value_type should be some unsigned integer type, but it need not match the Block type.
: {.bordered .hover .responsive tbl-colwidths=“[20,80]”}

Example — Overwriting a unsigned word(s) with the bits from a bit-vector

#include <bit/bit.h>
int main()
{
    auto v = bit::vector<std::uint8_t>::ones(77);

    std::cout << std::format("bit::vector: {:b}\n", v);
    std::cout << "Exporting that bit-vector to words of various types:\n";
    uint16_t word16;  v.export_bits(word16);
    std::cout << std::format("uint16_t:    {}\n", word16);
    uint32_t word32;  v.export_bits(word32);
    std::cout << std::format("uint32_t:    {}\n", word32);
    uint64_t word64;  v.export_bits(word64);
    std::cout << std::format("uint64_t:    {}\n", word64);
    std::cout << std::endl;

    std::cout << std::format("bit::vector: {:b}\n", v);
    std::cout << "Exporting that bit-vector to a std::array of words of various types:\n";
    constexpr std::size_t N = 4;
    std::array<uint16_t, N> arr16; v.export_bits(arr16);
    std::cout << std::format("std::array<uint16_t,4>: {}\n", arr16);
    std::array<uint32_t, N> arr32; v.export_bits(arr32);
    std::cout << std::format("std::array<uint32_t,4>: {}\n", arr32);
    std::array<uint64_t, N> arr64; v.export_bits(arr64);
    std::cout << std::format("std::array<uint64_t,4>: {}\n", arr64);
    std::cout << std::endl;

    std::cout << std::format("bit::vector: {:b}\n", v);
    std::cout << "Exporting that bit-vector to a std::vector of words of various types:\n";
    std::vector<uint16_t> vec16(N); v.export_bits(vec16);
    std::cout << std::format("std::vector<uint16_t>: {}\n", vec16);
    std::vector<uint32_t> vec32(N); v.export_bits(vec32);
    std::cout << std::format("std::vector<uint32_t>: {}\n", vec32);
    std::vector<uint64_t> vec64(N); v.export_bits(vec64);
    std::cout << std::format("std::vector<uint64_t>: {}\n", vec64);
    std::cout << std::endl;

    std::cout << std::format("bit::vector: {:b}\n", v);
    std::cout << "Exporting ALL of that bit-vector to a std::vector of words of various types:\n";
    v.export_all_bits(vec16);
    std::cout << std::format("std::vector<uint16_t>: {}\n", vec16);
    v.export_all_bits(vec32);
    std::cout << std::format("std::vector<uint32_t>: {}\n", vec32);
    v.export_all_bits(vec64);
    std::cout << std::format("std::vector<uint64_t>: {}\n", vec64);
    std::cout << std::endl;
}

Output – Assuming that std::format can handle std::arrays and std::vectors

bit::vector: 11111111111111111111111111111111111111111111111111111111111111111111111111111
Exporting that bit-vector to words of various types:
uint16_t:    65535
uint32_t:    4294967295
uint64_t:    18446744073709551615

bit::vector: 11111111111111111111111111111111111111111111111111111111111111111111111111111
Exporting that bit-vector to a std::array of words of various types:
std::array<uint16_t,4>: [65535, 65535, 65535, 65535]
std::array<uint32_t,4>: [4294967295, 4294967295, 8191, 0]
std::array<uint64_t,4>: [18446744073709551615, 8191, 0, 0]

bit::vector: 11111111111111111111111111111111111111111111111111111111111111111111111111111
Exporting that bit-vector to a std::vector of words of various types:
std::vector<uint16_t>: [65535, 65535, 65535, 65535]
std::vector<uint32_t>: [4294967295, 4294967295, 8191, 0]
std::vector<uint64_t>: [18446744073709551615, 8191, 0, 0]

bit::vector: 11111111111111111111111111111111111111111111111111111111111111111111111111111
Exporting ALL of that bit-vector to a std::vector of words of various types:
std::vector<uint16_t>: [65535, 65535, 65535, 65535, 8191]
std::vector<uint32_t>: [4294967295, 4294967295, 8191]
std::vector<uint64_t>: [18446744073709551615, 8191]

See Also

vector::append
vector::import_bits

Back to top