Chris@16
|
1 //-----------------------------------------------------------------------------
|
Chris@16
|
2 // boost variant/detail/apply_visitor_binary.hpp header file
|
Chris@16
|
3 // See http://www.boost.org for updates, documentation, and revision history.
|
Chris@16
|
4 //-----------------------------------------------------------------------------
|
Chris@16
|
5 //
|
Chris@101
|
6 // Copyright (c) 2002-2003 Eric Friedman
|
Chris@101
|
7 // Copyright (c) 2014 Antony Polukhin
|
Chris@16
|
8 //
|
Chris@16
|
9 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
10 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
11 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|
Chris@16
|
14 #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|
Chris@16
|
15
|
Chris@16
|
16 #include "boost/config.hpp"
|
Chris@16
|
17 #include "boost/detail/workaround.hpp"
|
Chris@16
|
18 #include "boost/variant/detail/generic_result_type.hpp"
|
Chris@16
|
19
|
Chris@16
|
20 #include "boost/variant/detail/apply_visitor_unary.hpp"
|
Chris@16
|
21
|
Chris@16
|
22 #if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
Chris@16
|
23 #include "boost/utility/enable_if.hpp"
|
Chris@16
|
24 #include "boost/mpl/not.hpp"
|
Chris@16
|
25 #include "boost/type_traits/is_const.hpp"
|
Chris@16
|
26 #endif
|
Chris@16
|
27
|
Chris@101
|
28
|
Chris@101
|
29 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
Chris@101
|
30 # include "boost/variant/detail/has_result_type.hpp"
|
Chris@101
|
31 #endif
|
Chris@101
|
32
|
Chris@16
|
33 namespace boost {
|
Chris@16
|
34
|
Chris@16
|
35 //////////////////////////////////////////////////////////////////////////
|
Chris@16
|
36 // function template apply_visitor(visitor, visitable1, visitable2)
|
Chris@16
|
37 //
|
Chris@16
|
38 // Visits visitable1 and visitable2 such that their values (which we
|
Chris@16
|
39 // shall call x and y, respectively) are used as arguments in the
|
Chris@16
|
40 // expression visitor(x, y).
|
Chris@16
|
41 //
|
Chris@16
|
42
|
Chris@16
|
43 namespace detail { namespace variant {
|
Chris@16
|
44
|
Chris@16
|
45 template <typename Visitor, typename Value1>
|
Chris@16
|
46 class apply_visitor_binary_invoke
|
Chris@16
|
47 {
|
Chris@16
|
48 public: // visitor typedefs
|
Chris@16
|
49
|
Chris@16
|
50 typedef typename Visitor::result_type
|
Chris@16
|
51 result_type;
|
Chris@16
|
52
|
Chris@16
|
53 private: // representation
|
Chris@16
|
54
|
Chris@16
|
55 Visitor& visitor_;
|
Chris@16
|
56 Value1& value1_;
|
Chris@16
|
57
|
Chris@16
|
58 public: // structors
|
Chris@16
|
59
|
Chris@101
|
60 apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
|
Chris@16
|
61 : visitor_(visitor)
|
Chris@16
|
62 , value1_(value1)
|
Chris@16
|
63 {
|
Chris@16
|
64 }
|
Chris@16
|
65
|
Chris@16
|
66 public: // visitor interfaces
|
Chris@16
|
67
|
Chris@16
|
68 template <typename Value2>
|
Chris@16
|
69 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
Chris@16
|
70 operator()(Value2& value2)
|
Chris@16
|
71 {
|
Chris@16
|
72 return visitor_(value1_, value2);
|
Chris@16
|
73 }
|
Chris@16
|
74
|
Chris@16
|
75 private:
|
Chris@16
|
76 apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
|
Chris@16
|
77 };
|
Chris@16
|
78
|
Chris@16
|
79 template <typename Visitor, typename Visitable2>
|
Chris@16
|
80 class apply_visitor_binary_unwrap
|
Chris@16
|
81 {
|
Chris@16
|
82 public: // visitor typedefs
|
Chris@16
|
83
|
Chris@16
|
84 typedef typename Visitor::result_type
|
Chris@16
|
85 result_type;
|
Chris@16
|
86
|
Chris@16
|
87 private: // representation
|
Chris@16
|
88
|
Chris@16
|
89 Visitor& visitor_;
|
Chris@16
|
90 Visitable2& visitable2_;
|
Chris@16
|
91
|
Chris@16
|
92 public: // structors
|
Chris@16
|
93
|
Chris@101
|
94 apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
|
Chris@16
|
95 : visitor_(visitor)
|
Chris@16
|
96 , visitable2_(visitable2)
|
Chris@16
|
97 {
|
Chris@16
|
98 }
|
Chris@16
|
99
|
Chris@16
|
100 public: // visitor interfaces
|
Chris@16
|
101
|
Chris@16
|
102 template <typename Value1>
|
Chris@16
|
103 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
Chris@16
|
104 operator()(Value1& value1)
|
Chris@16
|
105 {
|
Chris@16
|
106 apply_visitor_binary_invoke<
|
Chris@16
|
107 Visitor
|
Chris@16
|
108 , Value1
|
Chris@16
|
109 > invoker(visitor_, value1);
|
Chris@16
|
110
|
Chris@16
|
111 return boost::apply_visitor(invoker, visitable2_);
|
Chris@16
|
112 }
|
Chris@16
|
113
|
Chris@16
|
114 private:
|
Chris@16
|
115 apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
|
Chris@16
|
116
|
Chris@16
|
117 };
|
Chris@16
|
118
|
Chris@16
|
119 }} // namespace detail::variant
|
Chris@16
|
120
|
Chris@16
|
121 //
|
Chris@16
|
122 // nonconst-visitor version:
|
Chris@16
|
123 //
|
Chris@16
|
124
|
Chris@16
|
125 #if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
Chris@16
|
126
|
Chris@16
|
127 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
|
Chris@16
|
128 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
|
Chris@16
|
129 /**/
|
Chris@16
|
130
|
Chris@16
|
131 #else // EDG-based compilers
|
Chris@16
|
132
|
Chris@16
|
133 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
|
Chris@16
|
134 typename enable_if< \
|
Chris@16
|
135 mpl::not_< is_const< V > > \
|
Chris@16
|
136 , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
|
Chris@16
|
137 >::type \
|
Chris@16
|
138 /**/
|
Chris@16
|
139
|
Chris@16
|
140 #endif // EDG-based compilers workaround
|
Chris@16
|
141
|
Chris@16
|
142 template <typename Visitor, typename Visitable1, typename Visitable2>
|
Chris@16
|
143 inline
|
Chris@16
|
144 BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
|
Chris@16
|
145 apply_visitor(
|
Chris@16
|
146 Visitor& visitor
|
Chris@16
|
147 , Visitable1& visitable1, Visitable2& visitable2
|
Chris@16
|
148 )
|
Chris@16
|
149 {
|
Chris@16
|
150 ::boost::detail::variant::apply_visitor_binary_unwrap<
|
Chris@16
|
151 Visitor, Visitable2
|
Chris@16
|
152 > unwrapper(visitor, visitable2);
|
Chris@16
|
153
|
Chris@16
|
154 return boost::apply_visitor(unwrapper, visitable1);
|
Chris@16
|
155 }
|
Chris@16
|
156
|
Chris@16
|
157 #undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
|
Chris@16
|
158
|
Chris@16
|
159 //
|
Chris@16
|
160 // const-visitor version:
|
Chris@16
|
161 //
|
Chris@16
|
162
|
Chris@16
|
163 template <typename Visitor, typename Visitable1, typename Visitable2>
|
Chris@16
|
164 inline
|
Chris@16
|
165 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
|
Chris@16
|
166 typename Visitor::result_type
|
Chris@16
|
167 )
|
Chris@16
|
168 apply_visitor(
|
Chris@16
|
169 const Visitor& visitor
|
Chris@16
|
170 , Visitable1& visitable1, Visitable2& visitable2
|
Chris@16
|
171 )
|
Chris@16
|
172 {
|
Chris@16
|
173 ::boost::detail::variant::apply_visitor_binary_unwrap<
|
Chris@16
|
174 const Visitor, Visitable2
|
Chris@16
|
175 > unwrapper(visitor, visitable2);
|
Chris@16
|
176
|
Chris@16
|
177 return boost::apply_visitor(unwrapper, visitable1);
|
Chris@16
|
178 }
|
Chris@16
|
179
|
Chris@101
|
180
|
Chris@101
|
181 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
Chris@101
|
182
|
Chris@101
|
183 //////////////////////////////////////////////////////////////////////////
|
Chris@101
|
184 // function template apply_visitor(visitor, visitable1, visitable2)
|
Chris@101
|
185 //
|
Chris@101
|
186 // C++14 part.
|
Chris@101
|
187 //
|
Chris@101
|
188
|
Chris@101
|
189 namespace detail { namespace variant {
|
Chris@101
|
190
|
Chris@101
|
191 template <typename Visitor, typename Value1>
|
Chris@101
|
192 class apply_visitor_binary_invoke_cpp14
|
Chris@101
|
193 {
|
Chris@101
|
194 Visitor& visitor_;
|
Chris@101
|
195 Value1& value1_;
|
Chris@101
|
196
|
Chris@101
|
197 public: // structors
|
Chris@101
|
198
|
Chris@101
|
199 apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
|
Chris@101
|
200 : visitor_(visitor)
|
Chris@101
|
201 , value1_(value1)
|
Chris@101
|
202 {
|
Chris@101
|
203 }
|
Chris@101
|
204
|
Chris@101
|
205 public: // visitor interfaces
|
Chris@101
|
206
|
Chris@101
|
207 template <typename Value2>
|
Chris@101
|
208 decltype(auto) operator()(Value2& value2)
|
Chris@101
|
209 {
|
Chris@101
|
210 return visitor_(value1_, value2);
|
Chris@101
|
211 }
|
Chris@101
|
212
|
Chris@101
|
213 private:
|
Chris@101
|
214 apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
|
Chris@101
|
215 };
|
Chris@101
|
216
|
Chris@101
|
217 template <typename Visitor, typename Visitable2>
|
Chris@101
|
218 class apply_visitor_binary_unwrap_cpp14
|
Chris@101
|
219 {
|
Chris@101
|
220 Visitor& visitor_;
|
Chris@101
|
221 Visitable2& visitable2_;
|
Chris@101
|
222
|
Chris@101
|
223 public: // structors
|
Chris@101
|
224
|
Chris@101
|
225 apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
|
Chris@101
|
226 : visitor_(visitor)
|
Chris@101
|
227 , visitable2_(visitable2)
|
Chris@101
|
228 {
|
Chris@101
|
229 }
|
Chris@101
|
230
|
Chris@101
|
231 public: // visitor interfaces
|
Chris@101
|
232
|
Chris@101
|
233 template <typename Value1>
|
Chris@101
|
234 decltype(auto) operator()(Value1& value1)
|
Chris@101
|
235 {
|
Chris@101
|
236 apply_visitor_binary_invoke_cpp14<
|
Chris@101
|
237 Visitor
|
Chris@101
|
238 , Value1
|
Chris@101
|
239 > invoker(visitor_, value1);
|
Chris@101
|
240
|
Chris@101
|
241 return boost::apply_visitor(invoker, visitable2_);
|
Chris@101
|
242 }
|
Chris@101
|
243
|
Chris@101
|
244 private:
|
Chris@101
|
245 apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&);
|
Chris@101
|
246 };
|
Chris@101
|
247
|
Chris@101
|
248 }} // namespace detail::variant
|
Chris@101
|
249
|
Chris@101
|
250 template <typename Visitor, typename Visitable1, typename Visitable2>
|
Chris@101
|
251 inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2,
|
Chris@101
|
252 typename boost::disable_if<
|
Chris@101
|
253 boost::detail::variant::has_result_type<Visitor>
|
Chris@101
|
254 >::type* = 0)
|
Chris@101
|
255 {
|
Chris@101
|
256 ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
|
Chris@101
|
257 Visitor, Visitable2
|
Chris@101
|
258 > unwrapper(visitor, visitable2);
|
Chris@101
|
259
|
Chris@101
|
260 return boost::apply_visitor(unwrapper, visitable1);
|
Chris@101
|
261 }
|
Chris@101
|
262
|
Chris@101
|
263 template <typename Visitor, typename Visitable1, typename Visitable2>
|
Chris@101
|
264 inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2,
|
Chris@101
|
265 typename boost::disable_if<
|
Chris@101
|
266 boost::detail::variant::has_result_type<Visitor>
|
Chris@101
|
267 >::type* = 0)
|
Chris@101
|
268 {
|
Chris@101
|
269 ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
|
Chris@101
|
270 const Visitor, Visitable2
|
Chris@101
|
271 > unwrapper(visitor, visitable2);
|
Chris@101
|
272
|
Chris@101
|
273 return boost::apply_visitor(unwrapper, visitable1);
|
Chris@101
|
274 }
|
Chris@101
|
275
|
Chris@101
|
276 #endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
Chris@16
|
277
|
Chris@16
|
278 } // namespace boost
|
Chris@16
|
279
|
Chris@16
|
280 #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|