#pragma once template class mm::access : virtual public mm::basic_matrix { public: template friend class mm::access; using mm::basic_matrix::basic_matrix; access(mm::basic_matrix&& m) : basic_matrix(m) {} virtual T& at(std::size_t row, std::size_t col) = 0; virtual const T& at(std::size_t row, std::size_t col) const = 0; static constexpr std::size_t rows = Regular ? Rows : Cols; static constexpr std::size_t cols = Regular ? Cols : Rows; }; template class mm::row_access : public mm::access { public: template friend class mm::row_access; using mm::access::access; row_access(mm::basic_matrix&& m) : access(m) {} virtual T& at(std::size_t row, std::size_t col) override; virtual const T& at(std::size_t row, std::size_t col) const override; row_iterator operator[](std::size_t index); const_row_iterator operator[](std::size_t index) const; }; template class mm::col_access : public mm::access { public: template friend class mm::access; using mm::access::access; col_access(mm::basic_matrix&& m) : access(m) {} virtual T& at(std::size_t row, std::size_t col) override; virtual const T& at(std::size_t row, std::size_t col) const override; col_iterator operator[](std::size_t index); const_col_iterator operator[](std::size_t index) const; }; /* * Square interface */ template class mm::square_interface : virtual public mm::basic_matrix { public: template friend class mm::square_interface; using mm::basic_matrix::basic_matrix; T trace(); inline T tr() { return trace(); } mm::diag_iterator diagonal_iter(int index = 0) { return mm::diag_iterator(*this, index); } mm::diag_iterator diagonal_iter(int index = 0) const { return mm::const_diag_iterator(*this, index); } // TODO, determinant /// in place inverse // TODO, det != 0 // TODO, use gauss jordan for invertible ones //void invert();, TODO, section algorithm }; /* * derivated classes */ // simple format matrix template class mm::matrix : public mm::row_access { public: using mm::row_access::row_access; matrix(mm::t_matrix&& m) : row_access(std::move>(m)) { } operator mm::t_matrix() { return mm::t_matrix(*this); } mm::t_matrix& t() { return static_cast>(*this); } const mm::t_matrix& t() const { return static_cast>(*this); } }; template class mm::t_matrix : public mm::col_access { public: using mm::col_access::col_access; t_matrix(mm::matrix&& m) : col_access(std::move>(m)) { } operator mm::matrix() { return mm::matrix(*this); } mm::matrix& t() { return static_cast>(*this); } const mm::matrix& t() const { return static_cast>(*this); } }; // transposed matrix /*template class mm::t_matrix : public mm::basic_matrix, virtual public mm::access { public: using mm::basic_matrix::basic_matrix; };*/ /* row vector specialization */ template class mm::row_vec : public mm::matrix { public: using mm::matrix::matrix; // TODO, begin, end }; /* column vector specialization */ template class mm::col_vec : public mm::matrix { public: using mm::matrix::matrix; // TODO, begin, end }; /* square matrix specialization */ template class mm::square_matrix : public mm::matrix, public mm::square_interface { public: using mm::matrix::matrix; // get the identity of size N static inline constexpr square_matrix identity() { mm::square_matrix i; for (unsigned row = 0; row < N; row++) for (unsigned col = 0; col < N; col++) i.at(row, col) = (row == col) ? 1 : 0; return i; } }; template class mm::t_square_matrix : public mm::t_matrix, public mm::square_interface { public: using mm::t_matrix::t_matrix; }; /* * K-diagonal square matrix format * K is bounded between ]-N, N[ */ /*template class mm::diagonal_matrix : public mm::square_matrix { public: using mm::square_matrix::square_matrix; // TODO, redefine at, operator[] // TODO, matrix multiplication };*/ /* * Accessors implementation */ template T& mm::row_access::at(std::size_t row, std::size_t col) { return mm::basic_matrix::data[row * Cols + col]; } template const T& mm::row_access::at(std::size_t row, std::size_t col) const { return mm::basic_matrix::data[row * Cols + col]; } template T& mm::col_access::at(std::size_t row, std::size_t col) { return mm::basic_matrix::data[col * Cols + row]; // transpose } template const T& mm::col_access::at(std::size_t row, std::size_t col) const { return mm::basic_matrix::data[col * Cols + row]; // transpose } template mm::row_iterator mm::row_access::operator[](std::size_t index) { return mm::row_iterator(*this, static_cast(index)); } template mm::const_row_iterator mm::row_access::operator[](std::size_t index) const { return mm::const_row_iterator(*this, static_cast(index)); } template mm::col_iterator mm::col_access::operator[](std::size_t index) { return mm::col_iterator(*this, static_cast(index)); } template mm::const_col_iterator mm::col_access::operator[](std::size_t index) const { return mm::const_col_iterator(*this, static_cast(index)); } /* Square interface implementation */ template T mm::square_interface::trace() { T sum = 0; for (const auto& x : diagonal_iter()) sum += x; return sum; }