| 1 | // Boost.Varaint
|
|---|
| 2 | // Multivisitors defined here
|
|---|
| 3 | //
|
|---|
| 4 | // See http://www.boost.org for most recent version, including documentation.
|
|---|
| 5 | //
|
|---|
| 6 | // Copyright Antony Polukhin, 2013.
|
|---|
| 7 | //
|
|---|
| 8 | // Distributed under the Boost
|
|---|
| 9 | // Software License, Version 1.0. (See accompanying file
|
|---|
| 10 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
|
|---|
| 11 |
|
|---|
| 12 | #ifndef BOOST_VARIANT_MULTIVISITORS_HPP
|
|---|
| 13 | #define BOOST_VARIANT_MULTIVISITORS_HPP
|
|---|
| 14 |
|
|---|
| 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|---|
| 16 | # pragma once
|
|---|
| 17 | #endif
|
|---|
| 18 |
|
|---|
| 19 | #include <boost/variant.hpp>
|
|---|
| 20 | #include <boost/bind.hpp>
|
|---|
| 21 |
|
|---|
| 22 | #include <boost/preprocessor/repetition.hpp>
|
|---|
| 23 | #include <boost/preprocessor/punctuation/comma_if.hpp>
|
|---|
| 24 | #include <boost/preprocessor/arithmetic/add.hpp>
|
|---|
| 25 | #include <boost/preprocessor/arithmetic/sub.hpp>
|
|---|
| 26 |
|
|---|
| 27 | #ifndef BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS
|
|---|
| 28 | # define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 4
|
|---|
| 29 | #endif
|
|---|
| 30 |
|
|---|
| 31 | namespace boost {
|
|---|
| 32 |
|
|---|
| 33 | namespace detail { namespace variant {
|
|---|
| 34 |
|
|---|
| 35 | template <class VisitorT, class Visitable1T, class Visitable2T>
|
|---|
| 36 | struct two_variables_holder {
|
|---|
| 37 | private:
|
|---|
| 38 | VisitorT& visitor_;
|
|---|
| 39 | Visitable1T& visitable1_;
|
|---|
| 40 | Visitable2T& visitable2_;
|
|---|
| 41 |
|
|---|
| 42 | // required to supress warnings and enshure that we do not copy
|
|---|
| 43 | // this visitor
|
|---|
| 44 | two_variables_holder& operator=(const two_variables_holder&);
|
|---|
| 45 |
|
|---|
| 46 | public:
|
|---|
| 47 | typedef BOOST_DEDUCED_TYPENAME VisitorT::result_type result_type;
|
|---|
| 48 |
|
|---|
| 49 | explicit two_variables_holder(VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2) BOOST_NOEXCEPT
|
|---|
| 50 | : visitor_(visitor)
|
|---|
| 51 | , visitable1_(visitable1)
|
|---|
| 52 | , visitable2_(visitable2)
|
|---|
| 53 | {}
|
|---|
| 54 |
|
|---|
| 55 | #define BOOST_VARIANT_OPERATOR_BEG() \
|
|---|
| 56 | return ::boost::apply_visitor( \
|
|---|
| 57 | ::boost::bind<result_type>(boost::ref(visitor_), _1, _2 \
|
|---|
| 58 | /**/
|
|---|
| 59 |
|
|---|
| 60 | #define BOOST_VARIANT_OPERATOR_END() \
|
|---|
| 61 | ), visitable1_, visitable2_); \
|
|---|
| 62 | /**/
|
|---|
| 63 |
|
|---|
| 64 | #define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data) \
|
|---|
| 65 | BOOST_PP_COMMA() boost::ref( BOOST_PP_CAT(vis, n) ) \
|
|---|
| 66 | /**/
|
|---|
| 67 |
|
|---|
| 68 | #define BOOST_VARIANT_VISIT(z, n, data) \
|
|---|
| 69 | template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 1), class VisitableUnwrapped)> \
|
|---|
| 70 | BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()( \
|
|---|
| 71 | BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 1), VisitableUnwrapped, & vis) \
|
|---|
| 72 | ) const \
|
|---|
| 73 | { \
|
|---|
| 74 | BOOST_VARIANT_OPERATOR_BEG() \
|
|---|
| 75 | BOOST_PP_REPEAT(BOOST_PP_ADD(n, 1), BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~) \
|
|---|
| 76 | BOOST_VARIANT_OPERATOR_END() \
|
|---|
| 77 | } \
|
|---|
| 78 | /**/
|
|---|
| 79 |
|
|---|
| 80 | BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, ~)
|
|---|
| 81 | #undef BOOST_VARIANT_OPERATOR_BEG
|
|---|
| 82 | #undef BOOST_VARIANT_OPERATOR_END
|
|---|
| 83 | #undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER
|
|---|
| 84 | #undef BOOST_VARIANT_VISIT
|
|---|
| 85 |
|
|---|
| 86 | };
|
|---|
| 87 |
|
|---|
| 88 | template <class VisitorT, class Visitable1T, class Visitable2T>
|
|---|
| 89 | inline two_variables_holder<VisitorT, Visitable1T, Visitable2T> make_two_variables_holder(
|
|---|
| 90 | VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2
|
|---|
| 91 | ) BOOST_NOEXCEPT
|
|---|
| 92 | {
|
|---|
| 93 | return two_variables_holder<VisitorT, Visitable1T, Visitable2T>(visitor, visitable1, visitable2);
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 |
|
|---|
| 97 | }} // namespace detail::variant
|
|---|
| 98 |
|
|---|
| 99 | #define BOOST_VARIANT_APPLY_VISITOR_BEG() \
|
|---|
| 100 | return ::boost::apply_visitor( \
|
|---|
| 101 | boost::detail::variant::make_two_variables_holder(visitor, var0 , var1), \
|
|---|
| 102 | var2 \
|
|---|
| 103 | /**/
|
|---|
| 104 |
|
|---|
| 105 | #define BOOST_VARIANT_APPLY_VISITOR_END() \
|
|---|
| 106 | ); \
|
|---|
| 107 | /**/
|
|---|
| 108 |
|
|---|
| 109 | #define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data) \
|
|---|
| 110 | BOOST_PP_COMMA() BOOST_PP_CAT(var, BOOST_PP_ADD(n, 3)) \
|
|---|
| 111 | /**/
|
|---|
| 112 |
|
|---|
| 113 | #define BOOST_VARIANT_VISIT(z, n, data) \
|
|---|
| 114 | template <class Visitor BOOST_PP_COMMA() BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 3), class T)> \
|
|---|
| 115 | inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(BOOST_DEDUCED_TYPENAME Visitor::result_type) apply_visitor( \
|
|---|
| 116 | data BOOST_PP_COMMA() BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 3), T, & var) \
|
|---|
| 117 | ) \
|
|---|
| 118 | { \
|
|---|
| 119 | BOOST_VARIANT_APPLY_VISITOR_BEG() \
|
|---|
| 120 | BOOST_PP_REPEAT(n, BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~) \
|
|---|
| 121 | BOOST_VARIANT_APPLY_VISITOR_END() \
|
|---|
| 122 | } \
|
|---|
| 123 | /**/
|
|---|
| 124 |
|
|---|
| 125 | BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, Visitor& visitor)
|
|---|
| 126 | BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, const Visitor& visitor)
|
|---|
| 127 |
|
|---|
| 128 | #undef BOOST_VARIANT_APPLY_VISITOR_BEG
|
|---|
| 129 | #undef BOOST_VARIANT_APPLY_VISITOR_END
|
|---|
| 130 | #undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER
|
|---|
| 131 | #undef BOOST_VARIANT_VISIT
|
|---|
| 132 |
|
|---|
| 133 | } // namespace boost
|
|---|
| 134 |
|
|---|
| 135 | #endif // BOOST_VARIANT_MULTIVISITORS_HPP
|
|---|
| 136 |
|
|---|