#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)
#pragma warning(disable: 4510)
#pragma warning(disable: 4610)
#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
#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
typename mpl::eval_if_c<
result_of::is_nullary<Expr>::value
, nullary_actor_result<Expr>
, mpl::identity<detail::error_expecting_arguments>
>::type
type;
};
}
#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
#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
{
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