bit::vector — Construction

Constructors for a bit-vector.

1explicit constexpr bit::vector(std::size_t n = 0);

2explicit constexpr bit::vector(std::size_t n, Block value);

template<typename Iter>
    requires std::is_unsigned_v<typename std::iterator_traits<Iter>::value_type>
3explicit constexpr bit::vector(Iter b, Iter e);

template<std::unsigned_integral Src, std::size_t N>
4explicit constexpr vector(const std::array<Src, N>& src);

template<std::unsigned_integral Src>
5explicit constexpr vector(const std::vector<Src>& src);

template<std::size_t N>
6explicit constexpr bit::vector(const std::bitset<N> &bs);

explicit constexpr
7bit::vector(std::size_t n, std::invocable<std::size_t> auto f);

8explicit bit::vector(std::string_view str, bool bit_order = false);
1
Constructs a bit-vector with n elements all set to 0.
The default constructor creates the empty vector.
2
Create a bit-vector of size n by repeatedly copying the bits of a constant block value.
3
Construct a bit-vector from any iteration of unsigned integers.
The bits from each get appended to the vector.
4
Construct a bit-vector by copying all the bits from a std::array<Src, N> of N unsigned words.
5
Construct a bit-vector by copying all the bits from a std::vector<Src> of unsigned words.
6
Construct a bit-vector of size N from a std:::bitset<N>.
7
Construct a bit-vector with n elements using a function that takes a std::size_t argument.
Element i in the vector is set to 1 if f(i) != 0; otherwise it is 0.
8
Construct a bit-vector from a string that typically will be all 0’s and 1’s or all hex characters.
See below.

Template Parameters

Parameter Description
Iter An iterator — might be the type returned by any std::cbegin(collection) etc. Iter::value_type must be some unsigned integer type but not necessarily the same as Block.
Src The type of words we take bits from — must be some unsigned integer type but not necessarily the same as Block.
std::invocable std::invocable is the signature for a function over an index.

Method Arguments

Argument Description
n The size of the vector to construct.
f This function will be called as f(i) for \(i \in 0,\ldots,n-1\). A non-zero return is the signal to set the corresponding element in the vector to 1.
str A string that encodes the elements of the bit-vector. These are typically all 0’s and 1’s or they can be hex characters.
bit_order This defaults to false, but if present and set to true, any binary string is interpreted as encoding the bit-vector in bit-order where the least significant bit v~0 is on the right. This parameter is ignored for hex strings.

Construction from non-strings

Here are some examples of constructing a bit::vector from non-string data.

Example

#include <bit/bit.h>
int main()
{
1    bit::vector           v1;
2    bit::vector           v2{32};
    std::vector<uint16_t> vec{65535, 0};
3    bit::vector           v3{vec};
4    bit::vector           v4{32, [](size_t k) { return (k + 1) % 2; }};
    std::bitset<32>       bs{65535};
5    bit::vector           v5{bs};
    std::cout << "v1 = " << v1.to_string()    << '\n';
    std::cout << "v2 = " << v2.to_string()    << '\n';
    std::cout << "v3 = " << v3.to_string()    << '\n';
    std::cout << "v4 = " << v4.to_string()    << '\n';
    std::cout << "bs = " << bs                << '\n';
    std::cout << "v5 = " << v5.to_string()    << '\n';
    std::cout << "v5 = " << v5.to_bit_order() << " in bit-order!\n";
}
1
Default constructor makes an empty bit-vector.
2
bit::vector of size 32 whose elements default to 0.
3
bit::vector constructed from a std::vector containing two 16-bit integers.
4
bit::vector constructed using a lambda that returns true if the element index is even.
5
bit::vector constructed from a std::bitset.

Output

v1 =
v2 = 00000000000000000000000000000000
v3 = 11111111111111110000000000000000
v4 = 10101010101010101010101010101010
1bs = 00000000000000001111111111111111
2v5 = 11111111111111110000000000000000
3v5 = 00000000000000001111111111111111 in bit-order!
1
Note that the std::bitset prints with in bit-order.
2
This bit::vector has the same elements but prints in vector-order.
3
We can also print a bit::vector in bit-order if required.

Construction from strings

There are two principal ways we can encode a bit-vector as a string:

Binary String Encodings

The straightforward character encoding for a bit-vector is a binary string containing just 0’s and 1’s, e.g., “10101”. Each character in a binary string represents a single element in the bit-vector.

By default, we encode bit-vectors to binary strings in vector order \(v_0 v_1 \cdots v_{n-1}\). However, methods that read or write binary strings typically have an extra boolean argument, bit_order. This argument always defaults to false, but if present and set to true, then the binary string will encode the bit-vector in bit-order where the least significant bit v0 is on the right, so \(v_{n-1} \cdots v_1 v_0\). Hex-strings ignore the bit_order parameter.

Hex String Encodings

The other supported encoding for bit-vectors is a compact hex-type string containing just the 16 hex characters 0123456789ABCDEF. For example, the string “3ED02”. We allow for hex strings with an optional prefix “0x” or “0X,” e.g. “0x3ED02”.

Hex strings are not affected by a bit_order argument — we ignore that argument.

Each hex character naturally translates to four elements in a bit::vector. The hex string 0x0 is equivalent to the binary string 0000, and so on, up to string 0xF, which is the same as the binary 1111.

The hex pair 0x0F will be interpreted in the vector as 00001111. Of course, this is the advantage of hex. It is a more compact format that occupies a quarter of the space needed to write out the equivalent binary string.

However, what happens if you want to encode a vector whose size is not a multiple of 4? We handle that by allowing the final character in the string to have a base that is not 16. To accomplish that, we allow for an optional suffix, which must be one of _2, _4, or _8. If present, the prefix gives the base for just the preceding character in the otherwise hex-based string. If there is no suffix, the final character is assumed to be hex like all the others.

So the string 0x1 (no suffix, so the last character is the default hex base 16) is equivalent to 0001. On the other hand, the string 0x1_8 (the last character is base 8) is equivalent to 001. Similarly, the string 0x1_4 (the last character is base 4) is equivalent to 01, and finally, the string 0x1_2 (the previous character is base 2) is comparable to 1

In the string 0x3ED01_8, the first four characters, 3, E, D, and 0, are interpreted as hex values, and each will consume four slots in the vector. However, that final 1_8 is parsed as an octal 1, which takes up three slots 001. Therefore, this vector has size 19 (i.e., 4*4 + 3).

If the suffix is present, the final character must fit inside the base given by that suffix. The string 0x3_8 is OK, but trying to parse 0x3_2 will result in a std::nullopt return value because the final character is not either 0 or 1, which are the only valid options for something that is supposed to be base 2.

Example

#include <bit/bit.h>
int main()
{
1    bit::vector v1("111");
2    bit::vector v2("0b111");
3    bit::vector v3("0x111");
4    bit::vector v4("0xF1");
5    bit::vector v5("0xF1_8");
6    bit::vector v6("0xF1_4");
7    bit::vector v7("0xF1_2");

    std::cout << "v1 = " << v1 << '\n';
    std::cout << "v2 = " << v2 << '\n';
    std::cout << "v3 = " << v3 << '\n';
    std::cout << "v4 = " << v4 << '\n';
    std::cout << "v5 = " << v5 << '\n';
    std::cout << "v6 = " << v6 << '\n';
    std::cout << "v7 = " << v7 << '\n';
}
1
Construction from a string without a prefix. All characters are 0’s and 1’s so the string is interpreted as being binary,
2
Construction from the identical binary string with the prefix 0b.
3
Construction from the same digits, but each one is now interpreted as a hex character thanks to the 0x prefix
4
Construction where the final character has no suffix, so by default, it is parsed as a hex/base-16 number.
5
Construction where the final character has a suffix _8, parsed as a base-8 number.
6
Construction where the final character has a suffix _4, parsed as a base-4 number.
7
Construction where the final character has a suffix _2, parsed as a base-2 number.

Output

v1 = [1 1 1]
v2 = [1 1 1]
v3 = [1 0 0 0 1 0 0 0 1 0 0 0]
v4 = [1 1 1 1 1 0 0 0]
v5 = [1 1 1 1 1 0 0]
v6 = [1 1 1 1 1 0]
v7 = [1 1 1 1 1]

See Also

vector::from
vector::block_constructor

Back to top