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