1
/*=============================================================================
3
Copyright (c) 2001-2002 Joel de Guzman
5
Permission to copy, use, modify, sell and distribute this software
6
is granted provided this copyright notice appears in all copies.
7
This software is provided "as is" without express or implied
8
warranty, and with no claim as to its suitability for any purpose.
9
==============================================================================*/
10
#ifndef PHOENIX_STATEMENTS_HPP
11
#define PHOENIX_STATEMENTS_HPP
13
///////////////////////////////////////////////////////////////////////////////
14
#include "boost/spirit/phoenix/composite.hpp"
16
///////////////////////////////////////////////////////////////////////////////
19
///////////////////////////////////////////////////////////////////////////////
21
// sequential_composite
23
// Two or more actors separated by the comma generates a
24
// sequential_composite which is a composite actor. Example:
30
// The actors are evaluated sequentially. The result type of this
31
// is void. Note that the last actor should not have a trailing
34
///////////////////////////////////////////////////////////////////////////////
35
template <typename A0, typename A1>
36
struct sequential_composite {
38
typedef sequential_composite<A0, A1> self_t;
40
template <typename TupleT>
41
struct result { typedef void type; };
43
sequential_composite(A0 const& _0, A1 const& _1)
46
template <typename TupleT>
48
eval(TupleT const& args) const
54
A0 a0; A1 a1; // actors
57
//////////////////////////////////
58
template <typename BaseT0, typename BaseT1>
59
inline actor<sequential_composite<actor<BaseT0>, actor<BaseT1> > >
60
operator,(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
62
return sequential_composite<actor<BaseT0>, actor<BaseT1> >(_0, _1);
65
///////////////////////////////////////////////////////////////////////////////
67
// if_then_else_composite
69
// This composite has two (2) forms:
87
// where condition is an actor that evaluates to bool. If condition
88
// is true, the true_statement (again an actor) is executed
89
// otherwise, the false_statement (another actor) is executed. The
90
// result type of this is void. Note the trailing underscore after
91
// if_ and the the leading dot and the trailing underscore before
94
///////////////////////////////////////////////////////////////////////////////
95
template <typename CondT, typename ThenT, typename ElseT>
96
struct if_then_else_composite {
98
typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
100
template <typename TupleT>
106
if_then_else_composite(
110
: cond(cond_), then(then_), else_(else__) {}
112
template <typename TupleT>
113
void eval(TupleT const& args) const
121
CondT cond; ThenT then; ElseT else_; // actors
124
//////////////////////////////////
125
template <typename CondT, typename ThenT>
128
else_gen(CondT const& cond_, ThenT const& then_)
129
: cond(cond_), then(then_) {}
131
template <typename ElseT>
132
actor<if_then_else_composite<CondT, ThenT,
133
typename as_actor<ElseT>::type> >
134
operator[](ElseT const& else_)
136
typedef if_then_else_composite<CondT, ThenT,
137
typename as_actor<ElseT>::type>
140
return result(cond, then, as_actor<ElseT>::convert(else_));
143
CondT cond; ThenT then;
146
//////////////////////////////////
147
template <typename CondT, typename ThenT>
148
struct if_then_composite {
150
typedef if_then_composite<CondT, ThenT> self_t;
152
template <typename TupleT>
153
struct result { typedef void type; };
155
if_then_composite(CondT const& cond_, ThenT const& then_)
156
: cond(cond_), then(then_), else_(cond, then) {}
158
template <typename TupleT>
159
void eval(TupleT const& args) const
165
CondT cond; ThenT then; // actors
166
else_gen<CondT, ThenT> else_;
169
//////////////////////////////////
170
template <typename CondT>
173
if_gen(CondT const& cond_)
176
template <typename ThenT>
177
actor<if_then_composite<
178
typename as_actor<CondT>::type,
179
typename as_actor<ThenT>::type> >
180
operator[](ThenT const& then) const
182
typedef if_then_composite<
183
typename as_actor<CondT>::type,
184
typename as_actor<ThenT>::type>
188
as_actor<CondT>::convert(cond),
189
as_actor<ThenT>::convert(then));
195
//////////////////////////////////
196
template <typename CondT>
198
if_(CondT const& cond)
200
return if_gen<CondT>(cond);
203
///////////////////////////////////////////////////////////////////////////////
207
// This composite has the form:
214
// While the condition (an actor) evaluates to true, statement
215
// (another actor) is executed. The result type of this is void.
216
// Note the trailing underscore after while_.
218
///////////////////////////////////////////////////////////////////////////////
219
template <typename CondT, typename DoT>
220
struct while_composite {
222
typedef while_composite<CondT, DoT> self_t;
224
template <typename TupleT>
225
struct result { typedef void type; };
227
while_composite(CondT const& cond_, DoT const& do__)
228
: cond(cond_), do_(do__) {}
230
template <typename TupleT>
231
void eval(TupleT const& args) const
233
while (cond.eval(args))
241
//////////////////////////////////
242
template <typename CondT>
245
while_gen(CondT const& cond_)
248
template <typename DoT>
249
actor<while_composite<
250
typename as_actor<CondT>::type,
251
typename as_actor<DoT>::type> >
252
operator[](DoT const& do_) const
254
typedef while_composite<
255
typename as_actor<CondT>::type,
256
typename as_actor<DoT>::type>
260
as_actor<CondT>::convert(cond),
261
as_actor<DoT>::convert(do_));
267
//////////////////////////////////
268
template <typename CondT>
269
inline while_gen<CondT>
270
while_(CondT const& cond)
272
return while_gen<CondT>(cond);
275
///////////////////////////////////////////////////////////////////////////////
279
// This composite has the form:
285
// .while_(condition)
287
// While the condition (an actor) evaluates to true, statement
288
// (another actor) is executed. The statement is executed at least
289
// once. The result type of this is void. Note the trailing
290
// underscore after do_ and the the leading dot and the trailing
291
// underscore before and after .while_.
293
///////////////////////////////////////////////////////////////////////////////
294
template <typename DoT, typename CondT>
295
struct do_composite {
297
typedef do_composite<DoT, CondT> self_t;
299
template <typename TupleT>
300
struct result { typedef void type; };
302
do_composite(DoT const& do__, CondT const& cond_)
303
: do_(do__), cond(cond_) {}
305
template <typename TupleT>
306
void eval(TupleT const& args) const
310
while (cond.eval(args));
317
////////////////////////////////////
318
template <typename DoT>
321
do_gen2(DoT const& do__)
324
template <typename CondT>
326
typename as_actor<DoT>::type,
327
typename as_actor<CondT>::type> >
328
while_(CondT const& cond) const
330
typedef do_composite<
331
typename as_actor<DoT>::type,
332
typename as_actor<CondT>::type>
336
as_actor<DoT>::convert(do_),
337
as_actor<CondT>::convert(cond));
343
////////////////////////////////////
346
template <typename DoT>
348
operator[](DoT const& do_) const
350
return do_gen2<DoT>(do_);
354
do_gen const do_ = do_gen();
356
///////////////////////////////////////////////////////////////////////////////
360
// This statement has the form:
362
// for_(init, condition, step)
367
// Where init, condition, step and statement are all actors. init
368
// is executed once before entering the for-loop. The for-loop
369
// exits once condition evaluates to false. At each loop iteration,
370
// step and statement is called. The result of this statement is
371
// void. Note the trailing underscore after for_.
373
///////////////////////////////////////////////////////////////////////////////
374
template <typename InitT, typename CondT, typename StepT, typename DoT>
375
struct for_composite {
377
typedef composite<InitT, CondT, StepT, DoT> self_t;
379
template <typename TupleT>
380
struct result { typedef void type; };
387
: init(init_), cond(cond_), step(step_), do_(do__) {}
389
template <typename TupleT>
391
eval(TupleT const& args) const
393
for (init.eval(args); cond.eval(args); step.eval(args))
397
InitT init; CondT cond; StepT step; DoT do_; // actors
400
//////////////////////////////////
401
template <typename InitT, typename CondT, typename StepT>
408
: init(init_), cond(cond_), step(step_) {}
410
template <typename DoT>
412
typename as_actor<InitT>::type,
413
typename as_actor<CondT>::type,
414
typename as_actor<StepT>::type,
415
typename as_actor<DoT>::type> >
416
operator[](DoT const& do_) const
418
typedef for_composite<
419
typename as_actor<InitT>::type,
420
typename as_actor<CondT>::type,
421
typename as_actor<StepT>::type,
422
typename as_actor<DoT>::type>
426
as_actor<InitT>::convert(init),
427
as_actor<CondT>::convert(cond),
428
as_actor<StepT>::convert(step),
429
as_actor<DoT>::convert(do_));
432
InitT init; CondT cond; StepT step;
435
//////////////////////////////////
436
template <typename InitT, typename CondT, typename StepT>
437
inline for_gen<InitT, CondT, StepT>
438
for_(InitT const& init, CondT const& cond, StepT const& step)
440
return for_gen<InitT, CondT, StepT>(init, cond, step);
443
} // namespace phoenix