| /*============================================================================= |
| Phoenix v1.2 |
| Copyright (c) 2001-2002 Joel de Guzman |
| |
| 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 PHOENIX_ACTOR_HPP |
| #define PHOENIX_ACTOR_HPP |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| #include <boost/spirit/home/classic/phoenix/tuples.hpp> |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| namespace phoenix { |
| |
| // These are forward declared here because we cannot include impl.hpp |
| // or operators.hpp yet but the actor's assignment operator and index |
| // operator are required to be members. |
| |
| ////////////////////////////////// |
| struct assign_op; |
| struct index_op; |
| |
| ////////////////////////////////// |
| namespace impl { |
| |
| template <typename OperationT, typename BaseT, typename B> |
| struct make_binary1; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // unpack_tuple class |
| // |
| // This class is used to unpack a supplied tuple such, that the members of |
| // this tuple will be handled as if they would be supplied separately. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| template <typename TupleT> |
| struct unpack_tuple : public TupleT { |
| |
| typedef TupleT tuple_t; |
| |
| unpack_tuple() {} |
| unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {} |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // actor class |
| // |
| // This class is a protocol class for all actors. This class is |
| // essentially an interface contract. The actor class does not |
| // really know how how to act on anything but instead relies on the |
| // template parameter BaseT (from which the actor will derive from) |
| // to do the actual action. |
| // |
| // An actor is a functor that is capable of accepting arguments up |
| // to a predefined maximum. It is up to the base class to do the |
| // actual processing or possibly to limit the arity (no. of |
| // arguments) passed in. Upon invocation of the functor through a |
| // supplied operator(), the actor funnels the arguments passed in |
| // by the client into a tuple and calls the base eval member |
| // function. |
| // |
| // Schematically: |
| // |
| // arg0 ---------| |
| // arg1 ---------| |
| // arg2 ---------|---> tupled_args ---> base.eval |
| // ... | |
| // argN ---------| |
| // |
| // actor::operator()(arg0, arg1... argN) |
| // ---> BaseT::eval(tupled_args); |
| // |
| // Actor base classes from which this class inherits from are |
| // expected to have a corresponding member function eval compatible |
| // with the conceptual Interface: |
| // |
| // template <typename TupleT> |
| // actor_return_type |
| // eval(TupleT const& args) const; |
| // |
| // where args are the actual arguments passed in by the client |
| // funneled into a tuple (see tuple.hpp for details). |
| // |
| // The actor_return_type can be anything. Base classes are free to |
| // return any type, even argument dependent types (types that are |
| // deduced from the types of the arguments). After evaluating the |
| // parameters and doing some computations or actions, the eval |
| // member function concludes by returning something back to the |
| // client. To do this, the forwarding function (the actor's |
| // operator()) needs to know the return type of the eval member |
| // function that it is calling. For this purpose, actor base |
| // classes are required to provide a nested template class: |
| // |
| // template <typename TupleT> |
| // struct result; |
| // |
| // This auxiliary class provides the result type information |
| // returned by the eval member function of a base actor class. The |
| // nested template class result should have a typedef 'type' that |
| // reflects the return type of its member function eval. It is |
| // basically a type computer that answers the question "given |
| // arguments packed into a TupleT type, what will be the result |
| // type of the eval member function of ActorT?". The template class |
| // actor_result queries this to extract the return type of an |
| // actor. Example: |
| // |
| // typedef typename actor_result<ActorT, TupleT>::type |
| // actor_return_type; |
| // |
| // where actor_return_type is the actual type returned by ActorT's |
| // eval member function given some arguments in a TupleT. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| template <typename ActorT, typename TupleT> |
| struct actor_result { |
| |
| typedef typename ActorT::template result<TupleT>::type type; |
| typedef typename remove_reference<type>::type plain_type; |
| }; |
| |
| ////////////////////////////////// |
| #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) |
| #pragma warning(push) |
| #pragma warning(disable:4512) //assignment operator could not be generated |
| #endif |
| |
| template <typename BaseT> |
| struct actor : public BaseT { |
| |
| actor(); |
| actor(BaseT const& base); |
| |
| typename actor_result<BaseT, tuple<> >::type |
| operator()() const; |
| |
| template <typename A> |
| typename actor_result<BaseT, tuple<A&> >::type |
| operator()(A& a) const; |
| |
| template <typename A, typename B> |
| typename actor_result<BaseT, tuple<A&, B&> >::type |
| operator()(A& a, B& b) const; |
| |
| template <typename A, typename B, typename C> |
| typename actor_result<BaseT, tuple<A&, B&, C&> >::type |
| operator()(A& a, B& b, C& c) const; |
| |
| #if PHOENIX_LIMIT > 3 |
| template <typename A, typename B, typename C, typename D> |
| typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type |
| operator()(A& a, B& b, C& c, D& d) const; |
| |
| template <typename A, typename B, typename C, typename D, typename E> |
| typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type |
| operator()(A& a, B& b, C& c, D& d, E& e) const; |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F> |
| typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type |
| operator()(A& a, B& b, C& c, D& d, E& e, F& f) const; |
| |
| #if PHOENIX_LIMIT > 6 |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G> |
| typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type |
| operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const; |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&> |
| >::type |
| operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const; |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&> |
| >::type |
| operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const; |
| |
| #if PHOENIX_LIMIT > 9 |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&> |
| >::type |
| operator()( |
| A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const; |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&> |
| >::type |
| operator()( |
| A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, |
| K& k) const; |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&> |
| >::type |
| operator()( |
| A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, |
| K& k, L& l) const; |
| |
| #if PHOENIX_LIMIT > 12 |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L, typename M> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&> |
| >::type |
| operator()( |
| A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, |
| K& k, L& l, M& m) const; |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L, typename M, typename N> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&> |
| >::type |
| operator()( |
| A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, |
| K& k, L& l, M& m, N& n) const; |
| |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L, typename M, typename N, typename O> |
| typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&> |
| >::type |
| operator()( |
| A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j, |
| K& k, L& l, M& m, N& n, O& o) const; |
| |
| #endif |
| #endif |
| #endif |
| #endif |
| |
| template <typename TupleT> |
| typename actor_result<BaseT, unpack_tuple<TupleT> >::type |
| operator()(unpack_tuple<TupleT> const &t) const; |
| |
| template <typename B> |
| typename impl::make_binary1<assign_op, BaseT, B>::type |
| operator=(B const& b) const; |
| |
| template <typename B> |
| typename impl::make_binary1<index_op, BaseT, B>::type |
| operator[](B const& b) const; |
| }; |
| |
| #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) |
| #pragma warning(pop) |
| #endif |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // as_actor |
| // |
| // as_actor is a meta-program that converts an arbitrary type into |
| // an actor. All participants in the framework must be first-class |
| // actors. This meta-program is used all throughout the framework |
| // whenever an unknown type needs to be converted to an actor. |
| // as_actor specializations are expected to have a typedef 'type'. |
| // This is the destination actor type. A static member function |
| // 'convert' converts an object to this target type. |
| // |
| // The meta-program does no conversion if the object to be |
| // converted is already an actor. |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename T> |
| struct as_actor; |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| struct as_actor<actor<BaseT> > { |
| |
| typedef actor<BaseT> type; |
| static type convert(actor<BaseT> const& x) { return x; } |
| }; |
| |
| ////////////////////////////////// |
| template <> |
| struct as_actor<nil_t> { |
| |
| typedef nil_t type; |
| static nil_t convert(nil_t /*x*/) |
| { return nil_t(); } |
| }; |
| |
| ////////////////////////////////// |
| template <> |
| struct as_actor<void> { |
| |
| typedef void type; |
| // ERROR!!! |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // actor class implementation |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| template <typename BaseT> |
| actor<BaseT>::actor() |
| : BaseT() {} |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| actor<BaseT>::actor(BaseT const& base) |
| : BaseT(base) {} |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| inline typename actor_result<BaseT, tuple<> >::type |
| actor<BaseT>::operator()() const |
| { |
| return BaseT::eval(tuple<>()); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template <typename A> |
| inline typename actor_result<BaseT, tuple<A&> >::type |
| actor<BaseT>::operator()(A& a_) const |
| { |
| return BaseT::eval(tuple<A&>(a_)); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template <typename A, typename B> |
| inline typename actor_result<BaseT, tuple<A&, B&> >::type |
| actor<BaseT>::operator()(A& a_, B& b_) const |
| { |
| return BaseT::eval(tuple<A&, B&>(a_, b_)); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template <typename A, typename B, typename C> |
| inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type |
| actor<BaseT>::operator()(A& a_, B& b_, C& c_) const |
| { |
| return BaseT::eval(tuple<A&, B&, C&>(a_, b_, c_)); |
| } |
| |
| #if PHOENIX_LIMIT > 3 |
| ////////////////////////////////// |
| template <typename BaseT> |
| template <typename A, typename B, typename C, typename D> |
| inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type |
| actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_) const |
| { |
| return BaseT::eval(tuple<A&, B&, C&, D&>(a_, b_, c_, d_)); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template <typename A, typename B, typename C, typename D, typename E> |
| inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type |
| actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_, E& e_) const |
| { |
| return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a_, b_, c_, d_, e_)); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&> |
| (a_, b_, c_, d_, e_, f_) |
| ); |
| } |
| |
| #if PHOENIX_LIMIT > 6 |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&> |
| (a_, b_, c_, d_, e_, f_, g_) |
| ); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&> |
| (a_, b_, c_, d_, e_, f_, g_, h_) |
| ); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&> |
| (a_, b_, c_, d_, e_, f_, g_, h_, i_) |
| ); |
| } |
| |
| #if PHOENIX_LIMIT > 9 |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&> |
| (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_) |
| ); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, |
| K& k_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&> |
| (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_) |
| ); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, |
| K& k_, L& l_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&> |
| (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_) |
| ); |
| } |
| |
| #if PHOENIX_LIMIT > 12 |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L, typename M> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, |
| K& k_, L& l_, M& m_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&> |
| (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_) |
| ); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L, typename M, typename N> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, |
| K& k_, L& l_, M& m_, N& n_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&> |
| (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_) |
| ); |
| } |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template < |
| typename A, typename B, typename C, typename D, typename E, |
| typename F, typename G, typename H, typename I, typename J, |
| typename K, typename L, typename M, typename N, typename O> |
| inline typename actor_result<BaseT, |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&> |
| >::type |
| actor<BaseT>::operator()( |
| A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_, |
| K& k_, L& l_, M& m_, N& n_, O& o_ |
| ) const |
| { |
| return BaseT::eval( |
| tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&> |
| (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_) |
| ); |
| } |
| |
| #endif |
| #endif |
| #endif |
| #endif |
| |
| ////////////////////////////////// |
| template <typename BaseT> |
| template <typename TupleT> |
| typename actor_result<BaseT, unpack_tuple<TupleT> >::type |
| actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const |
| { |
| return BaseT::eval(t); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| } // namespace phoenix |
| |
| #endif |