Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:31:23

0001 /*=============================================================================
0002     Phoenix v1.2
0003     Copyright (c) 2001-2002 Joel de Guzman
0004 
0005   Distributed under the Boost Software License, Version 1.0. (See accompanying
0006   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 ==============================================================================*/
0008 #ifndef BOOST_SPIRIT_CLASSIC_PHOENIX_ACTOR_HPP
0009 #define BOOST_SPIRIT_CLASSIC_PHOENIX_ACTOR_HPP
0010 
0011 ///////////////////////////////////////////////////////////////////////////////
0012 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
0013 #include <boost/type_traits/remove_reference.hpp>
0014 
0015 ///////////////////////////////////////////////////////////////////////////////
0016 namespace phoenix {
0017 
0018 //  These are forward declared here because we cannot include impl.hpp
0019 //  or operators.hpp yet but the actor's assignment operator and index
0020 //  operator are required to be members.
0021 
0022 //////////////////////////////////
0023 struct assign_op;
0024 struct index_op;
0025 
0026 //////////////////////////////////
0027 namespace impl {
0028 
0029     template <typename OperationT, typename BaseT, typename B>
0030     struct make_binary1;
0031 }
0032 
0033 ///////////////////////////////////////////////////////////////////////////////
0034 //
0035 //  unpack_tuple class
0036 //
0037 //      This class is used to unpack a supplied tuple such, that the members of 
0038 //      this tuple will be handled as if they would be supplied separately.
0039 //
0040 ///////////////////////////////////////////////////////////////////////////////
0041 template <typename TupleT>
0042 struct unpack_tuple : public TupleT {
0043 
0044     typedef TupleT tuple_t;
0045     
0046     unpack_tuple() {}
0047     unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {}
0048 };
0049 
0050 ///////////////////////////////////////////////////////////////////////////////
0051 //
0052 //  actor class
0053 //
0054 //      This class is a protocol class for all actors. This class is
0055 //      essentially an interface contract. The actor class does not
0056 //      really know how how to act on anything but instead relies on the
0057 //      template parameter BaseT (from which the actor will derive from)
0058 //      to do the actual action.
0059 //
0060 //      An actor is a functor that is capable of accepting arguments up
0061 //      to a predefined maximum. It is up to the base class to do the
0062 //      actual processing or possibly to limit the arity (no. of
0063 //      arguments) passed in. Upon invocation of the functor through a
0064 //      supplied operator(), the actor funnels the arguments passed in
0065 //      by the client into a tuple and calls the base eval member
0066 //      function.
0067 //
0068 //      Schematically:
0069 //
0070 //          arg0 ---------|
0071 //          arg1 ---------|
0072 //          arg2 ---------|---> tupled_args ---> base.eval
0073 //          ...           |
0074 //          argN ---------|
0075 //
0076 //          actor::operator()(arg0, arg1... argN)
0077 //              ---> BaseT::eval(tupled_args);
0078 //
0079 //      Actor base classes from which this class inherits from are
0080 //      expected to have a corresponding member function eval compatible
0081 //      with the conceptual Interface:
0082 //
0083 //          template <typename TupleT>
0084 //          actor_return_type
0085 //          eval(TupleT const& args) const;
0086 //
0087 //      where args are the actual arguments passed in by the client
0088 //      funneled into a tuple (see tuple.hpp for details).
0089 //
0090 //      The actor_return_type can be anything. Base classes are free to
0091 //      return any type, even argument dependent types (types that are
0092 //      deduced from the types of the arguments). After evaluating the
0093 //      parameters and doing some computations or actions, the eval
0094 //      member function concludes by returning something back to the
0095 //      client. To do this, the forwarding function (the actor's
0096 //      operator()) needs to know the return type of the eval member
0097 //      function that it is calling. For this purpose, actor base
0098 //      classes are required to provide a nested template class:
0099 //
0100 //          template <typename TupleT>
0101 //          struct result;
0102 //
0103 //      This auxiliary class provides the result type information
0104 //      returned by the eval member function of a base actor class. The
0105 //      nested template class result should have a typedef 'type' that
0106 //      reflects the return type of its member function eval. It is
0107 //      basically a type computer that answers the question "given
0108 //      arguments packed into a TupleT type, what will be the result
0109 //      type of the eval member function of ActorT?". The template class
0110 //      actor_result queries this to extract the return type of an
0111 //      actor. Example:
0112 //
0113 //          typedef typename actor_result<ActorT, TupleT>::type
0114 //              actor_return_type;
0115 //
0116 //      where actor_return_type is the actual type returned by ActorT's
0117 //      eval member function given some arguments in a TupleT.
0118 //
0119 ///////////////////////////////////////////////////////////////////////////////
0120 template <typename ActorT, typename TupleT>
0121 struct actor_result {
0122 
0123     typedef typename ActorT::template result<TupleT>::type type;
0124     typedef typename boost::remove_reference<type>::type plain_type;
0125 };
0126 
0127 //////////////////////////////////
0128 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0129 #pragma warning(push)
0130 #pragma warning(disable:4512) //assignment operator could not be generated
0131 #endif
0132 
0133 template <typename BaseT>
0134 struct actor : public BaseT {
0135 
0136     actor();
0137     actor(BaseT const& base);
0138 
0139     typename actor_result<BaseT, tuple<> >::type
0140     operator()() const;
0141 
0142     template <typename A>
0143     typename actor_result<BaseT, tuple<A&> >::type
0144     operator()(A& a) const;
0145 
0146     template <typename A, typename B>
0147     typename actor_result<BaseT, tuple<A&, B&> >::type
0148     operator()(A& a, B& b) const;
0149 
0150     template <typename A, typename B, typename C>
0151     typename actor_result<BaseT, tuple<A&, B&, C&> >::type
0152     operator()(A& a, B& b, C& c) const;
0153 
0154 #if PHOENIX_LIMIT > 3
0155     template <typename A, typename B, typename C, typename D>
0156     typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
0157     operator()(A& a, B& b, C& c, D& d) const;
0158 
0159     template <typename A, typename B, typename C, typename D, typename E>
0160     typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
0161     operator()(A& a, B& b, C& c, D& d, E& e) const;
0162 
0163     template <
0164         typename A, typename B, typename C, typename D, typename E,
0165         typename F>
0166     typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type
0167     operator()(A& a, B& b, C& c, D& d, E& e, F& f) const;
0168 
0169 #if PHOENIX_LIMIT > 6
0170 
0171     template <
0172         typename A, typename B, typename C, typename D, typename E,
0173         typename F, typename G>
0174     typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type
0175     operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const;
0176 
0177     template <
0178         typename A, typename B, typename C, typename D, typename E,
0179         typename F, typename G, typename H>
0180     typename actor_result<BaseT,
0181         tuple<A&, B&, C&, D&, E&, F&, G&, H&>
0182     >::type
0183     operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
0184 
0185     template <
0186         typename A, typename B, typename C, typename D, typename E,
0187         typename F, typename G, typename H, typename I>
0188     typename actor_result<BaseT,
0189         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
0190     >::type
0191     operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
0192 
0193 #if PHOENIX_LIMIT > 9
0194 
0195     template <
0196         typename A, typename B, typename C, typename D, typename E,
0197         typename F, typename G, typename H, typename I, typename J>
0198     typename actor_result<BaseT,
0199         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
0200     >::type
0201     operator()(
0202         A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
0203 
0204     template <
0205         typename A, typename B, typename C, typename D, typename E,
0206         typename F, typename G, typename H, typename I, typename J,
0207         typename K>
0208     typename actor_result<BaseT,
0209         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
0210     >::type
0211     operator()(
0212         A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
0213         K& k) const;
0214 
0215     template <
0216         typename A, typename B, typename C, typename D, typename E,
0217         typename F, typename G, typename H, typename I, typename J,
0218         typename K, typename L>
0219     typename actor_result<BaseT,
0220         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
0221     >::type
0222     operator()(
0223         A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
0224         K& k, L& l) const;
0225 
0226 #if PHOENIX_LIMIT > 12
0227 
0228     template <
0229         typename A, typename B, typename C, typename D, typename E,
0230         typename F, typename G, typename H, typename I, typename J,
0231         typename K, typename L, typename M>
0232     typename actor_result<BaseT,
0233         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
0234     >::type
0235     operator()(
0236         A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
0237         K& k, L& l, M& m) const;
0238 
0239     template <
0240         typename A, typename B, typename C, typename D, typename E,
0241         typename F, typename G, typename H, typename I, typename J,
0242         typename K, typename L, typename M, typename N>
0243     typename actor_result<BaseT,
0244         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
0245     >::type
0246     operator()(
0247         A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
0248         K& k, L& l, M& m, N& n) const;
0249 
0250     template <
0251         typename A, typename B, typename C, typename D, typename E,
0252         typename F, typename G, typename H, typename I, typename J,
0253         typename K, typename L, typename M, typename N, typename O>
0254     typename actor_result<BaseT,
0255         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
0256     >::type
0257     operator()(
0258         A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
0259         K& k, L& l, M& m, N& n, O& o) const;
0260 
0261 #endif
0262 #endif
0263 #endif
0264 #endif
0265 
0266     template <typename TupleT>
0267     typename actor_result<BaseT, unpack_tuple<TupleT> >::type
0268     operator()(unpack_tuple<TupleT> const &t) const;
0269     
0270     template <typename B>
0271     typename impl::make_binary1<assign_op, BaseT, B>::type
0272     operator=(B const& b) const;
0273 
0274     template <typename B>
0275     typename impl::make_binary1<index_op, BaseT, B>::type
0276     operator[](B const& b) const;
0277 };
0278 
0279 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0280 #pragma warning(pop)
0281 #endif
0282 
0283 ///////////////////////////////////////////////////////////////////////////
0284 //
0285 //  as_actor
0286 //
0287 //      as_actor is a meta-program that converts an arbitrary type into
0288 //      an actor. All participants in the framework must be first-class
0289 //      actors. This meta-program is used all throughout the framework
0290 //      whenever an unknown type needs to be converted to an actor.
0291 //      as_actor specializations are expected to have a typedef 'type'.
0292 //      This is the destination actor type. A static member function
0293 //      'convert' converts an object to this target type.
0294 //
0295 //      The meta-program does no conversion if the object to be
0296 //      converted is already an actor.
0297 //
0298 ///////////////////////////////////////////////////////////////////////////
0299 template <typename T>
0300 struct as_actor;
0301 
0302 //////////////////////////////////
0303 template <typename BaseT>
0304 struct as_actor<actor<BaseT> > {
0305 
0306     typedef actor<BaseT> type;
0307     static type convert(actor<BaseT> const& x) { return x; }
0308 };
0309 
0310 //////////////////////////////////
0311 template <>
0312 struct as_actor<nil_t> {
0313 
0314     typedef nil_t type;
0315     static nil_t convert(nil_t /*x*/)
0316     { return nil_t(); }
0317 };
0318 
0319 //////////////////////////////////
0320 template <>
0321 struct as_actor<void> {
0322 
0323     typedef void type;
0324     //  ERROR!!!
0325 };
0326 
0327 ///////////////////////////////////////////////////////////////////////////////
0328 //
0329 //  actor class implementation
0330 //
0331 ///////////////////////////////////////////////////////////////////////////////
0332 template <typename BaseT>
0333 actor<BaseT>::actor()
0334 :   BaseT() {}
0335 
0336 //////////////////////////////////
0337 template <typename BaseT>
0338 actor<BaseT>::actor(BaseT const& base)
0339 :   BaseT(base) {}
0340 
0341 //////////////////////////////////
0342 template <typename BaseT>
0343 inline typename actor_result<BaseT, tuple<> >::type
0344 actor<BaseT>::operator()() const
0345 {
0346     return BaseT::eval(tuple<>());
0347 }
0348 
0349 //////////////////////////////////
0350 template <typename BaseT>
0351 template <typename A>
0352 inline typename actor_result<BaseT, tuple<A&> >::type
0353 actor<BaseT>::operator()(A& a_) const
0354 {
0355     return BaseT::eval(tuple<A&>(a_));
0356 }
0357 
0358 //////////////////////////////////
0359 template <typename BaseT>
0360 template <typename A, typename B>
0361 inline typename actor_result<BaseT, tuple<A&, B&> >::type
0362 actor<BaseT>::operator()(A& a_, B& b_) const
0363 {
0364     return BaseT::eval(tuple<A&, B&>(a_, b_));
0365 }
0366 
0367 //////////////////////////////////
0368 template <typename BaseT>
0369 template <typename A, typename B, typename C>
0370 inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type
0371 actor<BaseT>::operator()(A& a_, B& b_, C& c_) const
0372 {
0373     return BaseT::eval(tuple<A&, B&, C&>(a_, b_, c_));
0374 }
0375 
0376 #if PHOENIX_LIMIT > 3
0377 //////////////////////////////////
0378 template <typename BaseT>
0379 template <typename A, typename B, typename C, typename D>
0380 inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
0381 actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_) const
0382 {
0383     return BaseT::eval(tuple<A&, B&, C&, D&>(a_, b_, c_, d_));
0384 }
0385 
0386 //////////////////////////////////
0387 template <typename BaseT>
0388 template <typename A, typename B, typename C, typename D, typename E>
0389 inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
0390 actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_, E& e_) const
0391 {
0392     return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a_, b_, c_, d_, e_));
0393 }
0394 
0395 //////////////////////////////////
0396 template <typename BaseT>
0397 template <
0398     typename A, typename B, typename C, typename D, typename E,
0399     typename F>
0400 inline typename actor_result<BaseT,
0401     tuple<A&, B&, C&, D&, E&, F&>
0402 >::type
0403 actor<BaseT>::operator()(
0404     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_
0405 ) const
0406 {
0407     return BaseT::eval(
0408         tuple<A&, B&, C&, D&, E&, F&>
0409         (a_, b_, c_, d_, e_, f_)
0410     );
0411 }
0412 
0413 #if PHOENIX_LIMIT > 6
0414 //////////////////////////////////
0415 template <typename BaseT>
0416 template <
0417     typename A, typename B, typename C, typename D, typename E,
0418     typename F, typename G>
0419 inline typename actor_result<BaseT,
0420     tuple<A&, B&, C&, D&, E&, F&, G&>
0421 >::type
0422 actor<BaseT>::operator()(
0423     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_
0424 ) const
0425 {
0426     return BaseT::eval(
0427         tuple<A&, B&, C&, D&, E&, F&, G&>
0428         (a_, b_, c_, d_, e_, f_, g_)
0429     );
0430 }
0431 
0432 //////////////////////////////////
0433 template <typename BaseT>
0434 template <
0435     typename A, typename B, typename C, typename D, typename E,
0436     typename F, typename G, typename H>
0437 inline typename actor_result<BaseT,
0438     tuple<A&, B&, C&, D&, E&, F&, G&, H&>
0439 >::type
0440 actor<BaseT>::operator()(
0441     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_
0442 ) const
0443 {
0444     return BaseT::eval(
0445         tuple<A&, B&, C&, D&, E&, F&, G&, H&>
0446         (a_, b_, c_, d_, e_, f_, g_, h_)
0447     );
0448 }
0449 
0450 //////////////////////////////////
0451 template <typename BaseT>
0452 template <
0453     typename A, typename B, typename C, typename D, typename E,
0454     typename F, typename G, typename H, typename I>
0455 inline typename actor_result<BaseT,
0456     tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
0457 >::type
0458 actor<BaseT>::operator()(
0459     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_
0460 ) const
0461 {
0462     return BaseT::eval(
0463         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
0464         (a_, b_, c_, d_, e_, f_, g_, h_, i_)
0465     );
0466 }
0467 
0468 #if PHOENIX_LIMIT > 9
0469 //////////////////////////////////
0470 template <typename BaseT>
0471 template <
0472     typename A, typename B, typename C, typename D, typename E,
0473     typename F, typename G, typename H, typename I, typename J>
0474 inline typename actor_result<BaseT,
0475     tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
0476 >::type
0477 actor<BaseT>::operator()(
0478     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_
0479 ) const
0480 {
0481     return BaseT::eval(
0482         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
0483         (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_)
0484     );
0485 }
0486 
0487 //////////////////////////////////
0488 template <typename BaseT>
0489 template <
0490     typename A, typename B, typename C, typename D, typename E,
0491     typename F, typename G, typename H, typename I, typename J,
0492     typename K>
0493 inline typename actor_result<BaseT,
0494     tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
0495 >::type
0496 actor<BaseT>::operator()(
0497     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
0498     K& k_
0499 ) const
0500 {
0501     return BaseT::eval(
0502         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
0503         (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_)
0504     );
0505 }
0506 
0507 //////////////////////////////////
0508 template <typename BaseT>
0509 template <
0510     typename A, typename B, typename C, typename D, typename E,
0511     typename F, typename G, typename H, typename I, typename J,
0512     typename K, typename L>
0513 inline typename actor_result<BaseT,
0514     tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
0515 >::type
0516 actor<BaseT>::operator()(
0517     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
0518     K& k_, L& l_
0519 ) const
0520 {
0521     return BaseT::eval(
0522         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
0523         (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_)
0524     );
0525 }
0526 
0527 #if PHOENIX_LIMIT > 12
0528 //////////////////////////////////
0529 template <typename BaseT>
0530 template <
0531     typename A, typename B, typename C, typename D, typename E,
0532     typename F, typename G, typename H, typename I, typename J,
0533     typename K, typename L, typename M>
0534 inline typename actor_result<BaseT,
0535     tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
0536 >::type
0537 actor<BaseT>::operator()(
0538     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
0539     K& k_, L& l_, M& m_
0540 ) const
0541 {
0542     return BaseT::eval(
0543         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
0544         (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_)
0545     );
0546 }
0547 
0548 //////////////////////////////////
0549 template <typename BaseT>
0550 template <
0551     typename A, typename B, typename C, typename D, typename E,
0552     typename F, typename G, typename H, typename I, typename J,
0553     typename K, typename L, typename M, typename N>
0554 inline typename actor_result<BaseT,
0555     tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
0556 >::type
0557 actor<BaseT>::operator()(
0558     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
0559     K& k_, L& l_, M& m_, N& n_
0560 ) const
0561 {
0562     return BaseT::eval(
0563         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
0564         (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_)
0565     );
0566 }
0567 
0568 //////////////////////////////////
0569 template <typename BaseT>
0570 template <
0571     typename A, typename B, typename C, typename D, typename E,
0572     typename F, typename G, typename H, typename I, typename J,
0573     typename K, typename L, typename M, typename N, typename O>
0574 inline typename actor_result<BaseT,
0575     tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
0576 >::type
0577 actor<BaseT>::operator()(
0578     A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
0579     K& k_, L& l_, M& m_, N& n_, O& o_
0580 ) const
0581 {
0582     return BaseT::eval(
0583         tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
0584         (a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_)
0585     );
0586 }
0587 
0588 #endif
0589 #endif
0590 #endif
0591 #endif
0592 
0593 //////////////////////////////////
0594 template <typename BaseT>
0595 template <typename TupleT>
0596 typename actor_result<BaseT, unpack_tuple<TupleT> >::type
0597 actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const
0598 {
0599     return BaseT::eval(t);
0600 }
0601 
0602 ///////////////////////////////////////////////////////////////////////////////
0603 }   //  namespace phoenix
0604 
0605 #endif