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