1
/*=============================================================================
3
Copyright (c) 2001-2002 Joel de Guzman
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_STATEMENTS_HPP
9
#define PHOENIX_STATEMENTS_HPP
11
///////////////////////////////////////////////////////////////////////////////
12
#include <boost/spirit/home/classic/phoenix/composite.hpp>
14
///////////////////////////////////////////////////////////////////////////////
17
///////////////////////////////////////////////////////////////////////////////
19
// sequential_composite
21
// Two or more actors separated by the comma generates a
22
// sequential_composite which is a composite actor. Example:
28
// The actors are evaluated sequentially. The result type of this
29
// is void. Note that the last actor should not have a trailing
32
///////////////////////////////////////////////////////////////////////////////
33
template <typename A0, typename A1>
34
struct sequential_composite {
36
typedef sequential_composite<A0, A1> self_t;
38
template <typename TupleT>
39
struct result { typedef void type; };
41
sequential_composite(A0 const& _0, A1 const& _1)
44
template <typename TupleT>
46
eval(TupleT const& args) const
52
A0 a0; A1 a1; // actors
55
//////////////////////////////////
56
template <typename BaseT0, typename BaseT1>
57
inline actor<sequential_composite<actor<BaseT0>, actor<BaseT1> > >
58
operator,(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
60
return sequential_composite<actor<BaseT0>, actor<BaseT1> >(_0, _1);
63
///////////////////////////////////////////////////////////////////////////////
65
// if_then_else_composite
67
// This composite has two (2) forms:
85
// where condition is an actor that evaluates to bool. If condition
86
// is true, the true_statement (again an actor) is executed
87
// otherwise, the false_statement (another actor) is executed. The
88
// result type of this is void. Note the trailing underscore after
89
// if_ and the the leading dot and the trailing underscore before
92
///////////////////////////////////////////////////////////////////////////////
93
template <typename CondT, typename ThenT, typename ElseT>
94
struct if_then_else_composite {
96
typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
98
template <typename TupleT>
104
if_then_else_composite(
108
: cond(cond_), then(then_), else_(else__) {}
110
template <typename TupleT>
111
void eval(TupleT const& args) const
119
CondT cond; ThenT then; ElseT else_; // actors
122
//////////////////////////////////
123
template <typename CondT, typename ThenT>
126
else_gen(CondT const& cond_, ThenT const& then_)
127
: cond(cond_), then(then_) {}
129
template <typename ElseT>
130
actor<if_then_else_composite<CondT, ThenT,
131
typename as_actor<ElseT>::type> >
132
operator[](ElseT const& else_)
134
typedef if_then_else_composite<CondT, ThenT,
135
typename as_actor<ElseT>::type>
138
return result(cond, then, as_actor<ElseT>::convert(else_));
141
CondT cond; ThenT then;
144
//////////////////////////////////
145
template <typename CondT, typename ThenT>
146
struct if_then_composite {
148
typedef if_then_composite<CondT, ThenT> self_t;
150
template <typename TupleT>
151
struct result { typedef void type; };
153
if_then_composite(CondT const& cond_, ThenT const& then_)
154
: cond(cond_), then(then_), else_(cond, then) {}
156
template <typename TupleT>
157
void eval(TupleT const& args) const
163
CondT cond; ThenT then; // actors
164
else_gen<CondT, ThenT> else_;
167
//////////////////////////////////
168
template <typename CondT>
171
if_gen(CondT const& cond_)
174
template <typename ThenT>
175
actor<if_then_composite<
176
typename as_actor<CondT>::type,
177
typename as_actor<ThenT>::type> >
178
operator[](ThenT const& then) const
180
typedef if_then_composite<
181
typename as_actor<CondT>::type,
182
typename as_actor<ThenT>::type>
186
as_actor<CondT>::convert(cond),
187
as_actor<ThenT>::convert(then));
193
//////////////////////////////////
194
template <typename CondT>
196
if_(CondT const& cond)
198
return if_gen<CondT>(cond);
201
///////////////////////////////////////////////////////////////////////////////
205
// This composite has the form:
212
// While the condition (an actor) evaluates to true, statement
213
// (another actor) is executed. The result type of this is void.
214
// Note the trailing underscore after while_.
216
///////////////////////////////////////////////////////////////////////////////
217
template <typename CondT, typename DoT>
218
struct while_composite {
220
typedef while_composite<CondT, DoT> self_t;
222
template <typename TupleT>
223
struct result { typedef void type; };
225
while_composite(CondT const& cond_, DoT const& do__)
226
: cond(cond_), do_(do__) {}
228
template <typename TupleT>
229
void eval(TupleT const& args) const
231
while (cond.eval(args))
239
//////////////////////////////////
240
template <typename CondT>
243
while_gen(CondT const& cond_)
246
template <typename DoT>
247
actor<while_composite<
248
typename as_actor<CondT>::type,
249
typename as_actor<DoT>::type> >
250
operator[](DoT const& do_) const
252
typedef while_composite<
253
typename as_actor<CondT>::type,
254
typename as_actor<DoT>::type>
258
as_actor<CondT>::convert(cond),
259
as_actor<DoT>::convert(do_));
265
//////////////////////////////////
266
template <typename CondT>
267
inline while_gen<CondT>
268
while_(CondT const& cond)
270
return while_gen<CondT>(cond);
273
///////////////////////////////////////////////////////////////////////////////
277
// This composite has the form:
283
// .while_(condition)
285
// While the condition (an actor) evaluates to true, statement
286
// (another actor) is executed. The statement is executed at least
287
// once. The result type of this is void. Note the trailing
288
// underscore after do_ and the the leading dot and the trailing
289
// underscore before and after .while_.
291
///////////////////////////////////////////////////////////////////////////////
292
template <typename DoT, typename CondT>
293
struct do_composite {
295
typedef do_composite<DoT, CondT> self_t;
297
template <typename TupleT>
298
struct result { typedef void type; };
300
do_composite(DoT const& do__, CondT const& cond_)
301
: do_(do__), cond(cond_) {}
303
template <typename TupleT>
304
void eval(TupleT const& args) const
308
while (cond.eval(args));
315
////////////////////////////////////
316
template <typename DoT>
319
do_gen2(DoT const& do__)
322
template <typename CondT>
324
typename as_actor<DoT>::type,
325
typename as_actor<CondT>::type> >
326
while_(CondT const& cond) const
328
typedef do_composite<
329
typename as_actor<DoT>::type,
330
typename as_actor<CondT>::type>
334
as_actor<DoT>::convert(do_),
335
as_actor<CondT>::convert(cond));
341
////////////////////////////////////
344
template <typename DoT>
346
operator[](DoT const& do_) const
348
return do_gen2<DoT>(do_);
352
do_gen const do_ = do_gen();
354
///////////////////////////////////////////////////////////////////////////////
358
// This statement has the form:
360
// for_(init, condition, step)
365
// Where init, condition, step and statement are all actors. init
366
// is executed once before entering the for-loop. The for-loop
367
// exits once condition evaluates to false. At each loop iteration,
368
// step and statement is called. The result of this statement is
369
// void. Note the trailing underscore after for_.
371
///////////////////////////////////////////////////////////////////////////////
372
template <typename InitT, typename CondT, typename StepT, typename DoT>
373
struct for_composite {
375
typedef composite<InitT, CondT, StepT, DoT> self_t;
377
template <typename TupleT>
378
struct result { typedef void type; };
385
: init(init_), cond(cond_), step(step_), do_(do__) {}
387
template <typename TupleT>
389
eval(TupleT const& args) const
391
for (init.eval(args); cond.eval(args); step.eval(args))
395
InitT init; CondT cond; StepT step; DoT do_; // actors
398
//////////////////////////////////
399
template <typename InitT, typename CondT, typename StepT>
406
: init(init_), cond(cond_), step(step_) {}
408
template <typename DoT>
410
typename as_actor<InitT>::type,
411
typename as_actor<CondT>::type,
412
typename as_actor<StepT>::type,
413
typename as_actor<DoT>::type> >
414
operator[](DoT const& do_) const
416
typedef for_composite<
417
typename as_actor<InitT>::type,
418
typename as_actor<CondT>::type,
419
typename as_actor<StepT>::type,
420
typename as_actor<DoT>::type>
424
as_actor<InitT>::convert(init),
425
as_actor<CondT>::convert(cond),
426
as_actor<StepT>::convert(step),
427
as_actor<DoT>::convert(do_));
430
InitT init; CondT cond; StepT step;
433
//////////////////////////////////
434
template <typename InitT, typename CondT, typename StepT>
435
inline for_gen<InitT, CondT, StepT>
436
for_(InitT const& init, CondT const& cond, StepT const& step)
438
return for_gen<InitT, CondT, StepT>(init, cond, step);
441
} // namespace phoenix