Boost logo

Boost-Commit :

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;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk