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 _TR1_TYPE_TRAITS
00035 #define _TR1_TYPE_TRAITS 1
00036
00037 #include <bits/c++config.h>
00038 #include <tr1/type_traits_fwd.h>
00039
00040
00041 namespace std
00042 {
00043 _GLIBCXX_BEGIN_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
00568 template<typename _Tp, bool = (is_void<_Tp>::value
00569 || is_reference<_Tp>::value)>
00570 struct __add_reference_helper
00571 { typedef _Tp& type; };
00572
00573 template<typename _Tp>
00574 struct __add_reference_helper<_Tp, true>
00575 { typedef _Tp type; };
00576
00577 template<typename _Tp>
00578 struct add_reference
00579 : public __add_reference_helper<_Tp>
00580 { };
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 _GLIBCXX_END_NAMESPACE
00701 }
00702
00703 #endif