00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00034 #ifndef _TYPE_TRAITS
00035 #define _TYPE_TRAITS 1
00036
00037 #include <bits/c++config.h>
00038 #include <tr1/type_traits_fwd.h>
00039
00040
00041 namespace std
00042 {
00043 namespace tr1
00044 {
00045
00046 struct __sfinae_types
00047 {
00048 typedef char __one;
00049 typedef struct { char __arr[2]; } __two;
00050 };
00051
00052 template<typename _Tp>
00053 struct __in_array
00054 : public __sfinae_types
00055 {
00056 private:
00057 template<typename _Up>
00058 static __one __test(_Up(*)[1]);
00059 template<typename>
00060 static __two __test(...);
00061
00062 public:
00063 static const bool __value = sizeof(__test<_Tp>(0)) == 1;
00064 };
00065
00066 #define _DEFINE_SPEC_BODY(_Value) \
00067 : public integral_constant<bool, _Value> { };
00068
00069 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \
00070 template<> \
00071 struct _Spec \
00072 _DEFINE_SPEC_BODY(_Value)
00073
00074 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value) \
00075 template<typename _Tp> \
00076 struct _Spec \
00077 _DEFINE_SPEC_BODY(_Value)
00078
00079 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value) \
00080 template<typename _Tp, typename _Cp> \
00081 struct _Spec \
00082 _DEFINE_SPEC_BODY(_Value)
00083
00084 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \
00085 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \
00086 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \
00087 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \
00088 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
00089
00091 template<typename _Tp, _Tp __v>
00092 struct integral_constant
00093 {
00094 static const _Tp value = __v;
00095 typedef _Tp value_type;
00096 typedef integral_constant<_Tp, __v> type;
00097 };
00098 typedef integral_constant<bool, true> true_type;
00099 typedef integral_constant<bool, false> false_type;
00100
00101 template<typename _Tp, _Tp __v>
00102 const _Tp integral_constant<_Tp, __v>::value;
00103
00105 template<typename>
00106 struct is_void
00107 : public false_type { };
00108 _DEFINE_SPEC(0, is_void, void, true)
00109
00110 template<typename>
00111 struct is_integral
00112 : public false_type { };
00113 _DEFINE_SPEC(0, is_integral, bool, true)
00114 _DEFINE_SPEC(0, is_integral, char, true)
00115 _DEFINE_SPEC(0, is_integral, signed char, true)
00116 _DEFINE_SPEC(0, is_integral, unsigned char, true)
00117 #ifdef _GLIBCXX_USE_WCHAR_T
00118 _DEFINE_SPEC(0, is_integral, wchar_t, true)
00119 #endif
00120 _DEFINE_SPEC(0, is_integral, short, true)
00121 _DEFINE_SPEC(0, is_integral, unsigned short, true)
00122 _DEFINE_SPEC(0, is_integral, int, true)
00123 _DEFINE_SPEC(0, is_integral, unsigned int, true)
00124 _DEFINE_SPEC(0, is_integral, long, true)
00125 _DEFINE_SPEC(0, is_integral, unsigned long, true)
00126 _DEFINE_SPEC(0, is_integral, long long, true)
00127 _DEFINE_SPEC(0, is_integral, unsigned long long, true)
00128
00129 template<typename>
00130 struct is_floating_point
00131 : public false_type { };
00132 _DEFINE_SPEC(0, is_floating_point, float, true)
00133 _DEFINE_SPEC(0, is_floating_point, double, true)
00134 _DEFINE_SPEC(0, is_floating_point, long double, true)
00135
00136 template<typename>
00137 struct is_array
00138 : public false_type { };
00139
00140 template<typename _Tp, std::size_t _Size>
00141 struct is_array<_Tp[_Size]>
00142 : public true_type { };
00143
00144 template<typename _Tp>
00145 struct is_array<_Tp[]>
00146 : public true_type { };
00147
00148 template<typename>
00149 struct is_pointer
00150 : public false_type { };
00151 _DEFINE_SPEC(1, is_pointer, _Tp*, true)
00152
00153 template<typename>
00154 struct is_reference
00155 : public false_type { };
00156
00157 template<typename _Tp>
00158 struct is_reference<_Tp&>
00159 : public true_type { };
00160
00161 template<typename>
00162 struct is_member_object_pointer
00163 : public false_type { };
00164 _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
00165 !is_function<_Tp>::value)
00166
00167 template<typename>
00168 struct is_member_function_pointer
00169 : public false_type { };
00170 _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
00171 is_function<_Tp>::value)
00172
00173 template<typename _Tp>
00174 struct is_enum
00175 : public integral_constant<bool, !(is_fundamental<_Tp>::value
00176 || is_array<_Tp>::value
00177 || is_pointer<_Tp>::value
00178 || is_reference<_Tp>::value
00179 || is_member_pointer<_Tp>::value
00180 || is_function<_Tp>::value
00181 || __is_union_or_class<_Tp>::value)>
00182 { };
00183
00184 template<typename>
00185 struct is_union { };
00186
00187 template<typename>
00188 struct is_class { };
00189
00190 template<typename _Tp>
00191 struct is_function
00192 : public integral_constant<bool, !(__in_array<_Tp>::__value
00193 || __is_union_or_class<_Tp>::value
00194 || is_reference<_Tp>::value
00195 || is_void<_Tp>::value)>
00196 { };
00197
00199 template<typename _Tp>
00200 struct is_arithmetic
00201 : public integral_constant<bool, (is_integral<_Tp>::value
00202 || is_floating_point<_Tp>::value)>
00203 { };
00204
00205 template<typename _Tp>
00206 struct is_fundamental
00207 : public integral_constant<bool, (is_arithmetic<_Tp>::value
00208 || is_void<_Tp>::value)>
00209 { };
00210
00211 template<typename _Tp>
00212 struct is_object
00213 : public integral_constant<bool, !(is_function<_Tp>::value
00214 || is_reference<_Tp>::value
00215 || is_void<_Tp>::value)>
00216 { };
00217
00218 template<typename _Tp>
00219 struct is_scalar
00220 : public integral_constant<bool, (is_arithmetic<_Tp>::value
00221 || is_enum<_Tp>::value
00222 || is_pointer<_Tp>::value
00223 || is_member_pointer<_Tp>::value)>
00224 { };
00225
00226 template<typename _Tp>
00227 struct is_compound
00228 : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
00229
00230 template<typename _Tp>
00231 struct is_member_pointer
00232 : public integral_constant<bool,
00233 (is_member_object_pointer<_Tp>::value
00234 || is_member_function_pointer<_Tp>::value)>
00235 { };
00236
00237 template<typename _Tp>
00238 struct __is_union_or_class_helper
00239 : public __sfinae_types
00240 {
00241 private:
00242 template<typename _Up>
00243 static __one __test(int _Up::*);
00244 template<typename>
00245 static __two __test(...);
00246
00247 public:
00248 static const bool __value = sizeof(__test<_Tp>(0)) == 1;
00249 };
00250
00251
00252 template<typename _Tp>
00253 struct __is_union_or_class
00254 : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value>
00255 { };
00256
00258 template<typename>
00259 struct is_const
00260 : public false_type { };
00261
00262 template<typename _Tp>
00263 struct is_const<_Tp const>
00264 : public true_type { };
00265
00266 template<typename>
00267 struct is_volatile
00268 : public false_type { };
00269
00270 template<typename _Tp>
00271 struct is_volatile<_Tp volatile>
00272 : public true_type { };
00273
00274 template<typename _Tp>
00275 struct is_pod
00276 : public integral_constant<bool, (is_void<_Tp>::value
00277 || is_scalar<typename
00278 remove_all_extents<_Tp>::type>::value)>
00279 { };
00280
00281
00282
00283 template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
00284 struct __is_empty_helper
00285 {
00286 private:
00287 template<typename>
00288 struct __first { };
00289 template<typename _Up>
00290 struct __second
00291 : public _Up { };
00292
00293 public:
00294 static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
00295 };
00296
00297 template<typename _Tp>
00298 struct __is_empty_helper<_Tp, true>
00299 { static const bool __value = false; };
00300
00301 template<typename _Tp>
00302 struct is_empty
00303 : public integral_constant<bool, __is_empty_helper<_Tp>::__value>
00304 { };
00305
00306 template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
00307 struct __is_polymorphic_helper
00308 {
00309 private:
00310 template<typename _Up>
00311 struct __first
00312 : public _Up { };
00313 template<typename _Up>
00314 struct __second
00315 : public _Up
00316 {
00317 virtual void __dummy();
00318 virtual ~__second() throw();
00319 };
00320
00321 public:
00322 static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
00323 };
00324
00325 template<typename _Tp>
00326 struct __is_polymorphic_helper<_Tp, true>
00327 { static const bool __value = false; };
00328
00329 template<typename _Tp>
00330 struct is_polymorphic
00331 : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value>
00332 { };
00333
00334
00335 template<typename _Tp>
00336 struct is_abstract
00337 : public integral_constant<bool, (!__in_array<_Tp>::__value
00338 && __is_union_or_class<_Tp>::value)> { };
00339
00340 template<typename _Tp>
00341 struct has_trivial_constructor
00342 : public integral_constant<bool, is_pod<_Tp>::value> { };
00343
00344 template<typename _Tp>
00345 struct has_trivial_copy
00346 : public integral_constant<bool, is_pod<_Tp>::value> { };
00347
00348 template<typename _Tp>
00349 struct has_trivial_assign
00350 : public integral_constant<bool, is_pod<_Tp>::value> { };
00351
00352 template<typename _Tp>
00353 struct has_trivial_destructor
00354 : public integral_constant<bool, is_pod<_Tp>::value> { };
00355
00356 template<typename _Tp>
00357 struct has_nothrow_constructor
00358 : public integral_constant<bool, is_pod<_Tp>::value> { };
00359
00360 template<typename _Tp>
00361 struct has_nothrow_copy
00362 : public integral_constant<bool, is_pod<_Tp>::value> { };
00363
00364 template<typename _Tp>
00365 struct has_nothrow_assign
00366 : public integral_constant<bool, is_pod<_Tp>::value> { };
00367
00368 template<typename>
00369 struct has_virtual_destructor
00370 : public false_type { };
00371
00372 template<typename>
00373 struct is_signed
00374 : public false_type { };
00375 _DEFINE_SPEC(0, is_signed, signed char, true)
00376 _DEFINE_SPEC(0, is_signed, short, true)
00377 _DEFINE_SPEC(0, is_signed, int, true)
00378 _DEFINE_SPEC(0, is_signed, long, true)
00379 _DEFINE_SPEC(0, is_signed, long long, true)
00380
00381 template<typename>
00382 struct is_unsigned
00383 : public false_type { };
00384 _DEFINE_SPEC(0, is_unsigned, unsigned char, true)
00385 _DEFINE_SPEC(0, is_unsigned, unsigned short, true)
00386 _DEFINE_SPEC(0, is_unsigned, unsigned int, true)
00387 _DEFINE_SPEC(0, is_unsigned, unsigned long, true)
00388 _DEFINE_SPEC(0, is_unsigned, unsigned long long, true)
00389
00390 template<typename _Tp>
00391 struct alignment_of
00392 : public integral_constant<std::size_t, __alignof__(_Tp)> { };
00393
00394 template<typename>
00395 struct rank
00396 : public integral_constant<std::size_t, 0> { };
00397
00398 template<typename _Tp, std::size_t _Size>
00399 struct rank<_Tp[_Size]>
00400 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
00401
00402 template<typename _Tp>
00403 struct rank<_Tp[]>
00404 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
00405
00406 template<typename, unsigned>
00407 struct extent
00408 : public integral_constant<std::size_t, 0> { };
00409
00410 template<typename _Tp, unsigned _Uint, std::size_t _Size>
00411 struct extent<_Tp[_Size], _Uint>
00412 : public integral_constant<std::size_t,
00413 _Uint == 0 ? _Size : extent<_Tp,
00414 _Uint - 1>::value>
00415 { };
00416
00417 template<typename _Tp, unsigned _Uint>
00418 struct extent<_Tp[], _Uint>
00419 : public integral_constant<std::size_t,
00420 _Uint == 0 ? 0 : extent<_Tp,
00421 _Uint - 1>::value>
00422 { };
00423
00425 template<typename, typename>
00426 struct is_same
00427 : public false_type { };
00428
00429 template<typename _Tp>
00430 struct is_same<_Tp, _Tp>
00431 : public true_type { };
00432
00433
00434
00435 template<typename _Base, typename _Derived,
00436 bool = (!__is_union_or_class<_Base>::value
00437 || !__is_union_or_class<_Derived>::value
00438 || is_same<_Base, _Derived>::value)>
00439 struct __is_base_of_helper
00440 : public __sfinae_types
00441 {
00442 private:
00443 typedef typename remove_cv<_Base>::type _NoCv_Base;
00444 typedef typename remove_cv<_Derived>::type _NoCv_Derived;
00445
00446 template<typename _Up>
00447 static __one __test(_NoCv_Derived&, _Up);
00448 static __two __test(_NoCv_Base&, int);
00449
00450 struct _Conv
00451 {
00452 operator _NoCv_Derived&();
00453 operator _NoCv_Base&() const;
00454 };
00455
00456 public:
00457 static const bool __value = sizeof(__test(_Conv(), 0)) == 1;
00458 };
00459
00460 template<typename _Base, typename _Derived>
00461 struct __is_base_of_helper<_Base, _Derived, true>
00462 { static const bool __value = is_same<_Base, _Derived>::value; };
00463
00464 template<typename _Base, typename _Derived>
00465 struct is_base_of
00466 : public integral_constant<bool,
00467 __is_base_of_helper<_Base, _Derived>::__value>
00468 { };
00469
00470 template<typename _From, typename _To>
00471 struct __is_convertible_simple
00472 : public __sfinae_types
00473 {
00474 private:
00475 static __one __test(_To);
00476 static __two __test(...);
00477 static _From __makeFrom();
00478
00479 public:
00480 static const bool __value = sizeof(__test(__makeFrom())) == 1;
00481 };
00482
00483 template<typename _Tp>
00484 struct __is_int_or_cref
00485 {
00486 typedef typename remove_reference<_Tp>::type __rr_Tp;
00487 static const bool __value = (is_integral<_Tp>::value
00488 || (is_integral<__rr_Tp>::value
00489 && is_const<__rr_Tp>::value
00490 && !is_volatile<__rr_Tp>::value));
00491 };
00492
00493 template<typename _From, typename _To,
00494 bool = (is_void<_From>::value || is_void<_To>::value
00495 || is_function<_To>::value || is_array<_To>::value
00496
00497 || (is_floating_point<typename
00498 remove_reference<_From>::type>::value
00499 && __is_int_or_cref<_To>::__value))>
00500 struct __is_convertible_helper
00501 {
00502
00503 static const bool __value = (__is_convertible_simple<typename
00504 add_reference<_From>::type, _To>::__value);
00505 };
00506
00507 template<typename _From, typename _To>
00508 struct __is_convertible_helper<_From, _To, true>
00509 { static const bool __value = (is_void<_To>::value
00510 || (__is_int_or_cref<_To>::__value
00511 && !is_void<_From>::value)); };
00512
00513 template<typename _From, typename _To>
00514 struct is_convertible
00515 : public integral_constant<bool,
00516 __is_convertible_helper<_From, _To>::__value>
00517 { };
00518
00520 template<typename _Tp>
00521 struct remove_const
00522 { typedef _Tp type; };
00523
00524 template<typename _Tp>
00525 struct remove_const<_Tp const>
00526 { typedef _Tp type; };
00527
00528 template<typename _Tp>
00529 struct remove_volatile
00530 { typedef _Tp type; };
00531
00532 template<typename _Tp>
00533 struct remove_volatile<_Tp volatile>
00534 { typedef _Tp type; };
00535
00536 template<typename _Tp>
00537 struct remove_cv
00538 {
00539 typedef typename
00540 remove_const<typename remove_volatile<_Tp>::type>::type type;
00541 };
00542
00543 template<typename _Tp>
00544 struct add_const
00545 { typedef _Tp const type; };
00546
00547 template<typename _Tp>
00548 struct add_volatile
00549 { typedef _Tp volatile type; };
00550
00551 template<typename _Tp>
00552 struct add_cv
00553 {
00554 typedef typename
00555 add_const<typename add_volatile<_Tp>::type>::type type;
00556 };
00557
00559 template<typename _Tp>
00560 struct remove_reference
00561 { typedef _Tp type; };
00562
00563 template<typename _Tp>
00564 struct remove_reference<_Tp&>
00565 { typedef _Tp type; };
00566
00567 template<typename _Tp>
00568 struct add_reference
00569 { typedef _Tp& type; };
00570
00571 template<typename _Tp>
00572 struct add_reference<_Tp&>
00573 { typedef _Tp& type; };
00574
00576 template<typename _Tp>
00577 struct remove_extent
00578 { typedef _Tp type; };
00579
00580 template<typename _Tp, std::size_t _Size>
00581 struct remove_extent<_Tp[_Size]>
00582 { typedef _Tp type; };
00583
00584 template<typename _Tp>
00585 struct remove_extent<_Tp[]>
00586 { typedef _Tp type; };
00587
00588 template<typename _Tp>
00589 struct remove_all_extents
00590 { typedef _Tp type; };
00591
00592 template<typename _Tp, std::size_t _Size>
00593 struct remove_all_extents<_Tp[_Size]>
00594 { typedef typename remove_all_extents<_Tp>::type type; };
00595
00596 template<typename _Tp>
00597 struct remove_all_extents<_Tp[]>
00598 { typedef typename remove_all_extents<_Tp>::type type; };
00599
00601 #undef _DEFINE_SPEC_BODY
00602 #define _DEFINE_SPEC_BODY(_Value) \
00603 { typedef _Tp type; };
00604
00605 template<typename _Tp>
00606 struct remove_pointer
00607 { typedef _Tp type; };
00608 _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
00609
00610 template<typename _Tp>
00611 struct add_pointer
00612 { typedef typename remove_reference<_Tp>::type* type; };
00613
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 template<std::size_t, std::size_t>
00625 struct aligned_storage { };
00626
00627 template<std::size_t _Len>
00628 struct aligned_storage<_Len, 1>
00629 {
00630 union type
00631 {
00632 unsigned char __data[_Len];
00633 char __align __attribute__((__aligned__(1)));
00634 };
00635 };
00636
00637 template<std::size_t _Len>
00638 struct aligned_storage<_Len, 2>
00639 {
00640 union type
00641 {
00642 unsigned char __data[_Len];
00643 char __align __attribute__((__aligned__(2)));
00644 };
00645 };
00646
00647 template<std::size_t _Len>
00648 struct aligned_storage<_Len, 4>
00649 {
00650 union type
00651 {
00652 unsigned char __data[_Len];
00653 char __align __attribute__((__aligned__(4)));
00654 };
00655 };
00656
00657 template<std::size_t _Len>
00658 struct aligned_storage<_Len, 8>
00659 {
00660 union type
00661 {
00662 unsigned char __data[_Len];
00663 char __align __attribute__((__aligned__(8)));
00664 };
00665 };
00666
00667 template<std::size_t _Len>
00668 struct aligned_storage<_Len, 16>
00669 {
00670 union type
00671 {
00672 unsigned char __data[_Len];
00673 char __align __attribute__((__aligned__(16)));
00674 };
00675 };
00676
00677 template<std::size_t _Len>
00678 struct aligned_storage<_Len, 32>
00679 {
00680 union type
00681 {
00682 unsigned char __data[_Len];
00683 char __align __attribute__((__aligned__(32)));
00684 };
00685 };
00686
00687 #undef _DEFINE_SPEC_0_HELPER
00688 #undef _DEFINE_SPEC_1_HELPER
00689 #undef _DEFINE_SPEC_2_HELPER
00690 #undef _DEFINE_SPEC
00691 #undef _DEFINE_SPEC_BODY
00692
00693 }
00694 }
00695
00696 #endif