1/*=============================================================================
2 Phoenix V1.2.1
3 Copyright (c) 2001-2002 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7==============================================================================*/
8#ifndef BOOST_SPIRIT_CLASSIC_PHOENIX_PRIMITIVES_HPP
9#define BOOST_SPIRIT_CLASSIC_PHOENIX_PRIMITIVES_HPP
10
11///////////////////////////////////////////////////////////////////////////////
12#include <boost/spirit/home/classic/phoenix/actor.hpp>
13
14///////////////////////////////////////////////////////////////////////////////
15namespace phoenix {
16
17///////////////////////////////////////////////////////////////////////////////
18//
19// argument class
20//
21// Lazy arguments
22//
23// An actor base class that extracts and returns the Nth argument
24// from the argument list passed in the 'args' tuple in the eval
25// member function (see actor.hpp). There are some predefined
26// argument constants that can be used as actors (arg1..argN).
27//
28// The argument actor is a place-holder for the actual arguments
29// passed by the client. For example, wherever arg1 is seen placed
30// in a lazy function (see functions.hpp) or lazy operator (see
31// operators.hpp), this will be replaced by the actual first
32// argument in the actual function evaluation. Argument actors are
33// essentially lazy arguments. A lazy argument is a full actor in
34// its own right and can be evaluated through the actor's operator().
35//
36// Example:
37//
38// char c = 'A';
39// int i = 123;
40// const char* s = "Hello World";
41//
42// cout << arg1(c) << ' ';
43// cout << arg1(i, s) << ' ';
44// cout << arg2(i, s) << ' ';
45//
46// will print out "A 123 Hello World"
47//
48///////////////////////////////////////////////////////////////////////////////
49template <int N>
50struct argument {
51
52 template <typename TupleT>
53 struct result { typedef typename tuple_element<N, TupleT>::type type; };
54
55 template <typename TupleT>
56 typename tuple_element<N, TupleT>::type
57 eval(TupleT const& args) const
58 {
59 tuple_index<N> const idx;
60 return args[idx];
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///////////////////////////////////////////////////////////////////////////////
200#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
201#pragma warning(push)
202#pragma warning(disable:4512) //assignment operator could not be generated
203#endif
204
205template <typename T>
206struct variable {
207
208 template <typename TupleT>
209 struct result { typedef T& type; };
210
211 variable(T& var_)
212 : var(var_) {}
213
214 template <typename TupleT>
215 T&
216 eval(TupleT const& /*args*/) const
217 {
218 return var;
219 }
220
221 T& var;
222};
223
224#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
225#pragma warning(pop)
226#endif
227
228//////////////////////////////////
229template <typename T>
230inline actor<variable<T> > const
231var(T& v)
232{
233 return variable<T>(v);
234}
235
236//////////////////////////////////
237template <typename T>
238inline actor<variable<T const> > const
239const_(T const& v)
240{
241 return variable<T const>(v);
242}
243
244//////////////////////////////////
245template <typename BaseT>
246void
247var(actor<BaseT> const& v); // This is undefined and not allowed.
248
249//////////////////////////////////
250template <typename BaseT>
251void
252const_(actor<BaseT> const& v); // This is undefined and not allowed.
253
254///////////////////////////////////////////////////////////////////////////////
255} // namespace phoenix
256
257#endif
258

source code of boost/libs/spirit/include/boost/spirit/home/classic/phoenix/primitives.hpp