First public contribution.
1 // Boost Lambda Library -- loops.hpp ----------------------------------------
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
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