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