27#ifndef vtkMatrixUtilities_h
28#define vtkMatrixUtilities_h
60template <
int ContainerTypeT,
class ContainerT>
64 static_assert(std::is_integral<value_type>::value || std::is_floating_point<value_type>::value,
65 "value_type is not a numeric type");
69template <
class ContainerT>
72 typedef typename std::remove_pointer<
73 typename std::remove_all_extents<typename std::remove_pointer<ContainerT>::type>::type>::type
75 static_assert(std::is_integral<value_type>::value || std::is_floating_point<value_type>::value,
76 "value_type is not a numeric type");
89template <
class ContainerT>
93 typedef typename std::remove_reference<ContainerT>::type DerefContainer;
98 std::is_array<DerefContainer>::value || std::is_pointer<DerefContainer>::value,
100 static_assert(std::is_integral<value_type>::value || std::is_floating_point<value_type>::value,
101 "value_type is not a numeric type");
109template <
class MatrixT>
112 typedef typename std::remove_extent<MatrixT>::type Row;
113 typedef typename std::remove_extent<Row>::type Value;
114 return std::is_array<MatrixT>::value && std::is_array<Row>::value && !std::is_array<Value>::value;
122template <
class MatrixT>
125 typedef typename std::remove_pointer<MatrixT>::type Row;
126 typedef typename std::remove_pointer<Row>::type Value;
127 return std::is_pointer<MatrixT>::value && std::is_pointer<Row>::value &&
128 !std::is_pointer<Value>::value;
136template <
class MatrixT>
139 typedef typename std::remove_pointer<MatrixT>::type RowPointer;
140 typedef typename std::remove_extent<MatrixT>::type RowArray;
141 typedef typename std::remove_pointer<MatrixT>::type ValuePointerPointer;
142 typedef typename std::remove_extent<MatrixT>::type ValuePointerArray;
143 typedef typename std::remove_pointer<MatrixT>::type ValueArrayPointer;
144 typedef typename std::remove_extent<MatrixT>::type ValueArrayArray;
145 return ((std::is_array<RowPointer>::value && !std::is_same<RowPointer, MatrixT>::value) ||
146 std::is_pointer<RowPointer>::value || std::is_array<RowArray>::value ||
147 (std::is_pointer<RowArray>::value && !std::is_same<RowArray, MatrixT>::value)) &&
148 (!std::is_array<ValuePointerPointer>::value || !std::is_pointer<ValuePointerPointer>::value) &&
149 (!std::is_array<ValueArrayPointer>::value || !std::is_pointer<ValueArrayPointer>::value) &&
150 (!std::is_array<ValuePointerArray>::value || !std::is_pointer<ValuePointerArray>::value) &&
151 (!std::is_array<ValueArrayArray>::value || !std::is_pointer<ValueArrayArray>::value);
157template <
int RowsT,
int ColsT,
class LayoutT>
161template <
int RowsT,
int ColsT>
164 template <
int RowT,
int ColT>
167 static_assert(RowT >= 0 && RowT < RowsT,
"RowT out of bounds");
168 static_assert(ColT >= 0 && ColT < ColsT,
"ColT out of bounds");
169 return ColsT * RowT + ColT;
173template <
int RowsT,
int ColsT>
176 template <
int RowT,
int ColT>
179 static_assert(RowT >= 0 && RowT < RowsT,
"RowT out of bounds");
180 static_assert(ColT >= 0 && ColT < ColsT,
"ColT out of bounds");
181 return RowsT * ColT + RowT;
198template <
int RowsT,
int ColsT,
class LayoutT = Layout::Identity>
201 template <
int RowT,
int ColT>
211template <
int RowsT,
int ColsT,
class MatrixT,
class LayoutT,
bool MatrixLayoutIs2DT>
216template <
int RowsT,
int ColsT,
class MatrixT,
class LayoutT>
217class Wrapper<RowsT, ColsT, MatrixT, LayoutT, false>
223 template <
int RowT,
int ColT>
224 static const Scalar&
Get(
const MatrixT& M)
229 template <
int RowT,
int ColT>
230 static Scalar&
Get(MatrixT& M)
237template <
int RowsT,
int ColsT,
class MatrixT>
244 template <
int RowT,
int ColT>
245 static const Scalar&
Get(
const MatrixT& M)
247 return M[RowT][ColT];
250 template <
int RowT,
int ColT>
251 static Scalar&
Get(MatrixT& M)
253 return M[RowT][ColT];
258template <
int RowsT,
int ColsT,
class MatrixT>
265 template <
int RowT,
int ColT>
266 static const Scalar&
Get(
const MatrixT& M)
268 return M[ColT][RowT];
271 template <
int RowT,
int ColT>
272 static Scalar&
Get(MatrixT& M)
274 return M[ColT][RowT];
280template <
int RowsT,
int ColsT,
class MatrixT>
286 template <
int RowT,
int ColT>
289 static constexpr Scalar ZERO = Scalar(0);
291 static Scalar& Get(
const MatrixT&) {
return ZERO; }
295 struct Helper<RowT, RowT>
297 static Scalar& Get(MatrixT& M) {
return M[RowT]; }
299 static const Scalar& Get(
const MatrixT& M) {
return M[RowT]; }
303 template <
int RowT,
int ColT>
304 const Scalar&
Get(
const MatrixT& M)
306 return Helper<RowT, ColT>::Get(M);
309 template <
int RowT,
int ColT>
312 return Helper<RowT, ColT>::Get(M);
332template <
int RowsT,
int ColsT,
class MatrixT,
class LayoutT = Layout::Identity>
338 static_assert(!MatrixLayoutIs2D<MatrixT>() || !std::is_same<LayoutT, Layout::Diag>::value,
339 "A diagonal matrix cannot be a 2D array");
342 template <
int RowT,
int ColT>
343 static const Scalar&
Get(
const MatrixT& M)
346 MatrixLayoutIs2D<MatrixT>()>::template Get<RowT, ColT>(M);
349 template <
int RowT,
int ColT>
350 static Scalar&
Get(MatrixT& M)
353 MatrixLayoutIs2D<MatrixT>()>::template Get<RowT, ColT>(M);
static const Scalar & Get(const MatrixT &M)
static Scalar & Get(MatrixT &M)
static const Scalar & Get(const MatrixT &M)
static Scalar & Get(MatrixT &M)
const Scalar & Get(const MatrixT &M)
static Scalar & Get(MatrixT &M)
static const Scalar & Get(const MatrixT &M)
static Scalar & Get(MatrixT &M)
static const Scalar & Get(const MatrixT &M)
static constexpr bool MatrixIsPointerToPointer()
At compile time, returns true if the templated parameter is a pointer to pointer (double** for instan...
static constexpr bool MatrixIs2DArray()
At compile time, returns true if the templated parameter is a 2D array (double[3][3] for instance),...
static constexpr bool MatrixLayoutIs2D()
At compile time, returns true if the templated parameter layout is 2D, i.e.
This struct determines a prior transform to input matrices, chaging the way they are indexed.
This class is a helper class to compute at compile time the index of a matrix stored as a 1D array fr...
static constexpr int GetIndex()
static constexpr int GetIndex()
static constexpr int GetIndex()