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