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_void<_From>::value || is_void<_To>::value
00505 || is_function<_To>::value || is_array<_To>::value
00506
00507 || (is_floating_point<typename
00508 remove_reference<_From>::type>::value
00509 && __is_int_or_cref<_To>::__value))>
00510 struct __is_convertible_helper
00511 {
00512
00513 static const bool __value = (__conv_helper<typename
00514 add_reference<_From>::type, _To>::__value);
00515 };
00516
00517 template<typename _From, typename _To>
00518 struct __is_convertible_helper<_From, _To, true>
00519 { static const bool __value = (is_void<_To>::value
00520 || (__is_int_or_cref<_To>::__value
00521 && !is_void<_From>::value)); };
00522
00523 template<typename _From, typename _To>
00524 struct is_convertible
00525 : public integral_constant<bool,
00526 __is_convertible_helper<_From, _To>::__value>
00527 { };
00528
00529
00530 template<typename _Tp>
00531 struct remove_const
00532 { typedef _Tp type; };
00533
00534 template<typename _Tp>
00535 struct remove_const<_Tp const>
00536 { typedef _Tp type; };
00537
00538 template<typename _Tp>
00539 struct remove_volatile
00540 { typedef _Tp type; };
00541
00542 template<typename _Tp>
00543 struct remove_volatile<_Tp volatile>
00544 { typedef _Tp type; };
00545
00546 template<typename _Tp>
00547 struct remove_cv
00548 {
00549 typedef typename
00550 remove_const<typename remove_volatile<_Tp>::type>::type type;
00551 };
00552
00553 template<typename _Tp>
00554 struct add_const
00555 { typedef _Tp const type; };
00556
00557 template<typename _Tp>
00558 struct add_volatile
00559 { typedef _Tp volatile type; };
00560
00561 template<typename _Tp>
00562 struct add_cv
00563 {
00564 typedef typename
00565 add_const<typename add_volatile<_Tp>::type>::type type;
00566 };
00567
00568
00569 template<typename _Tp>
00570 struct remove_reference
00571 { typedef _Tp type; };
00572
00573 template<typename _Tp>
00574 struct remove_reference<_Tp&>
00575 { typedef _Tp type; };
00576
00577 template<typename _Tp>
00578 struct add_reference
00579 { typedef _Tp& type; };
00580
00581 template<typename _Tp>
00582 struct add_reference<_Tp&>
00583 { typedef _Tp& type; };
00584
00585
00586 template<typename _Tp>
00587 struct remove_extent
00588 { typedef _Tp type; };
00589
00590 template<typename _Tp, std::size_t _Size>
00591 struct remove_extent<_Tp[_Size]>
00592 { typedef _Tp type; };
00593
00594 template<typename _Tp>
00595 struct remove_extent<_Tp[]>
00596 { typedef _Tp type; };
00597
00598 template<typename _Tp>
00599 struct remove_all_extents
00600 { typedef _Tp type; };
00601
00602 template<typename _Tp, std::size_t _Size>
00603 struct remove_all_extents<_Tp[_Size]>
00604 { typedef typename remove_all_extents<_Tp>::type type; };
00605
00606 template<typename _Tp>
00607 struct remove_all_extents<_Tp[]>
00608 { typedef typename remove_all_extents<_Tp>::type type; };
00609
00610
00611 #undef _DEFINE_SPEC_BODY
00612 #define _DEFINE_SPEC_BODY(_Value) \
00613 { typedef _Tp type; };
00614
00615 template<typename _Tp>
00616 struct remove_pointer
00617 { typedef _Tp type; };
00618 _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
00619
00620 template<typename _Tp>
00621 struct add_pointer
00622 { typedef typename remove_reference<_Tp>::type* type; };
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 template<std::size_t, std::size_t>
00635 struct aligned_storage { };
00636
00637 template<std::size_t _Len>
00638 struct aligned_storage<_Len, 1>
00639 {
00640 union type
00641 {
00642 unsigned char __data[_Len];
00643 char __align __attribute__((__aligned__(1)));
00644 };
00645 };
00646
00647 template<std::size_t _Len>
00648 struct aligned_storage<_Len, 2>
00649 {
00650 union type
00651 {
00652 unsigned char __data[_Len];
00653 char __align __attribute__((__aligned__(2)));
00654 };
00655 };
00656
00657 template<std::size_t _Len>
00658 struct aligned_storage<_Len, 4>
00659 {
00660 union type
00661 {
00662 unsigned char __data[_Len];
00663 char __align __attribute__((__aligned__(4)));
00664 };
00665 };
00666
00667 template<std::size_t _Len>
00668 struct aligned_storage<_Len, 8>
00669 {
00670 union type
00671 {
00672 unsigned char __data[_Len];
00673 char __align __attribute__((__aligned__(8)));
00674 };
00675 };
00676
00677 template<std::size_t _Len>
00678 struct aligned_storage<_Len, 16>
00679 {
00680 union type
00681 {
00682 unsigned char __data[_Len];
00683 char __align __attribute__((__aligned__(16)));
00684 };
00685 };
00686
00687 template<std::size_t _Len>
00688 struct aligned_storage<_Len, 32>
00689 {
00690 union type
00691 {
00692 unsigned char __data[_Len];
00693 char __align __attribute__((__aligned__(32)));
00694 };
00695 };
00696
00697 #undef _DEFINE_SPEC_0_HELPER
00698 #undef _DEFINE_SPEC_1_HELPER
00699 #undef _DEFINE_SPEC_2_HELPER
00700 #undef _DEFINE_SPEC
00701 #undef _DEFINE_SPEC_BODY
00702
00703 }
00704 }
00705
00706 #endif