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 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 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