• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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