/* mmmatrix.hpp * Part of Mathematical library built (ab)using Modern C++ 17 abstractions. * * This library is not intended to be _performant_, it does not contain * hand written SMID / SSE / AVX optimizations. It is instead an example * of highly inefficient (but abstract!) code, where matrices can contain any * data type. * * Naoki Pross * 2018 ~ 2019 */ #pragma once #include #include #include #include #include namespace mm { using index = std::size_t; template class basic_matrix; /* specialisations */ template class matrix; template class square_matrix; template class diagonal_matrix; } /* * Matrix class, no access methods */ namespace mm { template class basic_matrix { public: using type = T; template friend class mm::matrix; // copy from another matrix template matrix(const basic_matrix& other); virtual T& at(index row, index col) = 0; virtual const T& at(index row, index col) const = 0; }; /* Specializations */ template struct matrix : public basic_matrix { public: virtual T& at(index row, index col) override { return m_data[row * Cols + col]; } virtual const T& at(index row, index col) const override { return at(row, col); } private: std::array m_data; }; template struct vector : public matrix {}; template struct square_matrix : public basic_matrix { public: virtual T& at(index row, index col) override { return m_data[row * N + col]; } virtual const T& at(index row, index col) const override { return at(row, col); } private: std::array m_data; }; template struct identity_matrix : public basic_matrix { public: const T& at(index row, index col) const override { return (row != col) ? static_cast(1) : static_cast(0); } private: T m_useless; T& at(index row, index col) { return m_useless; } } template struct diagonal_matrix : public basic_matrix { public: T& at(index row, index col) override { n_null_element = static_cast(0); return (row != col) ? m_data[row] : n_null_element; } const T& at(index row, index col) const override { return (row != col) ? m_data[row] : static_cast(0); } private: T m_null_element; std::array m_data; } }