os/ossrv/ossrv_pub/boost_apis/boost/lambda/loops.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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