source: NonGTP/Boost/boost/spirit/phoenix/primitives.hpp @ 857

Revision 857, 7.5 KB checked in by igarcia, 18 years ago (diff)
Line 
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///////////////////////////////////////////////////////////////////////////////
16namespace 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///////////////////////////////////////////////////////////////////////////////
50template <int N>
51struct 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//////////////////////////////////
65actor<argument<0> > const arg1 = argument<0>();
66actor<argument<1> > const arg2 = argument<1>();
67actor<argument<2> > const arg3 = argument<2>();
68
69#if PHOENIX_LIMIT > 3
70actor<argument<3> > const arg4 = argument<3>();
71actor<argument<4> > const arg5 = argument<4>();
72actor<argument<5> > const arg6 = argument<5>();
73
74#if PHOENIX_LIMIT > 6
75actor<argument<6> > const arg7 = argument<6>();
76actor<argument<7> > const arg8 = argument<7>();
77actor<argument<8> > const arg9 = argument<8>();
78
79#if PHOENIX_LIMIT > 9
80actor<argument<9> > const arg10 = argument<9>();
81actor<argument<10> > const arg11 = argument<10>();
82actor<argument<11> > const arg12 = argument<11>();
83
84#if PHOENIX_LIMIT > 12
85actor<argument<12> > const arg13 = argument<12>();
86actor<argument<13> > const arg14 = argument<13>();
87actor<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///////////////////////////////////////////////////////////////////////////////
114template <typename T>
115struct 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//////////////////////////////////
136template <typename T>
137inline actor<value<T> > const
138val(T v)
139{
140    return value<T>(v);
141}
142
143//////////////////////////////////
144template <typename BaseT>
145void
146val(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///////////////////////////////////////////////////////////////////////////
155template <typename T>
156struct as_actor {
157
158    typedef actor<value<T> > type;
159    static type convert(T const& x)
160    { return value<T>(x); }
161};
162
163//////////////////////////////////
164template <typename T, int N>
165struct 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///////////////////////////////////////////////////////////////////////////////
200template <typename T>
201struct 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//////////////////////////////////
220template <typename T>
221inline actor<variable<T> > const
222var(T& v)
223{
224    return variable<T>(v);
225}
226
227//////////////////////////////////
228template <typename T>
229inline actor<variable<T const> > const
230const_(T const& v)
231{
232    return variable<T const>(v);
233}
234
235//////////////////////////////////
236template <typename BaseT>
237void
238var(actor<BaseT> const& v);     //  This is undefined and not allowed.
239
240//////////////////////////////////
241template <typename BaseT>
242void
243const_(actor<BaseT> const& v);  //  This is undefined and not allowed.
244
245///////////////////////////////////////////////////////////////////////////////
246}   //  namespace phoenix
247
248#endif
Note: See TracBrowser for help on using the repository browser.