]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/phoenix/include/boost/phoenix/core/actor.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / phoenix / include / boost / phoenix / core / actor.hpp
1 /*=============================================================================
2 Copyright (c) 2005-2010 Joel de Guzman
3 Copyright (c) 2010 Eric Niebler
4 Copyright (c) 2010 Thomas Heller
5 Copyright (c) 2014 John Fletcher
6
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 ==============================================================================*/
10 #ifndef BOOST_PHOENIX_CORE_ACTOR_HPP
11 #define BOOST_PHOENIX_CORE_ACTOR_HPP
12
13 #include <boost/phoenix/core/limits.hpp>
14
15 #include <boost/is_placeholder.hpp>
16 #include <boost/mpl/identity.hpp>
17 #include <boost/mpl/eval_if.hpp>
18 #include <boost/phoenix/core/domain.hpp>
19 #include <boost/phoenix/core/environment.hpp>
20 #include <boost/phoenix/core/is_nullary.hpp>
21 #include <boost/phoenix/core/meta_grammar.hpp>
22 #include <boost/phoenix/support/iterate.hpp>
23 #include <boost/phoenix/support/vector.hpp>
24 #include <boost/proto/extends.hpp>
25 #include <boost/proto/make_expr.hpp>
26 #include <boost/utility/result_of.hpp>
27 #include <boost/mpl/void.hpp>
28 #include <cstring>
29 #ifndef BOOST_PHOENIX_NO_VARIADIC_ACTOR
30 # include <boost/mpl/if.hpp>
31 # include <boost/type_traits/is_reference.hpp>
32 # include <boost/phoenix/core/detail/index_sequence.hpp>
33 #endif
34
35 #ifdef BOOST_MSVC
36 #pragma warning(push)
37 #pragma warning(disable: 4522) // 'this' used in base member initializer list
38 #pragma warning(disable: 4510) // default constructor could not be generated
39 #pragma warning(disable: 4610) // can never be instantiated - user defined cons
40 #endif
41
42 namespace boost { namespace phoenix
43 {
44 template <typename Expr>
45 struct actor;
46
47 namespace detail
48 {
49 struct error_expecting_arguments
50 {
51 template <typename T>
52 error_expecting_arguments(T const&) {}
53 };
54
55 struct error_invalid_lambda_expr
56 {
57 template <typename T>
58 error_invalid_lambda_expr(T const&) {}
59 };
60
61 template <typename T>
62 struct result_type_deduction_helper
63 {
64 typedef T const & type;
65 };
66
67 template <typename T>
68 struct result_type_deduction_helper<T &>
69 {
70 typedef T & type;
71 };
72
73 template <typename T>
74 struct result_type_deduction_helper<T const &>
75 {
76 typedef T const & type;
77 };
78
79 struct do_assign
80 {
81 BOOST_PROTO_CALLABLE()
82
83 typedef void result_type;
84
85 template <typename T1, typename T2>
86 void operator()(T1 & t1, T2 const & t2) const
87 {
88 proto::value(t1) = proto::value(t2);
89 }
90 };
91
92 #ifdef BOOST_PHOENIX_NO_VARIADIC_ACTOR
93 #include <boost/phoenix/core/detail/cpp03/assign.hpp>
94 #else
95 struct assign : proto::transform<assign>
96 {
97 typedef assign proto_grammer;
98
99 template <typename Expr, typename State, typename Data
100 , typename Indices = typename detail::make_index_sequence<proto::arity_of<Expr>::value>::type >
101 struct impl;
102
103 template <std::size_t>
104 struct proto_expr { typedef proto::_ type; };
105
106 template <std::size_t Index>
107 struct nth_assign
108 {
109 typedef
110 assign type(
111 proto::_child_c<Index>
112 , proto::call<proto::_child_c<Index>(proto::_state)>
113 )
114 ;
115 };
116
117 template <typename Expr, typename State, typename Data>
118 struct impl<Expr, State, Data, detail::index_sequence<> >
119 : proto::when<
120 proto::terminal<proto::_>
121 , do_assign(proto::_, proto::_state)
122 >::template impl<Expr, State, Data>
123 {
124 };
125
126 template <typename Expr, typename State, typename Data
127 , std::size_t... Indices>
128 struct impl<Expr, State, Data, detail::index_sequence<Indices...> >
129 : proto::when<
130 proto::nary_expr<typename proto_expr<Indices>::type...>
131 , proto::and_<typename nth_assign<Indices>::type...>
132 >::template impl<Expr, State, Data>
133 {
134 };
135 };
136 #endif
137 }
138
139 namespace result_of
140 {
141 #ifdef BOOST_PHOENIX_NO_VARIADIC_ACTOR
142 // Bring in the result_of::actor<>
143 #include <boost/phoenix/core/detail/cpp03/actor_result_of.hpp>
144 #else
145 template <typename Expr, typename... A>
146 struct actor_impl
147 {
148 typedef
149 typename boost::phoenix::evaluator::impl<
150 Expr const&
151 , vector2<
152 typename vector_chooser<sizeof...(A) + 1>::
153 template apply<const ::boost::phoenix::actor<Expr> *, A...>::type&
154 , default_actions
155 > const &
156 , proto::empty_env
157 >::result_type
158 type;
159 };
160
161 template <typename Expr, typename... A>
162 struct actor : actor_impl<Expr, A...> {};
163
164 template <typename Expr>
165 struct nullary_actor_result : actor_impl<Expr> {};
166 #endif
167
168 template <typename Expr>
169 struct actor<Expr>
170 {
171 typedef
172 // avoid calling result_of::actor when this is false
173 typename mpl::eval_if_c<
174 result_of::is_nullary<Expr>::value
175 , nullary_actor_result<Expr>
176 , mpl::identity<detail::error_expecting_arguments>
177 >::type
178 type;
179 };
180 }
181
182 ////////////////////////////////////////////////////////////////////////////
183 //
184 // actor
185 //
186 // The actor class. The main thing! In phoenix, everything is an actor
187 // This class is responsible for full function evaluation. Partial
188 // function evaluation involves creating a hierarchy of actor objects.
189 //
190 ////////////////////////////////////////////////////////////////////////////
191 template <typename Expr>
192 struct actor
193 {
194 typedef typename
195 mpl::eval_if_c<
196 mpl::or_<
197 is_custom_terminal<Expr>
198 , mpl::bool_<is_placeholder<Expr>::value>
199 >::value
200 , proto::terminal<Expr>
201 , mpl::identity<Expr>
202 >::type
203 expr_type;
204
205 BOOST_PROTO_BASIC_EXTENDS(expr_type, actor<expr_type>, phoenix_domain)
206
207 // providing operator= to be assignable
208 actor& operator=(actor const& other)
209 {
210 detail::assign()(*this, other);
211 return *this;
212 }
213 actor& operator=(actor & other)
214 {
215 detail::assign()(*this, other);
216 return *this;
217 }
218
219 template <typename A0>
220 typename proto::result_of::make_expr<
221 proto::tag::assign
222 , phoenix_domain
223 , proto_base_expr
224 , A0
225 >::type const
226 operator=(A0 const & a0) const
227 {
228 return proto::make_expr<proto::tag::assign, phoenix_domain>(this->proto_expr_, a0);
229 }
230
231 template <typename A0>
232 typename proto::result_of::make_expr<
233 proto::tag::assign
234 , phoenix_domain
235 , proto_base_expr
236 , A0
237 >::type const
238 operator=(A0 & a0) const
239 {
240 return proto::make_expr<proto::tag::assign, phoenix_domain>(this->proto_expr_, a0);
241 }
242
243 template <typename A0>
244 typename proto::result_of::make_expr<
245 proto::tag::subscript
246 , phoenix_domain
247 , proto_base_expr
248 , A0
249 >::type const
250 operator[](A0 const & a0) const
251 {
252 return proto::make_expr<proto::tag::subscript, phoenix_domain>(this->proto_expr_, a0);
253 }
254
255 template <typename A0>
256 typename proto::result_of::make_expr<
257 proto::tag::subscript
258 , phoenix_domain
259 , proto_base_expr
260 , A0
261 >::type const
262 operator[](A0 & a0) const
263 {
264 return proto::make_expr<proto::tag::subscript, phoenix_domain>(this->proto_expr_, a0);
265 }
266
267 template <typename Sig>
268 struct result;
269
270 typename result_of::actor<proto_base_expr>::type
271 operator()()
272 {
273 typedef vector1<const actor<Expr> *> env_type;
274 env_type env = {this};
275
276 return phoenix::eval(*this, phoenix::context(env, default_actions()));
277 }
278
279 typename result_of::actor<proto_base_expr>::type
280 operator()() const
281 {
282 typedef vector1<const actor<Expr> *> env_type;
283 env_type env = {this};
284
285 return phoenix::eval(*this, phoenix::context(env, default_actions()));
286 }
287
288 template <typename Env>
289 typename evaluator::impl<
290 proto_base_expr const &
291 , typename result_of::context<
292 Env const &
293 , default_actions const &
294 >::type
295 , proto::empty_env
296 >::result_type
297 eval(Env const & env) const
298 {
299 return phoenix::eval(*this, phoenix::context(env, default_actions()));
300 }
301
302 #ifdef BOOST_PHOENIX_NO_VARIADIC_ACTOR
303 // Bring in the rest
304 #include <boost/phoenix/core/detail/cpp03/actor_operator.hpp>
305 #else
306 template <typename This, typename... A>
307 struct result<This(A...)>
308 : result_of::actor<
309 proto_base_expr
310 , typename mpl::if_<is_reference<A>, A, A const &>::type...
311 >
312 {};
313
314 template <typename... A>
315 typename result<actor(A...)>::type
316 operator()(A &&... a)
317 {
318 typedef
319 typename vector_chooser<sizeof...(A) + 1>::template apply<
320 const actor<Expr> *
321 , typename mpl::if_<is_reference<A>, A, A const &>::type...
322 >::type
323 env_type;
324
325 env_type env = {this, a...};
326 return phoenix::eval(*this, phoenix::context(env, default_actions()));
327 }
328
329 template <typename... A>
330 typename result<actor(A...)>::type
331 operator()(A &&... a) const
332 {
333 typedef
334 typename vector_chooser<sizeof...(A) + 1>::template apply<
335 const actor<Expr> *
336 , typename mpl::if_<is_reference<A>, A, A const &>::type...
337 >::type
338 env_type;
339
340 env_type env = {this, a...};
341 return phoenix::eval(*this, phoenix::context(env, default_actions()));
342 }
343 #endif
344 };
345 }}
346
347 namespace boost
348 {
349 // specialize boost::result_of to return the proper result type
350 template <typename Expr>
351 struct result_of<phoenix::actor<Expr>()>
352 : phoenix::result_of::actor<typename phoenix::actor<Expr>::proto_base_expr>
353 {};
354
355 template <typename Expr>
356 struct result_of<phoenix::actor<Expr> const()>
357 : phoenix::result_of::actor<typename phoenix::actor<Expr>::proto_base_expr>
358 {};
359 }
360
361
362 #ifdef BOOST_MSVC
363 #pragma warning(pop)
364 #endif
365
366 #endif
367