1 /*
2 Scan Tailor - Interactive post-processing tool for scanned pages.
3 Copyright (C) Joseph Artsimovich <joseph.artsimovich@gmail.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef MAT_MNT_H_
20 #define MAT_MNT_H_
21
22 #include <cstddef>
23
24 template <size_t M, size_t N, typename T>
25 class MatMNT;
26
27 typedef MatMNT<2, 2, float> Mat22f;
28 typedef MatMNT<2, 2, double> Mat22d;
29 typedef MatMNT<3, 3, float> Mat33f;
30 typedef MatMNT<3, 3, double> Mat33d;
31 typedef MatMNT<4, 4, float> Mat44f;
32 typedef MatMNT<4, 4, double> Mat44d;
33
34 /**
35 * \brief A matrix with pre-defined dimensions.
36 *
37 * \note The memory layout is always column-major, as that's what MatrixCalc uses.
38 */
39 template <size_t M, size_t N, typename T>
40 class MatMNT {
41 public:
42 typedef T type;
43 enum { ROWS = static_cast<int>(M), COLS = static_cast<int>(N) };
44
45 /**
46 * \brief Initializes matrix elements to T().
47 */
48 MatMNT();
49
50 /**
51 * \brief Construction from an array of elements of possibly different type.
52 *
53 * Conversion is done by static casts. Data elements must be in column-major order.
54 */
55 template <typename OT>
56 explicit MatMNT(const OT* data);
57
58 /**
59 * \brief Construction from a matrix of same dimensions but another type.
60 *
61 * Conversion is done by static casts.
62 */
63 template <typename OT>
64 explicit MatMNT(const MatMNT<M, N, OT>& other);
65
66 /**
67 * \brief Assignment from a matrix of same dimensions but another type.
68 *
69 * Conversion is done by static casts.
70 */
71 template <typename OT>
72 MatMNT& operator=(const MatMNT<M, N, OT>& other);
73
data()74 const T* data() const { return m_data; }
75
data()76 T* data() { return m_data; }
77
operator()78 const T& operator()(int i, int j) const { return m_data[i + j * M]; }
79
operator()80 T& operator()(int i, int j) { return m_data[i + j * M]; }
81
82 private:
83 T m_data[M * N];
84 };
85
86
87 template <size_t M, size_t N, typename T>
MatMNT()88 MatMNT<M, N, T>::MatMNT() {
89 const size_t len = ROWS * COLS;
90 for (size_t i = 0; i < len; ++i) {
91 m_data[i] = T();
92 }
93 }
94
95 template <size_t M, size_t N, typename T>
96 template <typename OT>
MatMNT(const OT * data)97 MatMNT<M, N, T>::MatMNT(const OT* data) {
98 const size_t len = ROWS * COLS;
99 for (size_t i = 0; i < len; ++i) {
100 m_data[i] = static_cast<T>(data[i]);
101 }
102 }
103
104 template <size_t M, size_t N, typename T>
105 template <typename OT>
MatMNT(const MatMNT<M,N,OT> & other)106 MatMNT<M, N, T>::MatMNT(const MatMNT<M, N, OT>& other) {
107 const OT* data = other.data();
108 const size_t len = ROWS * COLS;
109 for (size_t i = 0; i < len; ++i) {
110 m_data[i] = static_cast<T>(data[i]);
111 }
112 }
113
114 #endif // ifndef MAT_MNT_H_
115