#pragma once #include namespace mm::alg { template < template typename Matrix, typename T, std::size_t Rows, std::size_t Cols > struct visitor { using type = T; // copy constructible visitor(const visitor& other) = default; T& operator()(const Matrix& m, index row, index col) { return m.at(row, col); } const T& operator()(const Matrix& m, index row, index col) { return operator()(m, row, col); } }; template < template typename Matrix, typename T, std::size_t Rows, std::size_t Cols > struct transpose : public visitor { T& operator()(const Matrix m, index row, index col) { // assert(col < Rows) // assert(row < Cols) return m.at(col, row); } }; } namespace mm { template < template typename Matrix, typename T, std::size_t Rows, std::size_t Cols > struct view { Matrix& m; // std::stack> visitors; std::unique_ptr visitor; T& at(index row, index col) { return visitor(m, row, col); } view& operator|=(const alg::visitor& other) { // visitors.push(std::move(std::make_unique(other))); visitor = std::make_unique(other); } }; view operator|(const view& left, const alg::visitor& right) { return left |= right; } }