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
00030
00031
00032
00033
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
00090
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
00104
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
00198
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
00257
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
00424
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
00519
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
00558
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
00575
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
00600
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
00614
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