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 ///////////////////////////////////////////////////////////////////////////////
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         tuple_index<N> const idx;
60         return args[idx];
61     }
62 };
63 
64 //////////////////////////////////
65 actor<argument<0> > const arg1 = argument<0>();
66 actor<argument<1> > const arg2 = argument<1>();
67 actor<argument<2> > const arg3 = argument<2>();
68 
69 #if PHOENIX_LIMIT > 3
70 actor<argument<3> > const arg4 = argument<3>();
71 actor<argument<4> > const arg5 = argument<4>();
72 actor<argument<5> > const arg6 = argument<5>();
73 
74 #if PHOENIX_LIMIT > 6
75 actor<argument<6> > const arg7 = argument<6>();
76 actor<argument<7> > const arg8 = argument<7>();
77 actor<argument<8> > const arg9 = argument<8>();
78 
79 #if PHOENIX_LIMIT > 9
80 actor<argument<9> > const arg10 = argument<9>();
81 actor<argument<10> > const arg11 = argument<10>();
82 actor<argument<11> > const arg12 = argument<11>();
83 
84 #if PHOENIX_LIMIT > 12
85 actor<argument<12> > const arg13 = argument<12>();
86 actor<argument<13> > const arg14 = argument<13>();
87 actor<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 ///////////////////////////////////////////////////////////////////////////////
114 template <typename T>
115 struct 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 
valuephoenix::value122     value(plain_t val_)
123     :   val(val_) {}
124 
125     template <typename TupleT>
126     plain_t const
evalphoenix::value127     eval(TupleT const& /*args*/) const
128     {
129         return val;
130     }
131 
132     plain_t val;
133 };
134 
135 //////////////////////////////////
136 template <typename T>
137 inline actor<value<T> > const
val(T v)138 val(T v)
139 {
140     return value<T>(v);
141 }
142 
143 //////////////////////////////////
144 template <typename BaseT>
145 void
146 val(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 ///////////////////////////////////////////////////////////////////////////
155 template <typename T>
156 struct as_actor {
157 
158     typedef actor<value<T> > type;
convertphoenix::as_actor159     static type convert(T const& x)
160     { return value<T>(x); }
161 };
162 
163 //////////////////////////////////
164 template <typename T, int N>
165 struct as_actor<T[N]> {
166 
167     typedef actor<value<T const*> > type;
convertphoenix::as_actor168     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 
205 template <typename T>
206 struct variable {
207 
208     template <typename TupleT>
209     struct result { typedef T& type; };
210 
variablephoenix::variable211     variable(T& var_)
212     :   var(var_) {}
213 
214     template <typename TupleT>
215     T&
evalphoenix::variable216     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 //////////////////////////////////
229 template <typename T>
230 inline actor<variable<T> > const
var(T & v)231 var(T& v)
232 {
233     return variable<T>(v);
234 }
235 
236 //////////////////////////////////
237 template <typename T>
238 inline actor<variable<T const> > const
const_(T const & v)239 const_(T const& v)
240 {
241     return variable<T const>(v);
242 }
243 
244 //////////////////////////////////
245 template <typename BaseT>
246 void
247 var(actor<BaseT> const& v);     //  This is undefined and not allowed.
248 
249 //////////////////////////////////
250 template <typename BaseT>
251 void
252 const_(actor<BaseT> const& v);  //  This is undefined and not allowed.
253 
254 ///////////////////////////////////////////////////////////////////////////////
255 }   //  namespace phoenix
256 
257 #endif
258