GF2::Matrix — Logical Op= Operators

Methods to perform element-by-element binary AND, XOR, OR, +, -, * with another equal sized bit-matrix.

constexpr Matrix &operator&=(const Matrix &other);    (1)
constexpr Matrix &operator^=(const Matrix &other);    (2)
constexpr Matrix &operator|=(const Matrix &other);    (3)
constexpr Matrix &operator+=(const Matrix &other);    (4)
constexpr Matrix &operator-=(const Matrix &other);    (5)
constexpr Matrix &operator*=(const Matrix &other);    (6)
1 Sets this bit-matrix’s bits to the result of binary AND between the corresponding pairs of bits of *this and other.
2 Sets this bit-matrix’s bits to the result of binary XOR between the corresponding pairs of bits of *this and other.
3 Sets this bit-matrix’s bits to the result of binary OR between the corresponding pairs of bits of *this and other.
4 Sets this bit-matrix’s bits to the result of binary XOR between the corresponding pairs of bits of *this and other. In GF(2) addition corresponds to XOR.
5 Sets this bit-matrix’s bits to the result of binary XOR between the corresponding pairs of bits of *this and other. In GF(2) subtraction corresponds to XOR.
6 Sets this bit-matrix’s bits to the result of binary AND between the corresponding pairs of bits of *this and other. In GF(2) multiplication corresponds to AND.

These methods all return a reference to *this so they can be chained with other calls.

The two bit-matrices in question must be of the same size. If the GF2_DEBUG flag is set at compile time this is checked and any violation will cause the program to abort with a helpful message.
constexpr Matrix operator~() const;    (1)
1 Returns a copy of the bit-matrix with all the bits flipped
Example
#include <GF2/GF2.h>
int main()
{
    GF2::Matrix<> m1(4,[](std::size_t i, std::size_t j) { return (i + j) % 2; });
    auto m2 = GF2::Matrix<>::ones(4);

    std::cout << "m1:\n" << m1  << '\n';
    std::cout << "m2:\n" << m2  << '\n';
    std::cout << "m1 &= m2:\n"  << (m1 &= m2)   << '\n';
    std::cout << "m1 |= m2:\n"  << (m1 |= m2)   << '\n';
    std::cout << "m1 ^= m2:\n"  << (m1 ^= m2)   << '\n';
    std::cout << "~m1:\n"       << (~m1)        << '\n';
}
Output
m1:
0101
1010
0101
1010
m2:
1111
1111
1111
1111
m1 &= m2:
0101
1010
0101
1010
m1 |= m2:
1111
1111
1111
1111
m1 ^= m2:
0000
0000
0000
0000
~m1:
1111
1111
1111
1111