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