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