os/ossrv/ossrv_pub/boost_apis/boost/spirit/phoenix/primitives.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*=============================================================================
     2     Phoenix V1.2.1
     3     Copyright (c) 2001-2002 Joel de Guzman
     4 
     5     Use, modification and distribution is subject to the Boost Software
     6     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7     http://www.boost.org/LICENSE_1_0.txt)
     8 ==============================================================================*/
     9 #ifndef PHOENIX_PRIMITIVES_HPP
    10 #define PHOENIX_PRIMITIVES_HPP
    11 
    12 ///////////////////////////////////////////////////////////////////////////////
    13 #include <boost/spirit/phoenix/actor.hpp>
    14 
    15 ///////////////////////////////////////////////////////////////////////////////
    16 namespace phoenix {
    17 
    18 ///////////////////////////////////////////////////////////////////////////////
    19 //
    20 //  argument class
    21 //
    22 //      Lazy arguments
    23 //
    24 //      An actor base class that extracts and returns the Nth argument
    25 //      from the argument list passed in the 'args' tuple in the eval
    26 //      member function (see actor.hpp). There are some predefined
    27 //      argument constants that can be used as actors (arg1..argN).
    28 //
    29 //      The argument actor is a place-holder for the actual arguments
    30 //      passed by the client. For example, wherever arg1 is seen placed
    31 //      in a lazy function (see functions.hpp) or lazy operator (see
    32 //      operators.hpp), this will be replaced by the actual first
    33 //      argument in the actual function evaluation. Argument actors are
    34 //      essentially lazy arguments. A lazy argument is a full actor in
    35 //      its own right and can be evaluated through the actor's operator().
    36 //
    37 //      Example:
    38 //
    39 //          char        c = 'A';
    40 //          int         i = 123;
    41 //          const char* s = "Hello World";
    42 //
    43 //          cout << arg1(c) << ' ';
    44 //          cout << arg1(i, s) << ' ';
    45 //          cout << arg2(i, s) << ' ';
    46 //
    47 //       will print out "A 123 Hello World"
    48 //
    49 ///////////////////////////////////////////////////////////////////////////////
    50 template <int N>
    51 struct argument {
    52 
    53     template <typename TupleT>
    54     struct result { typedef typename tuple_element<N, TupleT>::type type; };
    55 
    56     template <typename TupleT>
    57     typename tuple_element<N, TupleT>::type
    58     eval(TupleT const& args) const
    59     {
    60         return args[tuple_index<N>()];
    61     }
    62 };
    63 
    64 //////////////////////////////////
    65 actor<argument<0> > const arg1 = argument<0>();
    66 actor<argument<1> > const arg2 = argument<1>();
    67 actor<argument<2> > const arg3 = argument<2>();
    68 
    69 #if PHOENIX_LIMIT > 3
    70 actor<argument<3> > const arg4 = argument<3>();
    71 actor<argument<4> > const arg5 = argument<4>();
    72 actor<argument<5> > const arg6 = argument<5>();
    73 
    74 #if PHOENIX_LIMIT > 6
    75 actor<argument<6> > const arg7 = argument<6>();
    76 actor<argument<7> > const arg8 = argument<7>();
    77 actor<argument<8> > const arg9 = argument<8>();
    78 
    79 #if PHOENIX_LIMIT > 9
    80 actor<argument<9> > const arg10 = argument<9>();
    81 actor<argument<10> > const arg11 = argument<10>();
    82 actor<argument<11> > const arg12 = argument<11>();
    83 
    84 #if PHOENIX_LIMIT > 12
    85 actor<argument<12> > const arg13 = argument<12>();
    86 actor<argument<13> > const arg14 = argument<13>();
    87 actor<argument<14> > const arg15 = argument<14>();
    88 
    89 #endif
    90 #endif
    91 #endif
    92 #endif
    93 ///////////////////////////////////////////////////////////////////////////////
    94 //
    95 //  value class
    96 //
    97 //      Lazy values
    98 //
    99 //      A bound actual parameter is kept in a value class for deferred
   100 //      access later when needed. A value object is immutable. Value
   101 //      objects are typically created through the val(x) free function
   102 //      which returns a value<T> with T deduced from the type of x. x is
   103 //      held in the value<T> object by value.
   104 //
   105 //      Lazy values are actors. As such, lazy values can be evaluated
   106 //      through the actor's operator(). Such invocation gives the value's
   107 //      identity. Example:
   108 //
   109 //          cout << val(3)() << val("Hello World")();
   110 //
   111 //      prints out "3 Hello World"
   112 //
   113 ///////////////////////////////////////////////////////////////////////////////
   114 template <typename T>
   115 struct value {
   116 
   117     typedef typename boost::remove_reference<T>::type plain_t;
   118 
   119     template <typename TupleT>
   120     struct result { typedef plain_t const type; };
   121 
   122     value(plain_t val_)
   123     :   val(val_) {}
   124 
   125     template <typename TupleT>
   126     plain_t const
   127     eval(TupleT const& /*args*/) const
   128     {
   129         return val;
   130     }
   131 
   132     plain_t val;
   133 };
   134 
   135 //////////////////////////////////
   136 template <typename T>
   137 inline actor<value<T> > const
   138 val(T v)
   139 {
   140     return value<T>(v);
   141 }
   142 
   143 //////////////////////////////////
   144 template <typename BaseT>
   145 void
   146 val(actor<BaseT> const& v);     //  This is undefined and not allowed.
   147 
   148 ///////////////////////////////////////////////////////////////////////////
   149 //
   150 //  Arbitrary types T are typically converted to a actor<value<T> >
   151 //  (see as_actor<T> in actor.hpp). A specialization is also provided
   152 //  for arrays. T[N] arrays are converted to actor<value<T const*> >.
   153 //
   154 ///////////////////////////////////////////////////////////////////////////
   155 template <typename T>
   156 struct as_actor {
   157 
   158     typedef actor<value<T> > type;
   159     static type convert(T const& x)
   160     { return value<T>(x); }
   161 };
   162 
   163 //////////////////////////////////
   164 template <typename T, int N>
   165 struct as_actor<T[N]> {
   166 
   167     typedef actor<value<T const*> > type;
   168     static type convert(T const x[N])
   169     { return value<T const*>(x); }
   170 };
   171 
   172 ///////////////////////////////////////////////////////////////////////////////
   173 //
   174 //  variable class
   175 //
   176 //      Lazy variables
   177 //
   178 //      A bound actual parameter may also be held by non-const reference
   179 //      in a variable class for deferred access later when needed. A
   180 //      variable object is mutable, i.e. its referenced variable can be
   181 //      modified. Variable objects are typically created through the
   182 //      var(x) free function which returns a variable<T> with T deduced
   183 //      from the type of x. x is held in the value<T> object by
   184 //      reference.
   185 //
   186 //      Lazy variables are actors. As such, lazy variables can be
   187 //      evaluated through the actor's operator(). Such invocation gives
   188 //      the variables's identity. Example:
   189 //
   190 //          int i = 3;
   191 //          char const* s = "Hello World";
   192 //          cout << var(i)() << var(s)();
   193 //
   194 //      prints out "3 Hello World"
   195 //
   196 //      Another free function const_(x) may also be used. const_(x) creates
   197 //      a variable<T const&> object using a constant reference.
   198 //
   199 ///////////////////////////////////////////////////////////////////////////////
   200 template <typename T>
   201 struct variable {
   202 
   203     template <typename TupleT>
   204     struct result { typedef T& type; };
   205 
   206     variable(T& var_)
   207     :   var(var_) {}
   208 
   209     template <typename TupleT>
   210     T&
   211     eval(TupleT const& /*args*/) const
   212     {
   213         return var;
   214     }
   215 
   216     T& var;
   217 };
   218 
   219 //////////////////////////////////
   220 template <typename T>
   221 inline actor<variable<T> > const
   222 var(T& v)
   223 {
   224     return variable<T>(v);
   225 }
   226 
   227 //////////////////////////////////
   228 template <typename T>
   229 inline actor<variable<T const> > const
   230 const_(T const& v)
   231 {
   232     return variable<T const>(v);
   233 }
   234 
   235 //////////////////////////////////
   236 template <typename BaseT>
   237 void
   238 var(actor<BaseT> const& v);     //  This is undefined and not allowed.
   239 
   240 //////////////////////////////////
   241 template <typename BaseT>
   242 void
   243 const_(actor<BaseT> const& v);  //  This is undefined and not allowed.
   244 
   245 ///////////////////////////////////////////////////////////////////////////////
   246 }   //  namespace phoenix
   247 
   248 #endif