1 /*=============================================================================
2 Copyright (c) 2016 Kohei Takahashi
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #ifndef BOOST_PHOENIX_CORE_EXPRESSION_HPP
8 #define BOOST_PHOENIX_CORE_EXPRESSION_HPP
10 #include <boost/phoenix/core/limits.hpp>
11 #include <boost/call_traits.hpp>
12 #include <boost/fusion/sequence/intrinsic/at.hpp>
13 #include <boost/phoenix/core/as_actor.hpp>
14 #include <boost/phoenix/core/detail/expression.hpp>
15 #include <boost/phoenix/core/domain.hpp>
16 #include <boost/proto/domain.hpp>
17 #include <boost/proto/make_expr.hpp>
18 #include <boost/proto/transform/pass_through.hpp>
20 namespace boost { namespace phoenix
22 template <typename Expr> struct actor;
24 #ifdef BOOST_PHOENIX_NO_VARIADIC_EXPRESSION
25 #include <boost/phoenix/core/detail/cpp03/expression.hpp>
27 template <template <typename> class Actor, typename Tag, typename... A>
30 // This void filter is necessary to avoid forming reference to void
31 // because most of other expressions are not based on variadics.
32 template <typename Tag, typename F, typename... T>
35 template <typename Tag, typename... A>
36 struct expr_impl<Tag, void(A...)> : expr_ext<actor, Tag, A...> {};
38 template <typename Tag, typename... A, typename... T>
39 struct expr_impl<Tag, void(A...), void, T...> : expr_impl<Tag, void(A...)> {};
41 template <typename Tag, typename... A, typename H, typename... T>
42 struct expr_impl<Tag, void(A...), H, T...> : expr_impl<Tag, void(A..., H), T...> {};
44 template <typename Tag, typename... A>
45 struct expr : expr_impl<Tag, void(), A...> {};
47 template <template <typename> class Actor, typename Tag, typename... A>
49 : proto::transform<expr_ext<Actor, Tag, A...>, int>
52 typename proto::result_of::make_expr<
54 , phoenix_default_domain //proto::basic_default_domain
55 , typename proto::detail::uncvref<typename call_traits<A>::value_type>::type...
59 typedef Actor<base_type> type;
61 typedef typename proto::nary_expr<Tag, A...>::proto_grammar proto_grammar;
63 static type make(typename call_traits<A>::param_type... a)
64 { //?? actor or Actor??
65 //Actor<base_type> const e =
66 actor<base_type> const e =
68 proto::make_expr<Tag, phoenix_default_domain>(a...)
73 template<typename Expr, typename State, typename Data>
75 : proto::pass_through<expr_ext>::template impl<Expr, State, Data>
78 typedef Tag proto_tag;