File indexing completed on 2025-01-18 09:39:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_LAMBDA_LAMBDA_TRAITS_HPP
0013 #define BOOST_LAMBDA_LAMBDA_TRAITS_HPP
0014
0015 #include "boost/type_traits/transform_traits.hpp"
0016 #include "boost/type_traits/cv_traits.hpp"
0017 #include "boost/type_traits/function_traits.hpp"
0018 #include "boost/type_traits/object_traits.hpp"
0019 #include "boost/tuple/tuple.hpp"
0020
0021 namespace boost {
0022 namespace lambda {
0023
0024
0025
0026
0027 namespace detail {
0028
0029 template <bool If, class Then, class Else> struct IF { typedef Then RET; };
0030
0031 template <class Then, class Else> struct IF<false, Then, Else> {
0032 typedef Else RET;
0033 };
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 template<class T>
0044 struct IF_type_
0045 {
0046 typedef typename T::type type;
0047 };
0048
0049
0050 template<bool C, class T, class E>
0051 struct IF_type
0052 {
0053 typedef typename
0054 IF_type_<typename IF<C, T, E>::RET >::type type;
0055 };
0056
0057
0058 template <class T> struct identity_mapping { typedef T type; };
0059
0060
0061
0062
0063
0064
0065 template<class T>
0066 struct IF_value_
0067 {
0068 BOOST_STATIC_CONSTANT(int, value = T::value);
0069 };
0070
0071
0072 template<bool C, class T, class E>
0073 struct IF_value
0074 {
0075 BOOST_STATIC_CONSTANT(int, value = (IF_value_<typename IF<C, T, E>::RET>::value));
0076 };
0077
0078
0079
0080
0081
0082 template<class T> class remove_reference_if_valid
0083 {
0084
0085 typedef typename boost::remove_reference<T>::type plainT;
0086 public:
0087 typedef typename IF<
0088 boost::is_function<plainT>::value,
0089 T,
0090 plainT
0091 >::RET type;
0092
0093 };
0094
0095
0096 template<class T> struct remove_reference_and_cv {
0097 typedef typename boost::remove_cv<
0098 typename boost::remove_reference<T>::type
0099 >::type type;
0100 };
0101
0102
0103
0104
0105 template<int N, class T> struct tuple_element_as_reference {
0106 typedef typename
0107 boost::tuples::access_traits<
0108 typename boost::tuples::element<N, T>::type
0109 >::non_const_type type;
0110 };
0111
0112
0113 template<int N, class T> struct tuple_element_stripped {
0114 typedef typename
0115 remove_reference_and_cv<
0116 typename boost::tuples::element<N, T>::type
0117 >::type type;
0118 };
0119
0120
0121
0122 template <class T> struct is_lambda_functor_ {
0123 BOOST_STATIC_CONSTANT(bool, value = false);
0124 };
0125
0126 template <class Arg> struct is_lambda_functor_<lambda_functor<Arg> > {
0127 BOOST_STATIC_CONSTANT(bool, value = true);
0128 };
0129
0130 }
0131
0132
0133 template <class T> struct is_lambda_functor {
0134 BOOST_STATIC_CONSTANT(bool,
0135 value =
0136 detail::is_lambda_functor_<
0137 typename detail::remove_reference_and_cv<T>::type
0138 >::value);
0139 };
0140
0141
0142 namespace detail {
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 template<class T1, class T2>
0160 struct parameter_traits_ {
0161 typedef T2 type;
0162 };
0163
0164
0165 template<class T, class Any> struct parameter_traits_<T&, Any> {
0166 typedef typename
0167 generate_error<T&>::
0168 parameter_traits_class_instantiated_with_reference_type type;
0169 };
0170
0171
0172 template<class T, int n, class Any> struct parameter_traits_<T[n], Any> {
0173 typedef T (&type)[n];
0174 };
0175
0176 template<class T, int n, class Any>
0177 struct parameter_traits_<const T[n], Any> {
0178 typedef const T (&type)[n];
0179 };
0180
0181 template<class T, int n, class Any>
0182 struct parameter_traits_<volatile T[n], Any> {
0183 typedef volatile T (&type)[n];
0184 };
0185 template<class T, int n, class Any>
0186 struct parameter_traits_<const volatile T[n], Any> {
0187 typedef const volatile T (&type)[n];
0188 };
0189
0190
0191 template<class T, class Any>
0192 struct parameter_traits_<boost::reference_wrapper<T>, Any >{
0193 typedef T& type;
0194 };
0195
0196 template<class T, class Any>
0197 struct parameter_traits_<const boost::reference_wrapper<T>, Any >{
0198 typedef T& type;
0199 };
0200
0201 template<class T, class Any>
0202 struct parameter_traits_<volatile boost::reference_wrapper<T>, Any >{
0203 typedef T& type;
0204 };
0205
0206 template<class T, class Any>
0207 struct parameter_traits_<const volatile boost::reference_wrapper<T>, Any >{
0208 typedef T& type;
0209 };
0210
0211 template<class Any>
0212 struct parameter_traits_<void, Any> {
0213 typedef void type;
0214 };
0215
0216 template<class Arg, class Any>
0217 struct parameter_traits_<lambda_functor<Arg>, Any > {
0218 typedef lambda_functor<Arg> type;
0219 };
0220
0221 template<class Arg, class Any>
0222 struct parameter_traits_<const lambda_functor<Arg>, Any > {
0223 typedef lambda_functor<Arg> type;
0224 };
0225
0226
0227 template<class Arg, class Any>
0228 struct parameter_traits_<volatile lambda_functor<Arg>, Any > {
0229 typedef lambda_functor<Arg> type;
0230 };
0231
0232 template<class Arg, class Any>
0233 struct parameter_traits_<const volatile lambda_functor<Arg>, Any > {
0234 typedef lambda_functor<Arg> type;
0235 };
0236
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 template<class T>
0252 struct const_copy_argument {
0253 typedef typename
0254 detail::parameter_traits_<
0255 T,
0256 typename detail::IF<boost::is_function<T>::value, T&, const T>::RET
0257 >::type type;
0258 };
0259
0260
0261
0262
0263
0264
0265
0266
0267 template<class T, int n> struct const_copy_argument <T[n]> {
0268 typedef const T (&type)[n];
0269 };
0270 template<class T, int n> struct const_copy_argument <volatile T[n]> {
0271 typedef const volatile T (&type)[n];
0272 };
0273
0274 template<class T>
0275 struct const_copy_argument<T&> {};
0276
0277
0278
0279
0280 template<>
0281 struct const_copy_argument<void> {
0282 typedef void type;
0283 };
0284
0285 template<>
0286 struct const_copy_argument<void const> {
0287 typedef void type;
0288 };
0289
0290
0291
0292 template<class T>
0293 struct bound_argument_conversion {
0294 typedef typename const_copy_argument<T>::type type;
0295 };
0296
0297 template<class T>
0298 struct bound_argument_conversion<T&> {
0299 typedef T& type;
0300 };
0301
0302
0303
0304
0305
0306
0307 template<class T>
0308 struct reference_argument {
0309 typedef typename detail::parameter_traits_<T, T&>::type type;
0310 };
0311
0312 template<class T>
0313 struct reference_argument<T&> {
0314 typedef typename detail::generate_error<T&>::references_not_allowed type;
0315 };
0316
0317 template<class Arg>
0318 struct reference_argument<lambda_functor<Arg> > {
0319 typedef lambda_functor<Arg> type;
0320 };
0321
0322 template<class Arg>
0323 struct reference_argument<const lambda_functor<Arg> > {
0324 typedef lambda_functor<Arg> type;
0325 };
0326
0327
0328 template<class Arg>
0329 struct reference_argument<volatile lambda_functor<Arg> > {
0330 typedef lambda_functor<Arg> type;
0331 };
0332
0333 template<class Arg>
0334 struct reference_argument<const volatile lambda_functor<Arg> > {
0335 typedef lambda_functor<Arg> type;
0336 };
0337
0338 template<>
0339 struct reference_argument<void> {
0340 typedef void type;
0341 };
0342
0343 namespace detail {
0344
0345
0346 template <class T>
0347 struct array_to_pointer {
0348 typedef T type;
0349 };
0350
0351 template <class T, int N>
0352 struct array_to_pointer <const T[N]> {
0353 typedef const T* type;
0354 };
0355 template <class T, int N>
0356 struct array_to_pointer <T[N]> {
0357 typedef T* type;
0358 };
0359
0360 template <class T, int N>
0361 struct array_to_pointer <const T (&) [N]> {
0362 typedef const T* type;
0363 };
0364 template <class T, int N>
0365 struct array_to_pointer <T (&) [N]> {
0366 typedef T* type;
0367 };
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393 template<class T>
0394 struct bind_traits {
0395 typedef const T type;
0396 };
0397
0398 template<class T>
0399 struct bind_traits<T&> {
0400 typedef T& type;
0401 };
0402
0403
0404
0405 template<>
0406 struct bind_traits<null_type> {
0407 typedef null_type type;
0408 };
0409
0410
0411
0412 template<>
0413 struct bind_traits<const null_type> {
0414 typedef null_type type;
0415 };
0416
0417
0418
0419
0420
0421 template<class T, int n> struct bind_traits <T[n]> {
0422 typedef const T (&type)[n];
0423 };
0424
0425 template<class T, int n>
0426 struct bind_traits<const T[n]> {
0427 typedef const T (&type)[n];
0428 };
0429
0430 template<class T, int n> struct bind_traits<volatile T[n]> {
0431 typedef const volatile T (&type)[n];
0432 };
0433
0434 template<class T, int n>
0435 struct bind_traits<const volatile T[n]> {
0436 typedef const volatile T (&type)[n];
0437 };
0438
0439 template<class R>
0440 struct bind_traits<R()> {
0441 typedef R(&type)();
0442 };
0443
0444 template<class R, class Arg1>
0445 struct bind_traits<R(Arg1)> {
0446 typedef R(&type)(Arg1);
0447 };
0448
0449 template<class R, class Arg1, class Arg2>
0450 struct bind_traits<R(Arg1, Arg2)> {
0451 typedef R(&type)(Arg1, Arg2);
0452 };
0453
0454 template<class R, class Arg1, class Arg2, class Arg3>
0455 struct bind_traits<R(Arg1, Arg2, Arg3)> {
0456 typedef R(&type)(Arg1, Arg2, Arg3);
0457 };
0458
0459 template<class R, class Arg1, class Arg2, class Arg3, class Arg4>
0460 struct bind_traits<R(Arg1, Arg2, Arg3, Arg4)> {
0461 typedef R(&type)(Arg1, Arg2, Arg3, Arg4);
0462 };
0463
0464 template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
0465 struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5)> {
0466 typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5);
0467 };
0468
0469 template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
0470 struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
0471 typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
0472 };
0473
0474 template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
0475 struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
0476 typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7);
0477 };
0478
0479 template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8>
0480 struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
0481 typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
0482 };
0483
0484 template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9>
0485 struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> {
0486 typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
0487 };
0488
0489 template<class T>
0490 struct bind_traits<reference_wrapper<T> >{
0491 typedef T& type;
0492 };
0493
0494 template<class T>
0495 struct bind_traits<const reference_wrapper<T> >{
0496 typedef T& type;
0497 };
0498
0499 template<>
0500 struct bind_traits<void> {
0501 typedef void type;
0502 };
0503
0504
0505
0506 template <
0507 class T0 = null_type, class T1 = null_type, class T2 = null_type,
0508 class T3 = null_type, class T4 = null_type, class T5 = null_type,
0509 class T6 = null_type, class T7 = null_type, class T8 = null_type,
0510 class T9 = null_type
0511 >
0512 struct bind_tuple_mapper {
0513 typedef
0514 tuple<typename bind_traits<T0>::type,
0515 typename bind_traits<T1>::type,
0516 typename bind_traits<T2>::type,
0517 typename bind_traits<T3>::type,
0518 typename bind_traits<T4>::type,
0519 typename bind_traits<T5>::type,
0520 typename bind_traits<T6>::type,
0521 typename bind_traits<T7>::type,
0522 typename bind_traits<T8>::type,
0523 typename bind_traits<T9>::type> type;
0524 };
0525
0526
0527
0528
0529 template <class T> struct remove_const_reference {
0530 typedef typename bind_traits<T>::type type;
0531 };
0532
0533 template <class T> struct remove_const_reference<const T&> {
0534 typedef const T type;
0535 };
0536
0537
0538
0539 template <
0540 class T0 = null_type, class T1 = null_type, class T2 = null_type,
0541 class T3 = null_type, class T4 = null_type, class T5 = null_type,
0542 class T6 = null_type, class T7 = null_type, class T8 = null_type,
0543 class T9 = null_type
0544 >
0545 class bind_type_generator {
0546
0547 typedef typename
0548 detail::bind_tuple_mapper<
0549 T0, T1, T2, T3, T4, T5, T6, T7, T8, T9
0550 >::type args_t;
0551
0552 BOOST_STATIC_CONSTANT(int, nof_elems = boost::tuples::length<args_t>::value);
0553
0554 typedef
0555 action<
0556 nof_elems,
0557 function_action<nof_elems>
0558 > action_type;
0559
0560 public:
0561 typedef
0562 lambda_functor<
0563 lambda_functor_base<
0564 action_type,
0565 args_t
0566 >
0567 > type;
0568
0569 };
0570
0571
0572
0573 }
0574
0575 template <class T> inline const T& make_const(const T& t) { return t; }
0576
0577
0578 }
0579 }
0580
0581
0582
0583 #endif