1 // Boost Lambda Library  lambda_functor_base.hpp -----------------------------
2 //
3 // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // For more information, see www.boost.org
10 
11 // ------------------------------------------------------------
12 
13 #ifndef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
14 #define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
15 
16 #include "boost/type_traits/add_reference.hpp"
17 #include "boost/type_traits/add_const.hpp"
18 #include "boost/type_traits/remove_const.hpp"
19 #include "boost/lambda/detail/lambda_fwd.hpp"
20 #include "boost/lambda/detail/lambda_traits.hpp"
21 
22 namespace boost {
23 namespace lambda {
24 
25 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
26 #pragma warning(push)
27 #pragma warning(disable:4512) //assignment operator could not be generated
28 #endif
29 
30   // for return type deductions we wrap bound argument to this class,
31   // which fulfils the base class contract for lambda_functors
32 template <class T>
33 class identity {
34 
35   T elem;
36 public:
37 
38   typedef T element_t;
39 
40   // take all parameters as const references. Note that non-const references
41   // stay as they are.
42   typedef typename boost::add_reference<
43     typename boost::add_const<T>::type
44   >::type par_t;
45 
identity(par_t t)46   explicit identity(par_t t) : elem(t) {}
47 
48   template <typename SigArgs>
49   struct sig { typedef typename boost::remove_const<element_t>::type type; };
50 
51   template<class RET, CALL_TEMPLATE_ARGS>
52   RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return elem; }
53 };
54 
55 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
56 #pragma warning(pop)
57 #endif
58 
59 template <class T>
var(T & t)60 inline lambda_functor<identity<T&> > var(T& t) { return identity<T&>(t); }
61 
62   // for lambda functors, var is an identity operator. It was forbidden
63   // at some point, but we might want to var something that can be a
64   // non-lambda functor or a lambda functor.
65 template <class T>
var(const lambda_functor<T> & t)66 lambda_functor<T> var(const lambda_functor<T>& t) { return t; }
67 
68 template <class T> struct var_type {
69   typedef lambda_functor<identity<T&> > type;
70 };
71 
72 
73 template <class T>
74 inline
75 lambda_functor<identity<typename bound_argument_conversion<const T>::type> >
constant(const T & t)76 constant(const T& t) {
77   return identity<typename bound_argument_conversion<const T>::type>(t);
78 }
79 template <class T>
constant(const lambda_functor<T> & t)80 lambda_functor<T> constant(const lambda_functor<T>& t) { return t; }
81 
82 template <class T> struct constant_type {
83   typedef
84    lambda_functor<
85      identity<typename bound_argument_conversion<const T>::type>
86    > type;
87 };
88 
89 
90 
91 template <class T>
constant_ref(const T & t)92 inline lambda_functor<identity<const T&> > constant_ref(const T& t) {
93   return identity<const T&>(t);
94 }
95 template <class T>
constant_ref(const lambda_functor<T> & t)96 lambda_functor<T> constant_ref(const lambda_functor<T>& t) { return t; }
97 
98 template <class T> struct constant_ref_type {
99   typedef
100    lambda_functor<identity<const T&> > type;
101 };
102 
103 
104 
105   // as_lambda_functor turns any types to lambda functors
106   // non-lambda_functors will be bound argument types
107 template <class T>
108 struct as_lambda_functor {
109   typedef typename
110     detail::remove_reference_and_cv<T>::type plain_T;
111   typedef typename
112     detail::IF<is_lambda_functor<plain_T>::value,
113       plain_T,
114       lambda_functor<
115         identity<typename bound_argument_conversion<T>::type>
116       >
117     >::RET type;
118 };
119 
120 // turns arbitrary objects into lambda functors
121 template <class T>
122 inline
123 lambda_functor<identity<typename bound_argument_conversion<const T>::type> >
to_lambda_functor(const T & t)124 to_lambda_functor(const T& t) {
125   return identity<typename bound_argument_conversion<const T>::type>(t);
126 }
127 
128 template <class T>
129 inline lambda_functor<T>
to_lambda_functor(const lambda_functor<T> & t)130 to_lambda_functor(const lambda_functor<T>& t) {
131   return t;
132 }
133 
134 namespace detail {
135 
136 
137 
138 // In a call constify_rvals<T>::go(x)
139 // x should be of type T. If T is a non-reference type, do
140 // returns x as const reference.
141 // Otherwise the type doesn't change.
142 // The purpose of this class is to avoid
143 // 'cannot bind temporaries to non-const references' errors.
144 template <class T> struct constify_rvals {
145   template<class U>
goboost::lambda::detail::constify_rvals146   static inline const U& go(const U& u) { return u; }
147 };
148 
149 template <class T> struct constify_rvals<T&> {
150   template<class U>
goboost::lambda::detail::constify_rvals151   static inline U& go(U& u) { return u; }
152 };
153 
154   // check whether one of the elements of a tuple (cons list) is of type
155   // null_type. Needed, because the compiler goes ahead and instantiates
156   // sig template for nullary case even if the nullary operator() is not
157   // called
158 template <class T> struct is_null_type
159 { BOOST_STATIC_CONSTANT(bool, value = false); };
160 
161 template <> struct is_null_type<null_type>
162 { BOOST_STATIC_CONSTANT(bool, value = true); };
163 
164 template<class Tuple> struct has_null_type {
165   BOOST_STATIC_CONSTANT(bool, value = (is_null_type<typename Tuple::head_type>::value || has_null_type<typename Tuple::tail_type>::value));
166 };
167 template<> struct has_null_type<null_type> {
168   BOOST_STATIC_CONSTANT(bool, value = false);
169 };
170 
171 
172 // helpers -------------------
173 
174 
175 template<class Args, class SigArgs>
176 class deduce_argument_types_ {
177   typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;
178   typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;
179 public:
180   typedef
181     boost::tuples::cons<
182       el_t,
183       typename deduce_argument_types_<typename Args::tail_type, SigArgs>::type
184     > type;
185 };
186 
187 template<class SigArgs>
188 class deduce_argument_types_<null_type, SigArgs> {
189 public:
190   typedef null_type type;
191 };
192 
193 
194 //  // note that tuples cannot have plain function types as elements.
195 //  // Hence, all other types will be non-const, except references to
196 //  // functions.
197 //  template <class T> struct remove_reference_except_from_functions {
198 //    typedef typename boost::remove_reference<T>::type t;
199 //    typedef typename detail::IF<boost::is_function<t>::value, T, t>::RET type;
200 //  };
201 
202 template<class Args, class SigArgs>
203 class deduce_non_ref_argument_types_ {
204   typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;
205   typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;
206 public:
207   typedef
208     boost::tuples::cons<
209   //      typename detail::remove_reference_except_from_functions<el_t>::type,
210       typename boost::remove_reference<el_t>::type,
211       typename deduce_non_ref_argument_types_<typename Args::tail_type, SigArgs>::type
212     > type;
213 };
214 
215 template<class SigArgs>
216 class deduce_non_ref_argument_types_<null_type, SigArgs> {
217 public:
218   typedef null_type type;
219 };
220 
221   // -------------
222 
223 // take stored Args and Open Args, and return a const list with
224 // deduced elements (real return types)
225 template<class Args, class SigArgs>
226 class deduce_argument_types {
227   typedef typename deduce_argument_types_<Args, SigArgs>::type t1;
228 public:
229   typedef typename detail::IF<
230     has_null_type<t1>::value, null_type, t1
231   >::RET type;
232 };
233 
234 // take stored Args and Open Args, and return a const list with
235 // deduced elements (references are stripped from the element types)
236 
237 template<class Args, class SigArgs>
238 class deduce_non_ref_argument_types {
239   typedef typename deduce_non_ref_argument_types_<Args, SigArgs>::type t1;
240 public:
241   typedef typename detail::IF<
242     has_null_type<t1>::value, null_type, t1
243   >::RET type;
244 };
245 
246 template <int N, class Args, class SigArgs>
247 struct nth_return_type_sig {
248   typedef typename
249           as_lambda_functor<
250             typename boost::tuples::element<N, Args>::type
251   //            typename tuple_element_as_reference<N, Args>::type
252         >::type lf_type;
253 
254   typedef typename lf_type::inherited::template sig<SigArgs>::type type;
255 };
256 
257 template<int N, class Tuple> struct element_or_null {
258   typedef typename boost::tuples::element<N, Tuple>::type type;
259 };
260 
261 template<int N> struct element_or_null<N, null_type> {
262   typedef null_type type;
263 };
264 
265 
266 
267 
268 } // end detail
269 
270  // -- lambda_functor base ---------------------
271 
272 // the explicit_return_type_action case -----------------------------------
273 template<class RET, class Args>
274 class lambda_functor_base<explicit_return_type_action<RET>, Args>
275 {
276 public:
277   Args args;
278 
279   typedef RET result_type;
280 
lambda_functor_base(const Args & a)281   explicit lambda_functor_base(const Args& a) : args(a) {}
282 
283   template <class SigArgs> struct sig { typedef RET type; };
284 
285   template<class RET_, CALL_TEMPLATE_ARGS>
call(CALL_FORMAL_ARGS) const286   RET call(CALL_FORMAL_ARGS) const
287   {
288     return detail::constify_rvals<RET>::go(
289      detail::r_select<RET>::go(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS));
290   }
291 };
292 
293 // the protect_action case -----------------------------------
294 template<class Args>
295 class lambda_functor_base<protect_action, Args>
296 {
297 public:
298   Args args;
299 public:
300 
lambda_functor_base(const Args & a)301   explicit lambda_functor_base(const Args& a) : args(a) {}
302 
303 
304   template<class RET, CALL_TEMPLATE_ARGS>
305   RET call(CALL_FORMAL_ARGS) const
306   {
307      CALL_USE_ARGS;
308      return boost::tuples::get<0>(args);
309   }
310 
311   template<class SigArgs> struct sig {
312     //    typedef typename detail::tuple_element_as_reference<0, SigArgs>::type type;
313     typedef typename boost::tuples::element<0, Args>::type type;
314   };
315 };
316 
317 // Do nothing --------------------------------------------------------
318 class do_nothing_action {};
319 
320 template<class Args>
321 class lambda_functor_base<do_nothing_action, Args> {
322   //  Args args;
323 public:
324   //  explicit lambda_functor_base(const Args& a) {}
lambda_functor_base()325   lambda_functor_base() {}
326 
327 
328   template<class RET, CALL_TEMPLATE_ARGS> RET call(CALL_FORMAL_ARGS) const {
329     return CALL_USE_ARGS;
330   }
331 
332   template<class SigArgs> struct sig { typedef void type; };
333 };
334 
335 
336 //  These specializations provide a shorter notation to define actions.
337 //  These lambda_functor_base instances take care of the recursive evaluation
338 //  of the arguments and pass the evaluated arguments to the apply function
339 //  of an action class. To make action X work with these classes, one must
340 //  instantiate the lambda_functor_base as:
341 //  lambda_functor_base<action<ARITY, X>, Args>
342 //  Where ARITY is the arity of the apply function in X
343 
344 //  The return type is queried as:
345 //  return_type_N<X, EvaluatedArgumentTypes>::type
346 //  for which there must be a specialization.
347 
348 //  Function actions, casts, throws,... all go via these classes.
349 
350 
351 template<class Act, class Args>
352 class lambda_functor_base<action<0, Act>, Args>
353 {
354 public:
355 //  Args args; not needed
lambda_functor_base(const Args &)356   explicit lambda_functor_base(const Args& /*a*/) {}
357 
358   template<class SigArgs> struct sig {
359     typedef typename return_type_N<Act, null_type>::type type;
360   };
361 
362   template<class RET, CALL_TEMPLATE_ARGS>
363   RET call(CALL_FORMAL_ARGS) const {
364     CALL_USE_ARGS;
365     return Act::template apply<RET>();
366   }
367 };
368 
369 
370 #if defined BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART
371 #error "Multiple defines of BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART"
372 #endif
373 
374 
375 #define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(ARITY)             \
376 template<class Act, class Args>                                        \
377 class lambda_functor_base<action<ARITY, Act>, Args>                    \
378 {                                                                      \
379 public:                                                                \
380   Args args;                                                           \
381                                                                        \
382   explicit lambda_functor_base(const Args& a) : args(a) {}             \
383                                                                        \
384   template<class SigArgs> struct sig {                                 \
385     typedef typename                                                   \
386     detail::deduce_argument_types<Args, SigArgs>::type rets_t;         \
387   public:                                                              \
388     typedef typename                                                   \
389       return_type_N_prot<Act, rets_t>::type type;                      \
390   };                                                                   \
391                                                                        \
392                                                                        \
393   template<class RET, CALL_TEMPLATE_ARGS>                              \
394   RET call(CALL_FORMAL_ARGS) const {                                   \
395     using boost::tuples::get;                                          \
396     using detail::constify_rvals;                                      \
397     using detail::r_select;                                            \
398     using detail::element_or_null;                                     \
399     using detail::deduce_argument_types;
400 
401 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(1)
402 
403   typedef typename
404     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
405   typedef typename element_or_null<0, rets_t>::type rt0;
406 
407   return Act::template apply<RET>(
408     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS))
409     );
410   }
411 };
412 
413 
414 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(2)
415 
416   typedef typename
417     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
418   typedef typename element_or_null<0, rets_t>::type rt0;
419   typedef typename element_or_null<1, rets_t>::type rt1;
420 
421   return Act::template apply<RET>(
422     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
423     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS))
424     );
425   }
426 };
427 
428 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(3)
429 
430   typedef typename
431     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
432 
433   typedef typename element_or_null<0, rets_t>::type rt0;
434   typedef typename element_or_null<1, rets_t>::type rt1;
435   typedef typename element_or_null<2, rets_t>::type rt2;
436 
437   return Act::template apply<RET>(
438     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
439     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
440     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS))
441     );
442   }
443 };
444 
445 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(4)
446   typedef typename
447     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
448   typedef typename element_or_null<0, rets_t>::type rt0;
449   typedef typename element_or_null<1, rets_t>::type rt1;
450   typedef typename element_or_null<2, rets_t>::type rt2;
451   typedef typename element_or_null<3, rets_t>::type rt3;
452 
453   return Act::template apply<RET>(
454     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
455     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
456     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
457     constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS))
458     );
459   }
460 };
461 
462 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(5)
463   typedef typename
464     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
465   typedef typename element_or_null<0, rets_t>::type rt0;
466   typedef typename element_or_null<1, rets_t>::type rt1;
467   typedef typename element_or_null<2, rets_t>::type rt2;
468   typedef typename element_or_null<3, rets_t>::type rt3;
469   typedef typename element_or_null<4, rets_t>::type rt4;
470 
471   return Act::template apply<RET>(
472     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
473     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
474     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
475     constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
476     constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS))
477     );
478   }
479 };
480 
481 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(6)
482 
483   typedef typename
484     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
485   typedef typename element_or_null<0, rets_t>::type rt0;
486   typedef typename element_or_null<1, rets_t>::type rt1;
487   typedef typename element_or_null<2, rets_t>::type rt2;
488   typedef typename element_or_null<3, rets_t>::type rt3;
489   typedef typename element_or_null<4, rets_t>::type rt4;
490   typedef typename element_or_null<5, rets_t>::type rt5;
491 
492 
493     return Act::template apply<RET>(
494     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
495     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
496     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
497     constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
498     constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
499     constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS))
500     );
501   }
502 };
503 
504 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(7)
505   typedef typename
506     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
507   typedef typename element_or_null<0, rets_t>::type rt0;
508   typedef typename element_or_null<1, rets_t>::type rt1;
509   typedef typename element_or_null<2, rets_t>::type rt2;
510   typedef typename element_or_null<3, rets_t>::type rt3;
511   typedef typename element_or_null<4, rets_t>::type rt4;
512   typedef typename element_or_null<5, rets_t>::type rt5;
513   typedef typename element_or_null<6, rets_t>::type rt6;
514 
515 
516   return Act::template apply<RET>(
517     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
518     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
519     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
520     constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
521     constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
522     constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
523     constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS))
524     );
525   }
526 };
527 
528 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(8)
529   typedef typename
530     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
531   typedef typename element_or_null<0, rets_t>::type rt0;
532   typedef typename element_or_null<1, rets_t>::type rt1;
533   typedef typename element_or_null<2, rets_t>::type rt2;
534   typedef typename element_or_null<3, rets_t>::type rt3;
535   typedef typename element_or_null<4, rets_t>::type rt4;
536   typedef typename element_or_null<5, rets_t>::type rt5;
537   typedef typename element_or_null<6, rets_t>::type rt6;
538   typedef typename element_or_null<7, rets_t>::type rt7;
539 
540   return Act::template apply<RET>(
541     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
542     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
543     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
544     constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
545     constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
546     constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
547     constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
548     constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS))
549     );
550   }
551 };
552 
553 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(9)
554   typedef typename
555     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
556   typedef typename element_or_null<0, rets_t>::type rt0;
557   typedef typename element_or_null<1, rets_t>::type rt1;
558   typedef typename element_or_null<2, rets_t>::type rt2;
559   typedef typename element_or_null<3, rets_t>::type rt3;
560   typedef typename element_or_null<4, rets_t>::type rt4;
561   typedef typename element_or_null<5, rets_t>::type rt5;
562   typedef typename element_or_null<6, rets_t>::type rt6;
563   typedef typename element_or_null<7, rets_t>::type rt7;
564   typedef typename element_or_null<8, rets_t>::type rt8;
565 
566   return Act::template apply<RET>(
567     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
568     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
569     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
570     constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
571     constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
572     constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
573     constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
574     constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS)),
575     constify_rvals<rt8>::go(r_select<rt8>::go(get<8>(args), CALL_ACTUAL_ARGS))
576     );
577   }
578 };
579 
580 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(10)
581   typedef typename
582     deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
583   typedef typename element_or_null<0, rets_t>::type rt0;
584   typedef typename element_or_null<1, rets_t>::type rt1;
585   typedef typename element_or_null<2, rets_t>::type rt2;
586   typedef typename element_or_null<3, rets_t>::type rt3;
587   typedef typename element_or_null<4, rets_t>::type rt4;
588   typedef typename element_or_null<5, rets_t>::type rt5;
589   typedef typename element_or_null<6, rets_t>::type rt6;
590   typedef typename element_or_null<7, rets_t>::type rt7;
591   typedef typename element_or_null<8, rets_t>::type rt8;
592   typedef typename element_or_null<9, rets_t>::type rt9;
593 
594   return Act::template apply<RET>(
595     constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
596     constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
597     constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
598     constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
599     constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
600     constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
601     constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
602     constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS)),
603     constify_rvals<rt8>::go(r_select<rt8>::go(get<8>(args), CALL_ACTUAL_ARGS)),
604     constify_rvals<rt9>::go(r_select<rt9>::go(get<9>(args), CALL_ACTUAL_ARGS))
605     );
606   }
607 };
608 
609 #undef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART
610 
611 
612 } // namespace lambda
613 } // namespace boost
614 
615 #endif
616