Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/spirit/phoenix/example/fundamental/sample7.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 8.4 KB
Line 
1/*=============================================================================
2    Phoenix V1.2.1
3    Copyright (c) 2001-2003 Joel de Guzman
4
5    Use, modification and distribution is subject to the Boost Software
6    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7    http://www.boost.org/LICENSE_1_0.txt)
8==============================================================================*/
9#include <vector>
10#include <algorithm>
11#include <iostream>
12
13#define PHOENIX_LIMIT 5
14#include <boost/spirit/phoenix/operators.hpp>
15#include <boost/spirit/phoenix/primitives.hpp>
16#include <boost/spirit/phoenix/composite.hpp>
17#include <boost/spirit/phoenix/special_ops.hpp>
18#include <boost/spirit/phoenix/statements.hpp>
19
20namespace phoenix {
21
22///////////////////////////////////////////////////////////////////////////////
23//
24//  local_tuple
25//
26//      This *is a* tuple like the one we see in TupleT in any actor
27//      base class' eval member function. local_tuple should look and
28//      feel the same as a tupled-args, that's why it is derived from
29//      TupleArgsT. It has an added member, locs which is another tuple
30//      where the local variables will be stored. locs is mutable to
31//      allow read-write access to our locals regardless of
32//      local_tuple's constness (The eval member function accepts it as
33//      a const argument).
34//
35///////////////////////////////////////////////////////////////////////////////
36template <typename TupleArgsT, typename TupleLocsT>
37struct local_tuple : public TupleArgsT {
38
39    typedef TupleLocsT local_vars_t;
40
41    local_tuple(TupleArgsT const& args, TupleLocsT const& locs_)
42    :   TupleArgsT(args), locs(locs_) {}
43
44    mutable TupleLocsT locs;
45};
46
47///////////////////////////////////////////////////////////////////////////////
48//
49//  local_var_result
50//
51//      This is a return type computer. Given a constant integer N and a
52//      tuple, get the Nth local variable type. If TupleT is not really
53//      a local_tuple, we just return nil_t. Otherwise we get the Nth
54//      local variable type.
55//
56///////////////////////////////////////////////////////////////////////////////
57template <int N, typename TupleT>
58struct local_var_result {
59
60    typedef nil_t type;
61};
62
63//////////////////////////////////
64template <int N, typename TupleArgsT, typename TupleLocsT>
65struct local_var_result<N, local_tuple<TupleArgsT, TupleLocsT> > {
66
67    typedef typename tuple_element<N, TupleLocsT>::type& type;
68};
69
70///////////////////////////////////////////////////////////////////////////////
71//
72//  local_var
73//
74//      This class looks so curiously like the argument class. local_var
75//      provides access to the Nth local variable packed in the tuple
76//      duo local_tuple above. Note that the member function eval
77//      expects a local_tuple argument. Otherwise the expression
78//      'tuple.locs' will fail (compile-time error). local_var
79//      primitives only work within the context of a locals_composite
80//      (see below).
81//
82//      Provided are some predefined local_var actors for 0..N local
83//      variable access: loc1..locN.
84//
85///////////////////////////////////////////////////////////////////////////////
86template <int N>
87struct local_var {
88
89    template <typename TupleT>
90    struct result {
91
92        typedef typename local_var_result<N, TupleT>::type type;
93    };
94
95    template <typename TupleT>
96    typename local_var_result<N, TupleT>::type
97    eval(TupleT const& tuple) const
98    {
99        return tuple.locs[tuple_index<N>()];
100    }
101};
102
103//////////////////////////////////
104actor<local_var<0> > const loc1 = local_var<0>();
105actor<local_var<1> > const loc2 = local_var<1>();
106actor<local_var<2> > const loc3 = local_var<2>();
107actor<local_var<3> > const loc4 = local_var<3>();
108actor<local_var<4> > const loc5 = local_var<4>();
109
110///////////////////////////////////////////////////////////////////////////////
111//
112//  locals_composite
113//
114//      This class encapsulates an actor and some local variable
115//      initializers packed in a tuple.
116//
117//      locals_composite is just like a proxy and delegates the actual
118//      evaluation to the actor. The actor does the actual work. In the
119//      eval member function, before invoking the embedded actor's eval
120//      member function, we first stuff an instance of our locals and
121//      bundle both 'args' and 'locals' in a local_tuple. This
122//      local_tuple instance is created in the stack initializing it
123//      with our locals member. We then pass this local_tuple instance
124//      as an argument to the actor's eval member function.
125//
126///////////////////////////////////////////////////////////////////////////////
127template <typename ActorT, typename LocsT>
128struct locals_composite {
129
130    typedef locals_composite<ActorT, LocsT> self_t;
131
132    template <typename TupleT>
133    struct result { typedef typename actor_result<ActorT, TupleT>::type type; };
134
135    locals_composite(ActorT const& actor_, LocsT const& locals_)
136    :   actor(actor_), locals(locals_) {}
137
138    template <typename TupleT>
139    typename actor_result<ActorT, TupleT>::type
140    eval(TupleT const& args) const
141    {
142        actor.eval(local_tuple<TupleT, LocsT>(args, locals));
143    }
144
145    ActorT actor;
146    LocsT locals;
147};
148
149///////////////////////////////////////////////////////////////////////////////
150//
151//  locals_gen
152//
153//      At construction time, this class is given some local var-
154//      initializers packed in a tuple. We just store this for later.
155//      The operator[] of this class creates the actual locals_composite
156//      given an actor. This is responsible for the construct
157//      locals<types>[actor].
158//
159///////////////////////////////////////////////////////////////////////////////
160template <typename LocsT>
161struct locals_gen {
162
163    locals_gen(LocsT const& locals_)
164    :   locals(locals_) {}
165
166    template <typename ActorT>
167    actor<locals_composite<typename as_actor<ActorT>::type, LocsT> >
168    operator[](ActorT const& actor)
169    {
170        return locals_composite<typename as_actor<ActorT>::type, LocsT>
171            (as_actor<ActorT>::convert(actor), locals);
172    }
173
174    LocsT locals;
175};
176
177///////////////////////////////////////////////////////////////////////////////
178//
179//    Front end generator functions. These generators are overloaded for
180//    1..N local variables. locals<T0,... TN>(i0,...iN) generate locals_gen
181//    objects (see above).
182//
183///////////////////////////////////////////////////////////////////////////////
184template <typename T0>
185inline locals_gen<tuple<T0> >
186locals(
187    T0 const& _0 = T0()
188)
189{
190    typedef tuple<T0> tuple_t;
191    return locals_gen<tuple_t>(tuple_t(_0));
192}
193
194//////////////////////////////////
195template <typename T0, typename T1>
196inline locals_gen<tuple<T0, T1> >
197locals(
198    T0 const& _0 = T0(),
199    T1 const& _1 = T1()
200)
201{
202    typedef tuple<T0, T1> tuple_t;
203    return locals_gen<tuple_t>(tuple_t(_0, _1));
204}
205
206//////////////////////////////////
207template <typename T0, typename T1, typename T2>
208inline locals_gen<tuple<T0, T1, T2> >
209locals(
210    T0 const& _0 = T0(),
211    T1 const& _1 = T1(),
212    T2 const& _2 = T2()
213)
214{
215    typedef tuple<T0, T1, T2> tuple_t;
216    return locals_gen<tuple_t>(tuple_t(_0, _1, _2));
217}
218
219//////////////////////////////////
220template <typename T0, typename T1, typename T2, typename T3>
221inline locals_gen<tuple<T0, T1, T2, T3> >
222locals(
223    T0 const& _0 = T0(),
224    T1 const& _1 = T1(),
225    T2 const& _2 = T2(),
226    T3 const& _3 = T3()
227)
228{
229    typedef tuple<T0, T1, T2, T3> tuple_t;
230    return locals_gen<tuple_t>(tuple_t(_0, _1, _2, _3));
231}
232
233//////////////////////////////////
234template <typename T0, typename T1, typename T2, typename T3, typename T4>
235inline locals_gen<tuple<T0, T1, T2, T3, T4> >
236locals(
237    T0 const& _0 = T0(),
238    T1 const& _1 = T1(),
239    T2 const& _2 = T2(),
240    T3 const& _3 = T3(),
241    T4 const& _4 = T4()
242)
243{
244    typedef tuple<T0, T1, T2, T3> tuple_t;
245    return locals_gen<tuple_t>(tuple_t(_0, _1, _2, _3, _4));
246}
247
248///////////////////////////////////////////////////////////////////////////////
249}
250
251//////////////////////////////////
252using namespace std;
253using namespace phoenix;
254
255//////////////////////////////////
256int
257main()
258{
259    int init[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
260    vector<int> c(init, init + 10);
261    typedef vector<int>::iterator iterator;
262
263    for_each(c.begin(), c.end(),
264        locals<int, char const*>(0, "...That's all\n")
265        [
266            for_(loc1 = 0, loc1 < arg1, ++loc1)
267            [
268                cout << loc1 << ", "
269            ],
270            cout << loc2
271        ]
272    );
273
274    return 0;
275}
Note: See TracBrowser for help on using the repository browser.