]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/variant/detail/apply_visitor_binary.hpp
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / 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-2017 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 #include <boost/utility/enable_if.hpp>
23
24 #if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
25 #include <boost/mpl/not.hpp>
26 #include <boost/type_traits/is_const.hpp>
27 #endif
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 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
34 # include <boost/type_traits/is_lvalue_reference.hpp>
35 # include <boost/type_traits/is_same.hpp>
36 # include <boost/move/move.hpp>
37 # include <boost/move/utility.hpp>
38 #endif
39
40 namespace boost {
41
42 //////////////////////////////////////////////////////////////////////////
43 // function template apply_visitor(visitor, visitable1, visitable2)
44 //
45 // Visits visitable1 and visitable2 such that their values (which we
46 // shall call x and y, respectively) are used as arguments in the
47 // expression visitor(x, y).
48 //
49
50 namespace detail { namespace variant {
51
52 template <typename Visitor, typename Value1, bool MoveSemantics>
53 class apply_visitor_binary_invoke
54 {
55 public: // visitor typedefs
56
57 typedef typename Visitor::result_type
58 result_type;
59
60 private: // representation
61
62 Visitor& visitor_;
63 Value1& value1_;
64
65 public: // structors
66
67 apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
68 : visitor_(visitor)
69 , value1_(value1)
70 {
71 }
72
73 public: // visitor interfaces
74
75 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
76
77 template <typename Value2>
78 typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)>::type
79 operator()(Value2&& value2)
80 {
81 return visitor_(::boost::move(value1_), ::boost::forward<Value2>(value2));
82 }
83
84 template <typename Value2>
85 typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)>::type
86 operator()(Value2&& value2)
87 {
88 return visitor_(value1_, ::boost::forward<Value2>(value2));
89 }
90
91 #else
92
93 template <typename Value2>
94 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
95 operator()(Value2& value2)
96 {
97 return visitor_(value1_, value2);
98 }
99
100 #endif
101
102 private:
103 apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
104 };
105
106 template <typename Visitor, typename Visitable2, bool MoveSemantics>
107 class apply_visitor_binary_unwrap
108 {
109 public: // visitor typedefs
110
111 typedef typename Visitor::result_type
112 result_type;
113
114 private: // representation
115
116 Visitor& visitor_;
117 Visitable2& visitable2_;
118
119 public: // structors
120
121 apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
122 : visitor_(visitor)
123 , visitable2_(visitable2)
124 {
125 }
126
127 public: // visitor interfaces
128
129 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
130
131 template <typename Value1>
132 typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)>::type
133 operator()(Value1&& value1)
134 {
135 apply_visitor_binary_invoke<
136 Visitor
137 , Value1
138 , ! ::boost::is_lvalue_reference<Value1>::value
139 > invoker(visitor_, value1);
140
141 return boost::apply_visitor(invoker, ::boost::move(visitable2_));
142 }
143
144 template <typename Value1>
145 typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)>::type
146 operator()(Value1&& value1)
147 {
148 apply_visitor_binary_invoke<
149 Visitor
150 , Value1
151 , ! ::boost::is_lvalue_reference<Value1>::value
152 > invoker(visitor_, value1);
153
154 return boost::apply_visitor(invoker, visitable2_);
155 }
156
157 #else
158
159 template <typename Value1>
160 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
161 operator()(Value1& value1)
162 {
163 apply_visitor_binary_invoke<
164 Visitor
165 , Value1
166 , false
167 > invoker(visitor_, value1);
168
169 return boost::apply_visitor(invoker, visitable2_);
170 }
171
172 #endif
173
174 private:
175 apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
176
177 };
178
179 }} // namespace detail::variant
180
181 //
182 // nonconst-visitor version:
183 //
184
185 #if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
186
187 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
188 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
189 /**/
190
191 #else // EDG-based compilers
192
193 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
194 typename enable_if< \
195 mpl::not_< is_const< V > > \
196 , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
197 >::type \
198 /**/
199
200 #endif // EDG-based compilers workaround
201
202 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
203
204 template <typename Visitor, typename Visitable1, typename Visitable2>
205 inline
206 BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
207 apply_visitor( Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2)
208 {
209 ::boost::detail::variant::apply_visitor_binary_unwrap<
210 Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
211 > unwrapper(visitor, visitable2);
212
213 return boost::apply_visitor(unwrapper, ::boost::forward<Visitable1>(visitable1));
214 }
215
216 #else
217
218 template <typename Visitor, typename Visitable1, typename Visitable2>
219 inline
220 BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
221 apply_visitor( Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2)
222 {
223 ::boost::detail::variant::apply_visitor_binary_unwrap<
224 Visitor, Visitable2, false
225 > unwrapper(visitor, visitable2);
226
227 return boost::apply_visitor(unwrapper, visitable1);
228 }
229
230 #endif
231
232 #undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
233
234 //
235 // const-visitor version:
236 //
237
238 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
239
240 template <typename Visitor, typename Visitable1, typename Visitable2>
241 inline
242 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
243 typename Visitor::result_type
244 )
245 apply_visitor( const Visitor& visitor , Visitable1&& visitable1 , Visitable2&& visitable2)
246 {
247 ::boost::detail::variant::apply_visitor_binary_unwrap<
248 const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
249 > unwrapper(visitor, visitable2);
250
251 return boost::apply_visitor(unwrapper, ::boost::forward<Visitable1>(visitable1));
252 }
253
254 #else
255
256 template <typename Visitor, typename Visitable1, typename Visitable2>
257 inline
258 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
259 typename Visitor::result_type
260 )
261 apply_visitor( const Visitor& visitor , Visitable1& visitable1 , Visitable2& visitable2)
262 {
263 ::boost::detail::variant::apply_visitor_binary_unwrap<
264 const Visitor, Visitable2, false
265 > unwrapper(visitor, visitable2);
266
267 return boost::apply_visitor(unwrapper, visitable1);
268 }
269
270 #endif
271
272
273 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
274
275 //////////////////////////////////////////////////////////////////////////
276 // function template apply_visitor(visitor, visitable1, visitable2)
277 //
278 // C++14 part.
279 //
280
281 namespace detail { namespace variant {
282
283 template <typename Visitor, typename Value1, bool MoveSemantics>
284 class apply_visitor_binary_invoke_cpp14
285 {
286 Visitor& visitor_;
287 Value1& value1_;
288
289 public: // structors
290
291 apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
292 : visitor_(visitor)
293 , value1_(value1)
294 {
295 }
296
297 public: // visitor interfaces
298
299 template <typename Value2>
300 decltype(auto) operator()(Value2&& value2, typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value>::type* = 0)
301 {
302 return visitor_(::boost::move(value1_), ::boost::forward<Value2>(value2));
303 }
304
305 template <typename Value2>
306 decltype(auto) operator()(Value2&& value2, typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value>::type* = 0)
307 {
308 return visitor_(value1_, ::boost::forward<Value2>(value2));
309 }
310
311 private:
312 apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
313 };
314
315 template <typename Visitor, typename Visitable2, bool MoveSemantics>
316 class apply_visitor_binary_unwrap_cpp14
317 {
318 Visitor& visitor_;
319 Visitable2& visitable2_;
320
321 public: // structors
322
323 apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
324 : visitor_(visitor)
325 , visitable2_(visitable2)
326 {
327 }
328
329 public: // visitor interfaces
330
331 template <typename Value1>
332 decltype(auto) operator()(Value1&& value1, typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value>::type* = 0)
333 {
334 apply_visitor_binary_invoke_cpp14<
335 Visitor
336 , Value1
337 , ! ::boost::is_lvalue_reference<Value1>::value
338 > invoker(visitor_, value1);
339
340 return boost::apply_visitor(invoker, ::boost::move(visitable2_));
341 }
342
343 template <typename Value1>
344 decltype(auto) operator()(Value1&& value1, typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value>::type* = 0)
345 {
346 apply_visitor_binary_invoke_cpp14<
347 Visitor
348 , Value1
349 , ! ::boost::is_lvalue_reference<Value1>::value
350 > invoker(visitor_, value1);
351
352 return boost::apply_visitor(invoker, visitable2_);
353 }
354
355 private:
356 apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&);
357 };
358
359 }} // namespace detail::variant
360
361 template <typename Visitor, typename Visitable1, typename Visitable2>
362 inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
363 typename boost::disable_if<
364 boost::detail::variant::has_result_type<Visitor>
365 >::type* = 0)
366 {
367 ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
368 Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
369 > unwrapper(visitor, visitable2);
370
371 return boost::apply_visitor(unwrapper, ::boost::forward<Visitable1>(visitable1));
372 }
373
374 template <typename Visitor, typename Visitable1, typename Visitable2>
375 inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
376 typename boost::disable_if<
377 boost::detail::variant::has_result_type<Visitor>
378 >::type* = 0)
379 {
380 ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
381 const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
382 > unwrapper(visitor, visitable2);
383
384 return boost::apply_visitor(unwrapper, ::boost::forward<Visitable1>(visitable1));
385 }
386
387
388 #endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
389
390 } // namespace boost
391
392 #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP