/*============================================================================= Copyright (c) 2005-2010 Joel de Guzman Copyright (c) 2010 Eric Niebler Copyright (c) 2010 Thomas Heller 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable: 4522) // 'this' used in base member initializer list #endif namespace boost { namespace phoenix { template struct actor; namespace detail { struct error_expecting_arguments { template error_expecting_arguments(T const&) {} }; struct error_invalid_lambda_expr { template error_invalid_lambda_expr(T const&) {} }; template struct result_type_deduction_helper { typedef T const & type; }; template struct result_type_deduction_helper { typedef T & type; }; template struct result_type_deduction_helper { typedef T const & type; }; struct do_assign { BOOST_PROTO_CALLABLE() typedef void result_type; template void operator()(T1 & t1, T2 const & t2) const { proto::value(t1) = proto::value(t2); } }; #define BOOST_PHOENIX_ACTOR_ASSIGN_CHILD(Z, N, D) \ assign( \ proto::_child_c \ , proto::call< \ proto::_child_c(proto::_state) \ > \ ) \ /**/ #define BOOST_PHOENIX_ACTOR_ASSIGN_CALL(Z, N, D) \ proto::when< \ proto::nary_expr \ , proto::and_< \ BOOST_PP_ENUM( \ N \ , BOOST_PHOENIX_ACTOR_ASSIGN_CHILD \ , _ \ ) \ > \ > \ /**/ #if !defined(BOOST_PHOENIX_DONT_USE_PREPROCESSED_FILES) #include #else #if defined(__WAVE__) && defined(BOOST_PHOENIX_CREATE_PREPROCESSED_FILES) #pragma wave option(preserve: 2, line: 0, output: "preprocessed/actor_" BOOST_PHOENIX_LIMIT_STR ".hpp") #endif /*============================================================================== Copyright (c) 2005-2010 Joel de Guzman Copyright (c) 2010-2011 Thomas Heller 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) ==============================================================================*/ #if defined(__WAVE__) && defined(BOOST_PHOENIX_CREATE_PREPROCESSED_FILES) #pragma wave option(preserve: 1) #endif struct assign : proto::or_< BOOST_PP_ENUM_SHIFTED( BOOST_PHOENIX_LIMIT , BOOST_PHOENIX_ACTOR_ASSIGN_CALL , _ ) , proto::when< proto::terminal , do_assign(proto::_, proto::_state) > > {}; #if defined(__WAVE__) && defined(BOOST_PHOENIX_CREATE_PREPROCESSED_FILES) #pragma wave option(output: null) #endif #endif #undef BOOST_PHOENIX_ACTOR_ASSIGN_CALL #undef BOOST_PHOENIX_ACTOR_ASSIGN_CHILD } // Bring in the result_of::actor<> #include //////////////////////////////////////////////////////////////////////////// // // 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. // //////////////////////////////////////////////////////////////////////////// template struct actor { typedef typename mpl::eval_if_c< mpl::or_< is_custom_terminal , mpl::bool_::value> >::value , proto::terminal , mpl::identity >::type expr_type; BOOST_PROTO_BASIC_EXTENDS(expr_type, actor, phoenix_domain) // providing operator= to be assignable actor& operator=(actor const& other) { detail::assign()(*this, other); return *this; } actor& operator=(actor & other) { detail::assign()(*this, other); return *this; } template typename proto::result_of::make_expr< proto::tag::assign , phoenix_domain , proto_base_expr , A0 >::type const operator=(A0 const & a0) const { return proto::make_expr(this->proto_expr_, a0); } template typename proto::result_of::make_expr< proto::tag::assign , phoenix_domain , proto_base_expr , A0 >::type const operator=(A0 & a0) const { return proto::make_expr(this->proto_expr_, a0); } template typename proto::result_of::make_expr< proto::tag::subscript , phoenix_domain , proto_base_expr , A0 >::type const operator[](A0 const & a0) const { return proto::make_expr(this->proto_expr_, a0); } template typename proto::result_of::make_expr< proto::tag::subscript , phoenix_domain , proto_base_expr , A0 >::type const operator[](A0 & a0) const { return proto::make_expr(this->proto_expr_, a0); } template struct result; typename result_of::actor::type operator()() { typedef vector1 *> env_type; env_type env = {this}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } typename result_of::actor::type operator()() const { typedef vector1 *> env_type; env_type env = {this}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template 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())); } // Bring in the rest #include }; }} namespace boost { // specialize boost::result_of to return the proper result type template struct result_of()> : phoenix::result_of::actor::proto_base_expr> {}; template struct result_of const()> : phoenix::result_of::actor::proto_base_expr> {}; } #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif