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 PHOENIX_PRIMITIVES_HPP
9 #define PHOENIX_PRIMITIVES_HPP
10 
11 ///////////////////////////////////////////////////////////////////////////////
12 #include <boost/spirit/home/classic/phoenix/actor.hpp>
13 
14 ///////////////////////////////////////////////////////////////////////////////
15 namespace 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 ///////////////////////////////////////////////////////////////////////////////
49 template <int N>
50 struct 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
evalphoenix::argument57     eval(TupleT const& args) const
58     {
59         return args[tuple_index<N>()];
60     }
61 };
62 
63 //////////////////////////////////
64 actor<argument<0> > const arg1 = argument<0>();
65 actor<argument<1> > const arg2 = argument<1>();
66 actor<argument<2> > const arg3 = argument<2>();
67 
68 #if PHOENIX_LIMIT > 3
69 actor<argument<3> > const arg4 = argument<3>();
70 actor<argument<4> > const arg5 = argument<4>();
71 actor<argument<5> > const arg6 = argument<5>();
72 
73 #if PHOENIX_LIMIT > 6
74 actor<argument<6> > const arg7 = argument<6>();
75 actor<argument<7> > const arg8 = argument<7>();
76 actor<argument<8> > const arg9 = argument<8>();
77 
78 #if PHOENIX_LIMIT > 9
79 actor<argument<9> > const arg10 = argument<9>();
80 actor<argument<10> > const arg11 = argument<10>();
81 actor<argument<11> > const arg12 = argument<11>();
82 
83 #if PHOENIX_LIMIT > 12
84 actor<argument<12> > const arg13 = argument<12>();
85 actor<argument<13> > const arg14 = argument<13>();
86 actor<argument<14> > const arg15 = argument<14>();
87 
88 #endif
89 #endif
90 #endif
91 #endif
92 ///////////////////////////////////////////////////////////////////////////////
93 //
94 //  value class
95 //
96 //      Lazy values
97 //
98 //      A bound actual parameter is kept in a value class for deferred
99 //      access later when needed. A value object is immutable. Value
100 //      objects are typically created through the val(x) free function
101 //      which returns a value<T> with T deduced from the type of x. x is
102 //      held in the value<T> object by value.
103 //
104 //      Lazy values are actors. As such, lazy values can be evaluated
105 //      through the actor's operator(). Such invocation gives the value's
106 //      identity. Example:
107 //
108 //          cout << val(3)() << val("Hello World")();
109 //
110 //      prints out "3 Hello World"
111 //
112 ///////////////////////////////////////////////////////////////////////////////
113 template <typename T>
114 struct value {
115 
116     typedef typename boost::remove_reference<T>::type plain_t;
117 
118     template <typename TupleT>
119     struct result { typedef plain_t const type; };
120 
valuephoenix::value121     value(plain_t val_)
122     :   val(val_) {}
123 
124     template <typename TupleT>
125     plain_t const
evalphoenix::value126     eval(TupleT const& /*args*/) const
127     {
128         return val;
129     }
130 
131     plain_t val;
132 };
133 
134 //////////////////////////////////
135 template <typename T>
136 inline actor<value<T> > const
val(T v)137 val(T v)
138 {
139     return value<T>(v);
140 }
141 
142 //////////////////////////////////
143 template <typename BaseT>
144 void
145 val(actor<BaseT> const& v);     //  This is undefined and not allowed.
146 
147 ///////////////////////////////////////////////////////////////////////////
148 //
149 //  Arbitrary types T are typically converted to a actor<value<T> >
150 //  (see as_actor<T> in actor.hpp). A specialization is also provided
151 //  for arrays. T[N] arrays are converted to actor<value<T const*> >.
152 //
153 ///////////////////////////////////////////////////////////////////////////
154 template <typename T>
155 struct as_actor {
156 
157     typedef actor<value<T> > type;
convertphoenix::as_actor158     static type convert(T const& x)
159     { return value<T>(x); }
160 };
161 
162 //////////////////////////////////
163 template <typename T, int N>
164 struct as_actor<T[N]> {
165 
166     typedef actor<value<T const*> > type;
convertphoenix::as_actor167     static type convert(T const x[N])
168     { return value<T const*>(x); }
169 };
170 
171 ///////////////////////////////////////////////////////////////////////////////
172 //
173 //  variable class
174 //
175 //      Lazy variables
176 //
177 //      A bound actual parameter may also be held by non-const reference
178 //      in a variable class for deferred access later when needed. A
179 //      variable object is mutable, i.e. its referenced variable can be
180 //      modified. Variable objects are typically created through the
181 //      var(x) free function which returns a variable<T> with T deduced
182 //      from the type of x. x is held in the value<T> object by
183 //      reference.
184 //
185 //      Lazy variables are actors. As such, lazy variables can be
186 //      evaluated through the actor's operator(). Such invocation gives
187 //      the variables's identity. Example:
188 //
189 //          int i = 3;
190 //          char const* s = "Hello World";
191 //          cout << var(i)() << var(s)();
192 //
193 //      prints out "3 Hello World"
194 //
195 //      Another free function const_(x) may also be used. const_(x) creates
196 //      a variable<T const&> object using a constant reference.
197 //
198 ///////////////////////////////////////////////////////////////////////////////
199 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
200 #pragma warning(push)
201 #pragma warning(disable:4512) //assignment operator could not be generated
202 #endif
203 
204 template <typename T>
205 struct variable {
206 
207     template <typename TupleT>
208     struct result { typedef T& type; };
209 
variablephoenix::variable210     variable(T& var_)
211     :   var(var_) {}
212 
213     template <typename TupleT>
214     T&
evalphoenix::variable215     eval(TupleT const& /*args*/) const
216     {
217         return var;
218     }
219 
220     T& var;
221 };
222 
223 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
224 #pragma warning(pop)
225 #endif
226 
227 //////////////////////////////////
228 template <typename T>
229 inline actor<variable<T> > const
var(T & v)230 var(T& v)
231 {
232     return variable<T>(v);
233 }
234 
235 //////////////////////////////////
236 template <typename T>
237 inline actor<variable<T const> > const
const_(T const & v)238 const_(T const& v)
239 {
240     return variable<T const>(v);
241 }
242 
243 //////////////////////////////////
244 template <typename BaseT>
245 void
246 var(actor<BaseT> const& v);     //  This is undefined and not allowed.
247 
248 //////////////////////////////////
249 template <typename BaseT>
250 void
251 const_(actor<BaseT> const& v);  //  This is undefined and not allowed.
252 
253 ///////////////////////////////////////////////////////////////////////////////
254 }   //  namespace phoenix
255 
256 #endif
257