$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r84112 - in trunk: boost/variant libs/variant/test
From: antoshkka_at_[hidden]
Date: 2013-05-02 12:45:59
Author: apolukhin
Date: 2013-05-02 12:45:58 EDT (Thu, 02 May 2013)
New Revision: 84112
URL: http://svn.boost.org/trac/boost/changeset/84112
Log:
Multivisitors commit (refs #8459)
Added:
   trunk/boost/variant/multivisitors.hpp   (contents, props changed)
   trunk/libs/variant/test/variant_multivisit_test.cpp   (contents, props changed)
Text files modified: 
   trunk/libs/variant/test/Jamfile.v2 |     1 +                                       
   1 files changed, 1 insertions(+), 0 deletions(-)
Added: trunk/boost/variant/multivisitors.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/variant/multivisitors.hpp	2013-05-02 12:45:58 EDT (Thu, 02 May 2013)
@@ -0,0 +1,143 @@
+//  Boost.Varaint
+//  Multivisitors defined here 
+//
+//  See http://www.boost.org for most recent version, including documentation.
+//
+//  Copyright Antony Polukhin, 2013.
+//
+//  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).
+
+#ifndef BOOST_VARIANT_MULTIVISITORS_HPP
+#define BOOST_VARIANT_MULTIVISITORS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/bind.hpp>
+
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/arithmetic/add.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+
+#ifndef BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS
+#   define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 4
+#endif
+
+namespace boost { 
+
+namespace detail { namespace variant {
+
+    template <class VisitorT, class Visitable1T, class Visitable2T>
+    struct two_variables_holder {
+    private:
+        VisitorT&       visitor_;
+        Visitable1T&    visitable1_;
+        Visitable2T&    visitable2_;
+
+        // required to supress warnings and enshure that we do not copy 
+        // this visitor
+        two_variables_holder& operator=(const two_variables_holder&);
+
+    public:
+        typedef BOOST_DEDUCED_TYPENAME VisitorT::result_type result_type;
+
+        explicit two_variables_holder(VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2) BOOST_NOEXCEPT 
+            : visitor_(visitor)
+            , visitable1_(visitable1)
+            , visitable2_(visitable2)
+        {}
+
+#define BOOST_VARIANT_OPERATOR_BEG()                            \
+    return ::boost::apply_visitor(                              \
+    ::boost::bind<result_type>(boost::ref(visitor_), _1, _2     \
+    /**/
+
+#define BOOST_VARIANT_OPERATOR_END()                            \
+    ), visitable1_, visitable2_);                               \
+    /**/
+
+#define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data)     \
+    BOOST_PP_COMMA() boost::ref( BOOST_PP_CAT(vis, n) )         \
+    /**/
+
+#define BOOST_VARIANT_VISIT(z, n, data)                                                     \
+    template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 1), class VisitableUnwrapped)>           \
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()(                          \
+        BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 1), VisitableUnwrapped, & vis)          \
+    ) const                                                                                 \
+    {                                                                                       \
+        BOOST_VARIANT_OPERATOR_BEG()                                                        \
+        BOOST_PP_REPEAT(BOOST_PP_ADD(n, 1), BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~)     \
+        BOOST_VARIANT_OPERATOR_END()                                                        \
+    }                                                                                       \
+    /**/
+
+BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, ~)
+#undef BOOST_VARIANT_OPERATOR_BEG
+#undef BOOST_VARIANT_OPERATOR_END
+#undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER
+#undef BOOST_VARIANT_VISIT
+
+    };
+
+    template <class VisitorT, class Visitable1T, class Visitable2T>
+    inline two_variables_holder<VisitorT, Visitable1T, Visitable2T> make_two_variables_holder(
+            VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2
+        ) BOOST_NOEXCEPT
+    {
+        return two_variables_holder<VisitorT, Visitable1T, Visitable2T>(visitor, visitable1, visitable2);
+    }
+
+    template <class VisitorT, class Visitable1T, class Visitable2T>
+    inline two_variables_holder<const VisitorT, Visitable1T, Visitable2T> make_two_variables_holder(
+            const VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2
+        ) BOOST_NOEXCEPT
+    {
+        return two_variables_holder<const VisitorT, Visitable1T, Visitable2T>(visitor, visitable1, visitable2);
+    }
+
+}} // namespace detail::variant
+
+#define BOOST_VARIANT_APPLY_VISITOR_BEG()                                               \
+    return ::boost::apply_visitor(                                                      \
+            boost::detail::variant::make_two_variables_holder(visitor, var0 , var1),    \
+            var2                                                                        \
+    /**/
+
+#define BOOST_VARIANT_APPLY_VISITOR_END()                       \
+    );                                                          \
+    /**/
+
+#define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data)     \
+    BOOST_PP_COMMA() BOOST_PP_CAT(var, BOOST_PP_ADD(n, 3))      \
+    /**/
+
+#define BOOST_VARIANT_VISIT(z, n, data)                                                                 \
+    template <class Visitor BOOST_PP_COMMA() BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 3), class T)>         \
+    inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(BOOST_DEDUCED_TYPENAME Visitor::result_type) apply_visitor( \
+        data BOOST_PP_COMMA() BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 3), T, & var)     \
+    )                                                                                                   \
+    {                                                                                                   \
+        BOOST_VARIANT_APPLY_VISITOR_BEG()                                                               \
+        BOOST_PP_REPEAT(n, BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~)                                  \
+        BOOST_VARIANT_APPLY_VISITOR_END()                                                               \
+    }                                                                                                   \
+    /**/
+
+BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, const Visitor& visitor)
+BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, Visitor& visitor)
+
+#undef BOOST_VARIANT_APPLY_VISITOR_BEG
+#undef BOOST_VARIANT_APPLY_VISITOR_END
+#undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER
+#undef BOOST_VARIANT_VISIT
+    
+} // namespace boost
+
+#endif // BOOST_VARIANT_MULTIVISITORS_HPP
+
Modified: trunk/libs/variant/test/Jamfile.v2
==============================================================================
--- trunk/libs/variant/test/Jamfile.v2	(original)
+++ trunk/libs/variant/test/Jamfile.v2	2013-05-02 12:45:58 EDT (Thu, 02 May 2013)
@@ -32,6 +32,7 @@
     [ run variant_reference_test.cpp ]
     [ run variant_comparison_test.cpp ]
     [ run variant_visit_test.cpp ]
+    [ run variant_multivisit_test.cpp ]
     [ run hash_variant_test.cpp ]
     [ run rvalue_test.cpp ]
    ; 
Added: trunk/libs/variant/test/variant_multivisit_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/variant/test/variant_multivisit_test.cpp	2013-05-02 12:45:58 EDT (Thu, 02 May 2013)
@@ -0,0 +1,93 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_multivisit_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2013
+// Antony Polukhin
+//
+// 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)
+
+#include "boost/config.hpp"
+#define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 5
+#include "boost/variant/multivisitors.hpp"
+
+#include "boost/test/minimal.hpp"
+
+typedef boost::variant<char, unsigned char, signed char, unsigned short, int, unsigned int>         variant6_t;
+
+struct test_visitor: boost::static_visitor<> {
+    // operators that shall not be called
+    template <class  T1, class  T2, class  T3>
+    void operator()(T1, T2, T3) const 
+    {
+        BOOST_CHECK(false);
+    }
+
+    template <class  T1, class  T2, class  T3, class  T4>
+    void operator()(T1, T2, T3, T4) const 
+    {
+        BOOST_CHECK(false);
+    }
+
+    template <class  T1, class  T2, class  T3, class  T4, class  T5>
+    void operator()(T1, T2, T3, T4, T5) const 
+    {
+        BOOST_CHECK(false);
+    }
+
+    // operators that are OK to call
+    void operator()(char v0, unsigned char v1, signed char v2) const 
+    {
+        BOOST_CHECK(v0 == 0);
+        BOOST_CHECK(v1 == 1);
+        BOOST_CHECK(v2 == 2);
+    }
+
+    void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3) const 
+    {
+        BOOST_CHECK(v0 == 0);
+        BOOST_CHECK(v1 == 1);
+        BOOST_CHECK(v2 == 2);
+        BOOST_CHECK(v3 == 3);
+    }
+
+    void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3, int v4) const 
+    {
+        BOOST_CHECK(v0 == 0);
+        BOOST_CHECK(v1 == 1);
+        BOOST_CHECK(v2 == 2);
+        BOOST_CHECK(v3 == 3);
+        BOOST_CHECK(v4 == 4);
+    }
+};
+
+int test_main(int , char* [])
+{
+    test_visitor v;
+
+    variant6_t v_array6[6];
+    v_array6[0] = char(0);
+    v_array6[1] = static_cast<unsigned char>(1);
+    v_array6[2] = static_cast<signed char>(2);
+    v_array6[3] = static_cast<unsigned short>(3);
+    v_array6[4] = static_cast<int>(4);
+    v_array6[5] = static_cast<unsigned int>(5);
+
+    boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2]);
+    boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2]);
+
+// Following test also pass, but requires many Gigabytes of RAM for compilation and compile for about 15 minutes
+//#define BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
+#ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME    
+    boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
+    boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
+
+    boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
+    boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
+#endif
+
+    return boost::exit_success;
+}