| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 | //  (C) Copyright Gennadiy Rozental 2001.//  Distributed under the Boost Software License, Version 1.0.//  (See accompanying file LICENSE_1_0.txt or copy at//  http://www.boost.org/LICENSE_1_0.txt)//  See http://www.boost.org/libs/test for the library home page.////!@file//!@brief Defines framework for automated assertion construction// ***************************************************************************#ifndef BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER#define BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER// Boost.Test#include <boost/test/tools/assertion_result.hpp>#include <boost/test/tools/detail/print_helper.hpp>#include <boost/test/tools/detail/fwd.hpp>// Boost#include <boost/type.hpp>#include <boost/type_traits/decay.hpp>#include <boost/mpl/assert.hpp>#include <boost/utility/declval.hpp>#include <boost/type_traits/remove_reference.hpp>#include <boost/type_traits/remove_const.hpp>// STL#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES#include <utility>#endif#include <boost/test/detail/suppress_warnings.hpp>//____________________________________________________________________________//namespace boost {namespace test_tools {namespace assertion {// ************************************************************************** //// **************             assertion::operators             ************** //// ************************************************************************** //// precedence 4: ->*, .*// precedence 5: *, /, %// precedence 6: +, -// precedence 7: << , >>// precedence 8: <, <=, > and >=// precedence 9: == and !=// precedence 10: bitwise AND// precedence 11: bitwise XOR// precedence 12: bitwise OR// precedence 13: logical AND//  disabled// precedence 14: logical OR//  disabled// precedence 15: ternary conditional//  disabled// precedence 16: = and OP= operators// precedence 17: throw operator//  not supported// precedence 18: comma//  not supportednamespace op {#define BOOST_TEST_FOR_EACH_COMP_OP(action) \    action( < , LT, >=, GE )                \    action( <=, LE, > , GT )                \    action( > , GT, <=, LE )                \    action( >=, GE, < , LT )                \    action( ==, EQ, !=, NE )                \    action( !=, NE, ==, EQ )                \/**///____________________________________________________________________________//#ifndef BOOST_NO_CXX11_DECLTYPE#define BOOST_TEST_FOR_EACH_CONST_OP(action)\    action(->*, MEMP, ->*, MEMP )           \                                            \    action( * , MUL , *  , MUL  )           \    action( / , DIV , /  , DIV  )           \    action( % , MOD , %  , MOD  )           \                                            \    action( + , ADD , +  , ADD  )           \    action( - , SUB , -  , SUB  )           \                                            \    action( <<, LSH , << , LSH  )           \    action( >>, RSH , >> , RSH  )           \                                            \    BOOST_TEST_FOR_EACH_COMP_OP(action)     \                                            \    action( & , BAND, &  , BAND )           \    action( ^ , XOR , ^  , XOR  )           \    action( | , BOR , |  , BOR  )           \/**/#else#define BOOST_TEST_FOR_EACH_CONST_OP(action)\    BOOST_TEST_FOR_EACH_COMP_OP(action)     \/**/#endif//____________________________________________________________________________//#define BOOST_TEST_FOR_EACH_MUT_OP(action)  \    action( = , SET , =  , SET  )           \    action( +=, IADD, += , IADD )           \    action( -=, ISUB, -= , ISUB )           \    action( *=, IMUL, *= , IMUL )           \    action( /=, IDIV, /= , IDIV )           \    action( %=, IMOD, %= , IMOD )           \    action(<<=, ILSH, <<=, ILSH )           \    action(>>=, IRSH, >>=, IRSH )           \    action( &=, IAND, &= , IAND )           \    action( ^=, IXOR, ^= , IXOR )           \    action( |=, IOR , |= , IOR  )           \/**///____________________________________________________________________________//#ifndef BOOST_NO_CXX11_DECLTYPE#   define DEDUCE_RESULT_TYPE( oper )                                   \    decltype(boost::declval<Lhs>() oper boost::declval<Rhs>() ) optype; \    typedef typename boost::remove_reference<optype>::type              \/**/#else#   define DEDUCE_RESULT_TYPE( oper ) bool#endif#define DEFINE_CONST_OPER_FWD_DECL( oper, name, rev, name_inverse ) \template<typename Lhs, typename Rhs,                \         typename Enabler=void>                     \struct name;                                        \/**/BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER_FWD_DECL )#define DEFINE_CONST_OPER( oper, name, rev, name_inverse ) \template<typename Lhs, typename Rhs,                \         typename Enabler>                          \struct name {                                       \    typedef DEDUCE_RESULT_TYPE( oper ) result_type; \    typedef name_inverse<Lhs, Rhs> inverse;         \                                                    \    static result_type                              \    eval( Lhs const& lhs, Rhs const& rhs )          \    {                                               \        return lhs oper rhs;                        \    }                                               \                                                    \    template<typename PrevExprType>                 \    static void                                     \    report( std::ostream&       ostr,               \            PrevExprType const& lhs,                \            Rhs const&          rhs)                \    {                                               \        lhs.report( ostr );                         \        ostr << revert()                            \             << tt_detail::print_helper( rhs );     \    }                                               \                                                    \    static char const* forward()                    \    { return " " #oper " "; }                       \    static char const* revert()                     \    { return " " #rev " "; }                        \};                                                  \/**/BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER )#undef DEDUCE_RESULT_TYPE#undef DEFINE_CONST_OPER//____________________________________________________________________________//} // namespace op// ************************************************************************** //// **************          assertion::expression_base          ************** //// ************************************************************************** //// Defines expression operatorstemplate<typename Lhs, typename Rhs, typename OP> class binary_expr;template<typename ExprType,typename ValType>class expression_base {public:#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES    template<typename T>    struct RhsT : remove_const<typename remove_reference<T>::type> {};    #define ADD_OP_SUPPORT( oper, name, _, _i )                     \    template<typename T>                                        \    binary_expr<ExprType,T,                                     \        op::name<ValType,typename RhsT<T>::type> >              \    operator oper( T&& rhs )                                    \    {                                                           \        return binary_expr<ExprType,T,                          \         op::name<ValType,typename RhsT<T>::type> >             \            ( std::forward<ExprType>(                           \                *static_cast<ExprType*>(this) ),                \              std::forward<T>(rhs) );                           \    }                                                           \/**/#else#define ADD_OP_SUPPORT( oper, name, _, _i )                     \    template<typename T>                                        \    binary_expr<ExprType,typename boost::decay<T const>::type,  \        op::name<ValType,typename boost::decay<T const>::type> >\    operator oper( T const& rhs ) const                         \    {                                                           \        typedef typename boost::decay<T const>::type Rhs;       \        return binary_expr<ExprType,Rhs,op::name<ValType,Rhs> > \            ( *static_cast<ExprType const*>(this),              \              rhs );                                            \    }                                                           \/**/#endif    BOOST_TEST_FOR_EACH_CONST_OP( ADD_OP_SUPPORT )    #undef ADD_OP_SUPPORT#ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS    // Disabled operators    template<typename T>    ExprType&    operator ||( T const& /*rhs*/ )    {        BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_OR_WITHIN_THIS_TESTING_TOOL, () );        return *static_cast<ExprType*>(this);    }    template<typename T>    ExprType&    operator &&( T const& /*rhs*/ )    {        BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_AND_WITHIN_THIS_TESTING_TOOL, () );        return *static_cast<ExprType*>(this);    }    operator bool()    {        BOOST_MPL_ASSERT_MSG(false, CANT_USE_TERNARY_OPERATOR_WITHIN_THIS_TESTING_TOOL, () );        return false;    }#endif};// ************************************************************************** //// **************            assertion::value_expr             ************** //// ************************************************************************** //// simple value expressiontemplate<typename T>class value_expr : public expression_base<value_expr<T>,typename remove_const<typename remove_reference<T>::type>::type> {public:    // Public types    typedef T                   result_type;    // Constructor#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES    value_expr( value_expr&& ve )    : m_value( std::forward<T>(ve.m_value) )    {}    explicit                    value_expr( T&& val )    : m_value( std::forward<T>(val) )    {}#else    explicit                    value_expr( T const& val )    : m_value( val )    {}#endif    // Specific expression interface    T const&                    value() const    {        return m_value;    }    void                        report( std::ostream& ostr ) const    {        ostr << tt_detail::print_helper( value() );    }    // Mutating operators#define ADD_OP_SUPPORT( OPER, ID, _, _i)\    template<typename U>                \    value_expr<T>&                      \    operator OPER( U const& rhs )       \    {                                   \        m_value OPER rhs;               \                                        \        return *this;                   \    }                                   \/**/    BOOST_TEST_FOR_EACH_MUT_OP( ADD_OP_SUPPORT )#undef ADD_OP_SUPPORT    // expression interface    assertion_result            evaluate( bool no_message = false ) const    {        assertion_result res( value() );        if( no_message || res )            return res;        format_message( res.message(), value() );        return tt_detail::format_assertion_result( "", res.message().str() );    }private:    template<typename U>    static void format_message( wrap_stringstream& ostr, U const& v )    {        ostr << "['" << tt_detail::print_helper(v) << "' evaluates to false]";    }    static void format_message( wrap_stringstream& /*ostr*/, bool /*v*/ ) {}    static void format_message( wrap_stringstream& /*ostr*/, assertion_result const& /*v*/ ) {}    // Data members    T                           m_value;};// ************************************************************************** //// **************            assertion::binary_expr            ************** //// ************************************************************************** //// binary expressiontemplate<typename LExpr, typename Rhs, typename OP>class binary_expr : public expression_base<binary_expr<LExpr,Rhs,OP>,typename OP::result_type> {public:    // Public types    typedef typename OP::result_type result_type;    // Constructor#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES    binary_expr( binary_expr&& be )    : m_lhs( std::forward<LExpr>(be.m_lhs) )    , m_rhs( std::forward<Rhs>(be.m_rhs) )    {}    binary_expr( LExpr&& lhs, Rhs&& rhs )    : m_lhs( std::forward<LExpr>(lhs) )    , m_rhs( std::forward<Rhs>(rhs) )    {}#else    binary_expr( LExpr const& lhs, Rhs const& rhs )    : m_lhs( lhs )    , m_rhs( rhs )    {}#endif    // Specific expression interface    result_type                 value() const    {        return OP::eval( m_lhs.value(), m_rhs );    }    void                        report( std::ostream& ostr ) const    {        return OP::report( ostr, m_lhs, m_rhs );    }    assertion_result            evaluate( bool no_message = false ) const    {        assertion_result const expr_res( value() );        if( no_message || expr_res )            return expr_res;        wrap_stringstream buff;        report( buff.stream() );        return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );    }    // To support custom manipulators    LExpr const&                lhs() const     { return m_lhs; }    Rhs const&                  rhs() const     { return m_rhs; }private:    // Data members    LExpr                       m_lhs;    Rhs                         m_rhs;};// ************************************************************************** //// **************               assertion::seed                ************** //// ************************************************************************** //// seed added ot the input expression to form an assertion expressionclass seed {public:    // ->* is highest precedence left to right operator    template<typename T>    value_expr<T>#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES    operator->*( T&& v ) const    {        return value_expr<T>( std::forward<T>( v ) );    }#else    operator->*( T const& v )  const    {        return value_expr<T>( v );    }#endif};#undef BOOST_TEST_FOR_EACH_CONST_OP} // namespace assertion} // namespace test_tools} // namespace boost#include <boost/test/detail/enable_warnings.hpp>#endif // BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
 |