$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r74880 - trunk/boost/test/tools
From: gennadiy.rozental_at_[hidden]
Date: 2011-10-10 04:39:05
Author: rogeeff
Date: 2011-10-10 04:39:04 EDT (Mon, 10 Oct 2011)
New Revision: 74880
URL: http://svn.boost.org/trac/boost/changeset/74880
Log:
new framework for automated assertion construction 
Added:
   trunk/boost/test/tools/assertion.hpp   (contents, props changed)
Added: trunk/boost/test/tools/assertion.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/tools/assertion.hpp	2011-10-10 04:39:04 EDT (Mon, 10 Oct 2011)
@@ -0,0 +1,372 @@
+//  (C) Copyright Gennadiy Rozental 2011.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision: 74663 $
+//
+//  Description : defines framework for automated assertion construction
+// ***************************************************************************
+
+#ifndef BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
+#define BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
+
+// Boost.Test
+
+// Boost
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/declval.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace test_tools {
+namespace assertion {
+
+// ************************************************************************** //
+// **************             assertion::expression            ************** //
+// ************************************************************************** //
+
+class expression {
+public:
+    // expression interface
+    virtual predicate_result    evaluate() const = 0;
+};
+
+// ************************************************************************** //
+// **************             assertion::operators             ************** //
+// ************************************************************************** //
+
+namespace op {
+
+enum id { 
+    // precedence 4: ->*, .*
+    MEMP, 
+    // precedence 5: *, /, %
+    MUL, DIV, MOD,  
+    // precedence 6: +, -
+    ADD, SUB,
+    // precedence 7: << , >>
+    LSH, RSH,
+    // precedence 8: <, <=, > and >=
+    LT, LE, GT, GE,
+    // precedence 9: == and !=
+    EQ, NE,
+    // precedence 10: bitwise AND
+    BAND,
+    // precedence 11: bitwise XOR
+    XOR,
+    // precedence 12: bitwise OR
+    BOR,
+    // precedence 13: logical AND
+    //  disabled
+    // precedence 14: logical OR
+    //  disabled
+    // precedence 15: ternary conditional
+    //  disabled
+
+    // precedence 16: = and OP= operators
+    SET, IADD, ISUB, IMUL, IDIV, IMOD,
+    ILSH, IRSH, 
+    IAND, IXOR, IOR
+    // precedence 17: throw operator
+    // not supported
+    // precedence 18: comma
+    // not supported
+};
+
+#define BOOST_TEST_FOR_EACH_OP( action )    \
+    action(->*, MEMP )                      \
+                                            \
+    action( * , MUL  )                      \
+    action( / , DIV  )                      \
+    action( % , MOD  )                      \
+                                            \
+    action( + , ADD  )                      \
+    action( - , SUB  )                      \
+                                            \
+    action( <<, LSH  )                      \
+    action( >>, RSH  )                      \
+                                            \
+    action( < , LT   )                      \
+    action( <=, LE   )                      \
+    action( > , GT   )                      \
+    action( >=, GE   )                      \
+                                            \
+    action( ==, EQ   )                      \
+    action( !=, NE   )                      \
+                                            \
+    action( & , BAND )                      \
+    action( ^ , XOR  )                      \
+    action( | , BOR  )                      \
+/**/
+
+#define BOOST_TEST_FOR_EACH_MUT_OP( action )\
+    action( = , SET  )                      \
+    action( +=, IADD )                      \
+    action( -=, ISUB )                      \
+    action( *=, IMUL )                      \
+    action( /=, IDIV )                      \
+    action( %=, IMOD )                      \
+    action(<<=, ILSH )                      \
+    action(>>=, IRSH )                      \
+    action( &=, IAND )                      \
+    action( ^=, IXOR )                      \
+    action( |=, IOR  )                      \
+/**/
+
+// ************************************************************************** //
+// **************          assertion::operator traits          ************** //
+// ************************************************************************** //
+
+template<id ID>
+struct traits {
+    static char const* reverse( char const* direct ) { return direct; }
+};
+
+template<> struct traits<EQ> { static char const* reverse( char const* ) { return "!="; } };
+template<> struct traits<NE> { static char const* reverse( char const* ) { return "=="; } };
+
+template<> struct traits<LT> { static char const* reverse( char const* ) { return ">="; } };
+template<> struct traits<LE> { static char const* reverse( char const* ) { return ">"; } };
+template<> struct traits<GT> { static char const* reverse( char const* ) { return "<="; } };
+template<> struct traits<GE> { static char const* reverse( char const* ) { return "<"; } };
+
+} // anmespace op
+
+// ************************************************************************** //
+// **************         assertion::expression_result         ************** //
+// ************************************************************************** //
+
+namespace detail {
+
+template<typename PrevExprType,typename Rhs,op::id OP>
+class expression_result;
+
+#ifndef BOOST_NO_DECLTYPE
+
+#define DEFINE_OP_EXPRESSION_RESULT( OPER, ID )             \
+template<typename PrevExprType,typename Rhs>                \
+class expression_result<PrevExprType,Rhs,op::ID> {          \
+    typedef typename PrevExprType::result_type Lhs;         \
+public:                                                     \
+                                                            \
+    typedef decltype(boost::declval<Lhs>() OPER             \
+                     boost::declval<Rhs>() ) type;          \
+                                                            \
+    static type                                             \
+    produce( Lhs const& lhs, Rhs const& rhs)                \
+    {                                                       \
+        return lhs OPER rhs;                                \
+    }                                                       \
+                                                            \
+    static void                                             \
+    report( std::ostream& ostr,                             \
+            PrevExprType const& lhs, Rhs const& rhs)        \
+    {                                                       \
+        lhs.report( ostr );                                 \
+        ostr << op::traits<op::ID>::reverse( #OPER )        \
+             << rhs;                                        \
+    }                                                       \
+};                                                          \
+/**/
+
+////////////////////////////////////////////////////////////////
+
+BOOST_TEST_FOR_EACH_OP( DEFINE_OP_EXPRESSION_RESULT );
+
+#undef DEFINE_OP_EXPRESSION_RESULT
+
+#endif
+
+} // namespace detail
+
+////////////////////////////////////////////////////////////////
+
+// ************************************************************************** //
+// **************           assertion::expression_op           ************** //
+// ************************************************************************** //
+// Defines expression operators
+
+template<typename Lhs,typename Rhs,op::id OP> class binary_expr;
+
+template<typename ExprType>
+class expression_op {
+public:
+#ifndef BOOST_NO_DECLTYPE
+
+#define ADD_OP_SUPPORT( OPER, ID )                          \
+    template<typename T>                                    \
+    binary_expr<ExprType,T,op::ID>                          \
+    operator OPER( T const& rhs ) const                     \
+    {                                                       \
+        return binary_expr<ExprType,T,op::ID>(              \
+            *static_cast<ExprType const*>(this),            \
+            rhs );                                          \
+    }                                                       \
+/**/
+
+    BOOST_TEST_FOR_EACH_OP( ADD_OP_SUPPORT );
+#undef ADD_OP_SUPPORT
+
+#endif
+
+    // 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;
+    }
+};
+
+// ************************************************************************** //
+// **************            assertion::value_expr             ************** //
+// ************************************************************************** //
+// simple value expression
+
+template<typename T>
+class value_expr : public expression, public expression_op<value_expr<T> > {
+public:
+    // Public types
+    typedef T                   result_type;
+
+    // Constructor
+    explicit                    value_expr( T&& val )
+    : m_value( val )
+    {}
+
+    // Specific expresson interface
+    T const&                    value() const
+    {
+        return m_value;
+    }
+    void                        report( std::ostream& ostr ) const
+    {
+        ostr << m_value;
+    }
+
+    // Mutating operators
+#define ADD_OP_SUPPORT( OPER, ID )                          \
+    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
+
+private:
+    // expression interface
+    virtual predicate_result    evaluate() const
+    {
+        predicate_result res( value() );
+        if( !res )
+            res.message() << "(bool)" << value() << " is false";
+        
+        return res;
+    }
+
+    // Data members
+    T                           m_value;
+};
+
+// ************************************************************************** //
+// **************         assertion::binary_expr_expr          ************** //
+// ************************************************************************** //
+// binary expression
+
+template<typename Lhs,typename Rhs,op::id OP>
+class binary_expr : public expression, public expression_op<binary_expr<Lhs,Rhs,OP> > {
+    typedef detail::expression_result<Lhs,Rhs,OP>   result;
+public:
+    // Public types
+    typedef typename result::type result_type;
+
+    // Constructor
+    binary_expr( Lhs const& lhs, Rhs const& rhs )
+    : m_lhs( lhs )
+    , m_rhs( rhs )
+    {}
+
+    // Specifica expression interface
+    result_type                 value() const
+    {
+        return result::produce( m_lhs.value(), m_rhs );
+    }
+    void                        report( std::ostream& ostr ) const
+    {
+        return result::report( ostr, m_lhs, m_rhs );
+    }
+
+private:
+    // expression interface
+    virtual predicate_result    evaluate() const
+    {
+        predicate_result res( value() );
+        if( !res )
+            report( res.message().stream() );
+        
+        return res;
+    }
+
+    // Data members
+    Lhs                         m_lhs;
+    Rhs                         m_rhs;
+};
+
+// ************************************************************************** //
+// **************               assertion::seed                ************** //
+// ************************************************************************** //
+// seed added ot the input expression to form an assertion expression
+
+class seed {
+public:
+    // ->* is highest precedence left to right operator
+    template<typename T>
+    value_expr<T>
+    operator->*( T&& v )
+    {
+        return value_expr<T>( std::forward<T>( v ) );
+    }
+};
+
+#undef BOOST_TEST_FOR_EACH_OP
+
+} // namespace assertion
+} // namespace test_tools
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
+