File indexing completed on 2025-01-18 09:52:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
0013 #define BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
0014
0015
0016 #include <boost/test/tools/assertion_result.hpp>
0017 #include <boost/test/tools/detail/print_helper.hpp>
0018 #include <boost/test/tools/detail/fwd.hpp>
0019
0020
0021 #include <boost/type.hpp>
0022 #include <boost/type_traits/decay.hpp>
0023 #include <boost/mpl/assert.hpp>
0024 #include <boost/utility/declval.hpp>
0025 #include <boost/type_traits/remove_reference.hpp>
0026 #include <boost/type_traits/remove_const.hpp>
0027
0028
0029 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0030 #include <utility>
0031 #endif
0032
0033 #include <boost/test/detail/suppress_warnings.hpp>
0034
0035
0036
0037 namespace boost {
0038 namespace test_tools {
0039 namespace assertion {
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 namespace op {
0066
0067 #define BOOST_TEST_FOR_EACH_COMP_OP(action) \
0068 action( < , LT, >=, GE ) \
0069 action( <=, LE, > , GT ) \
0070 action( > , GT, <=, LE ) \
0071 action( >=, GE, < , LT ) \
0072 action( ==, EQ, !=, NE ) \
0073 action( !=, NE, ==, EQ ) \
0074
0075
0076
0077
0078 #ifndef BOOST_NO_CXX11_DECLTYPE
0079
0080 #define BOOST_TEST_FOR_EACH_CONST_OP(action)\
0081 action(->*, MEMP, ->*, MEMP ) \
0082 \
0083 action( * , MUL , * , MUL ) \
0084 action( / , DIV , / , DIV ) \
0085 action( % , MOD , % , MOD ) \
0086 \
0087 action( + , ADD , + , ADD ) \
0088 action( - , SUB , - , SUB ) \
0089 \
0090 action( <<, LSH , << , LSH ) \
0091 action( >>, RSH , >> , RSH ) \
0092 \
0093 BOOST_TEST_FOR_EACH_COMP_OP(action) \
0094 \
0095 action( & , BAND, & , BAND ) \
0096 action( ^ , XOR , ^ , XOR ) \
0097 action( | , BOR , | , BOR ) \
0098
0099
0100 #else
0101
0102 #define BOOST_TEST_FOR_EACH_CONST_OP(action)\
0103 BOOST_TEST_FOR_EACH_COMP_OP(action) \
0104
0105
0106 #endif
0107
0108
0109
0110 #define BOOST_TEST_FOR_EACH_MUT_OP(action) \
0111 action( = , SET , = , SET ) \
0112 action( +=, IADD, += , IADD ) \
0113 action( -=, ISUB, -= , ISUB ) \
0114 action( *=, IMUL, *= , IMUL ) \
0115 action( /=, IDIV, /= , IDIV ) \
0116 action( %=, IMOD, %= , IMOD ) \
0117 action(<<=, ILSH, <<=, ILSH ) \
0118 action(>>=, IRSH, >>=, IRSH ) \
0119 action( &=, IAND, &= , IAND ) \
0120 action( ^=, IXOR, ^= , IXOR ) \
0121 action( |=, IOR , |= , IOR ) \
0122
0123
0124
0125
0126 #ifndef BOOST_NO_CXX11_DECLTYPE
0127 # define DEDUCE_RESULT_TYPE( oper ) \
0128 decltype(boost::declval<Lhs>() oper boost::declval<Rhs>() ) optype; \
0129 typedef typename boost::remove_reference<optype>::type \
0130
0131 #else
0132 # define DEDUCE_RESULT_TYPE( oper ) bool
0133 #endif
0134
0135 #define DEFINE_CONST_OPER_FWD_DECL( oper, name, rev, name_inverse ) \
0136 template<typename Lhs, typename Rhs, \
0137 typename Enabler=void> \
0138 struct name; \
0139
0140
0141 BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER_FWD_DECL )
0142
0143 #define DEFINE_CONST_OPER( oper, name, rev, name_inverse ) \
0144 template<typename Lhs, typename Rhs, \
0145 typename Enabler> \
0146 struct name { \
0147 typedef DEDUCE_RESULT_TYPE( oper ) result_type; \
0148 typedef name_inverse<Lhs, Rhs> inverse; \
0149 \
0150 static result_type \
0151 eval( Lhs const& lhs, Rhs const& rhs ) \
0152 { \
0153 return lhs oper rhs; \
0154 } \
0155 \
0156 template<typename PrevExprType> \
0157 static void \
0158 report( std::ostream& ostr, \
0159 PrevExprType const& lhs, \
0160 Rhs const& rhs) \
0161 { \
0162 lhs.report( ostr ); \
0163 ostr << revert() \
0164 << tt_detail::print_helper( rhs ); \
0165 } \
0166 \
0167 static char const* forward() \
0168 { return " " #oper " "; } \
0169 static char const* revert() \
0170 { return " " #rev " "; } \
0171 }; \
0172
0173
0174 BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER )
0175
0176 #undef DEDUCE_RESULT_TYPE
0177 #undef DEFINE_CONST_OPER
0178
0179
0180
0181 }
0182
0183
0184
0185
0186
0187
0188 template<typename Lhs, typename Rhs, typename OP> class binary_expr;
0189
0190 template<typename ExprType,typename ValType>
0191 class expression_base {
0192 public:
0193
0194 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0195 template<typename T>
0196 struct RhsT : remove_const<typename remove_reference<T>::type> {};
0197
0198 #define ADD_OP_SUPPORT( oper, name, _, _i ) \
0199 template<typename T> \
0200 binary_expr<ExprType,T, \
0201 op::name<ValType,typename RhsT<T>::type> > \
0202 operator oper( T&& rhs ) \
0203 { \
0204 return binary_expr<ExprType,T, \
0205 op::name<ValType,typename RhsT<T>::type> > \
0206 ( std::forward<ExprType>( \
0207 *static_cast<ExprType*>(this) ), \
0208 std::forward<T>(rhs) ); \
0209 } \
0210
0211 #else
0212
0213 #define ADD_OP_SUPPORT( oper, name, _, _i ) \
0214 template<typename T> \
0215 binary_expr<ExprType,typename boost::decay<T const>::type, \
0216 op::name<ValType,typename boost::decay<T const>::type> >\
0217 operator oper( T const& rhs ) const \
0218 { \
0219 typedef typename boost::decay<T const>::type Rhs; \
0220 return binary_expr<ExprType,Rhs,op::name<ValType,Rhs> > \
0221 ( *static_cast<ExprType const*>(this), \
0222 rhs ); \
0223 } \
0224
0225 #endif
0226
0227 BOOST_TEST_FOR_EACH_CONST_OP( ADD_OP_SUPPORT )
0228 #undef ADD_OP_SUPPORT
0229
0230 #ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS
0231
0232 template<typename T>
0233 ExprType&
0234 operator ||( T const& )
0235 {
0236 BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_OR_WITHIN_THIS_TESTING_TOOL, () );
0237
0238 return *static_cast<ExprType*>(this);
0239 }
0240
0241 template<typename T>
0242 ExprType&
0243 operator &&( T const& )
0244 {
0245 BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_AND_WITHIN_THIS_TESTING_TOOL, () );
0246
0247 return *static_cast<ExprType*>(this);
0248 }
0249
0250 operator bool()
0251 {
0252 BOOST_MPL_ASSERT_MSG(false, CANT_USE_TERNARY_OPERATOR_WITHIN_THIS_TESTING_TOOL, () );
0253
0254 return false;
0255 }
0256 #endif
0257 };
0258
0259
0260
0261
0262
0263
0264 template<typename T>
0265 class value_expr : public expression_base<value_expr<T>,typename remove_const<typename remove_reference<T>::type>::type> {
0266 public:
0267
0268 typedef T result_type;
0269
0270
0271 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0272 value_expr( value_expr&& ve )
0273 : m_value( std::forward<T>(ve.m_value) )
0274 {}
0275 explicit value_expr( T&& val )
0276 : m_value( std::forward<T>(val) )
0277 {}
0278 #else
0279 explicit value_expr( T const& val )
0280 : m_value( val )
0281 {}
0282 #endif
0283
0284
0285 T const& value() const
0286 {
0287 return m_value;
0288 }
0289 void report( std::ostream& ostr ) const
0290 {
0291 ostr << tt_detail::print_helper( value() );
0292 }
0293
0294
0295 #define ADD_OP_SUPPORT( OPER, ID, _, _i)\
0296 template<typename U> \
0297 value_expr<T>& \
0298 operator OPER( U const& rhs ) \
0299 { \
0300 m_value OPER rhs; \
0301 \
0302 return *this; \
0303 } \
0304
0305
0306 BOOST_TEST_FOR_EACH_MUT_OP( ADD_OP_SUPPORT )
0307 #undef ADD_OP_SUPPORT
0308
0309
0310 assertion_result evaluate( bool no_message = false ) const
0311 {
0312 assertion_result res( value() );
0313 if( no_message || res )
0314 return res;
0315
0316 format_message( res.message(), value() );
0317
0318 return tt_detail::format_assertion_result( "", res.message().str() );
0319 }
0320
0321 private:
0322 template<typename U>
0323 static void format_message( wrap_stringstream& ostr, U const& v )
0324 {
0325 ostr << "['" << tt_detail::print_helper(v) << "' evaluates to false]";
0326 }
0327 static void format_message( wrap_stringstream& , bool ) {}
0328 static void format_message( wrap_stringstream& , assertion_result const& ) {}
0329
0330
0331 T m_value;
0332 };
0333
0334
0335
0336
0337
0338
0339 template<typename LExpr, typename Rhs, typename OP>
0340 class binary_expr : public expression_base<binary_expr<LExpr,Rhs,OP>,typename OP::result_type> {
0341 public:
0342
0343 typedef typename OP::result_type result_type;
0344
0345
0346 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0347 binary_expr( binary_expr&& be )
0348 : m_lhs( std::forward<LExpr>(be.m_lhs) )
0349 , m_rhs( std::forward<Rhs>(be.m_rhs) )
0350 {}
0351 binary_expr( LExpr&& lhs, Rhs&& rhs )
0352 : m_lhs( std::forward<LExpr>(lhs) )
0353 , m_rhs( std::forward<Rhs>(rhs) )
0354 {}
0355 #else
0356 binary_expr( LExpr const& lhs, Rhs const& rhs )
0357 : m_lhs( lhs )
0358 , m_rhs( rhs )
0359 {}
0360 #endif
0361
0362
0363 result_type value() const
0364 {
0365 return OP::eval( m_lhs.value(), m_rhs );
0366 }
0367 void report( std::ostream& ostr ) const
0368 {
0369 return OP::report( ostr, m_lhs, m_rhs );
0370 }
0371
0372 assertion_result evaluate( bool no_message = false ) const
0373 {
0374 assertion_result const expr_res( value() );
0375 if( no_message || expr_res )
0376 return expr_res;
0377
0378 wrap_stringstream buff;
0379 report( buff.stream() );
0380
0381 return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );
0382 }
0383
0384
0385 LExpr const& lhs() const { return m_lhs; }
0386 Rhs const& rhs() const { return m_rhs; }
0387 private:
0388
0389 LExpr m_lhs;
0390 Rhs m_rhs;
0391 };
0392
0393
0394
0395
0396
0397
0398 class seed {
0399 public:
0400
0401 template<typename T>
0402 value_expr<T>
0403 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0404 operator->*( T&& v ) const
0405 {
0406 return value_expr<T>( std::forward<T>( v ) );
0407 }
0408 #else
0409 operator->*( T const& v ) const
0410 {
0411 return value_expr<T>( v );
0412 }
0413 #endif
0414 };
0415
0416 #undef BOOST_TEST_FOR_EACH_CONST_OP
0417
0418 }
0419 }
0420 }
0421
0422 #include <boost/test/detail/enable_warnings.hpp>
0423
0424 #endif