fix doc example typo
[boost.git] / boost / lambda / loops.hpp
blob4e9b60b7b9500b439ed8bf77f8afc8270954cbc3
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
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)
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"
20 namespace boost {
21 namespace lambda {
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 {};
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> >
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> >
51 ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
52 lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
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> >
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> >
73 ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
74 lambda_functor<Arg3> >(a1, a2, a3) );
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> >
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> >
92 ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
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> >
104 while_loop(const lambda_functor<Arg1>& a1) {
105 return
106 lambda_functor_base<
107 whileloop_no_body_action,
108 tuple<lambda_functor<Arg1> >
110 ( tuple<lambda_functor<Arg1> >(a1) );
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> >
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> >
129 ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
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> >
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> >
147 ( tuple<lambda_functor<Arg1> >(a1));
151 // Control loop lambda_functor_base specializations.
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) {}
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);
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) {}
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.
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) {}
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);
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) {}
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.
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) {}
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) );
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) {}
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.
262 // has been made.
264 ///////////////////////////////////////////////////////////////////////////////
266 // while_composite
268 // This composite has the form:
270 // while_(condition)
271 // [
272 // statement
273 // ]
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);
298 CondT cond;
299 DoT do_;
302 //////////////////////////////////
303 template <typename CondT>
304 struct while_gen {
306 while_gen(CondT const& cond_)
307 : cond(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>
318 result;
320 return result(
321 to_lambda_functor(cond),
322 to_lambda_functor(do_));
325 CondT cond;
328 //////////////////////////////////
329 template <typename CondT>
330 inline while_gen<CondT>
331 while_(CondT const& cond)
333 return while_gen<CondT>(cond);
336 ///////////////////////////////////////////////////////////////////////////////
338 // do_composite
340 // This composite has the form:
342 // do_
343 // [
344 // statement
345 // ]
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));
374 DoT do_;
375 CondT cond;
378 ////////////////////////////////////
379 template <typename DoT>
380 struct do_gen2 {
382 do_gen2(DoT const& do__)
383 : do_(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>
394 result;
396 return result(
397 to_lambda_functor(do_),
398 to_lambda_functor(cond));
401 DoT do_;
404 ////////////////////////////////////
405 struct do_gen {
407 template <typename DoT>
408 do_gen2<DoT>
409 operator[](DoT const& do_) const
411 return do_gen2<DoT>(do_);
415 do_gen const do_ = do_gen();
417 ///////////////////////////////////////////////////////////////////////////////
419 // for_composite
421 // This statement has the form:
423 // for_(init, condition, step)
424 // [
425 // statement
426 // ]
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; };
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__) {}
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>
461 struct for_gen {
463 for_gen(
464 InitT const& init_,
465 CondT const& cond_,
466 StepT const& step_)
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>
482 result;
484 return result(
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);
502 } // lambda
503 } // boost
505 #endif // BOOST_LAMBDA_LOOPS_HPP