File indexing completed on 2025-01-18 09:40:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
0015 #define BOOST_MOVE_DETAIL_META_UTILS_HPP
0016
0017 #if defined(BOOST_HAS_PRAGMA_ONCE)
0018 # pragma once
0019 #endif
0020 #include <boost/move/detail/config_begin.hpp>
0021 #include <boost/move/detail/workaround.hpp> //forceinline
0022 #include <boost/move/detail/meta_utils_core.hpp>
0023 #include <cstddef> //for std::size_t
0024 #include <boost/move/detail/addressof.hpp>
0025
0026
0027
0028 namespace boost {
0029
0030
0031 template <class T> class rv;
0032
0033 namespace move_detail {
0034
0035
0036
0037
0038 template<class T, class U>
0039 struct is_different
0040 {
0041 static const bool value = !is_same<T, U>::value;
0042 };
0043
0044
0045
0046
0047 template<class F, class Param>
0048 struct apply
0049 {
0050 typedef typename F::template apply<Param>::type type;
0051 };
0052
0053
0054
0055
0056
0057 template< bool C_ >
0058 struct bool_ : integral_constant<bool, C_>
0059 {
0060 BOOST_MOVE_FORCEINLINE operator bool() const { return C_; }
0061 BOOST_MOVE_FORCEINLINE bool operator()() const { return C_; }
0062 };
0063
0064 typedef bool_<true> true_;
0065 typedef bool_<false> false_;
0066
0067
0068
0069
0070 struct nat{};
0071 struct nat2{};
0072 struct nat3{};
0073
0074 template <unsigned N>
0075 struct natN
0076 {};
0077
0078
0079
0080
0081 typedef char yes_type;
0082
0083 struct no_type
0084 {
0085 char _[2];
0086 };
0087
0088
0089
0090
0091 template <class T> struct natify{};
0092
0093
0094
0095
0096 template<class T>
0097 struct remove_reference
0098 {
0099 typedef T type;
0100 };
0101
0102 template<class T>
0103 struct remove_reference<T&>
0104 {
0105 typedef T type;
0106 };
0107
0108 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0109
0110 template<class T>
0111 struct remove_reference<T&&>
0112 {
0113 typedef T type;
0114 };
0115
0116 #else
0117
0118 template<class T>
0119 struct remove_reference< rv<T> >
0120 {
0121 typedef T type;
0122 };
0123
0124 template<class T>
0125 struct remove_reference< rv<T> &>
0126 {
0127 typedef T type;
0128 };
0129
0130 template<class T>
0131 struct remove_reference< const rv<T> &>
0132 {
0133 typedef T type;
0134 };
0135
0136 #endif
0137
0138
0139
0140
0141
0142 template< class T > struct remove_pointer { typedef T type; };
0143 template< class T > struct remove_pointer<T*> { typedef T type; };
0144 template< class T > struct remove_pointer<T* const> { typedef T type; };
0145 template< class T > struct remove_pointer<T* volatile> { typedef T type; };
0146 template< class T > struct remove_pointer<T* const volatile> { typedef T type; };
0147
0148
0149
0150
0151 template< class T >
0152 struct add_pointer
0153 {
0154 typedef typename remove_reference<T>::type* type;
0155 };
0156
0157
0158
0159
0160 template<class T>
0161 struct add_const
0162 {
0163 typedef const T type;
0164 };
0165
0166 template<class T>
0167 struct add_const<T&>
0168 {
0169 typedef const T& type;
0170 };
0171
0172 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0173
0174 template<class T>
0175 struct add_const<T&&>
0176 {
0177 typedef T&& type;
0178 };
0179
0180 #endif
0181
0182
0183
0184
0185 template<class T>
0186 struct add_lvalue_reference
0187 { typedef T& type; };
0188
0189 template<class T> struct add_lvalue_reference<T&> { typedef T& type; };
0190 template<> struct add_lvalue_reference<void> { typedef void type; };
0191 template<> struct add_lvalue_reference<const void> { typedef const void type; };
0192 template<> struct add_lvalue_reference<volatile void> { typedef volatile void type; };
0193 template<> struct add_lvalue_reference<const volatile void>{ typedef const volatile void type; };
0194
0195 template<class T>
0196 struct add_const_lvalue_reference
0197 {
0198 typedef typename remove_reference<T>::type t_unreferenced;
0199 typedef typename add_const<t_unreferenced>::type t_unreferenced_const;
0200 typedef typename add_lvalue_reference
0201 <t_unreferenced_const>::type type;
0202 };
0203
0204
0205
0206
0207 template<class T>
0208 struct is_lvalue_reference
0209 {
0210 static const bool value = false;
0211 };
0212
0213 template<class T>
0214 struct is_lvalue_reference<T&>
0215 {
0216 static const bool value = true;
0217 };
0218
0219
0220
0221
0222
0223 template <class T>
0224 struct identity
0225 {
0226 typedef T type;
0227 typedef typename add_const_lvalue_reference<T>::type reference;
0228 BOOST_MOVE_FORCEINLINE reference operator()(reference t) const
0229 { return t; }
0230 };
0231
0232
0233
0234
0235 template<class T>
0236 struct is_class_or_union
0237 {
0238 struct twochar { char dummy[2]; };
0239 template <class U>
0240 static char is_class_or_union_tester(void(U::*)(void));
0241 template <class U>
0242 static twochar is_class_or_union_tester(...);
0243 static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
0244 };
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 template <class T>
0255 struct has_pointer_type
0256 {
0257 struct two { char c[2]; };
0258 template <class U> static two test(...);
0259 template <class U> static char test(typename U::pointer* = 0);
0260 static const bool value = sizeof(test<T>(0)) == 1;
0261 };
0262
0263
0264
0265
0266 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
0267
0268
0269
0270 template <class T, class U>
0271 struct is_convertible
0272 {
0273 static const bool value = __is_convertible_to(T, U);
0274 };
0275
0276 #else
0277
0278 template <class T, class U>
0279 class is_convertible
0280 {
0281 typedef typename add_lvalue_reference<T>::type t_reference;
0282 typedef char true_t;
0283 class false_t { char dummy[2]; };
0284 static false_t dispatch(...);
0285 static true_t dispatch(U);
0286 static t_reference trigger();
0287 public:
0288 static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
0289 };
0290
0291 #endif
0292
0293 template <class T, class U, bool IsSame = is_same<T, U>::value>
0294 struct is_same_or_convertible
0295 : is_convertible<T, U>
0296 {};
0297
0298 template <class T, class U>
0299 struct is_same_or_convertible<T, U, true>
0300 {
0301 static const bool value = true;
0302 };
0303
0304 template<
0305 bool C
0306 , typename F1
0307 , typename F2
0308 >
0309 struct eval_if_c
0310 : if_c<C,F1,F2>::type
0311 {};
0312
0313 template<
0314 typename C
0315 , typename T1
0316 , typename T2
0317 >
0318 struct eval_if
0319 : if_<C,T1,T2>::type
0320 {};
0321
0322
0323 #if defined(BOOST_GCC) && (BOOST_GCC <= 40000)
0324 #define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN
0325 #endif
0326
0327 template<class T, class U, class R = void>
0328 struct enable_if_convertible
0329 : enable_if< is_convertible<T, U>, R>
0330 {};
0331
0332 template<class T, class U, class R = void>
0333 struct disable_if_convertible
0334 : disable_if< is_convertible<T, U>, R>
0335 {};
0336
0337 template<class T, class U, class R = void>
0338 struct enable_if_same_or_convertible
0339 : enable_if< is_same_or_convertible<T, U>, R>
0340 {};
0341
0342 template<class T, class U, class R = void>
0343 struct disable_if_same_or_convertible
0344 : disable_if< is_same_or_convertible<T, U>, R>
0345 {};
0346
0347
0348
0349
0350
0351
0352 template<bool, class B = true_, class C = true_, class D = true_>
0353 struct and_impl
0354 : and_impl<B::value, C, D>
0355 {};
0356
0357 template<>
0358 struct and_impl<true, true_, true_, true_>
0359 {
0360 static const bool value = true;
0361 };
0362
0363 template<class B, class C, class D>
0364 struct and_impl<false, B, C, D>
0365 {
0366 static const bool value = false;
0367 };
0368
0369 template<class A, class B, class C = true_, class D = true_>
0370 struct and_
0371 : and_impl<A::value, B, C, D>
0372 {};
0373
0374
0375
0376
0377
0378
0379 template<bool, class B = false_, class C = false_, class D = false_>
0380 struct or_impl
0381 : or_impl<B::value, C, D>
0382 {};
0383
0384 template<>
0385 struct or_impl<false, false_, false_, false_>
0386 {
0387 static const bool value = false;
0388 };
0389
0390 template<class B, class C, class D>
0391 struct or_impl<true, B, C, D>
0392 {
0393 static const bool value = true;
0394 };
0395
0396 template<class A, class B, class C = false_, class D = false_>
0397 struct or_
0398 : or_impl<A::value, B, C, D>
0399 {};
0400
0401
0402
0403
0404
0405
0406 template<class T>
0407 struct not_
0408 {
0409 static const bool value = !T::value;
0410 };
0411
0412
0413
0414
0415
0416
0417
0418 template<class R, class A, class B, class C = true_, class D = true_>
0419 struct enable_if_and
0420 : enable_if_c< and_<A, B, C, D>::value, R>
0421 {};
0422
0423 template<class R, class A, class B, class C = true_, class D = true_>
0424 struct disable_if_and
0425 : disable_if_c< and_<A, B, C, D>::value, R>
0426 {};
0427
0428 template<class R, class A, class B, class C = false_, class D = false_>
0429 struct enable_if_or
0430 : enable_if_c< or_<A, B, C, D>::value, R>
0431 {};
0432
0433 template<class R, class A, class B, class C = false_, class D = false_>
0434 struct disable_if_or
0435 : disable_if_c< or_<A, B, C, D>::value, R>
0436 {};
0437
0438
0439
0440
0441
0442
0443 template<class T>
0444 struct has_move_emulation_enabled_impl
0445 : is_convertible< T, ::boost::rv<T>& >
0446 {};
0447
0448 template<class T>
0449 struct has_move_emulation_enabled_impl<T&>
0450 { static const bool value = false; };
0451
0452 template<class T>
0453 struct has_move_emulation_enabled_impl< ::boost::rv<T> >
0454 { static const bool value = false; };
0455
0456
0457
0458
0459
0460
0461
0462 template <class T>
0463 struct is_rv_impl
0464 { static const bool value = false; };
0465
0466 template <class T>
0467 struct is_rv_impl< rv<T> >
0468 { static const bool value = true; };
0469
0470 template <class T>
0471 struct is_rv_impl< const rv<T> >
0472 { static const bool value = true; };
0473
0474
0475
0476 template< class T >
0477 struct is_rvalue_reference
0478 { static const bool value = false; };
0479
0480 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0481
0482 template< class T >
0483 struct is_rvalue_reference< T&& >
0484 { static const bool value = true; };
0485
0486 #else
0487
0488 template< class T >
0489 struct is_rvalue_reference< boost::rv<T>& >
0490 { static const bool value = true; };
0491
0492 template< class T >
0493 struct is_rvalue_reference< const boost::rv<T>& >
0494 { static const bool value = true; };
0495
0496 #endif
0497
0498 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0499
0500 template< class T >
0501 struct add_rvalue_reference
0502 { typedef T&& type; };
0503
0504 #else
0505
0506 namespace detail_add_rvalue_reference
0507 {
0508 template< class T
0509 , bool emulation = has_move_emulation_enabled_impl<T>::value
0510 , bool rv = is_rv_impl<T>::value >
0511 struct add_rvalue_reference_impl { typedef T type; };
0512
0513 template< class T, bool emulation>
0514 struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
0515
0516 template< class T, bool rv >
0517 struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };
0518 }
0519
0520 template< class T >
0521 struct add_rvalue_reference
0522 : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
0523 { };
0524
0525 template< class T >
0526 struct add_rvalue_reference<T &>
0527 { typedef T & type; };
0528
0529 #endif
0530
0531 template< class T > struct remove_rvalue_reference { typedef T type; };
0532
0533 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0534 template< class T > struct remove_rvalue_reference< T&& > { typedef T type; };
0535 #else
0536 template< class T > struct remove_rvalue_reference< rv<T> > { typedef T type; };
0537 template< class T > struct remove_rvalue_reference< const rv<T> > { typedef T type; };
0538 template< class T > struct remove_rvalue_reference< volatile rv<T> > { typedef T type; };
0539 template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
0540 template< class T > struct remove_rvalue_reference< rv<T>& > { typedef T type; };
0541 template< class T > struct remove_rvalue_reference< const rv<T>& > { typedef T type; };
0542 template< class T > struct remove_rvalue_reference< volatile rv<T>& > { typedef T type; };
0543 template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
0544 #endif
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558 }
0559 }
0560
0561 #include <boost/move/detail/config_end.hpp>
0562
0563 #endif