GF2::Vector — Constructors

Constructors for a bit-vector.

constexpr GF2::Vector(std::size_t n = 0);                           (1)

template<std::unsigned_integral Src>
constexpr GF2::Vector(std::initializer_list<Src> src);              (2)

template<std::unsigned_integral Src>
constexpr GF2::Vector(const std::vector<Src>& src);                 (3)

template<typename Iter>
constexpr GF2::Vector(Iter b, Iter e);                              (4)

template<std::size_t N>
explicit constexpr GF2::Vector(const std::bitset<N> &bs);           (5)

explicit constexpr GF2::Vector(std::size_t n,
                            std::invocable<std::size_t> auto f);    (6)

explicit GF2::Vector(std::string_view str, bool bit_order = false); (7)
1 Constructs a bit-vector with n elements all set to 0. The default constructor creates the empty vector.
2 Construct a bit-vector from an initializer list of unsigned integers. The bits from each are appended to the vector.
3 Construct a bit-vector from a std::vector of unsigned integers. The bits from each element are appended to the vector.
4 Construct a bit-vector from any iteration of unsigned integers. The bits from each are appended to the vector.
5 Construct a bit-vector of size N from a std:::bitset<N>.
6 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.
7 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

Src

The type of the unsigned integers we are using to fill the vector. There is no requirement that Src and Block are the same. For example, we can create a bit-vector from a list of 32-bit unsigned integers while the storage scheme for the vector remains the default 64-bit type.

Iter

An iterator—​might be the type returned by any std::cbegin(collection) etc. Iter::value_type should be some unsigned integer type.

std::invocable<…​>

std::invocable<std::size_t> is the signature for a function over an index.

Parameters

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 bit elements of the vector. See below.

bit_order

This defaults to false but if present and set to true then any binary string is interpreted as encoding the vector in bit-order where the least significant bit v0 is on the right. This parameter is ignored for hex strings.

Example 1: Construction from non-string data
#include <GF2/GF2.h>
int main()
{
    GF2::Vector           v0;                                           (1)
    GF2::Vector           v1(32);                                       (2)
    GF2::Vector           v2({uint16_t(65535), uint16_t(0)});           (3)
    std::vector<uint16_t> vec{65535, 0};
    GF2::Vector           v3(vec);                                      (4)
    GF2::Vector           v4(vec.cbegin(), vec.cend());                 (5)
    std::bitset<32>       b5(65535);
    GF2::Vector           v5(b5);                                       (6)
    GF2::Vector           v6(32, [](size_t k) { return (k + 1) % 2; }); (7)
    std::cout << "v1 = " << v1 << std::endl;
    std::cout << "v2 = " << v2 << std::endl;
    std::cout << "v3 = " << v3 << std::endl;
    std::cout << "v4 = " << v4 << std::endl;
    std::cout << "b5 = " << b5 << std::endl;
    std::cout << "v5 = " << v5 << std::endl;
    std::cout << "v6 = " << v6 << std::endl;
}
1 Default constructor makes an empty vector.
2 Vector of size 32—​elements default to 0.
3 Vector constructed from an initializer list of two 16-bit integers.
4 Vector constructed from a std::vector with the same two 16-bit integers.
5 Vector constructed from an iterator pair over the same two 16-bit integers.
6 Vector constructed from a std::bitset with the same values.
7 Vector constructed using a lambda that returns true if the element index is even.
Output
v0 =
v1 = 00000000000000000000000000000000
v2 = 11111111111111110000000000000000
v3 = 11111111111111110000000000000000
v4 = 11111111111111110000000000000000
b5 = 00000000000000001111111111111111  (1)
v5 = 11111111111111110000000000000000  (2)
v6 = 10101010101010101010101010101010
1 Note that the std::bitset prints with in bit-order.
2 This GF2::Vector has the same elements but prints in vector-order!

Construction from strings

The most straightforward character encoding for any bit-vector is a binary string containing just 0’s and 1’s, e.g. "10101". We allow for an optional prefix "0b" or "0B" to act as a visual clue to the string’s contents, e.g. "0b10101". Apart from the optional prefix, each character in the binary string will translate to one element in the vector.

The other supported encoding is a compact hex type string containing just the 16 hex characters 0123456789ABCDEF. For example, the string "3ED02". Again, we allow for an optional prefix "0x" or "0X" e.g. "0x3ED02".

Each hex character naturally translates to 4 elements in a GF2::Vector. The hex string "0x0" is equivalent to the binary string "0b0000", and so on, up to string "0xF" which is the same as the binary "0b1111".

The hex pair "0x0F" will be interpreted in the vector as 0b00001111. This is of course the advantage of hex—​it is a more compact format that occupies a quarter of the space needed to write out a full 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. This is achieved by allowing for an optional suffix which must be one of "_2", "_4", or "_8". If present, the prefix gives the base for just the _final_ character in the otherwise hex based string. If there is no suffix the final character is assumed to be hex just like all the others.

So the string "0x1" (no suffix so the last character is the default hex base 16) is equivalent to "0b0001". On the other hand, the string "0x1_8" (the last character is base 8) is equivalent to "0b001". Similarly the string "0x1_4" (the last character is base 4) is equivalent to "0b01" and finally, the string "0x1_2" (the last character is base 2) is equivalent to "0b1"

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 so only takes up three slots 0b001. In all then this particular vector has size 4 x 4 + 3 = 19.

If the suffix is present, the final character must fit inside the base given by that suffix. The string "0x3_8" is fine but trying to parse "0x3_2" will result in a std::invalid_argument exception as 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 2: Construction from strings
#include <GF2/GF2.h>
int main()
{
    GF2::Vector v1("111");          (1)
    GF2::Vector v2("0b111");        (2)
    GF2::Vector v3("0x111");        (3)
    GF2::Vector v4("0xF1");         (4)
    GF2::Vector v5("0xF1_8");       (5)
    GF2::Vector v6("0xF1_4");       (6)
    GF2::Vector v7("0xF1_2");       (7)

    std::cout << "v1 = " << v1 << std::endl;
    std::cout << "v2 = " << v2 << std::endl;
    std::cout << "v3 = " << v3 << std::endl;
    std::cout << "v4 = " << v4 << std::endl;
    std::cout << "v5 = " << v5 << std::endl;
    std::cout << "v6 = " << v6 << std::endl;
    std::cout << "v7 = " << v7 << std::endl;
}
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 same binary string with the binary 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 is parsed as a hex/base-16 number.
5 Construction where the final character has a suffix "_8" so it is parsed as an base-8 number.
6 Construction where the final character has a suffix "_4" so it is parsed as an base-4 number.
7 Construction where the final character has a suffix "_2" so it is parsed as an base-2 number.
Output
v1 = 111
v2 = 111
v3 = 100010001000 (1)
v4 = 11111000
v5 = 1111100
v6 = 111110
v7 = 11111
1 By default, a GF2::Vector prints in vector-order with least significant bit, as it were, on the left.
See Also

append
to_string