summaryrefslogtreecommitdiffstats
path: root/include/mm/view.hpp
blob: 910c16a593a1cbff36b8e277efdcb8578fd17abc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#pragma once

#include <mmmatrix.hpp>


namespace mm::alg {

	template <
		template<typename, std::size_t, std::size_t> 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<T, Rows, Cols>& m, index row, index col) {
			return m.at(row, col);
		}

		const T& operator()(const Matrix<T, Rows, Cols>& m, index row, index col) {
			return operator()(m, row, col);
		}
	};

	template <
		template<typename, std::size_t, std::size_t> typename Matrix,
		typename T, std::size_t Rows, std::size_t Cols
	>
	struct transpose : public visitor<Matrix, T, Rows, Cols>
	{
		T& operator()(const Matrix<T, Rows, Cols> m, index row, index col) {
			// assert(col < Rows)
			// assert(row < Cols)
			return m.at(col, row);
		}
	};
}

namespace mm {
	template <
		template<typename, std::size_t, std::size_t> typename Matrix,
		typename T, std::size_t Rows, std::size_t Cols
	>
	struct view
	{
		Matrix<T, Rows, Cols>& m;
		// std::stack<std::unique_ptr<alg::visitor>> visitors;
		std::unique_ptr<alg::visitor> 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<alg::visitor>(other)));
			visitor = std::make_unique<alg::visistor>(other);
		}
	};

	view operator|(const view& left, const alg::visitor& right) {
		return left |= right;
	}
}