1
// Boost Lambda Library -- loops.hpp ----------------------------------------
3
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
4
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
5
// Copyright (c) 2001-2002 Joel de Guzman
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)
11
// For more information, see www.boost.org
13
// --------------------------------------------------------------------------
15
#if !defined(BOOST_LAMBDA_LOOPS_HPP)
16
#define BOOST_LAMBDA_LOOPS_HPP
18
#include "boost/lambda/core.hpp"
23
// -- loop control structure actions ----------------------
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 {};
34
template <class Arg1, class Arg2, class Arg3, class Arg4>
39
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
40
lambda_functor<Arg3>, lambda_functor<Arg4> >
43
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
44
const lambda_functor<Arg3>& a3, const lambda_functor<Arg4>& a4) {
48
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
49
lambda_functor<Arg3>, lambda_functor<Arg4> >
51
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
52
lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
57
template <class Arg1, class Arg2, class Arg3>
61
forloop_no_body_action,
62
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
65
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
66
const lambda_functor<Arg3>& a3) {
69
forloop_no_body_action,
70
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
71
lambda_functor<Arg3> >
73
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
74
lambda_functor<Arg3> >(a1, a2, a3) );
78
template <class Arg1, class Arg2>
83
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
86
while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
90
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
92
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
100
whileloop_no_body_action,
101
tuple<lambda_functor<Arg1> >
104
while_loop(const lambda_functor<Arg1>& a1) {
107
whileloop_no_body_action,
108
tuple<lambda_functor<Arg1> >
110
( tuple<lambda_functor<Arg1> >(a1) );
115
template <class Arg1, class Arg2>
120
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
123
do_while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
127
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
129
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
133
template <class Arg1>
137
dowhileloop_no_body_action,
138
tuple<lambda_functor<Arg1> >
141
do_while_loop(const lambda_functor<Arg1>& a1) {
144
dowhileloop_no_body_action,
145
tuple<lambda_functor<Arg1> >
147
( tuple<lambda_functor<Arg1> >(a1));
151
// Control loop lambda_functor_base specializations.
153
// Specialization for for_loop.
156
lambda_functor_base<forloop_action, Args> {
159
template <class T> struct sig { typedef void type; };
161
explicit lambda_functor_base(const Args& a) : args(a) {}
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))
169
detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS);
176
lambda_functor_base<forloop_no_body_action, Args> {
179
template <class T> struct sig { typedef void type; };
181
explicit lambda_functor_base(const Args& a) : args(a) {}
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)) {}
192
// Specialization for while_loop.
195
lambda_functor_base<whileloop_action, Args> {
198
template <class T> struct sig { typedef void type; };
200
explicit lambda_functor_base(const Args& a) : args(a) {}
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))
206
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
213
lambda_functor_base<whileloop_no_body_action, Args> {
216
template <class T> struct sig { typedef void type; };
218
explicit lambda_functor_base(const Args& a) : args(a) {}
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)) {}
226
// Specialization for do_while_loop.
227
// Note that the first argument is the condition.
230
lambda_functor_base<dowhileloop_action, Args> {
233
template <class T> struct sig { typedef void type; };
235
explicit lambda_functor_base(const Args& a) : args(a) {}
237
template<class RET, CALL_TEMPLATE_ARGS>
238
RET call(CALL_FORMAL_ARGS) const {
240
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
241
} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
248
lambda_functor_base<dowhileloop_no_body_action, Args> {
251
template <class T> struct sig { typedef void type; };
253
explicit lambda_functor_base(const Args& a) : args(a) {}
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) );
261
// The code below is from Joel de Guzman, some name changes etc.
264
///////////////////////////////////////////////////////////////////////////////
268
// This composite has the form:
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_.
279
///////////////////////////////////////////////////////////////////////////////
280
template <typename CondT, typename DoT>
281
struct while_composite {
283
typedef while_composite<CondT, DoT> self_t;
285
template <class SigArgs>
286
struct sig { typedef void type; };
288
while_composite(CondT const& cond_, DoT const& do__)
289
: cond(cond_), do_(do__) {}
291
template <class Ret, CALL_TEMPLATE_ARGS>
292
Ret call(CALL_FORMAL_ARGS) const
294
while (cond.internal_call(CALL_ACTUAL_ARGS))
295
do_.internal_call(CALL_ACTUAL_ARGS);
302
//////////////////////////////////
303
template <typename CondT>
306
while_gen(CondT const& cond_)
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
315
typedef while_composite<
316
typename as_lambda_functor<CondT>::type,
317
typename as_lambda_functor<DoT>::type>
321
to_lambda_functor(cond),
322
to_lambda_functor(do_));
328
//////////////////////////////////
329
template <typename CondT>
330
inline while_gen<CondT>
331
while_(CondT const& cond)
333
return while_gen<CondT>(cond);
336
///////////////////////////////////////////////////////////////////////////////
340
// This composite has the form:
346
// .while_(condition)
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_.
354
///////////////////////////////////////////////////////////////////////////////
355
template <typename DoT, typename CondT>
356
struct do_composite {
358
typedef do_composite<DoT, CondT> self_t;
360
template <class SigArgs>
361
struct sig { typedef void type; };
363
do_composite(DoT const& do__, CondT const& cond_)
364
: do_(do__), cond(cond_) {}
366
template <class Ret, CALL_TEMPLATE_ARGS>
367
Ret call(CALL_FORMAL_ARGS) const
370
do_.internal_call(CALL_ACTUAL_ARGS);
371
while (cond.internal_call(CALL_ACTUAL_ARGS));
378
////////////////////////////////////
379
template <typename DoT>
382
do_gen2(DoT const& do__)
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
391
typedef do_composite<
392
typename as_lambda_functor<DoT>::type,
393
typename as_lambda_functor<CondT>::type>
397
to_lambda_functor(do_),
398
to_lambda_functor(cond));
404
////////////////////////////////////
407
template <typename DoT>
409
operator[](DoT const& do_) const
411
return do_gen2<DoT>(do_);
415
do_gen const do_ = do_gen();
417
///////////////////////////////////////////////////////////////////////////////
421
// This statement has the form:
423
// for_(init, condition, step)
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_.
434
///////////////////////////////////////////////////////////////////////////////
435
template <typename InitT, typename CondT, typename StepT, typename DoT>
436
struct for_composite {
438
template <class SigArgs>
439
struct sig { typedef void type; };
446
: init(init_), cond(cond_), step(step_), do_(do__) {}
448
template <class Ret, CALL_TEMPLATE_ARGS>
450
call(CALL_FORMAL_ARGS) const
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);
456
InitT init; CondT cond; StepT step; DoT do_; // lambda_functors
459
//////////////////////////////////
460
template <typename InitT, typename CondT, typename StepT>
467
: init(init_), cond(cond_), step(step_) {}
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
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>
485
to_lambda_functor(init),
486
to_lambda_functor(cond),
487
to_lambda_functor(step),
488
to_lambda_functor(do_));
491
InitT init; CondT cond; StepT step;
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)
499
return for_gen<InitT, CondT, StepT>(init, cond, step);
505
#endif // BOOST_LAMBDA_LOOPS_HPP