Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
1 // Boost Lambda Library lambda_functor_base.hpp -----------------------------
3 // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
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)
9 // For more information, see www.boost.org
11 // ------------------------------------------------------------
13 #ifndef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
14 #define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
20 // for return type deductions we wrap bound argument to this class,
21 // which fulfils the base class contract for lambda_functors
30 // take all parameters as const references. Note that non-const references
32 typedef typename boost::add_reference<
33 typename boost::add_const<T>::type
36 explicit identity(par_t t) : elem(t) {}
38 template <typename SigArgs>
39 struct sig { typedef element_t type; };
41 template<class RET, CALL_TEMPLATE_ARGS>
42 RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return elem; }
46 inline lambda_functor<identity<T&> > var(T& t) { return identity<T&>(t); }
48 // for lambda functors, var is an identity operator. It was forbidden
49 // at some point, but we might want to var something that can be a
50 // non-lambda functor or a lambda functor.
52 lambda_functor<T> var(const lambda_functor<T>& t) { return t; }
54 template <class T> struct var_type {
55 typedef lambda_functor<identity<T&> > type;
61 lambda_functor<identity<typename bound_argument_conversion<const T>::type> >
62 constant(const T& t) {
63 return identity<typename bound_argument_conversion<const T>::type>(t);
66 lambda_functor<T> constant(const lambda_functor<T>& t) { return t; }
68 template <class T> struct constant_type {
71 identity<typename bound_argument_conversion<const T>::type>
78 inline lambda_functor<identity<const T&> > constant_ref(const T& t) {
79 return identity<const T&>(t);
82 lambda_functor<T> constant_ref(const lambda_functor<T>& t) { return t; }
84 template <class T> struct constant_ref_type {
86 lambda_functor<identity<const T&> > type;
91 // as_lambda_functor turns any types to lambda functors
92 // non-lambda_functors will be bound argument types
94 struct as_lambda_functor {
96 detail::remove_reference_and_cv<T>::type plain_T;
98 detail::IF<is_lambda_functor<plain_T>::value,
101 identity<typename bound_argument_conversion<T>::type>
106 // turns arbitrary objects into lambda functors
109 lambda_functor<identity<typename bound_argument_conversion<const T>::type> >
110 to_lambda_functor(const T& t) {
111 return identity<typename bound_argument_conversion<const T>::type>(t);
115 inline lambda_functor<T>
116 to_lambda_functor(const lambda_functor<T>& t) {
124 // In a call constify_rvals<T>::go(x)
125 // x should be of type T. If T is a non-reference type, do
126 // returns x as const reference.
127 // Otherwise the type doesn't change.
128 // The purpose of this class is to avoid
129 // 'cannot bind temporaries to non-const references' errors.
130 template <class T> struct constify_rvals {
132 static inline const U& go(const U& u) { return u; }
135 template <class T> struct constify_rvals<T&> {
137 static inline U& go(U& u) { return u; }
140 // check whether one of the elements of a tuple (cons list) is of type
141 // null_type. Needed, because the compiler goes ahead and instantiates
142 // sig template for nullary case even if the nullary operator() is not
144 template <class T> struct is_null_type
145 { BOOST_STATIC_CONSTANT(bool, value = false); };
147 template <> struct is_null_type<null_type>
148 { BOOST_STATIC_CONSTANT(bool, value = true); };
150 template<class Tuple> struct has_null_type {
151 BOOST_STATIC_CONSTANT(bool, value = (is_null_type<typename Tuple::head_type>::value || has_null_type<typename Tuple::tail_type>::value));
153 template<> struct has_null_type<null_type> {
154 BOOST_STATIC_CONSTANT(bool, value = false);
158 // helpers -------------------
161 template<class Args, class SigArgs>
162 class deduce_argument_types_ {
163 typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;
164 typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;
169 typename deduce_argument_types_<typename Args::tail_type, SigArgs>::type
173 template<class SigArgs>
174 class deduce_argument_types_<null_type, SigArgs> {
176 typedef null_type type;
180 // // note that tuples cannot have plain function types as elements.
181 // // Hence, all other types will be non-const, except references to
183 // template <class T> struct remove_reference_except_from_functions {
184 // typedef typename boost::remove_reference<T>::type t;
185 // typedef typename detail::IF<boost::is_function<t>::value, T, t>::RET type;
188 template<class Args, class SigArgs>
189 class deduce_non_ref_argument_types_ {
190 typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;
191 typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;
195 // typename detail::remove_reference_except_from_functions<el_t>::type,
196 typename boost::remove_reference<el_t>::type,
197 typename deduce_non_ref_argument_types_<typename Args::tail_type, SigArgs>::type
201 template<class SigArgs>
202 class deduce_non_ref_argument_types_<null_type, SigArgs> {
204 typedef null_type type;
209 // take stored Args and Open Args, and return a const list with
210 // deduced elements (real return types)
211 template<class Args, class SigArgs>
212 class deduce_argument_types {
213 typedef typename deduce_argument_types_<Args, SigArgs>::type t1;
215 typedef typename detail::IF<
216 has_null_type<t1>::value, null_type, t1
220 // take stored Args and Open Args, and return a const list with
221 // deduced elements (references are stripped from the element types)
223 template<class Args, class SigArgs>
224 class deduce_non_ref_argument_types {
225 typedef typename deduce_non_ref_argument_types_<Args, SigArgs>::type t1;
227 typedef typename detail::IF<
228 has_null_type<t1>::value, null_type, t1
232 template <int N, class Args, class SigArgs>
233 struct nth_return_type_sig {
236 typename boost::tuples::element<N, Args>::type
237 // typename tuple_element_as_reference<N, Args>::type
240 typedef typename lf_type::inherited::template sig<SigArgs>::type type;
243 template<int N, class Tuple> struct element_or_null {
244 typedef typename boost::tuples::element<N, Tuple>::type type;
247 template<int N> struct element_or_null<N, null_type> {
248 typedef null_type type;
256 // -- lambda_functor base ---------------------
258 // the explicit_return_type_action case -----------------------------------
259 template<class RET, class Args>
260 class lambda_functor_base<explicit_return_type_action<RET>, Args>
265 explicit lambda_functor_base(const Args& a) : args(a) {}
267 template <class SigArgs> struct sig { typedef RET type; };
269 template<class RET_, CALL_TEMPLATE_ARGS>
270 RET call(CALL_FORMAL_ARGS) const
272 return detail::constify_rvals<RET>::go(
273 detail::r_select<RET>::go(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS));
277 // the protect_action case -----------------------------------
279 class lambda_functor_base<protect_action, Args>
285 explicit lambda_functor_base(const Args& a) : args(a) {}
288 template<class RET, CALL_TEMPLATE_ARGS>
289 RET call(CALL_FORMAL_ARGS) const
292 return boost::tuples::get<0>(args);
295 template<class SigArgs> struct sig {
296 // typedef typename detail::tuple_element_as_reference<0, SigArgs>::type type;
297 typedef typename boost::tuples::element<0, Args>::type type;
301 // Do nothing --------------------------------------------------------
302 class do_nothing_action {};
305 class lambda_functor_base<do_nothing_action, Args> {
308 // explicit lambda_functor_base(const Args& a) {}
309 lambda_functor_base() {}
312 template<class RET, CALL_TEMPLATE_ARGS> RET call(CALL_FORMAL_ARGS) const {
313 return CALL_USE_ARGS;
316 template<class SigArgs> struct sig { typedef void type; };
320 // These specializations provide a shorter notation to define actions.
321 // These lambda_functor_base instances take care of the recursive evaluation
322 // of the arguments and pass the evaluated arguments to the apply function
323 // of an action class. To make action X work with these classes, one must
324 // instantiate the lambda_functor_base as:
325 // lambda_functor_base<action<ARITY, X>, Args>
326 // Where ARITY is the arity of the apply function in X
328 // The return type is queried as:
329 // return_type_N<X, EvaluatedArgumentTypes>::type
330 // for which there must be a specialization.
332 // Function actions, casts, throws,... all go via these classes.
335 template<class Act, class Args>
336 class lambda_functor_base<action<0, Act>, Args>
339 // Args args; not needed
340 explicit lambda_functor_base(const Args& a) {}
342 template<class SigArgs> struct sig {
343 typedef typename return_type_N<Act, null_type>::type type;
346 template<class RET, CALL_TEMPLATE_ARGS>
347 RET call(CALL_FORMAL_ARGS) const {
349 return Act::template apply<RET>();
354 #if defined BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART
355 #error "Multiple defines of BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART"
359 #define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(ARITY) \
360 template<class Act, class Args> \
361 class lambda_functor_base<action<ARITY, Act>, Args> \
366 explicit lambda_functor_base(const Args& a) : args(a) {} \
368 template<class SigArgs> struct sig { \
370 detail::deduce_non_ref_argument_types<Args, SigArgs>::type rets_t; \
373 return_type_N_prot<Act, rets_t>::type type; \
377 template<class RET, CALL_TEMPLATE_ARGS> \
378 RET call(CALL_FORMAL_ARGS) const { \
379 using boost::tuples::get; \
380 using detail::constify_rvals; \
381 using detail::r_select; \
382 using detail::element_or_null; \
383 using detail::deduce_argument_types;
385 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(1)
388 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
389 typedef typename element_or_null<0, rets_t>::type rt0;
391 return Act::template apply<RET>(
392 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS))
398 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(2)
401 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
402 typedef typename element_or_null<0, rets_t>::type rt0;
403 typedef typename element_or_null<1, rets_t>::type rt1;
405 return Act::template apply<RET>(
406 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
407 constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS))
412 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(3)
415 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
417 typedef typename element_or_null<0, rets_t>::type rt0;
418 typedef typename element_or_null<1, rets_t>::type rt1;
419 typedef typename element_or_null<2, rets_t>::type rt2;
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 constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS))
429 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(4)
431 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
432 typedef typename element_or_null<0, rets_t>::type rt0;
433 typedef typename element_or_null<1, rets_t>::type rt1;
434 typedef typename element_or_null<2, rets_t>::type rt2;
435 typedef typename element_or_null<3, rets_t>::type rt3;
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 constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS))
446 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(5)
448 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
449 typedef typename element_or_null<0, rets_t>::type rt0;
450 typedef typename element_or_null<1, rets_t>::type rt1;
451 typedef typename element_or_null<2, rets_t>::type rt2;
452 typedef typename element_or_null<3, rets_t>::type rt3;
453 typedef typename element_or_null<4, rets_t>::type rt4;
455 return Act::template apply<RET>(
456 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
457 constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
458 constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
459 constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
460 constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS))
465 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(6)
468 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
469 typedef typename element_or_null<0, rets_t>::type rt0;
470 typedef typename element_or_null<1, rets_t>::type rt1;
471 typedef typename element_or_null<2, rets_t>::type rt2;
472 typedef typename element_or_null<3, rets_t>::type rt3;
473 typedef typename element_or_null<4, rets_t>::type rt4;
474 typedef typename element_or_null<5, rets_t>::type rt5;
477 return Act::template apply<RET>(
478 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
479 constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
480 constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
481 constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
482 constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
483 constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS))
488 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(7)
490 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
491 typedef typename element_or_null<0, rets_t>::type rt0;
492 typedef typename element_or_null<1, rets_t>::type rt1;
493 typedef typename element_or_null<2, rets_t>::type rt2;
494 typedef typename element_or_null<3, rets_t>::type rt3;
495 typedef typename element_or_null<4, rets_t>::type rt4;
496 typedef typename element_or_null<5, rets_t>::type rt5;
497 typedef typename element_or_null<6, rets_t>::type rt6;
500 return Act::template apply<RET>(
501 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
502 constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
503 constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
504 constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
505 constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
506 constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
507 constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS))
512 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(8)
514 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
515 typedef typename element_or_null<0, rets_t>::type rt0;
516 typedef typename element_or_null<1, rets_t>::type rt1;
517 typedef typename element_or_null<2, rets_t>::type rt2;
518 typedef typename element_or_null<3, rets_t>::type rt3;
519 typedef typename element_or_null<4, rets_t>::type rt4;
520 typedef typename element_or_null<5, rets_t>::type rt5;
521 typedef typename element_or_null<6, rets_t>::type rt6;
522 typedef typename element_or_null<7, rets_t>::type rt7;
524 return Act::template apply<RET>(
525 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
526 constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
527 constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
528 constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
529 constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
530 constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
531 constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
532 constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS))
537 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(9)
539 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
540 typedef typename element_or_null<0, rets_t>::type rt0;
541 typedef typename element_or_null<1, rets_t>::type rt1;
542 typedef typename element_or_null<2, rets_t>::type rt2;
543 typedef typename element_or_null<3, rets_t>::type rt3;
544 typedef typename element_or_null<4, rets_t>::type rt4;
545 typedef typename element_or_null<5, rets_t>::type rt5;
546 typedef typename element_or_null<6, rets_t>::type rt6;
547 typedef typename element_or_null<7, rets_t>::type rt7;
548 typedef typename element_or_null<8, rets_t>::type rt8;
550 return Act::template apply<RET>(
551 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
552 constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
553 constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
554 constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
555 constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
556 constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
557 constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
558 constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS)),
559 constify_rvals<rt8>::go(r_select<rt8>::go(get<8>(args), CALL_ACTUAL_ARGS))
564 BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(10)
566 deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
567 typedef typename element_or_null<0, rets_t>::type rt0;
568 typedef typename element_or_null<1, rets_t>::type rt1;
569 typedef typename element_or_null<2, rets_t>::type rt2;
570 typedef typename element_or_null<3, rets_t>::type rt3;
571 typedef typename element_or_null<4, rets_t>::type rt4;
572 typedef typename element_or_null<5, rets_t>::type rt5;
573 typedef typename element_or_null<6, rets_t>::type rt6;
574 typedef typename element_or_null<7, rets_t>::type rt7;
575 typedef typename element_or_null<8, rets_t>::type rt8;
576 typedef typename element_or_null<9, rets_t>::type rt9;
578 return Act::template apply<RET>(
579 constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
580 constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
581 constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
582 constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
583 constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
584 constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
585 constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
586 constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS)),
587 constify_rvals<rt8>::go(r_select<rt8>::go(get<8>(args), CALL_ACTUAL_ARGS)),
588 constify_rvals<rt9>::go(r_select<rt9>::go(get<9>(args), CALL_ACTUAL_ARGS))
593 #undef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART
596 } // namespace lambda