Chris@16: /*============================================================================= Chris@16: Phoenix V1.2.1 Chris@16: Copyright (c) 2001-2002 Joel de Guzman Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #ifndef PHOENIX_STATEMENTS_HPP Chris@16: #define PHOENIX_STATEMENTS_HPP Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace phoenix { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // sequential_composite Chris@16: // Chris@16: // Two or more actors separated by the comma generates a Chris@16: // sequential_composite which is a composite actor. Example: Chris@16: // Chris@16: // actor, Chris@16: // actor, Chris@16: // actor Chris@16: // Chris@16: // The actors are evaluated sequentially. The result type of this Chris@16: // is void. Note that the last actor should not have a trailing Chris@16: // comma. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct sequential_composite { Chris@16: Chris@16: typedef sequential_composite self_t; Chris@16: Chris@16: template Chris@16: struct result { typedef void type; }; Chris@16: Chris@16: sequential_composite(A0 const& _0, A1 const& _1) Chris@16: : a0(_0), a1(_1) {} Chris@16: Chris@16: template Chris@16: void Chris@16: eval(TupleT const& args) const Chris@16: { Chris@16: a0.eval(args); Chris@16: a1.eval(args); Chris@16: } Chris@16: Chris@16: A0 a0; A1 a1; // actors Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline actor, actor > > Chris@16: operator,(actor const& _0, actor const& _1) Chris@16: { Chris@16: return sequential_composite, actor >(_0, _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // if_then_else_composite Chris@16: // Chris@16: // This composite has two (2) forms: Chris@16: // Chris@16: // if_(condition) Chris@16: // [ Chris@16: // statement Chris@16: // ] Chris@16: // Chris@16: // and Chris@16: // Chris@16: // if_(condition) Chris@16: // [ Chris@16: // true_statement Chris@16: // ] Chris@16: // .else_ Chris@16: // [ Chris@16: // false_statement Chris@16: // ] Chris@16: // Chris@16: // where condition is an actor that evaluates to bool. If condition Chris@16: // is true, the true_statement (again an actor) is executed Chris@16: // otherwise, the false_statement (another actor) is executed. The Chris@16: // result type of this is void. Note the trailing underscore after Chris@101: // if_ and the leading dot and the trailing underscore before Chris@16: // and after .else_. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct if_then_else_composite { Chris@16: Chris@16: typedef if_then_else_composite self_t; Chris@16: Chris@16: template Chris@16: struct result { Chris@16: Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: if_then_else_composite( Chris@16: CondT const& cond_, Chris@16: ThenT const& then_, Chris@16: ElseT const& else__) Chris@16: : cond(cond_), then(then_), else_(else__) {} Chris@16: Chris@16: template Chris@16: void eval(TupleT const& args) const Chris@16: { Chris@16: if (cond.eval(args)) Chris@16: then.eval(args); Chris@16: else Chris@16: else_.eval(args); Chris@16: } Chris@16: Chris@16: CondT cond; ThenT then; ElseT else_; // actors Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct else_gen { Chris@16: Chris@16: else_gen(CondT const& cond_, ThenT const& then_) Chris@16: : cond(cond_), then(then_) {} Chris@16: Chris@16: template Chris@16: actor::type> > Chris@16: operator[](ElseT const& else_) Chris@16: { Chris@16: typedef if_then_else_composite::type> Chris@16: result; Chris@16: Chris@16: return result(cond, then, as_actor::convert(else_)); Chris@16: } Chris@16: Chris@16: CondT cond; ThenT then; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct if_then_composite { Chris@16: Chris@16: typedef if_then_composite self_t; Chris@16: Chris@16: template Chris@16: struct result { typedef void type; }; Chris@16: Chris@16: if_then_composite(CondT const& cond_, ThenT const& then_) Chris@16: : cond(cond_), then(then_), else_(cond, then) {} Chris@16: Chris@16: template Chris@16: void eval(TupleT const& args) const Chris@16: { Chris@16: if (cond.eval(args)) Chris@16: then.eval(args); Chris@16: } Chris@16: Chris@16: CondT cond; ThenT then; // actors Chris@16: else_gen else_; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct if_gen { Chris@16: Chris@16: if_gen(CondT const& cond_) Chris@16: : cond(cond_) {} Chris@16: Chris@16: template Chris@16: actor::type, Chris@16: typename as_actor::type> > Chris@16: operator[](ThenT const& then) const Chris@16: { Chris@16: typedef if_then_composite< Chris@16: typename as_actor::type, Chris@16: typename as_actor::type> Chris@16: result; Chris@16: Chris@16: return result( Chris@16: as_actor::convert(cond), Chris@16: as_actor::convert(then)); Chris@16: } Chris@16: Chris@16: CondT cond; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline if_gen Chris@16: if_(CondT const& cond) Chris@16: { Chris@16: return if_gen(cond); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // while_composite Chris@16: // Chris@16: // This composite has the form: Chris@16: // Chris@16: // while_(condition) Chris@16: // [ Chris@16: // statement Chris@16: // ] Chris@16: // Chris@16: // While the condition (an actor) evaluates to true, statement Chris@16: // (another actor) is executed. The result type of this is void. Chris@16: // Note the trailing underscore after while_. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct while_composite { Chris@16: Chris@16: typedef while_composite self_t; Chris@16: Chris@16: template Chris@16: struct result { typedef void type; }; Chris@16: Chris@16: while_composite(CondT const& cond_, DoT const& do__) Chris@16: : cond(cond_), do_(do__) {} Chris@16: Chris@16: template Chris@16: void eval(TupleT const& args) const Chris@16: { Chris@16: while (cond.eval(args)) Chris@16: do_.eval(args); Chris@16: } Chris@16: Chris@16: CondT cond; Chris@16: DoT do_; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct while_gen { Chris@16: Chris@16: while_gen(CondT const& cond_) Chris@16: : cond(cond_) {} Chris@16: Chris@16: template Chris@16: actor::type, Chris@16: typename as_actor::type> > Chris@16: operator[](DoT const& do_) const Chris@16: { Chris@16: typedef while_composite< Chris@16: typename as_actor::type, Chris@16: typename as_actor::type> Chris@16: result; Chris@16: Chris@16: return result( Chris@16: as_actor::convert(cond), Chris@16: as_actor::convert(do_)); Chris@16: } Chris@16: Chris@16: CondT cond; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline while_gen Chris@16: while_(CondT const& cond) Chris@16: { Chris@16: return while_gen(cond); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // do_composite Chris@16: // Chris@16: // This composite has the form: Chris@16: // Chris@16: // do_ Chris@16: // [ Chris@16: // statement Chris@16: // ] Chris@16: // .while_(condition) Chris@16: // Chris@16: // While the condition (an actor) evaluates to true, statement Chris@16: // (another actor) is executed. The statement is executed at least Chris@16: // once. The result type of this is void. Note the trailing Chris@16: // underscore after do_ and the the leading dot and the trailing Chris@16: // underscore before and after .while_. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct do_composite { Chris@16: Chris@16: typedef do_composite self_t; Chris@16: Chris@16: template Chris@16: struct result { typedef void type; }; Chris@16: Chris@16: do_composite(DoT const& do__, CondT const& cond_) Chris@16: : do_(do__), cond(cond_) {} Chris@16: Chris@16: template Chris@16: void eval(TupleT const& args) const Chris@16: { Chris@16: do Chris@16: do_.eval(args); Chris@16: while (cond.eval(args)); Chris@16: } Chris@16: Chris@16: DoT do_; Chris@16: CondT cond; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////// Chris@16: template Chris@16: struct do_gen2 { Chris@16: Chris@16: do_gen2(DoT const& do__) Chris@16: : do_(do__) {} Chris@16: Chris@16: template Chris@16: actor::type, Chris@16: typename as_actor::type> > Chris@16: while_(CondT const& cond) const Chris@16: { Chris@16: typedef do_composite< Chris@16: typename as_actor::type, Chris@16: typename as_actor::type> Chris@16: result; Chris@16: Chris@16: return result( Chris@16: as_actor::convert(do_), Chris@16: as_actor::convert(cond)); Chris@16: } Chris@16: Chris@16: DoT do_; Chris@16: }; Chris@16: Chris@16: //////////////////////////////////// Chris@16: struct do_gen { Chris@16: Chris@16: template Chris@16: do_gen2 Chris@16: operator[](DoT const& do_) const Chris@16: { Chris@16: return do_gen2(do_); Chris@16: } Chris@16: }; Chris@16: Chris@16: do_gen const do_ = do_gen(); Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // for_composite Chris@16: // Chris@16: // This statement has the form: Chris@16: // Chris@16: // for_(init, condition, step) Chris@16: // [ Chris@16: // statement Chris@16: // ] Chris@16: // Chris@16: // Where init, condition, step and statement are all actors. init Chris@16: // is executed once before entering the for-loop. The for-loop Chris@16: // exits once condition evaluates to false. At each loop iteration, Chris@16: // step and statement is called. The result of this statement is Chris@16: // void. Note the trailing underscore after for_. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct for_composite { Chris@16: Chris@16: typedef composite self_t; Chris@16: Chris@16: template Chris@16: struct result { typedef void type; }; Chris@16: Chris@16: for_composite( Chris@16: InitT const& init_, Chris@16: CondT const& cond_, Chris@16: StepT const& step_, Chris@16: DoT const& do__) Chris@16: : init(init_), cond(cond_), step(step_), do_(do__) {} Chris@16: Chris@16: template Chris@16: void Chris@16: eval(TupleT const& args) const Chris@16: { Chris@16: for (init.eval(args); cond.eval(args); step.eval(args)) Chris@16: do_.eval(args); Chris@16: } Chris@16: Chris@16: InitT init; CondT cond; StepT step; DoT do_; // actors Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct for_gen { Chris@16: Chris@16: for_gen( Chris@16: InitT const& init_, Chris@16: CondT const& cond_, Chris@16: StepT const& step_) Chris@16: : init(init_), cond(cond_), step(step_) {} Chris@16: Chris@16: template Chris@16: actor::type, Chris@16: typename as_actor::type, Chris@16: typename as_actor::type, Chris@16: typename as_actor::type> > Chris@16: operator[](DoT const& do_) const Chris@16: { Chris@16: typedef for_composite< Chris@16: typename as_actor::type, Chris@16: typename as_actor::type, Chris@16: typename as_actor::type, Chris@16: typename as_actor::type> Chris@16: result; Chris@16: Chris@16: return result( Chris@16: as_actor::convert(init), Chris@16: as_actor::convert(cond), Chris@16: as_actor::convert(step), Chris@16: as_actor::convert(do_)); Chris@16: } Chris@16: Chris@16: InitT init; CondT cond; StepT step; Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline for_gen Chris@16: for_(InitT const& init, CondT const& cond, StepT const& step) Chris@16: { Chris@16: return for_gen(init, cond, step); Chris@16: } Chris@16: Chris@16: } // namespace phoenix Chris@16: Chris@16: #endif