2022-05-24 01:02:06 +02:00
|
|
|
#include "GCrypt/Block.h"
|
|
|
|
#include "GCrypt/Config.h"
|
2022-05-25 12:54:26 +02:00
|
|
|
#include "GCrypt/Util.h"
|
2022-05-24 01:02:06 +02:00
|
|
|
#include <sstream>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstring>
|
|
|
|
|
2022-05-24 21:41:49 +02:00
|
|
|
// Just to be sure, the compiler will optimize this
|
|
|
|
// little formula out, let's do it in the preprocessor
|
|
|
|
#define MAT_INDEX(row, column) (column*4 + row)
|
|
|
|
|
2022-05-24 01:02:06 +02:00
|
|
|
namespace Leonetienne::GCrypt {
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>::Basic_Block() {
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>::Basic_Block(const std::string& str) {
|
2022-05-24 01:02:06 +02:00
|
|
|
FromString(str);
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>::Basic_Block(const Basic_Block<T>& other) {
|
2022-05-24 01:02:06 +02:00
|
|
|
data = other.data;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::FromString(const std::string& str) {
|
2022-05-24 01:02:06 +02:00
|
|
|
|
2022-05-26 00:55:24 +02:00
|
|
|
assert(str.length() == BLOCK_SIZE_BITS);
|
2022-05-24 01:02:06 +02:00
|
|
|
|
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
data[i] = std::bitset<CHUNK_SIZE_BITS>(
|
|
|
|
str.substr(i*CHUNK_SIZE_BITS, CHUNK_SIZE_BITS)
|
|
|
|
).to_ulong();
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
std::string Basic_Block<T>::ToString() const {
|
2022-05-24 01:02:06 +02:00
|
|
|
|
|
|
|
std::stringstream ss;
|
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
ss << std::bitset<CHUNK_SIZE_BITS>(data[i]).to_string();
|
|
|
|
}
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::MMul(const Basic_Block<T>& o) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
Basic_Block<T> m;
|
2022-05-24 01:02:06 +02:00
|
|
|
|
2022-05-24 01:05:45 +02:00
|
|
|
// Maybe pre-calculate the 1d-index...?
|
|
|
|
|
2022-05-24 01:02:06 +02:00
|
|
|
m.Get(0, 0) = (this->Get(0, 0) * o.Get(0, 0)) + (this->Get(0, 1) * o.Get(1, 0)) + (this->Get(0, 2) * o.Get(2, 0)) + (this->Get(0, 3) * o.Get(3, 0));
|
|
|
|
m.Get(0, 1) = (this->Get(0, 0) * o.Get(0, 1)) + (this->Get(0, 1) * o.Get(1, 1)) + (this->Get(0, 2) * o.Get(2, 1)) + (this->Get(0, 3) * o.Get(3, 1));
|
|
|
|
m.Get(0, 2) = (this->Get(0, 0) * o.Get(0, 2)) + (this->Get(0, 1) * o.Get(1, 2)) + (this->Get(0, 2) * o.Get(2, 2)) + (this->Get(0, 3) * o.Get(3, 2));
|
|
|
|
m.Get(0, 3) = (this->Get(0, 0) * o.Get(0, 3)) + (this->Get(0, 1) * o.Get(1, 3)) + (this->Get(0, 2) * o.Get(2, 3)) + (this->Get(0, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
m.Get(1, 0) = (this->Get(1, 0) * o.Get(0, 0)) + (this->Get(1, 1) * o.Get(1, 0)) + (this->Get(1, 2) * o.Get(2, 0)) + (this->Get(1, 3) * o.Get(3, 0));
|
|
|
|
m.Get(1, 1) = (this->Get(1, 0) * o.Get(0, 1)) + (this->Get(1, 1) * o.Get(1, 1)) + (this->Get(1, 2) * o.Get(2, 1)) + (this->Get(1, 3) * o.Get(3, 1));
|
|
|
|
m.Get(1, 2) = (this->Get(1, 0) * o.Get(0, 2)) + (this->Get(1, 1) * o.Get(1, 2)) + (this->Get(1, 2) * o.Get(2, 2)) + (this->Get(1, 3) * o.Get(3, 2));
|
|
|
|
m.Get(1, 3) = (this->Get(1, 0) * o.Get(0, 3)) + (this->Get(1, 1) * o.Get(1, 3)) + (this->Get(1, 2) * o.Get(2, 3)) + (this->Get(1, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
m.Get(2, 0) = (this->Get(2, 0) * o.Get(0, 0)) + (this->Get(2, 1) * o.Get(1, 0)) + (this->Get(2, 2) * o.Get(2, 0)) + (this->Get(2, 3) * o.Get(3, 0));
|
|
|
|
m.Get(2, 1) = (this->Get(2, 0) * o.Get(0, 1)) + (this->Get(2, 1) * o.Get(1, 1)) + (this->Get(2, 2) * o.Get(2, 1)) + (this->Get(2, 3) * o.Get(3, 1));
|
|
|
|
m.Get(2, 2) = (this->Get(2, 0) * o.Get(0, 2)) + (this->Get(2, 1) * o.Get(1, 2)) + (this->Get(2, 2) * o.Get(2, 2)) + (this->Get(2, 3) * o.Get(3, 2));
|
|
|
|
m.Get(2, 3) = (this->Get(2, 0) * o.Get(0, 3)) + (this->Get(2, 1) * o.Get(1, 3)) + (this->Get(2, 2) * o.Get(2, 3)) + (this->Get(2, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
m.Get(3, 0) = (this->Get(3, 0) * o.Get(0, 0)) + (this->Get(3, 1) * o.Get(1, 0)) + (this->Get(3, 2) * o.Get(2, 0)) + (this->Get(3, 3) * o.Get(3, 0));
|
|
|
|
m.Get(3, 1) = (this->Get(3, 0) * o.Get(0, 1)) + (this->Get(3, 1) * o.Get(1, 1)) + (this->Get(3, 2) * o.Get(2, 1)) + (this->Get(3, 3) * o.Get(3, 1));
|
|
|
|
m.Get(3, 2) = (this->Get(3, 0) * o.Get(0, 2)) + (this->Get(3, 1) * o.Get(1, 2)) + (this->Get(3, 2) * o.Get(2, 2)) + (this->Get(3, 3) * o.Get(3, 2));
|
|
|
|
m.Get(3, 3) = (this->Get(3, 0) * o.Get(0, 3)) + (this->Get(3, 1) * o.Get(1, 3)) + (this->Get(3, 2) * o.Get(2, 3)) + (this->Get(3, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::operator*(const Basic_Block<T>& other) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
return this->MMul(other);
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::MMulInplace(const Basic_Block<T>& o) {
|
2022-05-24 01:02:06 +02:00
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
Basic_Block<T> m = *this;
|
2022-05-24 01:02:06 +02:00
|
|
|
|
2022-05-24 01:05:45 +02:00
|
|
|
// Maybe pre-calculate the 1d-index...?
|
|
|
|
|
2022-05-24 01:02:06 +02:00
|
|
|
this->Get(0, 0) = (m.Get(0, 0) * o.Get(0, 0)) + (m.Get(0, 1) * o.Get(1, 0)) + (m.Get(0, 2) * o.Get(2, 0)) + (m.Get(0, 3) * o.Get(3, 0));
|
|
|
|
this->Get(0, 1) = (m.Get(0, 0) * o.Get(0, 1)) + (m.Get(0, 1) * o.Get(1, 1)) + (m.Get(0, 2) * o.Get(2, 1)) + (m.Get(0, 3) * o.Get(3, 1));
|
|
|
|
this->Get(0, 2) = (m.Get(0, 0) * o.Get(0, 2)) + (m.Get(0, 1) * o.Get(1, 2)) + (m.Get(0, 2) * o.Get(2, 2)) + (m.Get(0, 3) * o.Get(3, 2));
|
|
|
|
this->Get(0, 3) = (m.Get(0, 0) * o.Get(0, 3)) + (m.Get(0, 1) * o.Get(1, 3)) + (m.Get(0, 2) * o.Get(2, 3)) + (m.Get(0, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
this->Get(1, 0) = (m.Get(1, 0) * o.Get(0, 0)) + (m.Get(1, 1) * o.Get(1, 0)) + (m.Get(1, 2) * o.Get(2, 0)) + (m.Get(1, 3) * o.Get(3, 0));
|
|
|
|
this->Get(1, 1) = (m.Get(1, 0) * o.Get(0, 1)) + (m.Get(1, 1) * o.Get(1, 1)) + (m.Get(1, 2) * o.Get(2, 1)) + (m.Get(1, 3) * o.Get(3, 1));
|
|
|
|
this->Get(1, 2) = (m.Get(1, 0) * o.Get(0, 2)) + (m.Get(1, 1) * o.Get(1, 2)) + (m.Get(1, 2) * o.Get(2, 2)) + (m.Get(1, 3) * o.Get(3, 2));
|
|
|
|
this->Get(1, 3) = (m.Get(1, 0) * o.Get(0, 3)) + (m.Get(1, 1) * o.Get(1, 3)) + (m.Get(1, 2) * o.Get(2, 3)) + (m.Get(1, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
this->Get(2, 0) = (m.Get(2, 0) * o.Get(0, 0)) + (m.Get(2, 1) * o.Get(1, 0)) + (m.Get(2, 2) * o.Get(2, 0)) + (m.Get(2, 3) * o.Get(3, 0));
|
|
|
|
this->Get(2, 1) = (m.Get(2, 0) * o.Get(0, 1)) + (m.Get(2, 1) * o.Get(1, 1)) + (m.Get(2, 2) * o.Get(2, 1)) + (m.Get(2, 3) * o.Get(3, 1));
|
|
|
|
this->Get(2, 2) = (m.Get(2, 0) * o.Get(0, 2)) + (m.Get(2, 1) * o.Get(1, 2)) + (m.Get(2, 2) * o.Get(2, 2)) + (m.Get(2, 3) * o.Get(3, 2));
|
|
|
|
this->Get(2, 3) = (m.Get(2, 0) * o.Get(0, 3)) + (m.Get(2, 1) * o.Get(1, 3)) + (m.Get(2, 2) * o.Get(2, 3)) + (m.Get(2, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
this->Get(3, 0) = (m.Get(3, 0) * o.Get(0, 0)) + (m.Get(3, 1) * o.Get(1, 0)) + (m.Get(3, 2) * o.Get(2, 0)) + (m.Get(3, 3) * o.Get(3, 0));
|
|
|
|
this->Get(3, 1) = (m.Get(3, 0) * o.Get(0, 1)) + (m.Get(3, 1) * o.Get(1, 1)) + (m.Get(3, 2) * o.Get(2, 1)) + (m.Get(3, 3) * o.Get(3, 1));
|
|
|
|
this->Get(3, 2) = (m.Get(3, 0) * o.Get(0, 2)) + (m.Get(3, 1) * o.Get(1, 2)) + (m.Get(3, 2) * o.Get(2, 2)) + (m.Get(3, 3) * o.Get(3, 2));
|
|
|
|
this->Get(3, 3) = (m.Get(3, 0) * o.Get(0, 3)) + (m.Get(3, 1) * o.Get(1, 3)) + (m.Get(3, 2) * o.Get(2, 3)) + (m.Get(3, 3) * o.Get(3, 3));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>& Basic_Block<T>::operator*=(const Basic_Block<T>& other) {
|
2022-05-24 01:02:06 +02:00
|
|
|
MMulInplace(other);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::Xor(const Basic_Block<T>& other) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
Basic_Block<T> m;
|
2022-05-24 01:02:06 +02:00
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
m.Get(i) = this->Get(i) ^ other.Get(i);
|
|
|
|
}
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::operator^(const Basic_Block<T>& other) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
return Xor(other);
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::XorInplace(const Basic_Block<T>& other) {
|
2022-05-24 01:02:06 +02:00
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
this->Get(i) ^= other.Get(i);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>& Basic_Block<T>::operator^=(const Basic_Block<T>& other) {
|
2022-05-24 01:02:06 +02:00
|
|
|
XorInplace(other);
|
2022-05-25 16:38:16 +02:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::Add(const Basic_Block<T>& other) const {
|
2022-05-24 21:41:49 +02:00
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
Basic_Block<T> m;
|
2022-05-24 21:41:49 +02:00
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
m.Get(i) = this->Get(i) + other.Get(i);
|
|
|
|
}
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::operator+(const Basic_Block<T>& other) const {
|
2022-05-24 21:41:49 +02:00
|
|
|
return Add(other);
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::AddInplace(const Basic_Block<T>& other) {
|
2022-05-24 21:41:49 +02:00
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
this->Get(i) += other.Get(i);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>& Basic_Block<T>::operator+=(const Basic_Block<T>& other) {
|
2022-05-24 21:41:49 +02:00
|
|
|
AddInplace(other);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::Sub(const Basic_Block<T>& other) const {
|
2022-05-24 21:41:49 +02:00
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
Basic_Block<T> m;
|
2022-05-24 21:41:49 +02:00
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
m.Get(i) = this->Get(i) - other.Get(i);
|
|
|
|
}
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::operator-(const Basic_Block<T>& other) const {
|
2022-05-24 21:41:49 +02:00
|
|
|
return Sub(other);
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::SubInplace(const Basic_Block<T>& other) {
|
2022-05-24 21:41:49 +02:00
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
this->Get(i) -= other.Get(i);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>& Basic_Block<T>::operator-=(const Basic_Block<T>& other) {
|
2022-05-24 21:41:49 +02:00
|
|
|
SubInplace(other);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftRowsUpInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(1, 0));
|
|
|
|
Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(1, 1));
|
|
|
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(1, 2));
|
|
|
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(1, 3));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(2, 0));
|
|
|
|
Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(2, 1));
|
|
|
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(2, 2));
|
|
|
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(2, 3));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(3, 0));
|
|
|
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(3, 1));
|
|
|
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(3, 2));
|
|
|
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(0, 0));
|
|
|
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(0, 1));
|
|
|
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(0, 2));
|
|
|
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(0, 3));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftRowsUp() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(1, 0));
|
|
|
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(1, 1));
|
|
|
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(1, 2));
|
|
|
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(1, 3));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(2, 0));
|
|
|
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(2, 1));
|
|
|
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(2, 2));
|
|
|
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(2, 3));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(3, 0));
|
|
|
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(3, 1));
|
|
|
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(3, 2));
|
|
|
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(0, 0));
|
|
|
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(0, 1));
|
|
|
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(0, 2));
|
|
|
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(0, 3));
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftRowsDownInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(3, 0));
|
|
|
|
Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(3, 1));
|
|
|
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(3, 2));
|
|
|
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(0, 0));
|
|
|
|
Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(0, 1));
|
|
|
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(0, 2));
|
|
|
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(0, 3));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(1, 0));
|
|
|
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(1, 1));
|
|
|
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(1, 2));
|
|
|
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(1, 3));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(2, 0));
|
|
|
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(2, 1));
|
|
|
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(2, 2));
|
|
|
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(2, 3));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftRowsDown() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(3, 0));
|
|
|
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(3, 1));
|
|
|
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(3, 2));
|
|
|
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(0, 0));
|
|
|
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(0, 1));
|
|
|
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(0, 2));
|
|
|
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(0, 3));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(1, 0));
|
|
|
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(1, 1));
|
|
|
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(1, 2));
|
|
|
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(1, 3));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(2, 0));
|
|
|
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(2, 1));
|
|
|
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(2, 2));
|
|
|
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(2, 3));
|
|
|
|
|
|
|
|
return b;
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftColumnsLeftInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(0, 1));
|
|
|
|
Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(1, 1));
|
|
|
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(2, 1));
|
|
|
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(3, 1));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(0, 2));
|
|
|
|
Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(1, 2));
|
|
|
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(2, 2));
|
|
|
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(3, 2));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(0, 3));
|
|
|
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(1, 3));
|
|
|
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(2, 3));
|
|
|
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(0, 0));
|
|
|
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(1, 0));
|
|
|
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(2, 0));
|
|
|
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(3, 0));
|
|
|
|
|
|
|
|
return;
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftColumnsLeft() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(0, 1));
|
|
|
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(1, 1));
|
|
|
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(2, 1));
|
|
|
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(3, 1));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(0, 2));
|
|
|
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(1, 2));
|
|
|
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(2, 2));
|
|
|
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(3, 2));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(0, 3));
|
|
|
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(1, 3));
|
|
|
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(2, 3));
|
|
|
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(0, 0));
|
|
|
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(1, 0));
|
|
|
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(2, 0));
|
|
|
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(3, 0));
|
|
|
|
|
|
|
|
return b;
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftColumnsRightInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(0, 0));
|
|
|
|
Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(1, 0));
|
|
|
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(2, 0));
|
|
|
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(3, 0));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(0, 1));
|
|
|
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(1, 1));
|
|
|
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(2, 1));
|
|
|
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(3, 1));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(0, 2));
|
|
|
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(1, 2));
|
|
|
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(2, 2));
|
|
|
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(3, 2));
|
|
|
|
|
|
|
|
Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(0, 3));
|
|
|
|
Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(1, 3));
|
|
|
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(2, 3));
|
|
|
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
return;
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftColumnsRight() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(0, 0));
|
|
|
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(1, 0));
|
|
|
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(2, 0));
|
|
|
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(3, 0));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(0, 1));
|
|
|
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(1, 1));
|
|
|
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(2, 1));
|
|
|
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(3, 1));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(0, 2));
|
|
|
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(1, 2));
|
|
|
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(2, 2));
|
|
|
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(3, 2));
|
|
|
|
|
|
|
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(0, 3));
|
|
|
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(1, 3));
|
|
|
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(2, 3));
|
|
|
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(3, 3));
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftCellsLeftInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
Get(15) = tmp.Get(0);
|
|
|
|
|
|
|
|
for (std::size_t i = 0; i < 15; i++) {
|
|
|
|
Get(i) = tmp.Get(i+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftCellsLeft() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
b.Get(15) = Get(0);
|
|
|
|
|
|
|
|
for (std::size_t i = 0; i < 15; i++) {
|
|
|
|
b.Get(i) = Get(i+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftCellsRightInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
Get(0) = tmp.Get(15);
|
|
|
|
|
|
|
|
for (std::size_t i = 1; i < 16; i++) {
|
|
|
|
Get(i) = tmp.Get(i-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftCellsRight() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-24 21:41:49 +02:00
|
|
|
|
|
|
|
b.Get(0) = Get(15);
|
|
|
|
|
|
|
|
for (std::size_t i = 1; i < 16; i++) {
|
|
|
|
b.Get(i) = Get(i-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return b;
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>& Basic_Block<T>::operator=(const Basic_Block<T>& other) {
|
2022-05-24 01:02:06 +02:00
|
|
|
data = other.data;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
bool Basic_Block<T>::GetBit(const std::size_t index) const {
|
2022-05-24 23:18:39 +02:00
|
|
|
// Fetch index of integer the bit is located in
|
|
|
|
const std::size_t intIndex = index / CHUNK_SIZE_BITS;
|
|
|
|
|
|
|
|
// Fetch bit index relative to that int
|
|
|
|
const std::size_t relBitIndex = index - (intIndex * CHUNK_SIZE_BITS);
|
|
|
|
|
2022-05-24 23:51:17 +02:00
|
|
|
// Pre-calculate the bitmask to use
|
|
|
|
const std::size_t bitmask = 1 << (CHUNK_SIZE_BITS - relBitIndex - 1);
|
|
|
|
|
|
|
|
return data[intIndex] & bitmask;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::SetBit(const std::size_t index, const bool state) {
|
2022-05-24 23:51:17 +02:00
|
|
|
// Fetch index of integer the bit is located in
|
|
|
|
const std::size_t intIndex = index / CHUNK_SIZE_BITS;
|
|
|
|
|
|
|
|
// Fetch bit index relative to that int
|
|
|
|
const std::size_t relBitIndex = index - (intIndex * CHUNK_SIZE_BITS);
|
|
|
|
|
|
|
|
// Pre-calculate the bitmask to use
|
|
|
|
const std::size_t bitmask = 1 << (CHUNK_SIZE_BITS - relBitIndex - 1);
|
|
|
|
|
|
|
|
// Set the bit
|
|
|
|
if (state) {
|
|
|
|
data[intIndex] |= bitmask;
|
|
|
|
}
|
|
|
|
// Clear the bit
|
|
|
|
else {
|
|
|
|
data[intIndex] &= ~bitmask;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::FlipBit(const std::size_t index) {
|
2022-05-24 23:51:17 +02:00
|
|
|
// Fetch index of integer the bit is located in
|
|
|
|
const std::size_t intIndex = index / CHUNK_SIZE_BITS;
|
|
|
|
|
|
|
|
// Fetch bit index relative to that int
|
|
|
|
const std::size_t relBitIndex = index - (intIndex * CHUNK_SIZE_BITS);
|
|
|
|
|
|
|
|
// Pre-calculate the bitmask to use
|
|
|
|
const std::size_t bitmask = 1 << (CHUNK_SIZE_BITS - relBitIndex - 1);
|
|
|
|
|
|
|
|
data[intIndex] ^= bitmask;
|
|
|
|
|
|
|
|
return;
|
2022-05-24 23:18:39 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftBitsLeft() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-25 12:54:26 +02:00
|
|
|
|
|
|
|
// First, copy this block over
|
|
|
|
b = *this;
|
|
|
|
|
|
|
|
// Then, shift all integers individually
|
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
b.data[i] <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Current state: the LSB is zero everywhere. We have to carry
|
|
|
|
// it over manually from the previous state.
|
|
|
|
|
|
|
|
// Carry over the MSB of data[i] to LSB of data[i-1]
|
|
|
|
constexpr std::size_t bitmaskMsb = 1 << (CHUNK_SIZE_BITS - 1);
|
|
|
|
constexpr std::size_t bitmaskLsb = 1;
|
|
|
|
for (int i = 0; i < data.size(); i++) {
|
|
|
|
const bool msb = data[i] & bitmaskMsb;
|
|
|
|
|
|
|
|
// Set the lsb
|
|
|
|
if (msb) {
|
|
|
|
b.data[Mod(i-1, data.size())] |= bitmaskLsb;
|
|
|
|
}
|
|
|
|
// Clear the lsb
|
|
|
|
else {
|
|
|
|
b.data[Mod(i-1, data.size())] &= ~bitmaskLsb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftBitsLeftInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-25 12:54:26 +02:00
|
|
|
|
|
|
|
// Then, shift all integers individually
|
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
data[i] <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Current state: the LSB is zero everywhere. We have to carry
|
|
|
|
// it over manually from the previous state.
|
|
|
|
|
|
|
|
// Carry over the MSB of data[i] to LSB of data[i-1]
|
|
|
|
constexpr std::size_t bitmaskMsb = 1 << (CHUNK_SIZE_BITS - 1);
|
|
|
|
constexpr std::size_t bitmaskLsb = 1;
|
|
|
|
for (int i = 0; i < data.size(); i++) {
|
|
|
|
const bool msb = tmp.data[i] & bitmaskMsb;
|
|
|
|
|
|
|
|
// Set the lsb
|
|
|
|
if (msb) {
|
|
|
|
data[Mod(i-1, data.size())] |= bitmaskLsb;
|
|
|
|
}
|
|
|
|
// Clear the lsb
|
|
|
|
else {
|
|
|
|
data[Mod(i-1, data.size())] &= ~bitmaskLsb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T> Basic_Block<T>::ShiftBitsRight() const {
|
|
|
|
Basic_Block<T> b;
|
2022-05-25 12:54:26 +02:00
|
|
|
|
|
|
|
// First, copy this block over
|
|
|
|
b = *this;
|
|
|
|
|
|
|
|
// Then, shift all integers individually
|
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
b.data[i] >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Current state: the LSB is zero everywhere. We have to carry
|
|
|
|
// it over manually from the previous state.
|
|
|
|
|
|
|
|
// Carry over the LSB of data[i] to MSB of data[i+1]
|
|
|
|
constexpr std::size_t bitmaskMsb = 1 << (CHUNK_SIZE_BITS - 1);
|
|
|
|
constexpr std::size_t bitmaskLsb = 1;
|
|
|
|
for (int i = 0; i < data.size(); i++) {
|
|
|
|
const bool lsb = data[i] & bitmaskLsb;
|
|
|
|
|
|
|
|
// Set the msb
|
|
|
|
if (lsb) {
|
|
|
|
b.data[Mod(i+1, data.size())] |= bitmaskMsb;
|
|
|
|
}
|
|
|
|
// Clear the msb
|
|
|
|
else {
|
|
|
|
b.data[Mod(i+1, data.size())] &= ~bitmaskMsb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::ShiftBitsRightInplace() {
|
|
|
|
Basic_Block<T> tmp = *this;
|
2022-05-25 12:54:26 +02:00
|
|
|
|
|
|
|
// Then, shift all integers individually
|
|
|
|
for (std::size_t i = 0; i < data.size(); i++) {
|
|
|
|
data[i] >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Current state: the LSB is zero everywhere. We have to carry
|
|
|
|
// it over manually from the previous state.
|
|
|
|
|
|
|
|
// Carry over the LSB of data[i] to MSB of data[i+1]
|
|
|
|
constexpr std::size_t bitmaskMsb = 1 << (CHUNK_SIZE_BITS - 1);
|
|
|
|
constexpr std::size_t bitmaskLsb = 1;
|
|
|
|
for (int i = 0; i < data.size(); i++) {
|
|
|
|
const bool lsb = tmp.data[i] & bitmaskLsb;
|
|
|
|
|
|
|
|
// Set the msb
|
|
|
|
if (lsb) {
|
|
|
|
data[Mod(i+1, data.size())] |= bitmaskMsb;
|
|
|
|
}
|
|
|
|
// Clear the msb
|
|
|
|
else {
|
|
|
|
data[Mod(i+1, data.size())] &= ~bitmaskMsb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
T& Basic_Block<T>::Get(const std::uint8_t row, const std::uint8_t column){
|
2022-05-24 21:41:49 +02:00
|
|
|
return data[MAT_INDEX(row, column)];
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
const T& Basic_Block<T>::Get(const std::uint8_t row, const std::uint8_t column) const {
|
2022-05-24 21:41:49 +02:00
|
|
|
return data[MAT_INDEX(row, column)];
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
T& Basic_Block<T>::Get(const std::uint8_t index) {
|
2022-05-24 01:02:06 +02:00
|
|
|
return data[index];
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
const T& Basic_Block<T>::Get(const std::uint8_t index) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
return data[index];
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
T& Basic_Block<T>::operator[](const std::uint8_t index) {
|
2022-05-24 01:02:06 +02:00
|
|
|
return data[index];
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
const T& Basic_Block<T>::operator[](const std::uint8_t index) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
return data[index];
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
bool Basic_Block<T>::operator==(const Basic_Block<T>& other) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
return data == other.data;
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
bool Basic_Block<T>::operator!=(const Basic_Block<T>& other) const {
|
2022-05-24 01:02:06 +02:00
|
|
|
return data != other.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined _WIN32 || defined _WIN64
|
|
|
|
#pragma optimize("", off )
|
|
|
|
#elif defined __GNUG__
|
|
|
|
#pragma GCC push_options
|
|
|
|
#pragma GCC optimize ("O0")
|
|
|
|
#endif
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
Basic_Block<T>::~Basic_Block() {
|
2022-05-24 01:02:06 +02:00
|
|
|
Reset();
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:38:16 +02:00
|
|
|
template <typename T>
|
|
|
|
void Basic_Block<T>::Reset() {
|
2022-05-24 01:02:06 +02:00
|
|
|
memset(data.data(), 0, CHUNK_SIZE*data.size());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#if defined _WIN32 || defined _WIN64
|
|
|
|
#pragma optimize("", on )
|
|
|
|
#elif defined __GNUG__
|
|
|
|
#pragma GCC pop_options
|
|
|
|
#endif
|
2022-05-24 01:07:00 +02:00
|
|
|
|
2022-05-24 01:02:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-24 21:41:49 +02:00
|
|
|
#undef MAT_INDEX
|
|
|
|
|