test_qvm.hpp 10 KB

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