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
7::vector(std::size_t n, std::invocable<std::size_t> auto f);
bit
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>
ofN
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 astd:::bitset<N>
. - 7
-
Construct a bit-vector with
n
elements using a function that takes astd::size_t
argument.
Elementi
in the vector is set to 1 iff(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::vector v1;
bit2::vector v2{32};
bitstd::vector<uint16_t> vec{65535, 0};
3::vector v3{vec};
bit4::vector v4{32, [](size_t k) { return (k + 1) % 2; }};
bitstd::bitset<32> bs{65535};
5::vector v5{bs};
bitstd::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 astd::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 astd::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::vector v1("111");
bit2::vector v2("0b111");
bit3::vector v3("0x111");
bit4::vector v4("0xF1");
bit5::vector v5("0xF1_8");
bit6::vector v6("0xF1_4");
bit7::vector v7("0xF1_2");
bit
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]