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