]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/test/include/boost/test/tools/assertion.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / test / include / boost / test / tools / assertion.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 Defines framework for automated assertion construction
10 // ***************************************************************************
11
12 #ifndef BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
13 #define BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
14
15 // Boost.Test
16 #include <boost/test/tools/assertion_result.hpp>
17 #include <boost/test/tools/detail/print_helper.hpp>
18 #include <boost/test/tools/detail/fwd.hpp>
19
20 // Boost
21 #include <boost/type.hpp>
22 #include <boost/type_traits/decay.hpp>
23 #include <boost/mpl/assert.hpp>
24 #include <boost/utility/declval.hpp>
25 #include <boost/type_traits/remove_reference.hpp>
26 #include <boost/type_traits/remove_const.hpp>
27
28 // STL
29 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
30 #include <utility>
31 #endif
32
33 #include <boost/test/detail/suppress_warnings.hpp>
34
35 //____________________________________________________________________________//
36
37 namespace boost {
38 namespace test_tools {
39 namespace assertion {
40
41 // ************************************************************************** //
42 // ************** assertion::operators ************** //
43 // ************************************************************************** //
44 // precedence 4: ->*, .*
45 // precedence 5: *, /, %
46 // precedence 6: +, -
47 // precedence 7: << , >>
48 // precedence 8: <, <=, > and >=
49 // precedence 9: == and !=
50 // precedence 10: bitwise AND
51 // precedence 11: bitwise XOR
52 // precedence 12: bitwise OR
53 // precedence 13: logical AND
54 // disabled
55 // precedence 14: logical OR
56 // disabled
57 // precedence 15: ternary conditional
58 // disabled
59 // precedence 16: = and OP= operators
60 // precedence 17: throw operator
61 // not supported
62 // precedence 18: comma
63 // not supported
64
65 namespace op {
66
67 #define BOOST_TEST_FOR_EACH_COMP_OP(action) \
68 action( < , LT, >= ) \
69 action( <=, LE, > ) \
70 action( > , GT, <= ) \
71 action( >=, GE, < ) \
72 action( ==, EQ, != ) \
73 action( !=, NE, == ) \
74 /**/
75
76 //____________________________________________________________________________//
77
78 #ifndef BOOST_NO_CXX11_DECLTYPE
79
80 #define BOOST_TEST_FOR_EACH_CONST_OP(action)\
81 action(->*, MEMP, ->* ) \
82 \
83 action( * , MUL, * ) \
84 action( / , DIV, / ) \
85 action( % , MOD, % ) \
86 \
87 action( + , ADD, + ) \
88 action( - , SUB, - ) \
89 \
90 action( <<, LSH, << ) \
91 action( >>, RSH, >> ) \
92 \
93 BOOST_TEST_FOR_EACH_COMP_OP(action) \
94 \
95 action( & , BAND, & ) \
96 action( ^ , XOR, ^ ) \
97 action( | , BOR, | ) \
98 /**/
99
100 #else
101
102 #define BOOST_TEST_FOR_EACH_CONST_OP(action)\
103 BOOST_TEST_FOR_EACH_COMP_OP(action) \
104 /**/
105
106 #endif
107
108 //____________________________________________________________________________//
109
110 #define BOOST_TEST_FOR_EACH_MUT_OP(action) \
111 action( = , SET , = ) \
112 action( +=, IADD, += ) \
113 action( -=, ISUB, -= ) \
114 action( *=, IMUL, *= ) \
115 action( /=, IDIV, /= ) \
116 action( %=, IMOD, %= ) \
117 action(<<=, ILSH, <<=) \
118 action(>>=, IRSH, >>=) \
119 action( &=, IAND, &= ) \
120 action( ^=, IXOR, ^= ) \
121 action( |=, IOR , |= ) \
122 /**/
123
124 //____________________________________________________________________________//
125
126 #ifndef BOOST_NO_CXX11_DECLTYPE
127 # define DEDUCE_RESULT_TYPE( oper ) \
128 decltype(boost::declval<Lhs>() oper boost::declval<Rhs>() ) optype; \
129 typedef typename boost::remove_reference<optype>::type \
130 /**/
131 #else
132 # define DEDUCE_RESULT_TYPE( oper ) bool
133 #endif
134
135 #define DEFINE_CONST_OPER( oper, name, rev ) \
136 template<typename Lhs, typename Rhs, \
137 typename Enabler=void> \
138 struct name { \
139 typedef DEDUCE_RESULT_TYPE( oper ) result_type; \
140 \
141 static result_type \
142 eval( Lhs const& lhs, Rhs const& rhs ) \
143 { \
144 return lhs oper rhs; \
145 } \
146 \
147 template<typename PrevExprType> \
148 static void \
149 report( std::ostream& ostr, \
150 PrevExprType const& lhs, \
151 Rhs const& rhs) \
152 { \
153 lhs.report( ostr ); \
154 ostr << revert() \
155 << tt_detail::print_helper( rhs ); \
156 } \
157 \
158 static char const* revert() \
159 { return " " #rev " "; } \
160 }; \
161 /**/
162
163 BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER )
164
165 #undef DEDUCE_RESULT_TYPE
166 #undef DEFINE_CONST_OPER
167
168 //____________________________________________________________________________//
169
170 } // namespace op
171
172 // ************************************************************************** //
173 // ************** assertion::expression_base ************** //
174 // ************************************************************************** //
175 // Defines expression operators
176
177 template<typename Lhs, typename Rhs, typename OP> class binary_expr;
178
179 template<typename ExprType,typename ValType>
180 class expression_base {
181 public:
182
183 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
184 template<typename T>
185 struct RhsT : remove_const<typename remove_reference<T>::type> {};
186
187 #define ADD_OP_SUPPORT( oper, name, _ ) \
188 template<typename T> \
189 binary_expr<ExprType,T, \
190 op::name<ValType,typename RhsT<T>::type> > \
191 operator oper( T&& rhs ) \
192 { \
193 return binary_expr<ExprType,T, \
194 op::name<ValType,typename RhsT<T>::type> > \
195 ( std::forward<ExprType>( \
196 *static_cast<ExprType*>(this) ), \
197 std::forward<T>(rhs) ); \
198 } \
199 /**/
200 #else
201
202 #define ADD_OP_SUPPORT( oper, name, _ ) \
203 template<typename T> \
204 binary_expr<ExprType,typename boost::decay<T const>::type, \
205 op::name<ValType,typename boost::decay<T const>::type> >\
206 operator oper( T const& rhs ) const \
207 { \
208 typedef typename boost::decay<T const>::type Rhs; \
209 return binary_expr<ExprType,Rhs,op::name<ValType,Rhs> > \
210 ( *static_cast<ExprType const*>(this), \
211 rhs ); \
212 } \
213 /**/
214 #endif
215
216 BOOST_TEST_FOR_EACH_CONST_OP( ADD_OP_SUPPORT )
217 #undef ADD_OP_SUPPORT
218
219 #ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS
220 // Disabled operators
221 template<typename T>
222 ExprType&
223 operator ||( T const& /*rhs*/ )
224 {
225 BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_OR_WITHIN_THIS_TESTING_TOOL, () );
226
227 return *static_cast<ExprType*>(this);
228 }
229
230 template<typename T>
231 ExprType&
232 operator &&( T const& /*rhs*/ )
233 {
234 BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_AND_WITHIN_THIS_TESTING_TOOL, () );
235
236 return *static_cast<ExprType*>(this);
237 }
238
239 operator bool()
240 {
241 BOOST_MPL_ASSERT_MSG(false, CANT_USE_TERNARY_OPERATOR_WITHIN_THIS_TESTING_TOOL, () );
242
243 return false;
244 }
245 #endif
246 };
247
248 // ************************************************************************** //
249 // ************** assertion::value_expr ************** //
250 // ************************************************************************** //
251 // simple value expression
252
253 template<typename T>
254 class value_expr : public expression_base<value_expr<T>,typename remove_const<typename remove_reference<T>::type>::type> {
255 public:
256 // Public types
257 typedef T result_type;
258
259 // Constructor
260 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
261 value_expr( value_expr&& ve )
262 : m_value( std::forward<T>(ve.m_value) )
263 {}
264 explicit value_expr( T&& val )
265 : m_value( std::forward<T>(val) )
266 {}
267 #else
268 explicit value_expr( T const& val )
269 : m_value( val )
270 {}
271 #endif
272
273 // Specific expression interface
274 T const& value() const
275 {
276 return m_value;
277 }
278 void report( std::ostream& ostr ) const
279 {
280 ostr << tt_detail::print_helper( m_value );
281 }
282
283 // Mutating operators
284 #define ADD_OP_SUPPORT( OPER, ID, _ ) \
285 template<typename U> \
286 value_expr<T>& \
287 operator OPER( U const& rhs ) \
288 { \
289 m_value OPER rhs; \
290 \
291 return *this; \
292 } \
293 /**/
294
295 BOOST_TEST_FOR_EACH_MUT_OP( ADD_OP_SUPPORT )
296 #undef ADD_OP_SUPPORT
297
298 // expression interface
299 assertion_result evaluate( bool no_message = false ) const
300 {
301 assertion_result res( value() );
302 if( no_message || res )
303 return res;
304
305 format_message( res.message(), value() );
306
307 return tt_detail::format_assertion_result( "", res.message().str() );
308 }
309
310 private:
311 template<typename U>
312 static void format_message( wrap_stringstream& ostr, U const& v ) { ostr << "[(bool)" << v << " is false]"; }
313 static void format_message( wrap_stringstream& /*ostr*/, bool /*v*/ ) {}
314 static void format_message( wrap_stringstream& /*ostr*/, assertion_result const& /*v*/ ) {}
315
316 // Data members
317 T m_value;
318 };
319
320 // ************************************************************************** //
321 // ************** assertion::binary_expr ************** //
322 // ************************************************************************** //
323 // binary expression
324
325 template<typename LExpr, typename Rhs, typename OP>
326 class binary_expr : public expression_base<binary_expr<LExpr,Rhs,OP>,typename OP::result_type> {
327 public:
328 // Public types
329 typedef typename OP::result_type result_type;
330
331 // Constructor
332 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
333 binary_expr( binary_expr&& be )
334 : m_lhs( std::forward<LExpr>(be.m_lhs) )
335 , m_rhs( std::forward<Rhs>(be.m_rhs) )
336 {}
337 binary_expr( LExpr&& lhs, Rhs&& rhs )
338 : m_lhs( std::forward<LExpr>(lhs) )
339 , m_rhs( std::forward<Rhs>(rhs) )
340 {}
341 #else
342 binary_expr( LExpr const& lhs, Rhs const& rhs )
343 : m_lhs( lhs )
344 , m_rhs( rhs )
345 {}
346 #endif
347
348 // Specific expression interface
349 result_type value() const
350 {
351 return OP::eval( m_lhs.value(), m_rhs );
352 }
353 void report( std::ostream& ostr ) const
354 {
355 return OP::report( ostr, m_lhs, m_rhs );
356 }
357
358 assertion_result evaluate( bool no_message = false ) const
359 {
360 assertion_result const expr_res( value() );
361 if( no_message || expr_res )
362 return expr_res;
363
364 wrap_stringstream buff;
365 report( buff.stream() );
366
367 return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );
368 }
369
370 // To support custom manipulators
371 LExpr const& lhs() const { return m_lhs; }
372 Rhs const& rhs() const { return m_rhs; }
373 private:
374 // Data members
375 LExpr m_lhs;
376 Rhs m_rhs;
377 };
378
379 // ************************************************************************** //
380 // ************** assertion::seed ************** //
381 // ************************************************************************** //
382 // seed added ot the input expression to form an assertion expression
383
384 class seed {
385 public:
386 // ->* is highest precedence left to right operator
387 template<typename T>
388 value_expr<T>
389 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
390 operator->*( T&& v ) const
391 {
392 return value_expr<T>( std::forward<T>( v ) );
393 }
394 #else
395 operator->*( T const& v ) const
396 {
397 return value_expr<T>( v );
398 }
399 #endif
400 };
401
402 #undef BOOST_TEST_FOR_EACH_CONST_OP
403
404 } // namespace assertion
405 } // namespace test_tools
406 } // namespace boost
407
408 #include <boost/test/detail/enable_warnings.hpp>
409
410 #endif // BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER