First public contribution.
1 /*=============================================================================
3 Copyright (c) 2001-2002 Joel de Guzman
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 #ifndef PHOENIX_STATEMENTS_HPP
10 #define PHOENIX_STATEMENTS_HPP
12 ///////////////////////////////////////////////////////////////////////////////
13 #include <boost/spirit/phoenix/composite.hpp>
15 ///////////////////////////////////////////////////////////////////////////////
18 ///////////////////////////////////////////////////////////////////////////////
20 // sequential_composite
22 // Two or more actors separated by the comma generates a
23 // sequential_composite which is a composite actor. Example:
29 // The actors are evaluated sequentially. The result type of this
30 // is void. Note that the last actor should not have a trailing
33 ///////////////////////////////////////////////////////////////////////////////
34 template <typename A0, typename A1>
35 struct sequential_composite {
37 typedef sequential_composite<A0, A1> self_t;
39 template <typename TupleT>
40 struct result { typedef void type; };
42 sequential_composite(A0 const& _0, A1 const& _1)
45 template <typename TupleT>
47 eval(TupleT const& args) const
53 A0 a0; A1 a1; // actors
56 //////////////////////////////////
57 template <typename BaseT0, typename BaseT1>
58 inline actor<sequential_composite<actor<BaseT0>, actor<BaseT1> > >
59 operator,(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
61 return sequential_composite<actor<BaseT0>, actor<BaseT1> >(_0, _1);
64 ///////////////////////////////////////////////////////////////////////////////
66 // if_then_else_composite
68 // This composite has two (2) forms:
86 // where condition is an actor that evaluates to bool. If condition
87 // is true, the true_statement (again an actor) is executed
88 // otherwise, the false_statement (another actor) is executed. The
89 // result type of this is void. Note the trailing underscore after
90 // if_ and the the leading dot and the trailing underscore before
93 ///////////////////////////////////////////////////////////////////////////////
94 template <typename CondT, typename ThenT, typename ElseT>
95 struct if_then_else_composite {
97 typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
99 template <typename TupleT>
105 if_then_else_composite(
109 : cond(cond_), then(then_), else_(else__) {}
111 template <typename TupleT>
112 void eval(TupleT const& args) const
120 CondT cond; ThenT then; ElseT else_; // actors
123 //////////////////////////////////
124 template <typename CondT, typename ThenT>
127 else_gen(CondT const& cond_, ThenT const& then_)
128 : cond(cond_), then(then_) {}
130 template <typename ElseT>
131 actor<if_then_else_composite<CondT, ThenT,
132 typename as_actor<ElseT>::type> >
133 operator[](ElseT const& else_)
135 typedef if_then_else_composite<CondT, ThenT,
136 typename as_actor<ElseT>::type>
139 return result(cond, then, as_actor<ElseT>::convert(else_));
142 CondT cond; ThenT then;
145 //////////////////////////////////
146 template <typename CondT, typename ThenT>
147 struct if_then_composite {
149 typedef if_then_composite<CondT, ThenT> self_t;
151 template <typename TupleT>
152 struct result { typedef void type; };
154 if_then_composite(CondT const& cond_, ThenT const& then_)
155 : cond(cond_), then(then_), else_(cond, then) {}
157 template <typename TupleT>
158 void eval(TupleT const& args) const
164 CondT cond; ThenT then; // actors
165 else_gen<CondT, ThenT> else_;
168 //////////////////////////////////
169 template <typename CondT>
172 if_gen(CondT const& cond_)
175 template <typename ThenT>
176 actor<if_then_composite<
177 typename as_actor<CondT>::type,
178 typename as_actor<ThenT>::type> >
179 operator[](ThenT const& then) const
181 typedef if_then_composite<
182 typename as_actor<CondT>::type,
183 typename as_actor<ThenT>::type>
187 as_actor<CondT>::convert(cond),
188 as_actor<ThenT>::convert(then));
194 //////////////////////////////////
195 template <typename CondT>
197 if_(CondT const& cond)
199 return if_gen<CondT>(cond);
202 ///////////////////////////////////////////////////////////////////////////////
206 // This composite has the form:
213 // While the condition (an actor) evaluates to true, statement
214 // (another actor) is executed. The result type of this is void.
215 // Note the trailing underscore after while_.
217 ///////////////////////////////////////////////////////////////////////////////
218 template <typename CondT, typename DoT>
219 struct while_composite {
221 typedef while_composite<CondT, DoT> self_t;
223 template <typename TupleT>
224 struct result { typedef void type; };
226 while_composite(CondT const& cond_, DoT const& do__)
227 : cond(cond_), do_(do__) {}
229 template <typename TupleT>
230 void eval(TupleT const& args) const
232 while (cond.eval(args))
240 //////////////////////////////////
241 template <typename CondT>
244 while_gen(CondT const& cond_)
247 template <typename DoT>
248 actor<while_composite<
249 typename as_actor<CondT>::type,
250 typename as_actor<DoT>::type> >
251 operator[](DoT const& do_) const
253 typedef while_composite<
254 typename as_actor<CondT>::type,
255 typename as_actor<DoT>::type>
259 as_actor<CondT>::convert(cond),
260 as_actor<DoT>::convert(do_));
266 //////////////////////////////////
267 template <typename CondT>
268 inline while_gen<CondT>
269 while_(CondT const& cond)
271 return while_gen<CondT>(cond);
274 ///////////////////////////////////////////////////////////////////////////////
278 // This composite has the form:
284 // .while_(condition)
286 // While the condition (an actor) evaluates to true, statement
287 // (another actor) is executed. The statement is executed at least
288 // once. The result type of this is void. Note the trailing
289 // underscore after do_ and the the leading dot and the trailing
290 // underscore before and after .while_.
292 ///////////////////////////////////////////////////////////////////////////////
293 template <typename DoT, typename CondT>
294 struct do_composite {
296 typedef do_composite<DoT, CondT> self_t;
298 template <typename TupleT>
299 struct result { typedef void type; };
301 do_composite(DoT const& do__, CondT const& cond_)
302 : do_(do__), cond(cond_) {}
304 template <typename TupleT>
305 void eval(TupleT const& args) const
309 while (cond.eval(args));
316 ////////////////////////////////////
317 template <typename DoT>
320 do_gen2(DoT const& do__)
323 template <typename CondT>
325 typename as_actor<DoT>::type,
326 typename as_actor<CondT>::type> >
327 while_(CondT const& cond) const
329 typedef do_composite<
330 typename as_actor<DoT>::type,
331 typename as_actor<CondT>::type>
335 as_actor<DoT>::convert(do_),
336 as_actor<CondT>::convert(cond));
342 ////////////////////////////////////
345 template <typename DoT>
347 operator[](DoT const& do_) const
349 return do_gen2<DoT>(do_);
353 do_gen const do_ = do_gen();
355 ///////////////////////////////////////////////////////////////////////////////
359 // This statement has the form:
361 // for_(init, condition, step)
366 // Where init, condition, step and statement are all actors. init
367 // is executed once before entering the for-loop. The for-loop
368 // exits once condition evaluates to false. At each loop iteration,
369 // step and statement is called. The result of this statement is
370 // void. Note the trailing underscore after for_.
372 ///////////////////////////////////////////////////////////////////////////////
373 template <typename InitT, typename CondT, typename StepT, typename DoT>
374 struct for_composite {
376 typedef composite<InitT, CondT, StepT, DoT> self_t;
378 template <typename TupleT>
379 struct result { typedef void type; };
386 : init(init_), cond(cond_), step(step_), do_(do__) {}
388 template <typename TupleT>
390 eval(TupleT const& args) const
392 for (init.eval(args); cond.eval(args); step.eval(args))
396 InitT init; CondT cond; StepT step; DoT do_; // actors
399 //////////////////////////////////
400 template <typename InitT, typename CondT, typename StepT>
407 : init(init_), cond(cond_), step(step_) {}
409 template <typename DoT>
411 typename as_actor<InitT>::type,
412 typename as_actor<CondT>::type,
413 typename as_actor<StepT>::type,
414 typename as_actor<DoT>::type> >
415 operator[](DoT const& do_) const
417 typedef for_composite<
418 typename as_actor<InitT>::type,
419 typename as_actor<CondT>::type,
420 typename as_actor<StepT>::type,
421 typename as_actor<DoT>::type>
425 as_actor<InitT>::convert(init),
426 as_actor<CondT>::convert(cond),
427 as_actor<StepT>::convert(step),
428 as_actor<DoT>::convert(do_));
431 InitT init; CondT cond; StepT step;
434 //////////////////////////////////
435 template <typename InitT, typename CondT, typename StepT>
436 inline for_gen<InitT, CondT, StepT>
437 for_(InitT const& init, CondT const& cond, StepT const& step)
439 return for_gen<InitT, CondT, StepT>(init, cond, step);
442 } // namespace phoenix