00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef checking_h
00014 #define checking_h
00015
00016 #include <cml/vector/vector_expr.h>
00017 #include <cml/matrix/matrix_expr.h>
00018 #include <cml/quaternion/quaternion_expr.h>
00019
00020
00021
00022 struct function_expects_vector_arg_error;
00023 struct function_expects_matrix_arg_error;
00024 struct function_expects_quaternion_arg_error;
00025
00026 struct function_expects_2D_vector_arg_error;
00027 struct function_expects_3D_vector_arg_error;
00028 struct function_expects_4D_vector_arg_error;
00029 struct function_expects_2D_or_3D_vector_arg_error;
00030 struct function_expects_2x2_matrix_arg_error;
00031 struct function_expects_3x3_matrix_arg_error;
00032 struct function_expects_4x4_matrix_arg_error;
00033 struct function_expects_square_matrix_arg_error;
00034
00035 struct matrix_arg_fails_minimum_size_requirement;
00036
00037 namespace cml {
00038 namespace detail {
00039
00041
00043
00045 template< class VecT > inline void
00046 CheckVec(const VecT&)
00047 {
00048 typedef et::ExprTraits<VecT> vector_traits;
00049 typedef typename vector_traits::result_tag result_type;
00050
00051 CML_STATIC_REQUIRE_M(
00052 (same_type<result_type, et::vector_result_tag>::is_true),
00053 function_expects_vector_arg_error);
00054 }
00055
00057 template< class VecT, size_t N, class ErrorT > inline void
00058 CheckVecN(const VecT& v, fixed_size_tag) {
00059 CheckVec(v);
00060
00061 CML_STATIC_REQUIRE_M(((size_t)VecT::array_size == N), ErrorT);
00062 }
00063
00065 template< class VecT, size_t N, class > inline void
00066 CheckVecN(const VecT& v, dynamic_size_tag) {
00067 CheckVec(v);
00068
00069 et::GetCheckedSize<VecT,VecT,dynamic_size_tag>()
00070 .equal_or_fail(v.size(),size_t(N));
00071 }
00072
00074 template< class VecT, size_t N, class ErrorT > inline void
00075 CheckVecN(const VecT& v) {
00076 typedef et::ExprTraits<VecT> vector_traits;
00077 typedef typename vector_traits::size_tag size_tag;
00078
00079 detail::CheckVecN<VecT,N,ErrorT>(v, size_tag());
00080 }
00081
00083 template< class VecT > inline void
00084 CheckVec2(const VecT& v) {
00085 detail::CheckVecN<VecT,2,function_expects_2D_vector_arg_error>(v);
00086 }
00087
00089 template< class VecT > inline void
00090 CheckVec3(const VecT& v) {
00091 detail::CheckVecN<VecT,3,function_expects_3D_vector_arg_error>(v);
00092 }
00093
00095 template< class VecT > inline void
00096 CheckVec4(const VecT& v) {
00097 CheckVecN<VecT,4,function_expects_4D_vector_arg_error>(v);
00098 }
00099
00101 template< class VecT > inline void
00102 CheckVec2Or3(const VecT& v, fixed_size_tag) {
00103 CheckVec(v);
00104
00105 CML_STATIC_REQUIRE_M(
00106 (VecT::array_size == 2 || VecT::array_size == 3),
00107 function_expects_2D_or_3D_vector_arg_error);
00108 }
00109
00111 template< class VecT > inline void
00112 CheckVec2Or3(const VecT& v, dynamic_size_tag) {
00113 CheckVec(v);
00114
00115 if (v.size() != 2 && v.size() != 3) {
00116 throw std::invalid_argument("2d or 3d vector arg expected");
00117 }
00118 }
00119
00121 template< class VecT > inline void
00122 CheckVec2Or3(const VecT& v) {
00123 typedef et::ExprTraits<VecT> vector_traits;
00124 typedef typename vector_traits::size_tag size_tag;
00125
00126 detail::CheckVec2Or3(v, size_tag());
00127 }
00128
00130
00132
00134 template< class MatT > inline void
00135 CheckMat(const MatT&)
00136 {
00137 typedef et::ExprTraits<MatT> matrix_traits;
00138 typedef typename matrix_traits::result_tag result_type;
00139
00140 CML_STATIC_REQUIRE_M(
00141 (same_type<result_type, et::matrix_result_tag>::is_true),
00142 function_expects_matrix_arg_error);
00143 }
00144
00146 template< class MatT, size_t N, size_t M, class ErrorT > inline void
00147 CheckMatNxM(const MatT& m, fixed_size_tag) {
00148 CheckMat(m);
00149
00150 CML_STATIC_REQUIRE_M(
00151 (MatT::array_rows == N && MatT::array_cols == M), ErrorT);
00152 }
00153
00155 template< class MatT, size_t N, size_t M, class > inline void
00156 CheckMatNxM(const MatT& m, dynamic_size_tag) {
00157 CheckMat(m);
00158
00159 et::GetCheckedSize<MatT,MatT,dynamic_size_tag>()
00160 .equal_or_fail(m.rows(),N);
00161 et::GetCheckedSize<MatT,MatT,dynamic_size_tag>()
00162 .equal_or_fail(m.cols(),M);
00163 }
00164
00166 template< class MatT, size_t N, size_t M, class ErrorT > inline void
00167 CheckMatNxM(const MatT& m) {
00168 typedef et::ExprTraits<MatT> matrix_traits;
00169 typedef typename matrix_traits::size_tag size_tag;
00170
00171 CheckMatNxM<MatT,N,M,ErrorT>(m, size_tag());
00172 }
00173
00175 template< class MatT, size_t N, class ErrorT > inline void
00176 CheckMatN(const MatT& m) {
00177 CheckMatNxM<MatT,N,N,ErrorT>(m);
00178 }
00179
00181 template< class MatT > inline void
00182 CheckMat2x2(const MatT& m) {
00183 CheckMatN<MatT,2,function_expects_2x2_matrix_arg_error>(m);
00184 }
00185
00187 template< class MatT > inline void
00188 CheckMat3x3(const MatT& m) {
00189 CheckMatN<MatT,3,function_expects_3x3_matrix_arg_error>(m);
00190 }
00191
00193 template< class MatT > inline void
00194 CheckMat4x4(const MatT& m) {
00195 CheckMatN<MatT,4,function_expects_4x4_matrix_arg_error>(m);
00196 }
00197
00199 template< class MatT, size_t N, size_t M, class ErrorT > inline void
00200 CheckMatMinNxM(const MatT& m, fixed_size_tag) {
00201 CheckMat(m);
00202
00203 CML_STATIC_REQUIRE_M(
00204 (MatT::array_rows >= N && MatT::array_cols >= M), ErrorT);
00205 }
00206
00208 template< class MatT, size_t N, size_t M, class > inline void
00209 CheckMatMinNxM(const MatT& m, dynamic_size_tag) {
00210 CheckMat(m);
00211
00212 if (m.rows() < N || m.cols() < M) {
00213 throw std::invalid_argument(
00214 "matrix does not meet minimum size requirement");
00215 }
00216 }
00217
00219 template< class MatT, size_t N, size_t M, class ErrorT > inline void
00220 CheckMatMinNxM(const MatT& m) {
00221 typedef et::ExprTraits<MatT> matrix_traits;
00222 typedef typename matrix_traits::size_tag size_tag;
00223
00224 CheckMatMinNxM<MatT,N,M,ErrorT>(m, size_tag());
00225 }
00226
00228 template< class MatT, size_t N, class ErrorT > inline void
00229 CheckMatMinN(const MatT& m) {
00230 CheckMatMinNxM<MatT,N,N,ErrorT>(m);
00231 }
00232
00234 template< class MatT > inline void
00235 CheckMatMin2x2(const MatT& m) {
00236 CheckMatMinN<MatT,2,matrix_arg_fails_minimum_size_requirement>(m);
00237 }
00238
00240 template< class MatT > inline void
00241 CheckMatMin3x3(const MatT& m) {
00242 CheckMatMinN<MatT,3,matrix_arg_fails_minimum_size_requirement>(m);
00243 }
00244
00246 template< class MatT > inline void
00247 CheckMatMin4x4(const MatT& m) {
00248 CheckMatMinN<MatT,4,matrix_arg_fails_minimum_size_requirement>(m);
00249 }
00250
00252 template< class MatT > inline void
00253 CheckMatLinear3D(const MatT& m) {
00254 CheckMatMin3x3(m);
00255 }
00256
00258 template< class MatT > inline void
00259 CheckMatLinear2D(const MatT& m) {
00260 CheckMatMin2x2(m);
00261 }
00262
00264 template< class MatT > inline void
00265 CheckMatAffine3D(const MatT& m, row_basis) {
00266 CheckMatMinNxM<MatT,4,3,matrix_arg_fails_minimum_size_requirement>(m);
00267 }
00268
00270 template< class MatT > inline void
00271 CheckMatAffine3D(const MatT& m, col_basis) {
00272 CheckMatMinNxM<MatT,3,4,matrix_arg_fails_minimum_size_requirement>(m);
00273 }
00274
00276 template< class MatT > inline void
00277 CheckMatAffine2D(const MatT& m, row_basis) {
00278 CheckMatMinNxM<MatT,3,2,matrix_arg_fails_minimum_size_requirement>(m);
00279 }
00280
00282 template< class MatT > inline void
00283 CheckMatAffine2D(const MatT& m, col_basis) {
00284 CheckMatMinNxM<MatT,2,3,matrix_arg_fails_minimum_size_requirement>(m);
00285 }
00286
00288 template< class MatT > inline void
00289 CheckMatAffine3D(const MatT& m) {
00290 CheckMatAffine3D(m, typename MatT::basis_orient());
00291 }
00292
00294 template< class MatT > inline void
00295 CheckMatAffine2D(const MatT& m) {
00296 CheckMatAffine2D(m, typename MatT::basis_orient());
00297 }
00298
00300 template< class MatT > inline void
00301 CheckMatHomogeneous3D(const MatT& m) {
00302 CheckMatMin4x4(m);
00303 }
00304
00306 template< class MatT, class ErrorT> inline void
00307 CheckMatSquare(const MatT& m, fixed_size_tag) {
00308 CheckMat(m);
00309
00310 CML_STATIC_REQUIRE_M(
00311 (MatT::array_rows == MatT::array_cols), ErrorT);
00312 }
00313
00315 template< class MatT, class > inline void
00316 CheckMatSquare(const MatT& m, dynamic_size_tag) {
00317 CheckMat(m);
00318
00319 if (m.rows() != m.cols()) {
00320 throw std::invalid_argument(
00321 "function expects square matrix as argument");
00322 }
00323 }
00324
00326 template< class MatT > inline void
00327 CheckMatSquare(const MatT& m) {
00328 typedef et::ExprTraits<MatT> matrix_traits;
00329 typedef typename matrix_traits::size_tag size_tag;
00330
00331 detail::CheckMatSquare<
00332 MatT,function_expects_square_matrix_arg_error>(m, size_tag());
00333 }
00334
00336
00338
00340 template< class QuatT > inline void
00341 CheckQuat(const QuatT& )
00342 {
00343 typedef et::ExprTraits<QuatT> quaternion_traits;
00344 typedef typename quaternion_traits::result_tag result_type;
00345
00346 CML_STATIC_REQUIRE_M(
00347 (same_type<result_type, et::quaternion_result_tag>::is_true),
00348 function_expects_quaternion_arg_error);
00349 }
00350
00352
00354
00356 inline void CheckValidArg(bool valid)
00357 {
00358 if (!valid) {
00359 throw std::invalid_argument("invalid function argument");
00360 }
00361 }
00362
00364 template < size_t N >
00365 inline void CheckIndexN(size_t index) {
00366 CheckValidArg(index < N);
00367 }
00368
00370 inline void CheckIndex2(size_t index) {
00371 CheckIndexN<2>(index);
00372 }
00373
00375 inline void CheckIndex3(size_t index) {
00376 CheckIndexN<3>(index);
00377 }
00378
00379 }
00380 }
00381
00382 #endif