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 |
|
---|