checking.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
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 /* Run- and compile-time checking of argument types, values and sizes. */
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 // Vector argument checking
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 /*ErrorT*/ > 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 // Matrix argument checking
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 /*ErrorT*/ > 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 /*ErrorT*/ > 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 /*ErrorT*/ > 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 // Quaternion argument checking
00338 
00340 template< class QuatT > inline void
00341 CheckQuat(const QuatT& /*q*/)
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 // Index argument checking
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 } // namespace detail
00380 } // namespace cml
00381 
00382 #endif

Generated on Sat Jul 18 19:35:21 2009 for CML 1.0 by  doxygen 1.5.9