Chris@16: // Boost Lambda Library -- loops.hpp ---------------------------------------- Chris@16: Chris@16: // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) Chris@16: // Copyright (C) 2000 Gary Powell (powellg@amazon.com) Chris@16: // Copyright (c) 2001-2002 Joel de Guzman Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see www.boost.org Chris@16: Chris@16: // -------------------------------------------------------------------------- Chris@16: Chris@16: #if !defined(BOOST_LAMBDA_LOOPS_HPP) Chris@16: #define BOOST_LAMBDA_LOOPS_HPP Chris@16: Chris@16: #include "boost/lambda/core.hpp" Chris@16: Chris@16: namespace boost { Chris@16: namespace lambda { Chris@16: Chris@16: // -- loop control structure actions ---------------------- Chris@16: Chris@16: class forloop_action {}; Chris@16: class forloop_no_body_action {}; Chris@16: class whileloop_action {}; Chris@16: class whileloop_no_body_action {}; Chris@16: class dowhileloop_action {}; Chris@16: class dowhileloop_no_body_action {}; Chris@16: Chris@16: Chris@16: // For loop Chris@16: template Chris@16: inline const Chris@16: lambda_functor< Chris@16: lambda_functor_base< Chris@16: forloop_action, Chris@16: tuple, lambda_functor, Chris@16: lambda_functor, lambda_functor > Chris@16: > Chris@16: > Chris@16: for_loop(const lambda_functor& a1, const lambda_functor& a2, Chris@16: const lambda_functor& a3, const lambda_functor& a4) { Chris@16: return Chris@16: lambda_functor_base< Chris@16: forloop_action, Chris@16: tuple, lambda_functor, Chris@16: lambda_functor, lambda_functor > Chris@16: > Chris@16: ( tuple, lambda_functor, Chris@16: lambda_functor, lambda_functor >(a1, a2, a3, a4) Chris@16: ); Chris@16: } Chris@16: Chris@16: // No body case. Chris@16: template Chris@16: inline const Chris@16: lambda_functor< Chris@16: lambda_functor_base< Chris@16: forloop_no_body_action, Chris@16: tuple, lambda_functor, lambda_functor > Chris@16: > Chris@16: > Chris@16: for_loop(const lambda_functor& a1, const lambda_functor& a2, Chris@16: const lambda_functor& a3) { Chris@16: return Chris@16: lambda_functor_base< Chris@16: forloop_no_body_action, Chris@16: tuple, lambda_functor, Chris@16: lambda_functor > Chris@16: > Chris@16: ( tuple, lambda_functor, Chris@16: lambda_functor >(a1, a2, a3) ); Chris@16: } Chris@16: Chris@16: // While loop Chris@16: template Chris@16: inline const Chris@16: lambda_functor< Chris@16: lambda_functor_base< Chris@16: whileloop_action, Chris@16: tuple, lambda_functor > Chris@16: > Chris@16: > Chris@16: while_loop(const lambda_functor& a1, const lambda_functor& a2) { Chris@16: return Chris@16: lambda_functor_base< Chris@16: whileloop_action, Chris@16: tuple, lambda_functor > Chris@16: > Chris@16: ( tuple, lambda_functor >(a1, a2)); Chris@16: } Chris@16: Chris@16: // No body case. Chris@16: template Chris@16: inline const Chris@16: lambda_functor< Chris@16: lambda_functor_base< Chris@16: whileloop_no_body_action, Chris@16: tuple > Chris@16: > Chris@16: > Chris@16: while_loop(const lambda_functor& a1) { Chris@16: return Chris@16: lambda_functor_base< Chris@16: whileloop_no_body_action, Chris@16: tuple > Chris@16: > Chris@16: ( tuple >(a1) ); Chris@16: } Chris@16: Chris@16: Chris@16: // Do While loop Chris@16: template Chris@16: inline const Chris@16: lambda_functor< Chris@16: lambda_functor_base< Chris@16: dowhileloop_action, Chris@16: tuple, lambda_functor > Chris@16: > Chris@16: > Chris@16: do_while_loop(const lambda_functor& a1, const lambda_functor& a2) { Chris@16: return Chris@16: lambda_functor_base< Chris@16: dowhileloop_action, Chris@16: tuple, lambda_functor > Chris@16: > Chris@16: ( tuple, lambda_functor >(a1, a2)); Chris@16: } Chris@16: Chris@16: // No body case. Chris@16: template Chris@16: inline const Chris@16: lambda_functor< Chris@16: lambda_functor_base< Chris@16: dowhileloop_no_body_action, Chris@16: tuple > Chris@16: > Chris@16: > Chris@16: do_while_loop(const lambda_functor& a1) { Chris@16: return Chris@16: lambda_functor_base< Chris@16: dowhileloop_no_body_action, Chris@16: tuple > Chris@16: > Chris@16: ( tuple >(a1)); Chris@16: } Chris@16: Chris@16: Chris@16: // Control loop lambda_functor_base specializations. Chris@16: Chris@16: // Specialization for for_loop. Chris@16: template Chris@16: class Chris@16: lambda_functor_base { Chris@16: public: Chris@16: Args args; Chris@16: template struct sig { typedef void type; }; Chris@16: public: Chris@16: explicit lambda_functor_base(const Args& a) : args(a) {} Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { Chris@16: for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); Chris@16: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); Chris@16: detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) Chris@16: Chris@16: detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS); Chris@16: } Chris@16: }; Chris@16: Chris@16: // No body case Chris@16: template Chris@16: class Chris@16: lambda_functor_base { Chris@16: public: Chris@16: Args args; Chris@16: template struct sig { typedef void type; }; Chris@16: public: Chris@16: explicit lambda_functor_base(const Args& a) : args(a) {} Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { Chris@16: for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); Chris@16: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); Chris@16: detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {} Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: // Specialization for while_loop. Chris@16: template Chris@16: class Chris@16: lambda_functor_base { Chris@16: public: Chris@16: Args args; Chris@16: template struct sig { typedef void type; }; Chris@16: public: Chris@16: explicit lambda_functor_base(const Args& a) : args(a) {} Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { Chris@16: while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) Chris@16: Chris@16: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); Chris@16: } Chris@16: }; Chris@16: Chris@16: // No body case Chris@16: template Chris@16: class Chris@16: lambda_functor_base { Chris@16: public: Chris@16: Args args; Chris@16: template struct sig { typedef void type; }; Chris@16: public: Chris@16: explicit lambda_functor_base(const Args& a) : args(a) {} Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { Chris@16: while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {} Chris@16: } Chris@16: }; Chris@16: Chris@16: // Specialization for do_while_loop. Chris@16: // Note that the first argument is the condition. Chris@16: template Chris@16: class Chris@16: lambda_functor_base { Chris@16: public: Chris@16: Args args; Chris@16: template struct sig { typedef void type; }; Chris@16: public: Chris@16: explicit lambda_functor_base(const Args& a) : args(a) {} Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { Chris@16: do { Chris@16: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); Chris@16: } while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ); Chris@16: } Chris@16: }; Chris@16: Chris@16: // No body case Chris@16: template Chris@16: class Chris@16: lambda_functor_base { Chris@16: public: Chris@16: Args args; Chris@16: template struct sig { typedef void type; }; Chris@16: public: Chris@16: explicit lambda_functor_base(const Args& a) : args(a) {} Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { Chris@16: do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ); Chris@16: } Chris@16: }; Chris@16: Chris@16: // The code below is from Joel de Guzman, some name changes etc. Chris@16: // has been made. 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 lambda_functor) evaluates to true, statement Chris@16: // (another lambda_functor) 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 sig { 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: Ret call(CALL_FORMAL_ARGS) const Chris@16: { Chris@16: while (cond.internal_call(CALL_ACTUAL_ARGS)) Chris@16: do_.internal_call(CALL_ACTUAL_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: lambda_functor::type, Chris@16: typename as_lambda_functor::type> > Chris@16: operator[](DoT const& do_) const Chris@16: { Chris@16: typedef while_composite< Chris@16: typename as_lambda_functor::type, Chris@16: typename as_lambda_functor::type> Chris@16: result; Chris@16: Chris@16: return result( Chris@16: to_lambda_functor(cond), Chris@16: to_lambda_functor(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 lambda_functor) evaluates to true, statement Chris@16: // (another lambda_functor) 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 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 sig { 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: Ret call(CALL_FORMAL_ARGS) const Chris@16: { Chris@16: do Chris@16: do_.internal_call(CALL_ACTUAL_ARGS); Chris@16: while (cond.internal_call(CALL_ACTUAL_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: lambda_functor::type, Chris@16: typename as_lambda_functor::type> > Chris@16: while_(CondT const& cond) const Chris@16: { Chris@16: typedef do_composite< Chris@16: typename as_lambda_functor::type, Chris@16: typename as_lambda_functor::type> Chris@16: result; Chris@16: Chris@16: return result( Chris@16: to_lambda_functor(do_), Chris@16: to_lambda_functor(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 lambda_functors. 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: template Chris@16: struct sig { 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: Ret Chris@16: call(CALL_FORMAL_ARGS) const Chris@16: { Chris@16: for (init.internal_call(CALL_ACTUAL_ARGS); cond.internal_call(CALL_ACTUAL_ARGS); step.internal_call(CALL_ACTUAL_ARGS)) Chris@16: do_.internal_call(CALL_ACTUAL_ARGS); Chris@16: } Chris@16: Chris@16: InitT init; CondT cond; StepT step; DoT do_; // lambda_functors 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: lambda_functor::type, Chris@16: typename as_lambda_functor::type, Chris@16: typename as_lambda_functor::type, Chris@16: typename as_lambda_functor::type> > Chris@16: operator[](DoT const& do_) const Chris@16: { Chris@16: typedef for_composite< Chris@16: typename as_lambda_functor::type, Chris@16: typename as_lambda_functor::type, Chris@16: typename as_lambda_functor::type, Chris@16: typename as_lambda_functor::type> Chris@16: result; Chris@16: Chris@16: return result( Chris@16: to_lambda_functor(init), Chris@16: to_lambda_functor(cond), Chris@16: to_lambda_functor(step), Chris@16: to_lambda_functor(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: } // lambda Chris@16: } // boost Chris@16: Chris@16: #endif // BOOST_LAMBDA_LOOPS_HPP