LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/test/tools - assertion.hpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 23 31 74.2 %
Date: 2026-06-25 07:23:43 Functions: 179 240 74.6 %

          Line data    Source code
       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       23150 : 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       23158 :     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       46316 :     value_expr( value_expr&& ve )
     273       23158 :     : m_value( std::forward<T>(ve.m_value) )
     274       46316 :     {}
     275       46316 :     explicit                    value_expr( T&& val )
     276       23158 :     : m_value( std::forward<T>(val) )
     277       46316 :     {}
     278             : #else
     279             :     explicit                    value_expr( T const& val )
     280             :     : m_value( val )
     281             :     {}
     282             : #endif
     283             : 
     284             :     // Specific expression interface
     285       23158 :     T const&                    value() const
     286             :     {
     287       23158 :         return m_value;
     288             :     }
     289           0 :     void                        report( std::ostream& ostr ) const
     290             :     {
     291           0 :         ostr << tt_detail::print_helper( value() );
     292           0 :     }
     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       46316 :     binary_expr( LExpr&& lhs, Rhs&& rhs )
     352       23158 :     : m_lhs( std::forward<LExpr>(lhs) )
     353       23158 :     , m_rhs( std::forward<Rhs>(rhs) )
     354       46316 :     {}
     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       23158 :     result_type                 value() const
     364             :     {
     365       23158 :         return OP::eval( m_lhs.value(), m_rhs );
     366             :     }
     367           0 :     void                        report( std::ostream& ostr ) const
     368             :     {
     369           0 :         return OP::report( ostr, m_lhs, m_rhs );
     370             :     }
     371             : 
     372       23158 :     assertion_result            evaluate( bool no_message = false ) const
     373             :     {
     374       23158 :         assertion_result const expr_res( value() );
     375       23158 :         if( no_message || expr_res )
     376       23158 :             return expr_res;
     377             : 
     378           0 :         wrap_stringstream buff;
     379           0 :         report( buff.stream() );
     380             : 
     381           0 :         return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );
     382       23158 :     }
     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       23158 :     operator->*( T&& v ) const
     405             :     {
     406       23158 :         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

Generated by: LCOV version 1.16