]> git.lyx.org Git - features.git/blob - 3rdparty/boost/boost/variant/detail/apply_visitor_binary.hpp
Update local boost version to version 1.62
[features.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 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