| 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 looptemplate <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 looptemplate <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 looptemplate <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 casetemplate<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 casetemplate<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 casetemplate<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
 |