sl@0: // Boost Lambda Library -- loops.hpp ---------------------------------------- sl@0: sl@0: // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) sl@0: // Copyright (C) 2000 Gary Powell (powellg@amazon.com) sl@0: // Copyright (c) 2001-2002 Joel de Guzman sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: // sl@0: // For more information, see www.boost.org sl@0: sl@0: // -------------------------------------------------------------------------- sl@0: sl@0: #if !defined(BOOST_LAMBDA_LOOPS_HPP) sl@0: #define BOOST_LAMBDA_LOOPS_HPP sl@0: sl@0: #include "boost/lambda/core.hpp" sl@0: sl@0: namespace boost { sl@0: namespace lambda { sl@0: sl@0: // -- loop control structure actions ---------------------- sl@0: sl@0: class forloop_action {}; sl@0: class forloop_no_body_action {}; sl@0: class whileloop_action {}; sl@0: class whileloop_no_body_action {}; sl@0: class dowhileloop_action {}; sl@0: class dowhileloop_no_body_action {}; sl@0: sl@0: sl@0: // For loop sl@0: template sl@0: inline const sl@0: lambda_functor< sl@0: lambda_functor_base< sl@0: forloop_action, sl@0: tuple, lambda_functor, sl@0: lambda_functor, lambda_functor > sl@0: > sl@0: > sl@0: for_loop(const lambda_functor& a1, const lambda_functor& a2, sl@0: const lambda_functor& a3, const lambda_functor& a4) { sl@0: return sl@0: lambda_functor_base< sl@0: forloop_action, sl@0: tuple, lambda_functor, sl@0: lambda_functor, lambda_functor > sl@0: > sl@0: ( tuple, lambda_functor, sl@0: lambda_functor, lambda_functor >(a1, a2, a3, a4) sl@0: ); sl@0: } sl@0: sl@0: // No body case. sl@0: template sl@0: inline const sl@0: lambda_functor< sl@0: lambda_functor_base< sl@0: forloop_no_body_action, sl@0: tuple, lambda_functor, lambda_functor > sl@0: > sl@0: > sl@0: for_loop(const lambda_functor& a1, const lambda_functor& a2, sl@0: const lambda_functor& a3) { sl@0: return sl@0: lambda_functor_base< sl@0: forloop_no_body_action, sl@0: tuple, lambda_functor, sl@0: lambda_functor > sl@0: > sl@0: ( tuple, lambda_functor, sl@0: lambda_functor >(a1, a2, a3) ); sl@0: } sl@0: sl@0: // While loop sl@0: template sl@0: inline const sl@0: lambda_functor< sl@0: lambda_functor_base< sl@0: whileloop_action, sl@0: tuple, lambda_functor > sl@0: > sl@0: > sl@0: while_loop(const lambda_functor& a1, const lambda_functor& a2) { sl@0: return sl@0: lambda_functor_base< sl@0: whileloop_action, sl@0: tuple, lambda_functor > sl@0: > sl@0: ( tuple, lambda_functor >(a1, a2)); sl@0: } sl@0: sl@0: // No body case. sl@0: template sl@0: inline const sl@0: lambda_functor< sl@0: lambda_functor_base< sl@0: whileloop_no_body_action, sl@0: tuple > sl@0: > sl@0: > sl@0: while_loop(const lambda_functor& a1) { sl@0: return sl@0: lambda_functor_base< sl@0: whileloop_no_body_action, sl@0: tuple > sl@0: > sl@0: ( tuple >(a1) ); sl@0: } sl@0: sl@0: sl@0: // Do While loop sl@0: template sl@0: inline const sl@0: lambda_functor< sl@0: lambda_functor_base< sl@0: dowhileloop_action, sl@0: tuple, lambda_functor > sl@0: > sl@0: > sl@0: do_while_loop(const lambda_functor& a1, const lambda_functor& a2) { sl@0: return sl@0: lambda_functor_base< sl@0: dowhileloop_action, sl@0: tuple, lambda_functor > sl@0: > sl@0: ( tuple, lambda_functor >(a1, a2)); sl@0: } sl@0: sl@0: // No body case. sl@0: template sl@0: inline const sl@0: lambda_functor< sl@0: lambda_functor_base< sl@0: dowhileloop_no_body_action, sl@0: tuple > sl@0: > sl@0: > sl@0: do_while_loop(const lambda_functor& a1) { sl@0: return sl@0: lambda_functor_base< sl@0: dowhileloop_no_body_action, sl@0: tuple > sl@0: > sl@0: ( tuple >(a1)); sl@0: } sl@0: sl@0: sl@0: // Control loop lambda_functor_base specializations. sl@0: sl@0: // Specialization for for_loop. sl@0: template sl@0: class sl@0: lambda_functor_base { sl@0: public: sl@0: Args args; sl@0: template struct sig { typedef void type; }; sl@0: public: sl@0: explicit lambda_functor_base(const Args& a) : args(a) {} sl@0: sl@0: template sl@0: RET call(CALL_FORMAL_ARGS) const { sl@0: for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); sl@0: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); sl@0: detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) sl@0: sl@0: detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS); sl@0: } sl@0: }; sl@0: sl@0: // No body case sl@0: template sl@0: class sl@0: lambda_functor_base { sl@0: public: sl@0: Args args; sl@0: template struct sig { typedef void type; }; sl@0: public: sl@0: explicit lambda_functor_base(const Args& a) : args(a) {} sl@0: sl@0: template sl@0: RET call(CALL_FORMAL_ARGS) const { sl@0: for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); sl@0: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); sl@0: detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {} sl@0: } sl@0: }; sl@0: sl@0: sl@0: // Specialization for while_loop. sl@0: template sl@0: class sl@0: lambda_functor_base { sl@0: public: sl@0: Args args; sl@0: template struct sig { typedef void type; }; sl@0: public: sl@0: explicit lambda_functor_base(const Args& a) : args(a) {} sl@0: sl@0: template sl@0: RET call(CALL_FORMAL_ARGS) const { sl@0: while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) sl@0: sl@0: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); sl@0: } sl@0: }; sl@0: sl@0: // No body case sl@0: template sl@0: class sl@0: lambda_functor_base { sl@0: public: sl@0: Args args; sl@0: template struct sig { typedef void type; }; sl@0: public: sl@0: explicit lambda_functor_base(const Args& a) : args(a) {} sl@0: sl@0: template sl@0: RET call(CALL_FORMAL_ARGS) const { sl@0: while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {} sl@0: } sl@0: }; sl@0: sl@0: // Specialization for do_while_loop. sl@0: // Note that the first argument is the condition. sl@0: template sl@0: class sl@0: lambda_functor_base { sl@0: public: sl@0: Args args; sl@0: template struct sig { typedef void type; }; sl@0: public: sl@0: explicit lambda_functor_base(const Args& a) : args(a) {} sl@0: sl@0: template sl@0: RET call(CALL_FORMAL_ARGS) const { sl@0: do { sl@0: detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); sl@0: } while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ); sl@0: } sl@0: }; sl@0: sl@0: // No body case sl@0: template sl@0: class sl@0: lambda_functor_base { sl@0: public: sl@0: Args args; sl@0: template struct sig { typedef void type; }; sl@0: public: sl@0: explicit lambda_functor_base(const Args& a) : args(a) {} sl@0: sl@0: template sl@0: RET call(CALL_FORMAL_ARGS) const { sl@0: do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ); sl@0: } sl@0: }; sl@0: sl@0: // The code below is from Joel de Guzman, some name changes etc. sl@0: // has been made. sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // while_composite sl@0: // sl@0: // This composite has the form: sl@0: // sl@0: // while_(condition) sl@0: // [ sl@0: // statement sl@0: // ] sl@0: // sl@0: // While the condition (an lambda_functor) evaluates to true, statement sl@0: // (another lambda_functor) is executed. The result type of this is void. sl@0: // Note the trailing underscore after while_. sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: template sl@0: struct while_composite { sl@0: sl@0: typedef while_composite self_t; sl@0: sl@0: template sl@0: struct sig { typedef void type; }; sl@0: sl@0: while_composite(CondT const& cond_, DoT const& do__) sl@0: : cond(cond_), do_(do__) {} sl@0: sl@0: template sl@0: Ret call(CALL_FORMAL_ARGS) const sl@0: { sl@0: while (cond.internal_call(CALL_ACTUAL_ARGS)) sl@0: do_.internal_call(CALL_ACTUAL_ARGS); sl@0: } sl@0: sl@0: CondT cond; sl@0: DoT do_; sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: template sl@0: struct while_gen { sl@0: sl@0: while_gen(CondT const& cond_) sl@0: : cond(cond_) {} sl@0: sl@0: template sl@0: lambda_functor::type, sl@0: typename as_lambda_functor::type> > sl@0: operator[](DoT const& do_) const sl@0: { sl@0: typedef while_composite< sl@0: typename as_lambda_functor::type, sl@0: typename as_lambda_functor::type> sl@0: result; sl@0: sl@0: return result( sl@0: to_lambda_functor(cond), sl@0: to_lambda_functor(do_)); sl@0: } sl@0: sl@0: CondT cond; sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: template sl@0: inline while_gen sl@0: while_(CondT const& cond) sl@0: { sl@0: return while_gen(cond); sl@0: } sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // do_composite sl@0: // sl@0: // This composite has the form: sl@0: // sl@0: // do_ sl@0: // [ sl@0: // statement sl@0: // ] sl@0: // .while_(condition) sl@0: // sl@0: // While the condition (an lambda_functor) evaluates to true, statement sl@0: // (another lambda_functor) is executed. The statement is executed at least sl@0: // once. The result type of this is void. Note the trailing sl@0: // underscore after do_ and the the leading dot and the trailing sl@0: // underscore before and after .while_. sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: template sl@0: struct do_composite { sl@0: sl@0: typedef do_composite self_t; sl@0: sl@0: template sl@0: struct sig { typedef void type; }; sl@0: sl@0: do_composite(DoT const& do__, CondT const& cond_) sl@0: : do_(do__), cond(cond_) {} sl@0: sl@0: template sl@0: Ret call(CALL_FORMAL_ARGS) const sl@0: { sl@0: do sl@0: do_.internal_call(CALL_ACTUAL_ARGS); sl@0: while (cond.internal_call(CALL_ACTUAL_ARGS)); sl@0: } sl@0: sl@0: DoT do_; sl@0: CondT cond; sl@0: }; sl@0: sl@0: //////////////////////////////////// sl@0: template sl@0: struct do_gen2 { sl@0: sl@0: do_gen2(DoT const& do__) sl@0: : do_(do__) {} sl@0: sl@0: template sl@0: lambda_functor::type, sl@0: typename as_lambda_functor::type> > sl@0: while_(CondT const& cond) const sl@0: { sl@0: typedef do_composite< sl@0: typename as_lambda_functor::type, sl@0: typename as_lambda_functor::type> sl@0: result; sl@0: sl@0: return result( sl@0: to_lambda_functor(do_), sl@0: to_lambda_functor(cond)); sl@0: } sl@0: sl@0: DoT do_; sl@0: }; sl@0: sl@0: //////////////////////////////////// sl@0: struct do_gen { sl@0: sl@0: template sl@0: do_gen2 sl@0: operator[](DoT const& do_) const sl@0: { sl@0: return do_gen2(do_); sl@0: } sl@0: }; sl@0: sl@0: do_gen const do_ = do_gen(); sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // for_composite sl@0: // sl@0: // This statement has the form: sl@0: // sl@0: // for_(init, condition, step) sl@0: // [ sl@0: // statement sl@0: // ] sl@0: // sl@0: // Where init, condition, step and statement are all lambda_functors. init sl@0: // is executed once before entering the for-loop. The for-loop sl@0: // exits once condition evaluates to false. At each loop iteration, sl@0: // step and statement is called. The result of this statement is sl@0: // void. Note the trailing underscore after for_. sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: template sl@0: struct for_composite { sl@0: sl@0: template sl@0: struct sig { typedef void type; }; sl@0: sl@0: for_composite( sl@0: InitT const& init_, sl@0: CondT const& cond_, sl@0: StepT const& step_, sl@0: DoT const& do__) sl@0: : init(init_), cond(cond_), step(step_), do_(do__) {} sl@0: sl@0: template sl@0: Ret sl@0: call(CALL_FORMAL_ARGS) const sl@0: { sl@0: for (init.internal_call(CALL_ACTUAL_ARGS); cond.internal_call(CALL_ACTUAL_ARGS); step.internal_call(CALL_ACTUAL_ARGS)) sl@0: do_.internal_call(CALL_ACTUAL_ARGS); sl@0: } sl@0: sl@0: InitT init; CondT cond; StepT step; DoT do_; // lambda_functors sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: template sl@0: struct for_gen { sl@0: sl@0: for_gen( sl@0: InitT const& init_, sl@0: CondT const& cond_, sl@0: StepT const& step_) sl@0: : init(init_), cond(cond_), step(step_) {} sl@0: sl@0: template sl@0: lambda_functor::type, sl@0: typename as_lambda_functor::type, sl@0: typename as_lambda_functor::type, sl@0: typename as_lambda_functor::type> > sl@0: operator[](DoT const& do_) const sl@0: { sl@0: typedef for_composite< sl@0: typename as_lambda_functor::type, sl@0: typename as_lambda_functor::type, sl@0: typename as_lambda_functor::type, sl@0: typename as_lambda_functor::type> sl@0: result; sl@0: sl@0: return result( sl@0: to_lambda_functor(init), sl@0: to_lambda_functor(cond), sl@0: to_lambda_functor(step), sl@0: to_lambda_functor(do_)); sl@0: } sl@0: sl@0: InitT init; CondT cond; StepT step; sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: template sl@0: inline for_gen sl@0: for_(InitT const& init, CondT const& cond, StepT const& step) sl@0: { sl@0: return for_gen(init, cond, step); sl@0: } sl@0: sl@0: } // lambda sl@0: } // boost sl@0: sl@0: #endif // BOOST_LAMBDA_LOOPS_HPP