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