1 //Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc. 2 3 //Distributed under the Boost Software License, Version 1.0. (See accompanying 4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_QVM_06E5D36EB6C211DEA317E19C55D89593 7 #define BOOST_QVM_06E5D36EB6C211DEA317E19C55D89593 8 9 #include <boost/test/tools/floating_point_comparison.hpp> 10 #include <boost/detail/lightweight_test.hpp> 11 #include <iostream> 12 13 #define BOOST_QVM_TEST_EQ(expra,exprb) ( ::test_qvm::detail::test_eq_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) ) 14 #define BOOST_QVM_TEST_NEQ(expra,exprb) ( ::test_qvm::detail::test_neq_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) ) 15 #define BOOST_QVM_TEST_CLOSE(expra,exprb,exprt) ( ::test_qvm::detail::test_close_impl(#expra, #exprb, #exprt, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb, exprt) ) 16 17 #define BOOST_QVM_TEST_EQ_QUAT(expra,exprb) ( ::test_qvm::detail::test_eq_q_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) ) 18 #define BOOST_QVM_TEST_NEQ_QUAT(expra,exprb) ( ::test_qvm::detail::test_neq_q_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) ) 19 #define BOOST_QVM_TEST_CLOSE_QUAT(expra,exprb,exprt) ( ::test_qvm::detail::test_close_q_impl(#expra, #exprb, #exprt, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb, exprt) ) 20 21 namespace 22 test_qvm 23 { 24 namespace 25 detail 26 { 27 inline 28 bool close_at_tolerance(float a,float b,float tolerance)29 close_at_tolerance( float a, float b, float tolerance ) 30 { 31 return boost::math::fpc::close_at_tolerance<float>(tolerance,boost::math::fpc::FPC_STRONG)(a,b); 32 } 33 34 inline 35 bool close_at_tolerance(double a,double b,double tolerance)36 close_at_tolerance( double a, double b, double tolerance ) 37 { 38 return boost::math::fpc::close_at_tolerance<double>(tolerance,boost::math::fpc::FPC_STRONG)(a,b); 39 } 40 41 template <class A,class B> 42 void dump_ab(A a,B b)43 dump_ab( A a, B b ) 44 { 45 std::cerr << a << '\t' << b << std::endl; 46 } 47 48 template <class A,class B,int D> 49 void dump_ab(A (& a)[D],B (& b)[D])50 dump_ab( A (&a)[D], B (&b)[D] ) 51 { 52 for( int i=0; i!=D; ++i ) 53 dump_ab(a[i],b[i]); 54 } 55 56 template <class A,class B> 57 void test_eq_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A a,B b)58 test_eq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A a, B b ) 59 { 60 using namespace ::boost::qvm; 61 if( !(a==b) ) 62 { 63 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ(" << expra << ',' << exprb 64 << ") failed in function " << function << '\n'; 65 dump_ab(a,b); 66 ++::boost::detail::test_errors(); 67 } 68 } 69 70 template <class A,class B,int M,int N> 71 void test_eq_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A (& a)[M][N],B (& b)[M][N])72 test_eq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[M][N], B (&b)[M][N] ) 73 { 74 using namespace ::boost::qvm; 75 for( int i=0; i<M; ++i ) 76 for( int j=0; j<N; ++j ) 77 if( !(a[i][j]==b[i][j]) ) 78 { 79 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ(" << expra << ',' << exprb 80 << ") failed in function " << function << '\n'; 81 dump_ab(a,b); 82 ++::boost::detail::test_errors(); 83 return; 84 } 85 } 86 87 template <class A,class B,int D> 88 void test_eq_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A (& a)[D],B (& b)[D])89 test_eq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[D], B (&b)[D] ) 90 { 91 using namespace ::boost::qvm; 92 for( int i=0; i<D; ++i ) 93 if( !(a[i]==b[i]) ) 94 { 95 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ" << expra << ',' << exprb 96 << ") failed in function " << function <<'\n'; 97 dump_ab(a,b); 98 ++::boost::detail::test_errors(); 99 return; 100 } 101 } 102 103 template <class A,class B> 104 void test_eq_q_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A (& a)[4],B (& b)[4])105 test_eq_q_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[4], B (&b)[4] ) 106 { 107 using namespace ::boost::qvm; 108 int i; 109 for( i=0; i<4; ++i ) 110 if( !(a[i]==b[i]) ) 111 break; 112 if( i==4 ) 113 return; 114 for( i=0; i<4; ++i ) 115 if( !(a[i]==-b[i]) ) 116 { 117 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ" << expra << ',' << exprb 118 << ") failed in function " << function <<'\n'; 119 dump_ab(a,b); 120 ++::boost::detail::test_errors(); 121 return; 122 } 123 } 124 125 template <class A,class B> 126 void test_neq_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A a,B b)127 test_neq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A a, B b ) 128 { 129 using namespace ::boost::qvm; 130 if( !(a!=b) ) 131 { 132 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_NEQ(" << expra << ',' << exprb 133 << ") failed in function " << function << '\n'; 134 dump_ab(a,b); 135 ++::boost::detail::test_errors(); 136 } 137 } 138 139 template <class A,class B,int M,int N> 140 void test_neq_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A (& a)[M][N],B (& b)[M][N])141 test_neq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[M][N], B (&b)[M][N] ) 142 { 143 using namespace ::boost::qvm; 144 for( int i=0; i<M; ++i ) 145 for( int j=0; j<N; ++j ) 146 if( a[i][j]!=b[i][j] ) 147 return; 148 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_NEQ(" << expra << ',' << exprb 149 << ") failed in function " << function << '\n'; 150 dump_ab(a,b); 151 ++::boost::detail::test_errors(); 152 } 153 154 template <class A,class B,int D> 155 void test_neq_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A (& a)[D],B (& b)[D])156 test_neq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[D], B (&b)[D] ) 157 { 158 using namespace ::boost::qvm; 159 for( int i=0; i<D; ++i ) 160 if( a[i]!=b[i] ) 161 return; 162 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_NEQ(" << expra << ',' << exprb 163 << ") failed in function " << function << '\n'; 164 dump_ab(a,b); 165 ++::boost::detail::test_errors(); 166 } 167 168 template <class A,class B> 169 void test_neq_q_impl(char const * expra,char const * exprb,char const * file,int line,char const * function,A (& a)[4],B (& b)[4])170 test_neq_q_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[4], B (&b)[4] ) 171 { 172 using namespace ::boost::qvm; 173 int i; 174 for( i=0; i<4; ++i ) 175 if( !(a[i]!=b[i]) ) 176 break; 177 if( i==4 ) 178 return; 179 for( i=0; i<4; ++i ) 180 if( !(a[i]!=-b[i]) ) 181 { 182 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ" << expra << ',' << exprb 183 << ") failed in function " << function <<'\n'; 184 dump_ab(a,b); 185 ++::boost::detail::test_errors(); 186 return; 187 } 188 } 189 190 template <class A,class B,class T> 191 void test_close_impl(char const * expra,char const *,char const *,char const * file,int line,char const * function,A a,B b,T t)192 test_close_impl( char const * expra, char const * /*exprb*/, char const * /*exprt*/, char const * file, int line, char const * function, A a, B b, T t ) 193 { 194 if( !close_at_tolerance(a,b,t) ) 195 { 196 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE(" << expra << ',' << b << ',' << t 197 << ") failed in function " << function << '\n'; 198 ++::boost::detail::test_errors(); 199 return; 200 } 201 } 202 203 template <class A,class B,class T,int M,int N> 204 void test_close_impl(char const * expra,char const * exprb,char const * exprt,char const * file,int line,char const * function,A (& a)[M][N],B (& b)[M][N],T t)205 test_close_impl( char const * expra, char const * exprb, char const * exprt, char const * file, int line, char const * function, A (&a)[M][N], B (&b)[M][N], T t ) 206 { 207 for( int i=0; i<M; ++i ) 208 for( int j=0; j<N; ++j ) 209 if( !close_at_tolerance(a[i][j],b[i][j],t) ) 210 { 211 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE(" << expra << ',' << exprb << ',' << exprt 212 << ") failed in function " << function << '\n'; 213 dump_ab(a,b); 214 ++::boost::detail::test_errors(); 215 return; 216 } 217 } 218 219 template <class A,class B,class T,int D> 220 void test_close_impl(char const * expra,char const * exprb,char const * exprt,char const * file,int line,char const * function,A (& a)[D],B (& b)[D],T t)221 test_close_impl( char const * expra, char const * exprb, char const * exprt, char const * file, int line, char const * function, A (&a)[D], B (&b)[D], T t ) 222 { 223 for( int i=0; i<D; ++i ) 224 if( !close_at_tolerance(a[i],b[i],t) ) 225 { 226 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE(" << expra << ',' << exprb << ',' << exprt 227 << ") failed in function " << function << '\n'; 228 dump_ab(a,b); 229 ++::boost::detail::test_errors(); 230 return; 231 } 232 } 233 234 template <class A,class B,class T> 235 void test_close_q_impl(char const * expra,char const * exprb,char const * exprt,char const * file,int line,char const * function,A (& a)[4],B (& b)[4],T t)236 test_close_q_impl( char const * expra, char const * exprb, char const * exprt, char const * file, int line, char const * function, A (&a)[4], B (&b)[4], T t ) 237 { 238 int i; 239 for( i=0; i<4; ++i ) 240 if( !close_at_tolerance(a[i],b[i],t) ) 241 break; 242 if( i==4 ) 243 return; 244 for( i=0; i<4; ++i ) 245 if( !close_at_tolerance(a[i],-b[i],t) ) 246 { 247 std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE_QUAT(" << expra << ',' << exprb << ',' << exprt 248 << ") failed in function " << function << '\n'; 249 dump_ab(a,b); 250 ++::boost::detail::test_errors(); 251 return; 252 } 253 } 254 } 255 } 256 257 #endif 258