source: NonGTP/Boost/boost/lambda/loops.hpp @ 857

Revision 857, 13.9 KB checked in by igarcia, 19 years ago (diff)
Line 
1// Boost Lambda Library -- loops.hpp ----------------------------------------
2
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
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)
10//
11// For more information, see www.boost.org
12
13// --------------------------------------------------------------------------
14
15#if !defined(BOOST_LAMBDA_LOOPS_HPP)
16#define BOOST_LAMBDA_LOOPS_HPP
17
18#include "boost/lambda/core.hpp"
19
20namespace boost {
21namespace lambda {
22
23// -- loop control structure actions ----------------------
24
25class forloop_action {};
26class forloop_no_body_action {};
27class whileloop_action {};
28class whileloop_no_body_action {};
29class dowhileloop_action {};
30class dowhileloop_no_body_action {};
31
32
33// For loop
34template <class Arg1, class Arg2, class Arg3, class Arg4>
35inline const
36lambda_functor<
37  lambda_functor_base<
38    forloop_action,
39    tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
40          lambda_functor<Arg3>, lambda_functor<Arg4> >
41  >
42>
43for_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> >
50      >
51    ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
52            lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
53    );
54}
55
56// No body case.
57template <class Arg1, class Arg2, class Arg3>
58inline const
59lambda_functor<
60  lambda_functor_base<
61    forloop_no_body_action,
62    tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
63  >
64>
65for_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> >
72      >
73      ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
74               lambda_functor<Arg3> >(a1, a2, a3) );
75}
76
77// While loop
78template <class Arg1, class Arg2>
79inline const
80lambda_functor<
81  lambda_functor_base<
82    whileloop_action,
83    tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
84  >
85>
86while_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> >
91      >
92      ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
93}
94
95// No body case.
96template <class Arg1>
97inline const
98lambda_functor<
99  lambda_functor_base<
100    whileloop_no_body_action,
101    tuple<lambda_functor<Arg1> >
102  >
103>
104while_loop(const lambda_functor<Arg1>& a1) {
105  return
106      lambda_functor_base<
107        whileloop_no_body_action,
108        tuple<lambda_functor<Arg1> >
109      >
110      ( tuple<lambda_functor<Arg1> >(a1) );
111}
112
113
114// Do While loop
115template <class Arg1, class Arg2>
116inline const
117lambda_functor<
118  lambda_functor_base<
119    dowhileloop_action,
120    tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
121  >
122>
123do_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> >
128      >
129      ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
130}
131
132// No body case.
133template <class Arg1>
134inline const
135lambda_functor<
136  lambda_functor_base<
137    dowhileloop_no_body_action,
138    tuple<lambda_functor<Arg1> >
139  >
140>
141do_while_loop(const lambda_functor<Arg1>& a1) {
142  return
143      lambda_functor_base<
144        dowhileloop_no_body_action,
145        tuple<lambda_functor<Arg1> >
146      >
147      ( tuple<lambda_functor<Arg1> >(a1));
148}
149
150
151// Control loop lambda_functor_base specializations.
152
153// Specialization for for_loop.
154template<class Args>
155class
156lambda_functor_base<forloop_action, Args> {
157public:
158  Args args;
159  template <class T> struct sig { typedef void type; };
160public:
161  explicit lambda_functor_base(const Args& a) : args(a) {}
162
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))
168     
169      detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS);
170  }
171};
172
173// No body case
174template<class Args>
175class
176lambda_functor_base<forloop_no_body_action, Args> {
177public:
178  Args args;
179  template <class T> struct sig { typedef void type; };
180public:
181  explicit lambda_functor_base(const Args& a) : args(a) {}
182
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)) {}
188   }
189};
190
191
192// Specialization for while_loop.
193template<class Args>
194class
195lambda_functor_base<whileloop_action, Args> {
196public:
197  Args args;
198  template <class T> struct sig { typedef void type; };
199public:
200  explicit lambda_functor_base(const Args& a) : args(a) {}
201
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))
205     
206      detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
207  }
208};
209
210// No body case
211template<class Args>
212class
213lambda_functor_base<whileloop_no_body_action, Args> {
214public:
215  Args args;
216  template <class T> struct sig { typedef void type; };
217public:
218  explicit lambda_functor_base(const Args& a) : args(a) {}
219
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)) {}
223  }
224};
225
226// Specialization for do_while_loop.
227// Note that the first argument is the condition.
228template<class Args>
229class
230lambda_functor_base<dowhileloop_action, Args> {
231public:
232  Args args;
233  template <class T> struct sig { typedef void type; };
234public:
235  explicit lambda_functor_base(const Args& a) : args(a) {}
236
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) );
242  }
243};
244
245// No body case
246template<class Args>
247class
248lambda_functor_base<dowhileloop_no_body_action, Args> {
249public:
250  Args args;
251  template <class T> struct sig { typedef void type; };
252public:
253  explicit lambda_functor_base(const Args& a) : args(a) {}
254
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) );
258  }
259};
260
261  // The code below is from Joel de Guzman, some name changes etc.
262  // has been made.
263
264///////////////////////////////////////////////////////////////////////////////
265//
266//  while_composite
267//
268//      This composite has the form:
269//
270//          while_(condition)
271//          [
272//              statement
273//          ]
274//
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_.
278//
279///////////////////////////////////////////////////////////////////////////////
280template <typename CondT, typename DoT>
281struct while_composite {
282
283    typedef while_composite<CondT, DoT> self_t;
284
285    template <class SigArgs>
286    struct sig { typedef void type; };
287
288    while_composite(CondT const& cond_, DoT const& do__)
289    :   cond(cond_), do_(do__) {}
290
291    template <class Ret, CALL_TEMPLATE_ARGS>
292    Ret call(CALL_FORMAL_ARGS) const
293    {
294        while (cond.internal_call(CALL_ACTUAL_ARGS))
295            do_.internal_call(CALL_ACTUAL_ARGS);
296    }
297
298    CondT cond;
299    DoT do_;
300};
301
302//////////////////////////////////
303template <typename CondT>
304struct while_gen {
305
306    while_gen(CondT const& cond_)
307    :   cond(cond_) {}
308
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
314    {
315        typedef while_composite<
316            typename as_lambda_functor<CondT>::type,
317            typename as_lambda_functor<DoT>::type>
318        result;
319
320        return result(
321            to_lambda_functor(cond),
322            to_lambda_functor(do_));
323    }
324
325    CondT cond;
326};
327
328//////////////////////////////////
329template <typename CondT>
330inline while_gen<CondT>
331while_(CondT const& cond)
332{
333    return while_gen<CondT>(cond);
334}
335
336///////////////////////////////////////////////////////////////////////////////
337//
338//  do_composite
339//
340//      This composite has the form:
341//
342//          do_
343//          [
344//              statement
345//          ]
346//          .while_(condition)
347//
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_.
353//
354///////////////////////////////////////////////////////////////////////////////
355template <typename DoT, typename CondT>
356struct do_composite {
357
358    typedef do_composite<DoT, CondT> self_t;
359
360    template <class SigArgs>
361    struct sig { typedef void type; };
362
363    do_composite(DoT const& do__, CondT const& cond_)
364    :   do_(do__), cond(cond_) {}
365
366    template <class Ret, CALL_TEMPLATE_ARGS>
367    Ret call(CALL_FORMAL_ARGS) const
368    {
369        do
370            do_.internal_call(CALL_ACTUAL_ARGS);
371        while (cond.internal_call(CALL_ACTUAL_ARGS));
372    }
373
374    DoT do_;
375    CondT cond;
376};
377
378////////////////////////////////////
379template <typename DoT>
380struct do_gen2 {
381
382    do_gen2(DoT const& do__)
383    :   do_(do__) {}
384
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
390    {
391        typedef do_composite<
392            typename as_lambda_functor<DoT>::type,
393            typename as_lambda_functor<CondT>::type>
394        result;
395
396        return result(
397            to_lambda_functor(do_),
398            to_lambda_functor(cond));
399    }
400
401    DoT do_;
402};
403
404////////////////////////////////////
405struct do_gen {
406
407    template <typename DoT>
408    do_gen2<DoT>
409    operator[](DoT const& do_) const
410    {
411        return do_gen2<DoT>(do_);
412    }
413};
414
415do_gen const do_ = do_gen();
416
417///////////////////////////////////////////////////////////////////////////////
418//
419//  for_composite
420//
421//      This statement has the form:
422//
423//          for_(init, condition, step)
424//          [
425//              statement
426//          ]
427//
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_.
433//
434///////////////////////////////////////////////////////////////////////////////
435template <typename InitT, typename CondT, typename StepT, typename DoT>
436struct for_composite {
437
438    template <class SigArgs>
439    struct sig { typedef void type; };
440
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__) {}
447
448    template <class Ret, CALL_TEMPLATE_ARGS>
449    Ret
450    call(CALL_FORMAL_ARGS) const
451    {
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);
454    }
455
456    InitT init; CondT cond; StepT step; DoT do_; //  lambda_functors
457};
458
459//////////////////////////////////
460template <typename InitT, typename CondT, typename StepT>
461struct for_gen {
462
463    for_gen(
464        InitT const& init_,
465        CondT const& cond_,
466        StepT const& step_)
467    :   init(init_), cond(cond_), step(step_) {}
468
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
476    {
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;
483
484        return result(
485            to_lambda_functor(init),
486            to_lambda_functor(cond),
487            to_lambda_functor(step),
488            to_lambda_functor(do_));
489    }
490
491    InitT init; CondT cond; StepT step;
492};
493
494//////////////////////////////////
495template <typename InitT, typename CondT, typename StepT>
496inline for_gen<InitT, CondT, StepT>
497for_(InitT const& init, CondT const& cond, StepT const& step)
498{
499    return for_gen<InitT, CondT, StepT>(init, cond, step);
500}
501
502} // lambda
503} // boost
504
505#endif // BOOST_LAMBDA_LOOPS_HPP
Note: See TracBrowser for help on using the repository browser.