]> Dogcows Code - chaz/yoink/blob - src/Moof/cml/mathlib/checking.h
beginnings of scene rendering
[chaz/yoink] / src / Moof / cml / mathlib / checking.h
1 /* -*- C++ -*- ------------------------------------------------------------
2
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
4
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
7
8 *-----------------------------------------------------------------------*/
9 /** @file
10 * @brief
11 */
12
13 #ifndef checking_h
14 #define checking_h
15
16 #include <cml/vector/vector_expr.h>
17 #include <cml/matrix/matrix_expr.h>
18 #include <cml/quaternion/quaternion_expr.h>
19
20 /* Run- and compile-time checking of argument types, values and sizes. */
21
22 struct function_expects_vector_arg_error;
23 struct function_expects_matrix_arg_error;
24 struct function_expects_quaternion_arg_error;
25
26 struct function_expects_2D_vector_arg_error;
27 struct function_expects_3D_vector_arg_error;
28 struct function_expects_4D_vector_arg_error;
29 struct function_expects_2D_or_3D_vector_arg_error;
30 struct function_expects_2x2_matrix_arg_error;
31 struct function_expects_3x3_matrix_arg_error;
32 struct function_expects_4x4_matrix_arg_error;
33 struct function_expects_square_matrix_arg_error;
34
35 struct matrix_arg_fails_minimum_size_requirement;
36
37 namespace cml {
38 namespace detail {
39
40 //////////////////////////////////////////////////////////////////////////////
41 // Vector argument checking
42 //////////////////////////////////////////////////////////////////////////////
43
44 /** Compile-time check for a vector argument */
45 template< class VecT > inline void
46 CheckVec(const VecT&)
47 {
48 typedef et::ExprTraits<VecT> vector_traits;
49 typedef typename vector_traits::result_tag result_type;
50
51 CML_STATIC_REQUIRE_M(
52 (same_type<result_type, et::vector_result_tag>::is_true),
53 function_expects_vector_arg_error);
54 }
55
56 /** Compile-time check for a vector of size N */
57 template< class VecT, size_t N, class ErrorT > inline void
58 CheckVecN(const VecT& v, fixed_size_tag) {
59 CheckVec(v);
60
61 CML_STATIC_REQUIRE_M(((size_t)VecT::array_size == N), ErrorT);
62 }
63
64 /** Run-time check for a vector of size N */
65 template< class VecT, size_t N, class /*ErrorT*/ > inline void
66 CheckVecN(const VecT& v, dynamic_size_tag) {
67 CheckVec(v);
68
69 et::GetCheckedSize<VecT,VecT,dynamic_size_tag>()
70 .equal_or_fail(v.size(),size_t(N));
71 }
72
73 /** Check for a vector of size N */
74 template< class VecT, size_t N, class ErrorT > inline void
75 CheckVecN(const VecT& v) {
76 typedef et::ExprTraits<VecT> vector_traits;
77 typedef typename vector_traits::size_tag size_tag;
78
79 detail::CheckVecN<VecT,N,ErrorT>(v, size_tag());
80 }
81
82 /** Check for a vector of size 2 */
83 template< class VecT > inline void
84 CheckVec2(const VecT& v) {
85 detail::CheckVecN<VecT,2,function_expects_2D_vector_arg_error>(v);
86 }
87
88 /** Check for a vector of size 3 */
89 template< class VecT > inline void
90 CheckVec3(const VecT& v) {
91 detail::CheckVecN<VecT,3,function_expects_3D_vector_arg_error>(v);
92 }
93
94 /** Check for a vector of size 4 */
95 template< class VecT > inline void
96 CheckVec4(const VecT& v) {
97 CheckVecN<VecT,4,function_expects_4D_vector_arg_error>(v);
98 }
99
100 /** Compile-time check for a vector of size 2 or 3 */
101 template< class VecT > inline void
102 CheckVec2Or3(const VecT& v, fixed_size_tag) {
103 CheckVec(v);
104
105 CML_STATIC_REQUIRE_M(
106 (VecT::array_size == 2 || VecT::array_size == 3),
107 function_expects_2D_or_3D_vector_arg_error);
108 }
109
110 /** Run-time check for a vector of size 2 or 3 */
111 template< class VecT > inline void
112 CheckVec2Or3(const VecT& v, dynamic_size_tag) {
113 CheckVec(v);
114
115 if (v.size() != 2 && v.size() != 3) {
116 throw std::invalid_argument("2d or 3d vector arg expected");
117 }
118 }
119
120 /** Check for a vector of size 2 or 3 */
121 template< class VecT > inline void
122 CheckVec2Or3(const VecT& v) {
123 typedef et::ExprTraits<VecT> vector_traits;
124 typedef typename vector_traits::size_tag size_tag;
125
126 detail::CheckVec2Or3(v, size_tag());
127 }
128
129 //////////////////////////////////////////////////////////////////////////////
130 // Matrix argument checking
131 //////////////////////////////////////////////////////////////////////////////
132
133 /** Compile-time check for a matrix argument */
134 template< class MatT > inline void
135 CheckMat(const MatT&)
136 {
137 typedef et::ExprTraits<MatT> matrix_traits;
138 typedef typename matrix_traits::result_tag result_type;
139
140 CML_STATIC_REQUIRE_M(
141 (same_type<result_type, et::matrix_result_tag>::is_true),
142 function_expects_matrix_arg_error);
143 }
144
145 /** Compile-time check for a matrix of size NxM */
146 template< class MatT, size_t N, size_t M, class ErrorT > inline void
147 CheckMatNxM(const MatT& m, fixed_size_tag) {
148 CheckMat(m);
149
150 CML_STATIC_REQUIRE_M(
151 (MatT::array_rows == N && MatT::array_cols == M), ErrorT);
152 }
153
154 /** Run-time check for a matrix of size NxM */
155 template< class MatT, size_t N, size_t M, class /*ErrorT*/ > inline void
156 CheckMatNxM(const MatT& m, dynamic_size_tag) {
157 CheckMat(m);
158
159 et::GetCheckedSize<MatT,MatT,dynamic_size_tag>()
160 .equal_or_fail(m.rows(),N);
161 et::GetCheckedSize<MatT,MatT,dynamic_size_tag>()
162 .equal_or_fail(m.cols(),M);
163 }
164
165 /** Check for a matrix of size NxM */
166 template< class MatT, size_t N, size_t M, class ErrorT > inline void
167 CheckMatNxM(const MatT& m) {
168 typedef et::ExprTraits<MatT> matrix_traits;
169 typedef typename matrix_traits::size_tag size_tag;
170
171 CheckMatNxM<MatT,N,M,ErrorT>(m, size_tag());
172 }
173
174 /** Check for a square matrix of size NxN */
175 template< class MatT, size_t N, class ErrorT > inline void
176 CheckMatN(const MatT& m) {
177 CheckMatNxM<MatT,N,N,ErrorT>(m);
178 }
179
180 /** Check for a square matrix of size 2x2 */
181 template< class MatT > inline void
182 CheckMat2x2(const MatT& m) {
183 CheckMatN<MatT,2,function_expects_2x2_matrix_arg_error>(m);
184 }
185
186 /** Check for a square matrix of size 3x3 */
187 template< class MatT > inline void
188 CheckMat3x3(const MatT& m) {
189 CheckMatN<MatT,3,function_expects_3x3_matrix_arg_error>(m);
190 }
191
192 /** Check for a square matrix of size 4x4 */
193 template< class MatT > inline void
194 CheckMat4x4(const MatT& m) {
195 CheckMatN<MatT,4,function_expects_4x4_matrix_arg_error>(m);
196 }
197
198 /** Compile-time check for a matrix with minimum dimensions NxM */
199 template< class MatT, size_t N, size_t M, class ErrorT > inline void
200 CheckMatMinNxM(const MatT& m, fixed_size_tag) {
201 CheckMat(m);
202
203 CML_STATIC_REQUIRE_M(
204 (MatT::array_rows >= N && MatT::array_cols >= M), ErrorT);
205 }
206
207 /** Run-time check for a matrix with minimum dimensions NxM */
208 template< class MatT, size_t N, size_t M, class /*ErrorT*/ > inline void
209 CheckMatMinNxM(const MatT& m, dynamic_size_tag) {
210 CheckMat(m);
211
212 if (m.rows() < N || m.cols() < M) {
213 throw std::invalid_argument(
214 "matrix does not meet minimum size requirement");
215 }
216 }
217
218 /** Check for a matrix with minimum dimensions NxM */
219 template< class MatT, size_t N, size_t M, class ErrorT > inline void
220 CheckMatMinNxM(const MatT& m) {
221 typedef et::ExprTraits<MatT> matrix_traits;
222 typedef typename matrix_traits::size_tag size_tag;
223
224 CheckMatMinNxM<MatT,N,M,ErrorT>(m, size_tag());
225 }
226
227 /** Check for a matrix with minimum dimensions NxN */
228 template< class MatT, size_t N, class ErrorT > inline void
229 CheckMatMinN(const MatT& m) {
230 CheckMatMinNxM<MatT,N,N,ErrorT>(m);
231 }
232
233 /** Check for a matrix with minimum dimensions 2x2 */
234 template< class MatT > inline void
235 CheckMatMin2x2(const MatT& m) {
236 CheckMatMinN<MatT,2,matrix_arg_fails_minimum_size_requirement>(m);
237 }
238
239 /** Check for a matrix with minimum dimensions 3x3 */
240 template< class MatT > inline void
241 CheckMatMin3x3(const MatT& m) {
242 CheckMatMinN<MatT,3,matrix_arg_fails_minimum_size_requirement>(m);
243 }
244
245 /** Check for a matrix with minimum dimensions 4x4 */
246 template< class MatT > inline void
247 CheckMatMin4x4(const MatT& m) {
248 CheckMatMinN<MatT,4,matrix_arg_fails_minimum_size_requirement>(m);
249 }
250
251 /** Check for a matrix that can represent a 3D linear transform */
252 template< class MatT > inline void
253 CheckMatLinear3D(const MatT& m) {
254 CheckMatMin3x3(m);
255 }
256
257 /** Check for a matrix that can represent a 2D linear transform */
258 template< class MatT > inline void
259 CheckMatLinear2D(const MatT& m) {
260 CheckMatMin2x2(m);
261 }
262
263 /** Check for a matrix that can represent a 3D row-basis affine transform */
264 template< class MatT > inline void
265 CheckMatAffine3D(const MatT& m, row_basis) {
266 CheckMatMinNxM<MatT,4,3,matrix_arg_fails_minimum_size_requirement>(m);
267 }
268
269 /** Check for a matrix that can represent a 3D col-basis affine transform */
270 template< class MatT > inline void
271 CheckMatAffine3D(const MatT& m, col_basis) {
272 CheckMatMinNxM<MatT,3,4,matrix_arg_fails_minimum_size_requirement>(m);
273 }
274
275 /** Check for a matrix that can represent a 2D row-basis affine transform */
276 template< class MatT > inline void
277 CheckMatAffine2D(const MatT& m, row_basis) {
278 CheckMatMinNxM<MatT,3,2,matrix_arg_fails_minimum_size_requirement>(m);
279 }
280
281 /** Check for a matrix that can represent a 2D col-basis affine transform */
282 template< class MatT > inline void
283 CheckMatAffine2D(const MatT& m, col_basis) {
284 CheckMatMinNxM<MatT,2,3,matrix_arg_fails_minimum_size_requirement>(m);
285 }
286
287 /** Check for a matrix that can represent a 3D affine transform */
288 template< class MatT > inline void
289 CheckMatAffine3D(const MatT& m) {
290 CheckMatAffine3D(m, typename MatT::basis_orient());
291 }
292
293 /** Check for a matrix that can represent a 2D affine transform */
294 template< class MatT > inline void
295 CheckMatAffine2D(const MatT& m) {
296 CheckMatAffine2D(m, typename MatT::basis_orient());
297 }
298
299 /** Check for a matrix that can represent a 3D homogenous transform */
300 template< class MatT > inline void
301 CheckMatHomogeneous3D(const MatT& m) {
302 CheckMatMin4x4(m);
303 }
304
305 /** Compile-time check for a square matrix */
306 template< class MatT, class ErrorT> inline void
307 CheckMatSquare(const MatT& m, fixed_size_tag) {
308 CheckMat(m);
309
310 CML_STATIC_REQUIRE_M(
311 (MatT::array_rows == MatT::array_cols), ErrorT);
312 }
313
314 /** Run-time check for a square matrix */
315 template< class MatT, class /*ErrorT*/ > inline void
316 CheckMatSquare(const MatT& m, dynamic_size_tag) {
317 CheckMat(m);
318
319 if (m.rows() != m.cols()) {
320 throw std::invalid_argument(
321 "function expects square matrix as argument");
322 }
323 }
324
325 /** Check for a square matrix */
326 template< class MatT > inline void
327 CheckMatSquare(const MatT& m) {
328 typedef et::ExprTraits<MatT> matrix_traits;
329 typedef typename matrix_traits::size_tag size_tag;
330
331 detail::CheckMatSquare<
332 MatT,function_expects_square_matrix_arg_error>(m, size_tag());
333 }
334
335 //////////////////////////////////////////////////////////////////////////////
336 // Quaternion argument checking
337 //////////////////////////////////////////////////////////////////////////////
338
339 /** Compile-time check for a quaternion argument*/
340 template< class QuatT > inline void
341 CheckQuat(const QuatT& /*q*/)
342 {
343 typedef et::ExprTraits<QuatT> quaternion_traits;
344 typedef typename quaternion_traits::result_tag result_type;
345
346 CML_STATIC_REQUIRE_M(
347 (same_type<result_type, et::quaternion_result_tag>::is_true),
348 function_expects_quaternion_arg_error);
349 }
350
351 //////////////////////////////////////////////////////////////////////////////
352 // Index argument checking
353 //////////////////////////////////////////////////////////////////////////////
354
355 /** Run-time check for a valid argument */
356 inline void CheckValidArg(bool valid)
357 {
358 if (!valid) {
359 throw std::invalid_argument("invalid function argument");
360 }
361 }
362
363 /** Check for a valid integer index with value < N */
364 template < size_t N >
365 inline void CheckIndexN(size_t index) {
366 CheckValidArg(index < N);
367 }
368
369 /** Check for a valid integer index with value < 2 */
370 inline void CheckIndex2(size_t index) {
371 CheckIndexN<2>(index);
372 }
373
374 /** Check for a valid integer index with value < 3 */
375 inline void CheckIndex3(size_t index) {
376 CheckIndexN<3>(index);
377 }
378
379 } // namespace detail
380 } // namespace cml
381
382 #endif
This page took 0.046468 seconds and 4 git commands to generate.