ossrv_pub/boost_apis/boost/lambda/loops.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Boost Lambda Library -- loops.hpp ----------------------------------------
       
     2 
       
     3 // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
       
     4 // Copyright (C) 2000 Gary Powell (powellg@amazon.com)
       
     5 // Copyright (c) 2001-2002 Joel de Guzman
       
     6 //
       
     7 // Distributed under the Boost Software License, Version 1.0. (See
       
     8 // accompanying file LICENSE_1_0.txt or copy at
       
     9 // http://www.boost.org/LICENSE_1_0.txt)
       
    10 //
       
    11 // For more information, see www.boost.org
       
    12 
       
    13 // --------------------------------------------------------------------------
       
    14 
       
    15 #if !defined(BOOST_LAMBDA_LOOPS_HPP)
       
    16 #define BOOST_LAMBDA_LOOPS_HPP
       
    17 
       
    18 #include "boost/lambda/core.hpp"
       
    19 
       
    20 namespace boost { 
       
    21 namespace lambda {
       
    22 
       
    23 // -- loop control structure actions ----------------------
       
    24 
       
    25 class forloop_action {};
       
    26 class forloop_no_body_action {};
       
    27 class whileloop_action {};
       
    28 class whileloop_no_body_action {};
       
    29 class dowhileloop_action {};
       
    30 class dowhileloop_no_body_action {};
       
    31 
       
    32 
       
    33 // For loop
       
    34 template <class Arg1, class Arg2, class Arg3, class Arg4>
       
    35 inline const 
       
    36 lambda_functor<
       
    37   lambda_functor_base<
       
    38     forloop_action, 
       
    39     tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, 
       
    40           lambda_functor<Arg3>, lambda_functor<Arg4> >
       
    41   > 
       
    42 >
       
    43 for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2, 
       
    44          const lambda_functor<Arg3>& a3, const lambda_functor<Arg4>& a4) { 
       
    45   return 
       
    46       lambda_functor_base<
       
    47         forloop_action, 
       
    48         tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, 
       
    49               lambda_functor<Arg3>, lambda_functor<Arg4> >
       
    50       > 
       
    51     ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, 
       
    52             lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
       
    53     );
       
    54 }
       
    55 
       
    56 // No body case.
       
    57 template <class Arg1, class Arg2, class Arg3>
       
    58 inline const 
       
    59 lambda_functor<
       
    60   lambda_functor_base<
       
    61     forloop_no_body_action, 
       
    62     tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
       
    63   > 
       
    64 >
       
    65 for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2, 
       
    66          const lambda_functor<Arg3>& a3) { 
       
    67   return 
       
    68       lambda_functor_base<
       
    69         forloop_no_body_action, 
       
    70         tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, 
       
    71               lambda_functor<Arg3> >
       
    72       > 
       
    73       ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, 
       
    74                lambda_functor<Arg3> >(a1, a2, a3) );
       
    75 }
       
    76 
       
    77 // While loop
       
    78 template <class Arg1, class Arg2>
       
    79 inline const 
       
    80 lambda_functor<
       
    81   lambda_functor_base<
       
    82     whileloop_action, 
       
    83     tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
       
    84   > 
       
    85 >
       
    86 while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) { 
       
    87   return 
       
    88       lambda_functor_base<
       
    89         whileloop_action, 
       
    90         tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
       
    91       > 
       
    92       ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
       
    93 }
       
    94 
       
    95 // No body case.
       
    96 template <class Arg1>
       
    97 inline const 
       
    98 lambda_functor<
       
    99   lambda_functor_base<
       
   100     whileloop_no_body_action, 
       
   101     tuple<lambda_functor<Arg1> >
       
   102   > 
       
   103 >
       
   104 while_loop(const lambda_functor<Arg1>& a1) { 
       
   105   return 
       
   106       lambda_functor_base<
       
   107         whileloop_no_body_action, 
       
   108         tuple<lambda_functor<Arg1> >
       
   109       > 
       
   110       ( tuple<lambda_functor<Arg1> >(a1) );
       
   111 }
       
   112 
       
   113 
       
   114 // Do While loop
       
   115 template <class Arg1, class Arg2>
       
   116 inline const 
       
   117 lambda_functor<
       
   118   lambda_functor_base<
       
   119     dowhileloop_action, 
       
   120     tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
       
   121   > 
       
   122 >
       
   123 do_while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
       
   124   return 
       
   125       lambda_functor_base<
       
   126         dowhileloop_action, 
       
   127         tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
       
   128       > 
       
   129       ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
       
   130 }
       
   131 
       
   132 // No body case.
       
   133 template <class Arg1>
       
   134 inline const 
       
   135 lambda_functor<
       
   136   lambda_functor_base<
       
   137     dowhileloop_no_body_action, 
       
   138     tuple<lambda_functor<Arg1> >
       
   139   > 
       
   140 >
       
   141 do_while_loop(const lambda_functor<Arg1>& a1) { 
       
   142   return 
       
   143       lambda_functor_base<
       
   144         dowhileloop_no_body_action, 
       
   145         tuple<lambda_functor<Arg1> >
       
   146       > 
       
   147       ( tuple<lambda_functor<Arg1> >(a1));
       
   148 }
       
   149 
       
   150 
       
   151 // Control loop lambda_functor_base specializations.
       
   152 
       
   153 // Specialization for for_loop.
       
   154 template<class Args>
       
   155 class 
       
   156 lambda_functor_base<forloop_action, Args> {
       
   157 public:
       
   158   Args args;
       
   159   template <class T> struct sig { typedef void type; };
       
   160 public:
       
   161   explicit lambda_functor_base(const Args& a) : args(a) {}
       
   162 
       
   163   template<class RET, CALL_TEMPLATE_ARGS>
       
   164   RET call(CALL_FORMAL_ARGS) const {
       
   165     for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); 
       
   166         detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); 
       
   167         detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS))
       
   168       
       
   169       detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS);
       
   170   }
       
   171 };
       
   172 
       
   173 // No body case
       
   174 template<class Args>
       
   175 class 
       
   176 lambda_functor_base<forloop_no_body_action, Args> {
       
   177 public:
       
   178   Args args;
       
   179   template <class T> struct sig { typedef void type; };
       
   180 public:
       
   181   explicit lambda_functor_base(const Args& a) : args(a) {}
       
   182 
       
   183   template<class RET, CALL_TEMPLATE_ARGS>
       
   184   RET call(CALL_FORMAL_ARGS) const {
       
   185     for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); 
       
   186         detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); 
       
   187         detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {}
       
   188    }
       
   189 };
       
   190 
       
   191 
       
   192 // Specialization for while_loop.
       
   193 template<class Args>
       
   194 class 
       
   195 lambda_functor_base<whileloop_action, Args> {
       
   196 public:
       
   197   Args args;
       
   198   template <class T> struct sig { typedef void type; };
       
   199 public:
       
   200   explicit lambda_functor_base(const Args& a) : args(a) {}
       
   201 
       
   202   template<class RET, CALL_TEMPLATE_ARGS>
       
   203   RET call(CALL_FORMAL_ARGS) const {
       
   204     while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
       
   205       
       
   206       detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
       
   207   }
       
   208 };
       
   209 
       
   210 // No body case
       
   211 template<class Args> 
       
   212 class 
       
   213 lambda_functor_base<whileloop_no_body_action, Args> {
       
   214 public:
       
   215   Args args;
       
   216   template <class T> struct sig { typedef void type; };
       
   217 public:
       
   218   explicit lambda_functor_base(const Args& a) : args(a) {}
       
   219 
       
   220   template<class RET, CALL_TEMPLATE_ARGS>
       
   221   RET call(CALL_FORMAL_ARGS) const {
       
   222           while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {}
       
   223   }
       
   224 };
       
   225 
       
   226 // Specialization for do_while_loop.
       
   227 // Note that the first argument is the condition.
       
   228 template<class Args>
       
   229 class 
       
   230 lambda_functor_base<dowhileloop_action, Args> {
       
   231 public:
       
   232   Args args;
       
   233   template <class T> struct sig { typedef void type; };
       
   234 public:
       
   235   explicit lambda_functor_base(const Args& a) : args(a) {}
       
   236 
       
   237   template<class RET, CALL_TEMPLATE_ARGS>
       
   238   RET call(CALL_FORMAL_ARGS) const {
       
   239     do {
       
   240       detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);      
       
   241     } while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
       
   242   }
       
   243 };
       
   244 
       
   245 // No body case
       
   246 template<class Args>
       
   247 class 
       
   248 lambda_functor_base<dowhileloop_no_body_action, Args> {
       
   249 public:
       
   250   Args args;
       
   251   template <class T> struct sig { typedef void type; };
       
   252 public:
       
   253   explicit lambda_functor_base(const Args& a) : args(a) {}
       
   254 
       
   255   template<class RET, CALL_TEMPLATE_ARGS>
       
   256   RET call(CALL_FORMAL_ARGS) const {
       
   257           do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
       
   258   }
       
   259 };
       
   260 
       
   261   // The code below is from Joel de Guzman, some name changes etc. 
       
   262   // has been made.
       
   263 
       
   264 ///////////////////////////////////////////////////////////////////////////////
       
   265 //
       
   266 //  while_composite
       
   267 //
       
   268 //      This composite has the form:
       
   269 //
       
   270 //          while_(condition)
       
   271 //          [
       
   272 //              statement
       
   273 //          ]
       
   274 //
       
   275 //      While the condition (an lambda_functor) evaluates to true, statement
       
   276 //      (another lambda_functor) is executed. The result type of this is void.
       
   277 //      Note the trailing underscore after while_.
       
   278 //
       
   279 ///////////////////////////////////////////////////////////////////////////////
       
   280 template <typename CondT, typename DoT>
       
   281 struct while_composite {
       
   282 
       
   283     typedef while_composite<CondT, DoT> self_t;
       
   284 
       
   285     template <class SigArgs>
       
   286     struct sig { typedef void type; };
       
   287 
       
   288     while_composite(CondT const& cond_, DoT const& do__)
       
   289     :   cond(cond_), do_(do__) {}
       
   290 
       
   291     template <class Ret, CALL_TEMPLATE_ARGS>
       
   292     Ret call(CALL_FORMAL_ARGS) const
       
   293     {
       
   294         while (cond.internal_call(CALL_ACTUAL_ARGS))
       
   295             do_.internal_call(CALL_ACTUAL_ARGS);
       
   296     }
       
   297 
       
   298     CondT cond;
       
   299     DoT do_;
       
   300 };
       
   301 
       
   302 //////////////////////////////////
       
   303 template <typename CondT>
       
   304 struct while_gen {
       
   305 
       
   306     while_gen(CondT const& cond_)
       
   307     :   cond(cond_) {}
       
   308 
       
   309     template <typename DoT>
       
   310     lambda_functor<while_composite<
       
   311         typename as_lambda_functor<CondT>::type,
       
   312         typename as_lambda_functor<DoT>::type> >
       
   313     operator[](DoT const& do_) const
       
   314     {
       
   315         typedef while_composite<
       
   316             typename as_lambda_functor<CondT>::type,
       
   317             typename as_lambda_functor<DoT>::type>
       
   318         result;
       
   319 
       
   320         return result(
       
   321             to_lambda_functor(cond),
       
   322             to_lambda_functor(do_));
       
   323     }
       
   324 
       
   325     CondT cond;
       
   326 };
       
   327 
       
   328 //////////////////////////////////
       
   329 template <typename CondT>
       
   330 inline while_gen<CondT>
       
   331 while_(CondT const& cond)
       
   332 {
       
   333     return while_gen<CondT>(cond);
       
   334 }
       
   335 
       
   336 ///////////////////////////////////////////////////////////////////////////////
       
   337 //
       
   338 //  do_composite
       
   339 //
       
   340 //      This composite has the form:
       
   341 //
       
   342 //          do_
       
   343 //          [
       
   344 //              statement
       
   345 //          ]
       
   346 //          .while_(condition)
       
   347 //
       
   348 //      While the condition (an lambda_functor) evaluates to true, statement
       
   349 //      (another lambda_functor) is executed. The statement is executed at least
       
   350 //      once. The result type of this is void. Note the trailing
       
   351 //      underscore after do_ and the the leading dot and the trailing
       
   352 //      underscore before and after .while_.
       
   353 //
       
   354 ///////////////////////////////////////////////////////////////////////////////
       
   355 template <typename DoT, typename CondT>
       
   356 struct do_composite {
       
   357 
       
   358     typedef do_composite<DoT, CondT> self_t;
       
   359 
       
   360     template <class SigArgs>
       
   361     struct sig { typedef void type; };
       
   362 
       
   363     do_composite(DoT const& do__, CondT const& cond_)
       
   364     :   do_(do__), cond(cond_) {}
       
   365 
       
   366     template <class Ret, CALL_TEMPLATE_ARGS>
       
   367     Ret call(CALL_FORMAL_ARGS) const
       
   368     {
       
   369         do
       
   370             do_.internal_call(CALL_ACTUAL_ARGS);
       
   371         while (cond.internal_call(CALL_ACTUAL_ARGS));
       
   372     }
       
   373 
       
   374     DoT do_;
       
   375     CondT cond;
       
   376 };
       
   377 
       
   378 ////////////////////////////////////
       
   379 template <typename DoT>
       
   380 struct do_gen2 {
       
   381 
       
   382     do_gen2(DoT const& do__)
       
   383     :   do_(do__) {}
       
   384 
       
   385     template <typename CondT>
       
   386     lambda_functor<do_composite<
       
   387         typename as_lambda_functor<DoT>::type,
       
   388         typename as_lambda_functor<CondT>::type> >
       
   389     while_(CondT const& cond) const
       
   390     {
       
   391         typedef do_composite<
       
   392             typename as_lambda_functor<DoT>::type,
       
   393             typename as_lambda_functor<CondT>::type>
       
   394         result;
       
   395 
       
   396         return result(
       
   397             to_lambda_functor(do_),
       
   398             to_lambda_functor(cond));
       
   399     }
       
   400 
       
   401     DoT do_;
       
   402 };
       
   403 
       
   404 ////////////////////////////////////
       
   405 struct do_gen {
       
   406 
       
   407     template <typename DoT>
       
   408     do_gen2<DoT>
       
   409     operator[](DoT const& do_) const
       
   410     {
       
   411         return do_gen2<DoT>(do_);
       
   412     }
       
   413 };
       
   414 
       
   415 do_gen const do_ = do_gen();
       
   416 
       
   417 ///////////////////////////////////////////////////////////////////////////////
       
   418 //
       
   419 //  for_composite
       
   420 //
       
   421 //      This statement has the form:
       
   422 //
       
   423 //          for_(init, condition, step)
       
   424 //          [
       
   425 //              statement
       
   426 //          ]
       
   427 //
       
   428 //      Where init, condition, step and statement are all lambda_functors. init
       
   429 //      is executed once before entering the for-loop. The for-loop
       
   430 //      exits once condition evaluates to false. At each loop iteration,
       
   431 //      step and statement is called. The result of this statement is
       
   432 //      void. Note the trailing underscore after for_.
       
   433 //
       
   434 ///////////////////////////////////////////////////////////////////////////////
       
   435 template <typename InitT, typename CondT, typename StepT, typename DoT>
       
   436 struct for_composite {
       
   437 
       
   438     template <class SigArgs>
       
   439     struct sig { typedef void type; };
       
   440 
       
   441     for_composite(
       
   442         InitT const& init_,
       
   443         CondT const& cond_,
       
   444         StepT const& step_,
       
   445         DoT const& do__)
       
   446     :   init(init_), cond(cond_), step(step_), do_(do__) {}
       
   447 
       
   448     template <class Ret, CALL_TEMPLATE_ARGS>
       
   449     Ret
       
   450     call(CALL_FORMAL_ARGS) const
       
   451     {
       
   452         for (init.internal_call(CALL_ACTUAL_ARGS); cond.internal_call(CALL_ACTUAL_ARGS); step.internal_call(CALL_ACTUAL_ARGS))
       
   453             do_.internal_call(CALL_ACTUAL_ARGS);
       
   454     }
       
   455 
       
   456     InitT init; CondT cond; StepT step; DoT do_; //  lambda_functors
       
   457 };
       
   458 
       
   459 //////////////////////////////////
       
   460 template <typename InitT, typename CondT, typename StepT>
       
   461 struct for_gen {
       
   462 
       
   463     for_gen(
       
   464         InitT const& init_,
       
   465         CondT const& cond_,
       
   466         StepT const& step_)
       
   467     :   init(init_), cond(cond_), step(step_) {}
       
   468 
       
   469     template <typename DoT>
       
   470     lambda_functor<for_composite<
       
   471         typename as_lambda_functor<InitT>::type,
       
   472         typename as_lambda_functor<CondT>::type,
       
   473         typename as_lambda_functor<StepT>::type,
       
   474         typename as_lambda_functor<DoT>::type> >
       
   475     operator[](DoT const& do_) const
       
   476     {
       
   477         typedef for_composite<
       
   478             typename as_lambda_functor<InitT>::type,
       
   479             typename as_lambda_functor<CondT>::type,
       
   480             typename as_lambda_functor<StepT>::type,
       
   481             typename as_lambda_functor<DoT>::type>
       
   482         result;
       
   483 
       
   484         return result(
       
   485             to_lambda_functor(init),
       
   486             to_lambda_functor(cond),
       
   487             to_lambda_functor(step),
       
   488             to_lambda_functor(do_));
       
   489     }
       
   490 
       
   491     InitT init; CondT cond; StepT step;
       
   492 };
       
   493 
       
   494 //////////////////////////////////
       
   495 template <typename InitT, typename CondT, typename StepT>
       
   496 inline for_gen<InitT, CondT, StepT>
       
   497 for_(InitT const& init, CondT const& cond, StepT const& step)
       
   498 {
       
   499     return for_gen<InitT, CondT, StepT>(init, cond, step);
       
   500 }
       
   501 
       
   502 } // lambda
       
   503 } // boost
       
   504 
       
   505 #endif // BOOST_LAMBDA_LOOPS_HPP