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