123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- /*=============================================================================
- Copyright (c) 2005-2010 Joel de Guzman
- Copyright (c) 2010 Eric Niebler
- Copyright (c) 2010 Thomas Heller
- Copyright (c) 2014 John Fletcher
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- ==============================================================================*/
- #ifndef BOOST_PHOENIX_CORE_ACTOR_HPP
- #define BOOST_PHOENIX_CORE_ACTOR_HPP
- #include <boost/phoenix/core/limits.hpp>
- #include <boost/is_placeholder.hpp>
- #include <boost/mpl/identity.hpp>
- #include <boost/mpl/eval_if.hpp>
- #include <boost/phoenix/core/domain.hpp>
- #include <boost/phoenix/core/environment.hpp>
- #include <boost/phoenix/core/is_nullary.hpp>
- #include <boost/phoenix/core/meta_grammar.hpp>
- #include <boost/phoenix/support/iterate.hpp>
- #include <boost/phoenix/support/vector.hpp>
- #include <boost/proto/extends.hpp>
- #include <boost/proto/make_expr.hpp>
- #include <boost/utility/result_of.hpp>
- #include <boost/mpl/void.hpp>
- #include <cstring>
- #ifndef BOOST_PHOENIX_NO_VARIADIC_ACTOR
- # include <boost/mpl/if.hpp>
- # include <boost/type_traits/is_reference.hpp>
- # include <boost/phoenix/core/detail/index_sequence.hpp>
- #endif
- #ifdef BOOST_MSVC
- #pragma warning(push)
- #pragma warning(disable: 4522) // 'this' used in base member initializer list
- #pragma warning(disable: 4510) // default constructor could not be generated
- #pragma warning(disable: 4610) // can never be instantiated - user defined cons
- #endif
- namespace boost { namespace phoenix
- {
- template <typename Expr>
- struct actor;
- namespace detail
- {
- struct error_expecting_arguments
- {
- template <typename T>
- error_expecting_arguments(T const&) {}
- };
- struct error_invalid_lambda_expr
- {
- template <typename T>
- error_invalid_lambda_expr(T const&) {}
- };
- template <typename T>
- struct result_type_deduction_helper
- {
- typedef T const & type;
- };
- template <typename T>
- struct result_type_deduction_helper<T &>
- {
- typedef T & type;
- };
- template <typename T>
- struct result_type_deduction_helper<T const &>
- {
- typedef T const & type;
- };
- }
- namespace result_of
- {
- #ifdef BOOST_PHOENIX_NO_VARIADIC_ACTOR
- // Bring in the result_of::actor<>
- #include <boost/phoenix/core/detail/cpp03/actor_result_of.hpp>
- #else
- template <typename Expr, typename... A>
- struct actor_impl
- {
- typedef
- typename boost::phoenix::evaluator::impl<
- Expr const&
- , vector2<
- typename vector_chooser<sizeof...(A) + 1>::
- template apply<const ::boost::phoenix::actor<Expr> *, A...>::type&
- , default_actions
- > const &
- , proto::empty_env
- >::result_type
- type;
- };
- template <typename Expr, typename... A>
- struct actor : actor_impl<Expr, A...> {};
- template <typename Expr>
- struct nullary_actor_result : actor_impl<Expr> {};
- #endif
- template <typename Expr>
- struct actor<Expr>
- {
- typedef
- // avoid calling result_of::actor when this is false
- typename mpl::eval_if_c<
- result_of::is_nullary<Expr>::value
- , nullary_actor_result<Expr>
- , mpl::identity<detail::error_expecting_arguments>
- >::type
- type;
- };
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // actor
- //
- // The actor class. The main thing! In phoenix, everything is an actor
- // This class is responsible for full function evaluation. Partial
- // function evaluation involves creating a hierarchy of actor objects.
- //
- ////////////////////////////////////////////////////////////////////////////
- #if defined __clang__ && defined __has_warning
- # pragma clang diagnostic push
- # if __has_warning("-Wdeprecated-copy")
- # pragma clang diagnostic ignored "-Wdeprecated-copy"
- # endif
- #endif
- template <typename Expr>
- struct actor
- {
- typedef typename
- mpl::eval_if_c<
- mpl::or_<
- is_custom_terminal<Expr>
- , mpl::bool_<is_placeholder<Expr>::value>
- >::value
- , proto::terminal<Expr>
- , mpl::identity<Expr>
- >::type
- expr_type;
- BOOST_PROTO_BASIC_EXTENDS(expr_type, actor<Expr>, phoenix_domain)
- BOOST_PROTO_EXTENDS_SUBSCRIPT()
- BOOST_PROTO_EXTENDS_ASSIGN_()
- template <typename Sig>
- struct result;
- typename result_of::actor<proto_base_expr>::type
- operator()()
- {
- typedef vector1<const actor<Expr> *> env_type;
- env_type env = {this};
- return phoenix::eval(*this, phoenix::context(env, default_actions()));
- }
- typename result_of::actor<proto_base_expr>::type
- operator()() const
- {
- typedef vector1<const actor<Expr> *> env_type;
- env_type env = {this};
- return phoenix::eval(*this, phoenix::context(env, default_actions()));
- }
- template <typename Env>
- typename evaluator::impl<
- proto_base_expr const &
- , typename result_of::context<
- Env const &
- , default_actions const &
- >::type
- , proto::empty_env
- >::result_type
- eval(Env const & env) const
- {
- return phoenix::eval(*this, phoenix::context(env, default_actions()));
- }
- #ifdef BOOST_PHOENIX_NO_VARIADIC_ACTOR
- // Bring in the rest
- #include <boost/phoenix/core/detail/cpp03/actor_operator.hpp>
- #else
- template <typename This, typename... A>
- struct result<This(A...)>
- : result_of::actor<
- proto_base_expr
- , typename mpl::if_<is_reference<A>, A, A const &>::type...
- >
- {};
- template <typename... A>
- typename result<actor(A...)>::type
- operator()(A &&... a)
- {
- typedef
- typename vector_chooser<sizeof...(A) + 1>::template apply<
- const actor<Expr> *
- , typename mpl::if_<is_reference<A>, A, A const &>::type...
- >::type
- env_type;
- env_type env = {this, a...};
- return phoenix::eval(*this, phoenix::context(env, default_actions()));
- }
- template <typename... A>
- typename result<actor(A...)>::type
- operator()(A &&... a) const
- {
- typedef
- typename vector_chooser<sizeof...(A) + 1>::template apply<
- const actor<Expr> *
- , typename mpl::if_<is_reference<A>, A, A const &>::type...
- >::type
- env_type;
- env_type env = {this, a...};
- return phoenix::eval(*this, phoenix::context(env, default_actions()));
- }
- #endif
- BOOST_DELETED_FUNCTION(actor& operator=(actor const&))
- };
- #if defined __clang__ && defined __has_warning
- # pragma clang diagnostic pop
- #endif
- }}
- namespace boost
- {
- // specialize boost::result_of to return the proper result type
- template <typename Expr>
- struct result_of<phoenix::actor<Expr>()>
- : phoenix::result_of::actor<typename phoenix::actor<Expr>::proto_base_expr>
- {};
- template <typename Expr>
- struct result_of<phoenix::actor<Expr> const()>
- : phoenix::result_of::actor<typename phoenix::actor<Expr>::proto_base_expr>
- {};
- }
- #ifdef BOOST_MSVC
- #pragma warning(pop)
- #endif
- #endif
|