]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/test/tools/assertion.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / 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, >=, GE ) \
69 action( <=, LE, > , GT ) \
70 action( > , GT, <=, LE ) \
71 action( >=, GE, < , LT ) \
72 action( ==, EQ, !=, NE ) \
73 action( !=, NE, ==, EQ ) \
74 /**/
75
76 //____________________________________________________________________________//
77
78 #ifndef BOOST_NO_CXX11_DECLTYPE
79
80 #define BOOST_TEST_FOR_EACH_CONST_OP(action)\
81 action(->*, MEMP, ->*, MEMP ) \
82 \
83 action( * , MUL , * , MUL ) \
84 action( / , DIV , / , DIV ) \
85 action( % , MOD , % , MOD ) \
86 \
87 action( + , ADD , + , ADD ) \
88 action( - , SUB , - , SUB ) \
89 \
90 action( <<, LSH , << , LSH ) \
91 action( >>, RSH , >> , RSH ) \
92 \
93 BOOST_TEST_FOR_EACH_COMP_OP(action) \
94 \
95 action( & , BAND, & , BAND ) \
96 action( ^ , XOR , ^ , XOR ) \
97 action( | , BOR , | , 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 , = , SET ) \
112 action( +=, IADD, += , IADD ) \
113 action( -=, ISUB, -= , ISUB ) \
114 action( *=, IMUL, *= , IMUL ) \
115 action( /=, IDIV, /= , IDIV ) \
116 action( %=, IMOD, %= , IMOD ) \
117 action(<<=, ILSH, <<=, ILSH ) \
118 action(>>=, IRSH, >>=, IRSH ) \
119 action( &=, IAND, &= , IAND ) \
120 action( ^=, IXOR, ^= , IXOR ) \
121 action( |=, IOR , |= , 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_FWD_DECL( oper, name, rev, name_inverse ) \
136 template<typename Lhs, typename Rhs, \
137 typename Enabler=void> \
138 struct name; \
139 /**/
140
141 BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER_FWD_DECL )
142
143 #define DEFINE_CONST_OPER( oper, name, rev, name_inverse ) \
144 template<typename Lhs, typename Rhs, \
145 typename Enabler> \
146 struct name { \
147 typedef DEDUCE_RESULT_TYPE( oper ) result_type; \
148 typedef name_inverse<Lhs, Rhs> inverse; \
149 \
150 static result_type \
151 eval( Lhs const& lhs, Rhs const& rhs ) \
152 { \
153 return lhs oper rhs; \
154 } \
155 \
156 template<typename PrevExprType> \
157 static void \
158 report( std::ostream& ostr, \
159 PrevExprType const& lhs, \
160 Rhs const& rhs) \
161 { \
162 lhs.report( ostr ); \
163 ostr << revert() \
164 << tt_detail::print_helper( rhs ); \
165 } \
166 \
167 static char const* forward() \
168 { return " " #oper " "; } \
169 static char const* revert() \
170 { return " " #rev " "; } \
171 }; \
172 /**/
173
174 BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER )
175
176 #undef DEDUCE_RESULT_TYPE
177 #undef DEFINE_CONST_OPER
178
179 //____________________________________________________________________________//
180
181 } // namespace op
182
183 // ************************************************************************** //
184 // ************** assertion::expression_base ************** //
185 // ************************************************************************** //
186 // Defines expression operators
187
188 template<typename Lhs, typename Rhs, typename OP> class binary_expr;
189
190 template<typename ExprType,typename ValType>
191 class expression_base {
192 public:
193
194 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
195 template<typename T>
196 struct RhsT : remove_const<typename remove_reference<T>::type> {};
197
198 #define ADD_OP_SUPPORT( oper, name, _, _i ) \
199 template<typename T> \
200 binary_expr<ExprType,T, \
201 op::name<ValType,typename RhsT<T>::type> > \
202 operator oper( T&& rhs ) \
203 { \
204 return binary_expr<ExprType,T, \
205 op::name<ValType,typename RhsT<T>::type> > \
206 ( std::forward<ExprType>( \
207 *static_cast<ExprType*>(this) ), \
208 std::forward<T>(rhs) ); \
209 } \
210 /**/
211 #else
212
213 #define ADD_OP_SUPPORT( oper, name, _, _i ) \
214 template<typename T> \
215 binary_expr<ExprType,typename boost::decay<T const>::type, \
216 op::name<ValType,typename boost::decay<T const>::type> >\
217 operator oper( T const& rhs ) const \
218 { \
219 typedef typename boost::decay<T const>::type Rhs; \
220 return binary_expr<ExprType,Rhs,op::name<ValType,Rhs> > \
221 ( *static_cast<ExprType const*>(this), \
222 rhs ); \
223 } \
224 /**/
225 #endif
226
227 BOOST_TEST_FOR_EACH_CONST_OP( ADD_OP_SUPPORT )
228 #undef ADD_OP_SUPPORT
229
230 #ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS
231 // Disabled operators
232 template<typename T>
233 ExprType&
234 operator ||( T const& /*rhs*/ )
235 {
236 BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_OR_WITHIN_THIS_TESTING_TOOL, () );
237
238 return *static_cast<ExprType*>(this);
239 }
240
241 template<typename T>
242 ExprType&
243 operator &&( T const& /*rhs*/ )
244 {
245 BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_AND_WITHIN_THIS_TESTING_TOOL, () );
246
247 return *static_cast<ExprType*>(this);
248 }
249
250 operator bool()
251 {
252 BOOST_MPL_ASSERT_MSG(false, CANT_USE_TERNARY_OPERATOR_WITHIN_THIS_TESTING_TOOL, () );
253
254 return false;
255 }
256 #endif
257 };
258
259 // ************************************************************************** //
260 // ************** assertion::value_expr ************** //
261 // ************************************************************************** //
262 // simple value expression
263
264 template<typename T>
265 class value_expr : public expression_base<value_expr<T>,typename remove_const<typename remove_reference<T>::type>::type> {
266 public:
267 // Public types
268 typedef T result_type;
269
270 // Constructor
271 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
272 value_expr( value_expr&& ve )
273 : m_value( std::forward<T>(ve.m_value) )
274 {}
275 explicit value_expr( T&& val )
276 : m_value( std::forward<T>(val) )
277 {}
278 #else
279 explicit value_expr( T const& val )
280 : m_value( val )
281 {}
282 #endif
283
284 // Specific expression interface
285 T const& value() const
286 {
287 return m_value;
288 }
289 void report( std::ostream& ostr ) const
290 {
291 ostr << tt_detail::print_helper( value() );
292 }
293
294 // Mutating operators
295 #define ADD_OP_SUPPORT( OPER, ID, _, _i)\
296 template<typename U> \
297 value_expr<T>& \
298 operator OPER( U const& rhs ) \
299 { \
300 m_value OPER rhs; \
301 \
302 return *this; \
303 } \
304 /**/
305
306 BOOST_TEST_FOR_EACH_MUT_OP( ADD_OP_SUPPORT )
307 #undef ADD_OP_SUPPORT
308
309 // expression interface
310 assertion_result evaluate( bool no_message = false ) const
311 {
312 assertion_result res( value() );
313 if( no_message || res )
314 return res;
315
316 format_message( res.message(), value() );
317
318 return tt_detail::format_assertion_result( "", res.message().str() );
319 }
320
321 private:
322 template<typename U>
323 static void format_message( wrap_stringstream& ostr, U const& v )
324 {
325 ostr << "['" << tt_detail::print_helper(v) << "' evaluates to false]";
326 }
327 static void format_message( wrap_stringstream& /*ostr*/, bool /*v*/ ) {}
328 static void format_message( wrap_stringstream& /*ostr*/, assertion_result const& /*v*/ ) {}
329
330 // Data members
331 T m_value;
332 };
333
334 // ************************************************************************** //
335 // ************** assertion::binary_expr ************** //
336 // ************************************************************************** //
337 // binary expression
338
339 template<typename LExpr, typename Rhs, typename OP>
340 class binary_expr : public expression_base<binary_expr<LExpr,Rhs,OP>,typename OP::result_type> {
341 public:
342 // Public types
343 typedef typename OP::result_type result_type;
344
345 // Constructor
346 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
347 binary_expr( binary_expr&& be )
348 : m_lhs( std::forward<LExpr>(be.m_lhs) )
349 , m_rhs( std::forward<Rhs>(be.m_rhs) )
350 {}
351 binary_expr( LExpr&& lhs, Rhs&& rhs )
352 : m_lhs( std::forward<LExpr>(lhs) )
353 , m_rhs( std::forward<Rhs>(rhs) )
354 {}
355 #else
356 binary_expr( LExpr const& lhs, Rhs const& rhs )
357 : m_lhs( lhs )
358 , m_rhs( rhs )
359 {}
360 #endif
361
362 // Specific expression interface
363 result_type value() const
364 {
365 return OP::eval( m_lhs.value(), m_rhs );
366 }
367 void report( std::ostream& ostr ) const
368 {
369 return OP::report( ostr, m_lhs, m_rhs );
370 }
371
372 assertion_result evaluate( bool no_message = false ) const
373 {
374 assertion_result const expr_res( value() );
375 if( no_message || expr_res )
376 return expr_res;
377
378 wrap_stringstream buff;
379 report( buff.stream() );
380
381 return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );
382 }
383
384 // To support custom manipulators
385 LExpr const& lhs() const { return m_lhs; }
386 Rhs const& rhs() const { return m_rhs; }
387 private:
388 // Data members
389 LExpr m_lhs;
390 Rhs m_rhs;
391 };
392
393 // ************************************************************************** //
394 // ************** assertion::seed ************** //
395 // ************************************************************************** //
396 // seed added ot the input expression to form an assertion expression
397
398 class seed {
399 public:
400 // ->* is highest precedence left to right operator
401 template<typename T>
402 value_expr<T>
403 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
404 operator->*( T&& v ) const
405 {
406 return value_expr<T>( std::forward<T>( v ) );
407 }
408 #else
409 operator->*( T const& v ) const
410 {
411 return value_expr<T>( v );
412 }
413 #endif
414 };
415
416 #undef BOOST_TEST_FOR_EACH_CONST_OP
417
418 } // namespace assertion
419 } // namespace test_tools
420 } // namespace boost
421
422 #include <boost/test/detail/enable_warnings.hpp>
423
424 #endif // BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER