]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/test/include/boost/test/tools/fpc_op.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / test / include / boost / test / tools / fpc_op.hpp
1 // (C) Copyright Gennadiy Rozental 2001.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 // See http://www.boost.org/libs/test for the library home page.
7 //
8 //!@file
9 //!@brief Floating point comparison with enhanced reporting
10 // ***************************************************************************
11
12 #ifndef BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
13 #define BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
14
15 // Boost.Test
16 #include <boost/test/tools/assertion.hpp>
17
18 #include <boost/test/tools/floating_point_comparison.hpp>
19 #include <boost/test/tools/fpc_tolerance.hpp>
20
21 // Boost
22 #include <boost/type_traits/common_type.hpp>
23 #include <boost/utility/enable_if.hpp>
24
25 #include <boost/test/detail/suppress_warnings.hpp>
26
27 //____________________________________________________________________________//
28
29 namespace boost {
30 namespace test_tools {
31 namespace assertion {
32 namespace op {
33
34 // ************************************************************************** //
35 // ************** fpctraits ************** //
36 // ************************************************************************** //
37 // set of floating point comparison traits per comparison OP
38
39 template<typename OP>
40 struct fpctraits {
41 static const bool cmp_direct = true;
42 };
43
44 template <typename Lhs, typename Rhs>
45 struct fpctraits<op::NE<Lhs,Rhs> > {
46 static const bool cmp_direct = false;
47 };
48
49 template <typename Lhs, typename Rhs>
50 struct fpctraits<op::LT<Lhs,Rhs> > {
51 static const bool cmp_direct = false;
52 };
53
54 template <typename Lhs, typename Rhs>
55 struct fpctraits<op::GT<Lhs,Rhs> > {
56 static const bool cmp_direct = false;
57 };
58
59 //____________________________________________________________________________//
60
61 // ************************************************************************** //
62 // ************** set of overloads to select correct fpc algo ************** //
63 // ************************************************************************** //
64 // we really only care about EQ vs NE. All other comparisons use direct first
65 // and then need EQ. For example a < b (tolerance t) IFF a < b OR a == b (tolerance t)
66
67 template <typename FPT, typename Lhs, typename Rhs, typename OP>
68 inline assertion_result
69 compare_fpv( Lhs const& lhs, Rhs const& rhs, OP* )
70 {
71 fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_STRONG );
72
73 assertion_result ar( P( lhs, rhs ) );
74 if( !ar )
75 ar.message() << "Relative difference exceeds tolerance ["
76 << P.tested_rel_diff() << " > " << P.fraction_tolerance() << ']';
77 return ar;
78 }
79
80 //____________________________________________________________________________//
81
82 template <typename FPT, typename OP>
83 inline assertion_result
84 compare_fpv_near_zero( FPT const& fpv, OP* )
85 {
86 fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
87
88 assertion_result ar( P( fpv ) );
89 if( !ar )
90 ar.message() << "Absolute value exceeds tolerance [|" << fpv << "| > "<< fpc_tolerance<FPT>() << ']';
91
92 return ar;
93 }
94
95 //____________________________________________________________________________//
96
97 template <typename FPT, typename Lhs, typename Rhs>
98 inline assertion_result
99 compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
100 {
101 fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_WEAK );
102
103 assertion_result ar( !P( lhs, rhs ) );
104 if( !ar )
105 ar.message() << "Relative difference is within tolerance ["
106 << P.tested_rel_diff() << " < " << fpc_tolerance<FPT>() << ']';
107
108 return ar;
109 }
110
111 //____________________________________________________________________________//
112
113 template <typename FPT, typename Lhs, typename Rhs>
114 inline assertion_result
115 compare_fpv_near_zero( FPT const& fpv, op::NE<Lhs,Rhs>* )
116 {
117 fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
118
119 assertion_result ar( !P( fpv ) );
120 if( !ar )
121 ar.message() << "Absolute value is within tolerance [|" << fpv << "| < "<< fpc_tolerance<FPT>() << ']';
122 return ar;
123 }
124
125 //____________________________________________________________________________//
126
127 template <typename FPT, typename Lhs, typename Rhs>
128 inline assertion_result
129 compare_fpv( Lhs const& lhs, Rhs const& rhs, op::LT<Lhs,Rhs>* )
130 {
131 return lhs >= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
132 }
133
134 template <typename FPT, typename Lhs, typename Rhs>
135 inline assertion_result
136 compare_fpv_near_zero( FPT const& fpv, op::LT<Lhs,Rhs>* )
137 {
138 return fpv >= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
139 }
140
141 //____________________________________________________________________________//
142
143 template <typename FPT, typename Lhs, typename Rhs>
144 inline assertion_result
145 compare_fpv( Lhs const& lhs, Rhs const& rhs, op::GT<Lhs,Rhs>* )
146 {
147 return lhs <= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
148 }
149
150 template <typename FPT, typename Lhs, typename Rhs>
151 inline assertion_result
152 compare_fpv_near_zero( FPT const& fpv, op::GT<Lhs,Rhs>* )
153 {
154 return fpv <= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
155 }
156
157
158 //____________________________________________________________________________//
159
160 #define DEFINE_FPV_COMPARISON( oper, name, rev ) \
161 template<typename Lhs,typename Rhs> \
162 struct name<Lhs,Rhs,typename boost::enable_if_c< \
163 (fpc::tolerance_based<Lhs>::value && \
164 fpc::tolerance_based<Rhs>::value)>::type> { \
165 public: \
166 typedef typename common_type<Lhs,Rhs>::type FPT; \
167 typedef name<Lhs,Rhs> OP; \
168 \
169 typedef assertion_result result_type; \
170 \
171 static bool \
172 eval_direct( Lhs const& lhs, Rhs const& rhs ) \
173 { \
174 return lhs oper rhs; \
175 } \
176 \
177 static assertion_result \
178 eval( Lhs const& lhs, Rhs const& rhs ) \
179 { \
180 if( lhs == 0 ) \
181 return compare_fpv_near_zero( rhs, (OP*)0 ); \
182 \
183 if( rhs == 0 ) \
184 return compare_fpv_near_zero( lhs, (OP*)0 ); \
185 \
186 bool direct_res = eval_direct( lhs, rhs ); \
187 \
188 if( (direct_res && fpctraits<OP>::cmp_direct) || \
189 fpc_tolerance<FPT>() == FPT(0) ) \
190 return direct_res; \
191 \
192 return compare_fpv<FPT>( lhs, rhs, (OP*)0 ); \
193 } \
194 \
195 template<typename PrevExprType> \
196 static void \
197 report( std::ostream& ostr, \
198 PrevExprType const& lhs, \
199 Rhs const& rhs ) \
200 { \
201 lhs.report( ostr ); \
202 ostr << revert() \
203 << tt_detail::print_helper( rhs ); \
204 } \
205 \
206 static char const* revert() \
207 { return " " #rev " "; } \
208 }; \
209 /**/
210
211 BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_FPV_COMPARISON )
212 #undef DEFINE_FPV_COMPARISON
213
214 //____________________________________________________________________________//
215
216 } // namespace op
217 } // namespace assertion
218 } // namespace test_tools
219 } // namespace boost
220
221 #include <boost/test/detail/enable_warnings.hpp>
222
223 #endif // BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
224