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