// -*- c++ -*- #pragma once #include #include #include template class Matrix { public: Matrix() : data(T{}, W * H) { } Matrix(Matrix&& other) { *this = std::move(other); } Matrix(const Matrix& other) { *this = other; } Matrix& operator=(Matrix&& other) { data = std::move(other.data); return *this; } Matrix& operator=(const Matrix& other) { data = other.data; return *this; } T& m(std::size_t x, std::size_t y) { if(x >= W || y >= H) throw std::out_of_range("Subscript out of range."); return data[x + y * W]; } const T& m(std::size_t x, std::size_t y) const { if(x >= W || y >= H) throw std::out_of_range("Subscript out of range."); return data[x + y * W]; } Matrix operator+(const Matrix& other) const { Matrix m(*this); m.data += other.data; return m; } Matrix operator+(T val) { Matrix m(*this); m.data += val; return m; } Matrix operator-(const Matrix& other) const { Matrix m(*this); m.data -= other.data; return m; } Matrix operator-(T val) { Matrix m(*this); m.data -= val; return m; } Matrix operator%(const Matrix& other) const { Matrix m(*this); m.data %= other.data; return m; } Matrix operator%(T val) { Matrix m(*this); m.data %= val; return m; } template Matrix operator*(const Matrix& other) const { Matrix out; for(std::size_t i = 0; i < W; ++i) { for(std::size_t j = 0; j < N; ++j) { out.m(i,j) = {}; for(std::size_t k = 0; k < H; ++k) { out.m(i,j) += m(i, j) * other.m(k, j); } } } return out; } Matrix operator*(T val) { Matrix m(*this); m.data *= val; return m; } template Matrix operator/(const Matrix& other) const { Matrix out; for(std::size_t i = 0; i < W; ++i) { for(std::size_t j = 0; j < N; ++j) { out.m(i,j) = {}; for(std::size_t k = 0; k < H; ++k) { out.m(i,j) += m(i, j) / other.m(k, j); } } } return out; } Matrix operator/(T val) const { Matrix m(*this); m.data /= val; return m; } struct pos_t { std::size_t x; std::size_t y; }; void Move(pos_t from, pos_t to) { m(to.x, to.x) = m(from.x, from.x); m(from.x, from.y) = {}; } std::vector Row(std::size_t n) const { if(n >= H) throw std::out_of_range("Subscript out of range."); std::vector out; for(std::size_t x = 0; x < W; ++x) { out.push_back(m(x, n)); } return out; } std::vector Column(std::size_t n) const { if(n >= W) throw std::out_of_range("Subscript out of range."); std::vector out; for(std::size_t y = 0; y < H; ++y) { out.push_back(m(n, y)); } return out; } private: // Invariant; at all times data contains w * h initialized data members std::valarray data; // default initialized to empty };