Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:40

0001 //  (C) Copyright Gennadiy Rozental 2001.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 //!@file
0009 //!@brief Defines framework for automated assertion construction
0010 // ***************************************************************************
0011 
0012 #ifndef BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
0013 #define BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
0014 
0015 // Boost.Test
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 // Boost
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 // STL
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 // **************             assertion::operators             ************** //
0043 // ************************************************************************** //
0044 // precedence 4: ->*, .*
0045 // precedence 5: *, /, %
0046 // precedence 6: +, -
0047 // precedence 7: << , >>
0048 // precedence 8: <, <=, > and >=
0049 // precedence 9: == and !=
0050 // precedence 10: bitwise AND
0051 // precedence 11: bitwise XOR
0052 // precedence 12: bitwise OR
0053 // precedence 13: logical AND
0054 //  disabled
0055 // precedence 14: logical OR
0056 //  disabled
0057 // precedence 15: ternary conditional
0058 //  disabled
0059 // precedence 16: = and OP= operators
0060 // precedence 17: throw operator
0061 //  not supported
0062 // precedence 18: comma
0063 //  not supported
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 } // namespace op
0182 
0183 // ************************************************************************** //
0184 // **************          assertion::expression_base          ************** //
0185 // ************************************************************************** //
0186 // Defines expression operators
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     // Disabled operators
0232     template<typename T>
0233     ExprType&
0234     operator ||( T const& /*rhs*/ )
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& /*rhs*/ )
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 // **************            assertion::value_expr             ************** //
0261 // ************************************************************************** //
0262 // simple value expression
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     // Public types
0268     typedef T                   result_type;
0269 
0270     // Constructor
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     // Specific expression interface
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     // Mutating operators
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     // expression interface
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& /*ostr*/, bool /*v*/ ) {}
0328     static void format_message( wrap_stringstream& /*ostr*/, assertion_result const& /*v*/ ) {}
0329 
0330     // Data members
0331     T                           m_value;
0332 };
0333 
0334 // ************************************************************************** //
0335 // **************            assertion::binary_expr            ************** //
0336 // ************************************************************************** //
0337 // binary expression
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     // Public types
0343     typedef typename OP::result_type result_type;
0344 
0345     // Constructor
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     // Specific expression interface
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     // To support custom manipulators
0385     LExpr const&                lhs() const     { return m_lhs; }
0386     Rhs const&                  rhs() const     { return m_rhs; }
0387 private:
0388     // Data members
0389     LExpr                       m_lhs;
0390     Rhs                         m_rhs;
0391 };
0392 
0393 // ************************************************************************** //
0394 // **************               assertion::seed                ************** //
0395 // ************************************************************************** //
0396 // seed added ot the input expression to form an assertion expression
0397 
0398 class seed {
0399 public:
0400     // ->* is highest precedence left to right operator
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 } // namespace assertion
0419 } // namespace test_tools
0420 } // namespace boost
0421 
0422 #include <boost/test/detail/enable_warnings.hpp>
0423 
0424 #endif // BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER