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