libstdc++
|
00001 // C++0x type_traits -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/type_traits 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 #ifndef _GLIBCXX_TYPE_TRAITS 00030 #define _GLIBCXX_TYPE_TRAITS 1 00031 00032 #pragma GCC system_header 00033 00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00035 # include <bits/c++0x_warning.h> 00036 #else 00037 00038 #include <bits/c++config.h> 00039 00040 namespace std _GLIBCXX_VISIBILITY(default) 00041 { 00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00043 00044 /** 00045 * @addtogroup metaprogramming 00046 * @{ 00047 */ 00048 struct __sfinae_types 00049 { 00050 typedef char __one; 00051 typedef struct { char __arr[2]; } __two; 00052 }; 00053 00054 #define _DEFINE_SPEC_0_HELPER \ 00055 template<> 00056 00057 #define _DEFINE_SPEC_1_HELPER \ 00058 template<typename _Tp> 00059 00060 #define _DEFINE_SPEC_2_HELPER \ 00061 template<typename _Tp, typename _Cp> 00062 00063 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ 00064 _DEFINE_SPEC_##_Order##_HELPER \ 00065 struct _Trait<_Type> \ 00066 : public integral_constant<bool, _Value> { }; 00067 00068 // helper classes. 00069 00070 /// integral_constant 00071 template<typename _Tp, _Tp __v> 00072 struct integral_constant 00073 { 00074 static constexpr _Tp value = __v; 00075 typedef _Tp value_type; 00076 typedef integral_constant<_Tp, __v> type; 00077 constexpr operator value_type() { return value; } 00078 }; 00079 00080 /// typedef for true_type 00081 typedef integral_constant<bool, true> true_type; 00082 00083 /// typedef for false_type 00084 typedef integral_constant<bool, false> false_type; 00085 00086 template<typename _Tp, _Tp __v> 00087 constexpr _Tp integral_constant<_Tp, __v>::value; 00088 00089 /// remove_cv 00090 template<typename> 00091 struct remove_cv; 00092 00093 template<typename> 00094 struct __is_void_helper 00095 : public false_type { }; 00096 _DEFINE_SPEC(0, __is_void_helper, void, true) 00097 00098 // primary type categories. 00099 00100 /// is_void 00101 template<typename _Tp> 00102 struct is_void 00103 : public integral_constant<bool, (__is_void_helper<typename 00104 remove_cv<_Tp>::type>::value)> 00105 { }; 00106 00107 template<typename> 00108 struct __is_integral_helper 00109 : public false_type { }; 00110 _DEFINE_SPEC(0, __is_integral_helper, bool, true) 00111 _DEFINE_SPEC(0, __is_integral_helper, char, true) 00112 _DEFINE_SPEC(0, __is_integral_helper, signed char, true) 00113 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) 00114 #ifdef _GLIBCXX_USE_WCHAR_T 00115 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) 00116 #endif 00117 _DEFINE_SPEC(0, __is_integral_helper, char16_t, true) 00118 _DEFINE_SPEC(0, __is_integral_helper, char32_t, true) 00119 _DEFINE_SPEC(0, __is_integral_helper, short, true) 00120 _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true) 00121 _DEFINE_SPEC(0, __is_integral_helper, int, true) 00122 _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true) 00123 _DEFINE_SPEC(0, __is_integral_helper, long, true) 00124 _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true) 00125 _DEFINE_SPEC(0, __is_integral_helper, long long, true) 00126 _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true) 00127 00128 /// is_integral 00129 template<typename _Tp> 00130 struct is_integral 00131 : public integral_constant<bool, (__is_integral_helper<typename 00132 remove_cv<_Tp>::type>::value)> 00133 { }; 00134 00135 template<typename> 00136 struct __is_floating_point_helper 00137 : public false_type { }; 00138 _DEFINE_SPEC(0, __is_floating_point_helper, float, true) 00139 _DEFINE_SPEC(0, __is_floating_point_helper, double, true) 00140 _DEFINE_SPEC(0, __is_floating_point_helper, long double, true) 00141 00142 /// is_floating_point 00143 template<typename _Tp> 00144 struct is_floating_point 00145 : public integral_constant<bool, (__is_floating_point_helper<typename 00146 remove_cv<_Tp>::type>::value)> 00147 { }; 00148 00149 /// is_array 00150 template<typename> 00151 struct is_array 00152 : public false_type { }; 00153 00154 template<typename _Tp, std::size_t _Size> 00155 struct is_array<_Tp[_Size]> 00156 : public true_type { }; 00157 00158 template<typename _Tp> 00159 struct is_array<_Tp[]> 00160 : public true_type { }; 00161 00162 template<typename> 00163 struct __is_pointer_helper 00164 : public false_type { }; 00165 _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true) 00166 00167 /// is_pointer 00168 template<typename _Tp> 00169 struct is_pointer 00170 : public integral_constant<bool, (__is_pointer_helper<typename 00171 remove_cv<_Tp>::type>::value)> 00172 { }; 00173 00174 /// is_reference 00175 template<typename _Tp> 00176 struct is_reference; 00177 00178 /// is_function 00179 template<typename _Tp> 00180 struct is_function; 00181 00182 template<typename> 00183 struct __is_member_object_pointer_helper 00184 : public false_type { }; 00185 _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*, 00186 !is_function<_Tp>::value) 00187 00188 /// is_member_object_pointer 00189 template<typename _Tp> 00190 struct is_member_object_pointer 00191 : public integral_constant<bool, (__is_member_object_pointer_helper< 00192 typename remove_cv<_Tp>::type>::value)> 00193 { }; 00194 00195 template<typename> 00196 struct __is_member_function_pointer_helper 00197 : public false_type { }; 00198 _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*, 00199 is_function<_Tp>::value) 00200 00201 /// is_member_function_pointer 00202 template<typename _Tp> 00203 struct is_member_function_pointer 00204 : public integral_constant<bool, (__is_member_function_pointer_helper< 00205 typename remove_cv<_Tp>::type>::value)> 00206 { }; 00207 00208 /// is_enum 00209 template<typename _Tp> 00210 struct is_enum 00211 : public integral_constant<bool, __is_enum(_Tp)> 00212 { }; 00213 00214 /// is_union 00215 template<typename _Tp> 00216 struct is_union 00217 : public integral_constant<bool, __is_union(_Tp)> 00218 { }; 00219 00220 /// is_class 00221 template<typename _Tp> 00222 struct is_class 00223 : public integral_constant<bool, __is_class(_Tp)> 00224 { }; 00225 00226 /// is_function 00227 template<typename> 00228 struct is_function 00229 : public false_type { }; 00230 template<typename _Res, typename... _ArgTypes> 00231 struct is_function<_Res(_ArgTypes...)> 00232 : public true_type { }; 00233 template<typename _Res, typename... _ArgTypes> 00234 struct is_function<_Res(_ArgTypes......)> 00235 : public true_type { }; 00236 template<typename _Res, typename... _ArgTypes> 00237 struct is_function<_Res(_ArgTypes...) const> 00238 : public true_type { }; 00239 template<typename _Res, typename... _ArgTypes> 00240 struct is_function<_Res(_ArgTypes......) const> 00241 : public true_type { }; 00242 template<typename _Res, typename... _ArgTypes> 00243 struct is_function<_Res(_ArgTypes...) volatile> 00244 : public true_type { }; 00245 template<typename _Res, typename... _ArgTypes> 00246 struct is_function<_Res(_ArgTypes......) volatile> 00247 : public true_type { }; 00248 template<typename _Res, typename... _ArgTypes> 00249 struct is_function<_Res(_ArgTypes...) const volatile> 00250 : public true_type { }; 00251 template<typename _Res, typename... _ArgTypes> 00252 struct is_function<_Res(_ArgTypes......) const volatile> 00253 : public true_type { }; 00254 00255 template<typename> 00256 struct __is_nullptr_t_helper 00257 : public false_type { }; 00258 _DEFINE_SPEC(0, __is_nullptr_t_helper, std::nullptr_t, true) 00259 00260 // __is_nullptr_t (extension). 00261 template<typename _Tp> 00262 struct __is_nullptr_t 00263 : public integral_constant<bool, (__is_nullptr_t_helper<typename 00264 remove_cv<_Tp>::type>::value)> 00265 { }; 00266 00267 // composite type traits. 00268 00269 /// is_arithmetic 00270 template<typename _Tp> 00271 struct is_arithmetic 00272 : public integral_constant<bool, (is_integral<_Tp>::value 00273 || is_floating_point<_Tp>::value)> 00274 { }; 00275 00276 /// is_fundamental 00277 template<typename _Tp> 00278 struct is_fundamental 00279 : public integral_constant<bool, (is_arithmetic<_Tp>::value 00280 || is_void<_Tp>::value)> 00281 { }; 00282 00283 /// is_object 00284 template<typename _Tp> 00285 struct is_object 00286 : public integral_constant<bool, !(is_function<_Tp>::value 00287 || is_reference<_Tp>::value 00288 || is_void<_Tp>::value)> 00289 { }; 00290 00291 /// is_member_pointer 00292 template<typename _Tp> 00293 struct is_member_pointer; 00294 00295 /// is_scalar 00296 template<typename _Tp> 00297 struct is_scalar 00298 : public integral_constant<bool, (is_arithmetic<_Tp>::value 00299 || is_enum<_Tp>::value 00300 || is_pointer<_Tp>::value 00301 || is_member_pointer<_Tp>::value 00302 || __is_nullptr_t<_Tp>::value)> 00303 { }; 00304 00305 /// is_compound 00306 template<typename _Tp> 00307 struct is_compound 00308 : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 00309 00310 /// is_member_pointer 00311 template<typename _Tp> 00312 struct __is_member_pointer_helper 00313 : public false_type { }; 00314 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) 00315 00316 template<typename _Tp> 00317 struct is_member_pointer 00318 : public integral_constant<bool, (__is_member_pointer_helper< 00319 typename remove_cv<_Tp>::type>::value)> 00320 { }; 00321 00322 // type properties. 00323 /// is_const 00324 template<typename> 00325 struct is_const 00326 : public false_type { }; 00327 00328 template<typename _Tp> 00329 struct is_const<_Tp const> 00330 : public true_type { }; 00331 00332 /// is_volatile 00333 template<typename> 00334 struct is_volatile 00335 : public false_type { }; 00336 00337 template<typename _Tp> 00338 struct is_volatile<_Tp volatile> 00339 : public true_type { }; 00340 00341 /// is_empty 00342 template<typename _Tp> 00343 struct is_empty 00344 : public integral_constant<bool, __is_empty(_Tp)> 00345 { }; 00346 00347 /// is_polymorphic 00348 template<typename _Tp> 00349 struct is_polymorphic 00350 : public integral_constant<bool, __is_polymorphic(_Tp)> 00351 { }; 00352 00353 /// is_abstract 00354 template<typename _Tp> 00355 struct is_abstract 00356 : public integral_constant<bool, __is_abstract(_Tp)> 00357 { }; 00358 00359 /// has_virtual_destructor 00360 template<typename _Tp> 00361 struct has_virtual_destructor 00362 : public integral_constant<bool, __has_virtual_destructor(_Tp)> 00363 { }; 00364 00365 /// alignment_of 00366 template<typename _Tp> 00367 struct alignment_of 00368 : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 00369 00370 /// rank 00371 template<typename> 00372 struct rank 00373 : public integral_constant<std::size_t, 0> { }; 00374 00375 template<typename _Tp, std::size_t _Size> 00376 struct rank<_Tp[_Size]> 00377 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 00378 00379 template<typename _Tp> 00380 struct rank<_Tp[]> 00381 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 00382 00383 /// extent 00384 template<typename, unsigned _Uint = 0> 00385 struct extent 00386 : public integral_constant<std::size_t, 0> { }; 00387 00388 template<typename _Tp, unsigned _Uint, std::size_t _Size> 00389 struct extent<_Tp[_Size], _Uint> 00390 : public integral_constant<std::size_t, 00391 _Uint == 0 ? _Size : extent<_Tp, 00392 _Uint - 1>::value> 00393 { }; 00394 00395 template<typename _Tp, unsigned _Uint> 00396 struct extent<_Tp[], _Uint> 00397 : public integral_constant<std::size_t, 00398 _Uint == 0 ? 0 : extent<_Tp, 00399 _Uint - 1>::value> 00400 { }; 00401 00402 // relationships between types [4.6]. 00403 00404 /// is_same 00405 template<typename, typename> 00406 struct is_same 00407 : public false_type { }; 00408 00409 template<typename _Tp> 00410 struct is_same<_Tp, _Tp> 00411 : public true_type { }; 00412 00413 // const-volatile modifications [4.7.1]. 00414 00415 /// remove_const 00416 template<typename _Tp> 00417 struct remove_const 00418 { typedef _Tp type; }; 00419 00420 template<typename _Tp> 00421 struct remove_const<_Tp const> 00422 { typedef _Tp type; }; 00423 00424 /// remove_volatile 00425 template<typename _Tp> 00426 struct remove_volatile 00427 { typedef _Tp type; }; 00428 00429 template<typename _Tp> 00430 struct remove_volatile<_Tp volatile> 00431 { typedef _Tp type; }; 00432 00433 /// remove_cv 00434 template<typename _Tp> 00435 struct remove_cv 00436 { 00437 typedef typename 00438 remove_const<typename remove_volatile<_Tp>::type>::type type; 00439 }; 00440 00441 /// add_const 00442 template<typename _Tp> 00443 struct add_const 00444 { typedef _Tp const type; }; 00445 00446 /// add_volatile 00447 template<typename _Tp> 00448 struct add_volatile 00449 { typedef _Tp volatile type; }; 00450 00451 /// add_cv 00452 template<typename _Tp> 00453 struct add_cv 00454 { 00455 typedef typename 00456 add_const<typename add_volatile<_Tp>::type>::type type; 00457 }; 00458 00459 // array modifications. 00460 00461 /// remove_extent 00462 template<typename _Tp> 00463 struct remove_extent 00464 { typedef _Tp type; }; 00465 00466 template<typename _Tp, std::size_t _Size> 00467 struct remove_extent<_Tp[_Size]> 00468 { typedef _Tp type; }; 00469 00470 template<typename _Tp> 00471 struct remove_extent<_Tp[]> 00472 { typedef _Tp type; }; 00473 00474 /// remove_all_extents 00475 template<typename _Tp> 00476 struct remove_all_extents 00477 { typedef _Tp type; }; 00478 00479 template<typename _Tp, std::size_t _Size> 00480 struct remove_all_extents<_Tp[_Size]> 00481 { typedef typename remove_all_extents<_Tp>::type type; }; 00482 00483 template<typename _Tp> 00484 struct remove_all_extents<_Tp[]> 00485 { typedef typename remove_all_extents<_Tp>::type type; }; 00486 00487 // pointer modifications. 00488 00489 template<typename _Tp, typename> 00490 struct __remove_pointer_helper 00491 { typedef _Tp type; }; 00492 00493 template<typename _Tp, typename _Up> 00494 struct __remove_pointer_helper<_Tp, _Up*> 00495 { typedef _Up type; }; 00496 00497 /// remove_pointer 00498 template<typename _Tp> 00499 struct remove_pointer 00500 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> 00501 { }; 00502 00503 template<typename> 00504 struct remove_reference; 00505 00506 /// add_pointer 00507 template<typename _Tp> 00508 struct add_pointer 00509 { typedef typename remove_reference<_Tp>::type* type; }; 00510 00511 // Primary classification traits. 00512 00513 /// is_lvalue_reference 00514 template<typename> 00515 struct is_lvalue_reference 00516 : public false_type { }; 00517 00518 template<typename _Tp> 00519 struct is_lvalue_reference<_Tp&> 00520 : public true_type { }; 00521 00522 /// is_rvalue_reference 00523 template<typename> 00524 struct is_rvalue_reference 00525 : public false_type { }; 00526 00527 template<typename _Tp> 00528 struct is_rvalue_reference<_Tp&&> 00529 : public true_type { }; 00530 00531 // Secondary classification traits. 00532 00533 /// is_reference 00534 template<typename _Tp> 00535 struct is_reference 00536 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value 00537 || is_rvalue_reference<_Tp>::value)> 00538 { }; 00539 00540 // Reference transformations. 00541 00542 /// remove_reference 00543 template<typename _Tp> 00544 struct remove_reference 00545 { typedef _Tp type; }; 00546 00547 template<typename _Tp> 00548 struct remove_reference<_Tp&> 00549 { typedef _Tp type; }; 00550 00551 template<typename _Tp> 00552 struct remove_reference<_Tp&&> 00553 { typedef _Tp type; }; 00554 00555 template<typename _Tp, 00556 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value, 00557 bool = is_rvalue_reference<_Tp>::value> 00558 struct __add_lvalue_reference_helper 00559 { typedef _Tp type; }; 00560 00561 template<typename _Tp> 00562 struct __add_lvalue_reference_helper<_Tp, true, false> 00563 { typedef _Tp& type; }; 00564 00565 template<typename _Tp> 00566 struct __add_lvalue_reference_helper<_Tp, false, true> 00567 { typedef typename remove_reference<_Tp>::type& type; }; 00568 00569 /// add_lvalue_reference 00570 template<typename _Tp> 00571 struct add_lvalue_reference 00572 : public __add_lvalue_reference_helper<_Tp> 00573 { }; 00574 00575 template<typename _Tp, 00576 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value> 00577 struct __add_rvalue_reference_helper 00578 { typedef _Tp type; }; 00579 00580 template<typename _Tp> 00581 struct __add_rvalue_reference_helper<_Tp, true> 00582 { typedef _Tp&& type; }; 00583 00584 /// add_rvalue_reference 00585 template<typename _Tp> 00586 struct add_rvalue_reference 00587 : public __add_rvalue_reference_helper<_Tp> 00588 { }; 00589 00590 // Scalar properties and transformations. 00591 00592 template<typename _Tp, 00593 bool = is_integral<_Tp>::value, 00594 bool = is_floating_point<_Tp>::value> 00595 struct __is_signed_helper 00596 : public false_type { }; 00597 00598 template<typename _Tp> 00599 struct __is_signed_helper<_Tp, false, true> 00600 : public true_type { }; 00601 00602 template<typename _Tp> 00603 struct __is_signed_helper<_Tp, true, false> 00604 : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))> 00605 { }; 00606 00607 /// is_signed 00608 template<typename _Tp> 00609 struct is_signed 00610 : public integral_constant<bool, __is_signed_helper<_Tp>::value> 00611 { }; 00612 00613 /// is_unsigned 00614 template<typename _Tp> 00615 struct is_unsigned 00616 : public integral_constant<bool, (is_arithmetic<_Tp>::value 00617 && !is_signed<_Tp>::value)> 00618 { }; 00619 00620 // Member introspection. 00621 00622 /// is_trivial 00623 template<typename _Tp> 00624 struct is_trivial 00625 : public integral_constant<bool, __is_trivial(_Tp)> 00626 { }; 00627 00628 /// is_standard_layout 00629 template<typename _Tp> 00630 struct is_standard_layout 00631 : public integral_constant<bool, __is_standard_layout(_Tp)> 00632 { }; 00633 00634 /// is_pod 00635 // Could use is_standard_layout && is_trivial instead of the builtin. 00636 template<typename _Tp> 00637 struct is_pod 00638 : public integral_constant<bool, __is_pod(_Tp)> 00639 { }; 00640 00641 /// is_literal_type 00642 template<typename _Tp> 00643 struct is_literal_type 00644 : public integral_constant<bool, __is_literal_type(_Tp)> 00645 { }; 00646 00647 template<typename _Tp> 00648 typename add_rvalue_reference<_Tp>::type declval() noexcept; 00649 00650 template<typename _Tp, typename... _Args> 00651 class __is_constructible_helper 00652 : public __sfinae_types 00653 { 00654 template<typename _Tp1, typename... _Args1> 00655 static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int); 00656 00657 template<typename, typename...> 00658 static __two __test(...); 00659 00660 public: 00661 static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1; 00662 }; 00663 00664 template<typename _Tp, typename _Arg> 00665 class __is_constructible_helper<_Tp, _Arg> 00666 : public __sfinae_types 00667 { 00668 template<typename _Tp1, typename _Arg1> 00669 static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one()) 00670 __test(int); 00671 00672 template<typename, typename> 00673 static __two __test(...); 00674 00675 public: 00676 static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1; 00677 }; 00678 00679 /// is_constructible 00680 // XXX FIXME 00681 // The C++0x specifications require front-end support, see N2255. 00682 template<typename _Tp, typename... _Args> 00683 struct is_constructible 00684 : public integral_constant<bool, 00685 __is_constructible_helper<_Tp, 00686 _Args...>::__value> 00687 { }; 00688 00689 template<bool, typename _Tp, typename... _Args> 00690 struct __is_nt_constructible_helper 00691 { static const bool __value = false; }; 00692 00693 template<typename _Tp, typename... _Args> 00694 struct __is_nt_constructible_helper<true, _Tp, _Args...> 00695 { static const bool __value = noexcept(_Tp(declval<_Args>()...)); }; 00696 00697 template<typename _Tp, typename _Arg> 00698 struct __is_nt_constructible_helper<true, _Tp, _Arg> 00699 { 00700 static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>())); 00701 }; 00702 00703 /// is_nothrow_constructible 00704 template<typename _Tp, typename... _Args> 00705 struct is_nothrow_constructible 00706 : public integral_constant<bool, 00707 __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value, 00708 _Tp, _Args...>::__value> 00709 { }; 00710 00711 /// has_trivial_default_constructor 00712 template<typename _Tp> 00713 struct has_trivial_default_constructor 00714 : public integral_constant<bool, __has_trivial_constructor(_Tp)> 00715 { }; 00716 00717 /// has_trivial_copy_constructor 00718 template<typename _Tp> 00719 struct has_trivial_copy_constructor 00720 : public integral_constant<bool, __has_trivial_copy(_Tp)> 00721 { }; 00722 00723 /// has_trivial_copy_assign 00724 template<typename _Tp> 00725 struct has_trivial_copy_assign 00726 : public integral_constant<bool, __has_trivial_assign(_Tp)> 00727 { }; 00728 00729 /// has_trivial_destructor 00730 template<typename _Tp> 00731 struct has_trivial_destructor 00732 : public integral_constant<bool, __has_trivial_destructor(_Tp)> 00733 { }; 00734 00735 /// has_nothrow_default_constructor 00736 template<typename _Tp> 00737 struct has_nothrow_default_constructor 00738 : public integral_constant<bool, __has_nothrow_constructor(_Tp)> 00739 { }; 00740 00741 /// has_nothrow_copy_constructor 00742 template<typename _Tp> 00743 struct has_nothrow_copy_constructor 00744 : public integral_constant<bool, __has_nothrow_copy(_Tp)> 00745 { }; 00746 00747 /// has_nothrow_copy_assign 00748 template<typename _Tp> 00749 struct has_nothrow_copy_assign 00750 : public integral_constant<bool, __has_nothrow_assign(_Tp)> 00751 { }; 00752 00753 // Relationships between types. 00754 00755 /// is_base_of 00756 template<typename _Base, typename _Derived> 00757 struct is_base_of 00758 : public integral_constant<bool, __is_base_of(_Base, _Derived)> 00759 { }; 00760 00761 template<typename _From, typename _To, 00762 bool = (is_void<_From>::value || is_function<_To>::value 00763 || is_array<_To>::value)> 00764 struct __is_convertible_helper 00765 { static const bool __value = is_void<_To>::value; }; 00766 00767 template<typename _From, typename _To> 00768 class __is_convertible_helper<_From, _To, false> 00769 : public __sfinae_types 00770 { 00771 template<typename _To1> 00772 static void __test_aux(_To1); 00773 00774 template<typename _From1, typename _To1> 00775 static decltype(__test_aux<_To1>(std::declval<_From1>()), __one()) 00776 __test(int); 00777 00778 template<typename, typename> 00779 static __two __test(...); 00780 00781 public: 00782 static const bool __value = sizeof(__test<_From, _To>(0)) == 1; 00783 }; 00784 00785 /// is_convertible 00786 // XXX FIXME 00787 // The C++0x specifications require front-end support, see N2255. 00788 template<typename _From, typename _To> 00789 struct is_convertible 00790 : public integral_constant<bool, 00791 __is_convertible_helper<_From, _To>::__value> 00792 { }; 00793 00794 /// is_explicitly_convertible 00795 template<typename _From, typename _To> 00796 struct is_explicitly_convertible 00797 : public is_constructible<_To, _From> 00798 { }; 00799 00800 template<std::size_t _Len> 00801 struct __aligned_storage_msa 00802 { 00803 union __type 00804 { 00805 unsigned char __data[_Len]; 00806 struct __attribute__((__aligned__)) { } __align; 00807 }; 00808 }; 00809 00810 /** 00811 * @brief Alignment type. 00812 * 00813 * The value of _Align is a default-alignment which shall be the 00814 * most stringent alignment requirement for any C++ object type 00815 * whose size is no greater than _Len (3.9). The member typedef 00816 * type shall be a POD type suitable for use as uninitialized 00817 * storage for any object whose size is at most _Len and whose 00818 * alignment is a divisor of _Align. 00819 */ 00820 template<std::size_t _Len, std::size_t _Align = 00821 __alignof__(typename __aligned_storage_msa<_Len>::__type)> 00822 struct aligned_storage 00823 { 00824 union type 00825 { 00826 unsigned char __data[_Len]; 00827 struct __attribute__((__aligned__((_Align)))) { } __align; 00828 }; 00829 }; 00830 00831 00832 // Define a nested type if some predicate holds. 00833 // Primary template. 00834 /// enable_if 00835 template<bool, typename _Tp = void> 00836 struct enable_if 00837 { }; 00838 00839 // Partial specialization for true. 00840 template<typename _Tp> 00841 struct enable_if<true, _Tp> 00842 { typedef _Tp type; }; 00843 00844 00845 // A conditional expression, but for types. If true, first, if false, second. 00846 // Primary template. 00847 /// conditional 00848 template<bool _Cond, typename _Iftrue, typename _Iffalse> 00849 struct conditional 00850 { typedef _Iftrue type; }; 00851 00852 // Partial specialization for false. 00853 template<typename _Iftrue, typename _Iffalse> 00854 struct conditional<false, _Iftrue, _Iffalse> 00855 { typedef _Iffalse type; }; 00856 00857 00858 // Decay trait for arrays and functions, used for perfect forwarding 00859 // in make_pair, make_tuple, etc. 00860 template<typename _Up, 00861 bool _IsArray = is_array<_Up>::value, 00862 bool _IsFunction = is_function<_Up>::value> 00863 struct __decay_selector; 00864 00865 // NB: DR 705. 00866 template<typename _Up> 00867 struct __decay_selector<_Up, false, false> 00868 { typedef typename remove_cv<_Up>::type __type; }; 00869 00870 template<typename _Up> 00871 struct __decay_selector<_Up, true, false> 00872 { typedef typename remove_extent<_Up>::type* __type; }; 00873 00874 template<typename _Up> 00875 struct __decay_selector<_Up, false, true> 00876 { typedef typename add_pointer<_Up>::type __type; }; 00877 00878 /// decay 00879 template<typename _Tp> 00880 class decay 00881 { 00882 typedef typename remove_reference<_Tp>::type __remove_type; 00883 00884 public: 00885 typedef typename __decay_selector<__remove_type>::__type type; 00886 }; 00887 00888 template<typename _Tp> 00889 class reference_wrapper; 00890 00891 // Helper which adds a reference to a type when given a reference_wrapper 00892 template<typename _Tp> 00893 struct __strip_reference_wrapper 00894 { 00895 typedef _Tp __type; 00896 }; 00897 00898 template<typename _Tp> 00899 struct __strip_reference_wrapper<reference_wrapper<_Tp> > 00900 { 00901 typedef _Tp& __type; 00902 }; 00903 00904 template<typename _Tp> 00905 struct __strip_reference_wrapper<const reference_wrapper<_Tp> > 00906 { 00907 typedef _Tp& __type; 00908 }; 00909 00910 template<typename _Tp> 00911 struct __decay_and_strip 00912 { 00913 typedef typename __strip_reference_wrapper< 00914 typename decay<_Tp>::type>::__type __type; 00915 }; 00916 00917 00918 // Utility for constructing identically cv-qualified types. 00919 template<typename _Unqualified, bool _IsConst, bool _IsVol> 00920 struct __cv_selector; 00921 00922 template<typename _Unqualified> 00923 struct __cv_selector<_Unqualified, false, false> 00924 { typedef _Unqualified __type; }; 00925 00926 template<typename _Unqualified> 00927 struct __cv_selector<_Unqualified, false, true> 00928 { typedef volatile _Unqualified __type; }; 00929 00930 template<typename _Unqualified> 00931 struct __cv_selector<_Unqualified, true, false> 00932 { typedef const _Unqualified __type; }; 00933 00934 template<typename _Unqualified> 00935 struct __cv_selector<_Unqualified, true, true> 00936 { typedef const volatile _Unqualified __type; }; 00937 00938 template<typename _Qualified, typename _Unqualified, 00939 bool _IsConst = is_const<_Qualified>::value, 00940 bool _IsVol = is_volatile<_Qualified>::value> 00941 class __match_cv_qualifiers 00942 { 00943 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; 00944 00945 public: 00946 typedef typename __match::__type __type; 00947 }; 00948 00949 00950 // Utility for finding the unsigned versions of signed integral types. 00951 template<typename _Tp> 00952 struct __make_unsigned 00953 { typedef _Tp __type; }; 00954 00955 template<> 00956 struct __make_unsigned<char> 00957 { typedef unsigned char __type; }; 00958 00959 template<> 00960 struct __make_unsigned<signed char> 00961 { typedef unsigned char __type; }; 00962 00963 template<> 00964 struct __make_unsigned<short> 00965 { typedef unsigned short __type; }; 00966 00967 template<> 00968 struct __make_unsigned<int> 00969 { typedef unsigned int __type; }; 00970 00971 template<> 00972 struct __make_unsigned<long> 00973 { typedef unsigned long __type; }; 00974 00975 template<> 00976 struct __make_unsigned<long long> 00977 { typedef unsigned long long __type; }; 00978 00979 00980 // Select between integral and enum: not possible to be both. 00981 template<typename _Tp, 00982 bool _IsInt = is_integral<_Tp>::value, 00983 bool _IsEnum = is_enum<_Tp>::value> 00984 class __make_unsigned_selector; 00985 00986 template<typename _Tp> 00987 class __make_unsigned_selector<_Tp, true, false> 00988 { 00989 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt; 00990 typedef typename __unsignedt::__type __unsigned_type; 00991 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; 00992 00993 public: 00994 typedef typename __cv_unsigned::__type __type; 00995 }; 00996 00997 template<typename _Tp> 00998 class __make_unsigned_selector<_Tp, false, true> 00999 { 01000 // With -fshort-enums, an enum may be as small as a char. 01001 typedef unsigned char __smallest; 01002 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 01003 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); 01004 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); 01005 typedef conditional<__b2, unsigned int, unsigned long> __cond2; 01006 typedef typename __cond2::type __cond2_type; 01007 typedef conditional<__b1, unsigned short, __cond2_type> __cond1; 01008 typedef typename __cond1::type __cond1_type; 01009 01010 public: 01011 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 01012 }; 01013 01014 // Given an integral/enum type, return the corresponding unsigned 01015 // integer type. 01016 // Primary template. 01017 /// make_unsigned 01018 template<typename _Tp> 01019 struct make_unsigned 01020 { typedef typename __make_unsigned_selector<_Tp>::__type type; }; 01021 01022 // Integral, but don't define. 01023 template<> 01024 struct make_unsigned<bool>; 01025 01026 01027 // Utility for finding the signed versions of unsigned integral types. 01028 template<typename _Tp> 01029 struct __make_signed 01030 { typedef _Tp __type; }; 01031 01032 template<> 01033 struct __make_signed<char> 01034 { typedef signed char __type; }; 01035 01036 template<> 01037 struct __make_signed<unsigned char> 01038 { typedef signed char __type; }; 01039 01040 template<> 01041 struct __make_signed<unsigned short> 01042 { typedef signed short __type; }; 01043 01044 template<> 01045 struct __make_signed<unsigned int> 01046 { typedef signed int __type; }; 01047 01048 template<> 01049 struct __make_signed<unsigned long> 01050 { typedef signed long __type; }; 01051 01052 template<> 01053 struct __make_signed<unsigned long long> 01054 { typedef signed long long __type; }; 01055 01056 01057 // Select between integral and enum: not possible to be both. 01058 template<typename _Tp, 01059 bool _IsInt = is_integral<_Tp>::value, 01060 bool _IsEnum = is_enum<_Tp>::value> 01061 class __make_signed_selector; 01062 01063 template<typename _Tp> 01064 class __make_signed_selector<_Tp, true, false> 01065 { 01066 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt; 01067 typedef typename __signedt::__type __signed_type; 01068 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; 01069 01070 public: 01071 typedef typename __cv_signed::__type __type; 01072 }; 01073 01074 template<typename _Tp> 01075 class __make_signed_selector<_Tp, false, true> 01076 { 01077 // With -fshort-enums, an enum may be as small as a char. 01078 typedef signed char __smallest; 01079 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 01080 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short); 01081 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); 01082 typedef conditional<__b2, signed int, signed long> __cond2; 01083 typedef typename __cond2::type __cond2_type; 01084 typedef conditional<__b1, signed short, __cond2_type> __cond1; 01085 typedef typename __cond1::type __cond1_type; 01086 01087 public: 01088 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 01089 }; 01090 01091 // Given an integral/enum type, return the corresponding signed 01092 // integer type. 01093 // Primary template. 01094 /// make_signed 01095 template<typename _Tp> 01096 struct make_signed 01097 { typedef typename __make_signed_selector<_Tp>::__type type; }; 01098 01099 // Integral, but don't define. 01100 template<> 01101 struct make_signed<bool>; 01102 01103 /// common_type 01104 template<typename... _Tp> 01105 struct common_type; 01106 01107 template<typename _Tp> 01108 struct common_type<_Tp> 01109 { typedef _Tp type; }; 01110 01111 template<typename _Tp, typename _Up> 01112 struct common_type<_Tp, _Up> 01113 { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; }; 01114 01115 template<typename _Tp, typename _Up, typename... _Vp> 01116 struct common_type<_Tp, _Up, _Vp...> 01117 { 01118 typedef typename 01119 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; 01120 }; 01121 01122 /// declval 01123 template<typename _Tp> 01124 struct __declval_protector 01125 { 01126 static const bool __stop = false; 01127 static typename add_rvalue_reference<_Tp>::type __delegate(); 01128 }; 01129 01130 template<typename _Tp> 01131 inline typename add_rvalue_reference<_Tp>::type 01132 declval() noexcept 01133 { 01134 static_assert(__declval_protector<_Tp>::__stop, 01135 "declval() must not be used!"); 01136 return __declval_protector<_Tp>::__delegate(); 01137 } 01138 01139 /// result_of 01140 template<typename _Signature> 01141 class result_of; 01142 01143 template<typename _MemPtr, typename _Arg> 01144 struct _Result_of_memobj; 01145 01146 template<typename _Res, typename _Class, typename _Arg> 01147 struct _Result_of_memobj<_Res _Class::*, _Arg> 01148 { 01149 private: 01150 typedef _Res _Class::* _Func; 01151 01152 template<typename _Tp> 01153 static _Tp _S_get(const _Class&); 01154 template<typename _Tp> 01155 static decltype(*std::declval<_Tp>()) _S_get(...); 01156 01157 public: 01158 typedef 01159 decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) 01160 __type; 01161 }; 01162 01163 template<typename _MemPtr, typename _Arg, typename... _ArgTypes> 01164 struct _Result_of_memfun; 01165 01166 template<typename _Res, typename _Class, typename _Arg, typename... _Args> 01167 struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...> 01168 { 01169 private: 01170 typedef _Res _Class::* _Func; 01171 01172 template<typename _Tp> 01173 static _Tp _S_get(const _Class&); 01174 template<typename _Tp> 01175 static decltype(*std::declval<_Tp>()) _S_get(...); 01176 01177 public: 01178 typedef 01179 decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) 01180 (std::declval<_Args>()...) ) 01181 __type; 01182 }; 01183 01184 template<bool, bool, typename _Functor, typename... _ArgTypes> 01185 struct _Result_of_impl; 01186 01187 template<typename _Functor, typename... _ArgTypes> 01188 struct _Result_of_impl<false, false, _Functor, _ArgTypes...> 01189 { 01190 typedef 01191 decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) ) 01192 __type; 01193 }; 01194 01195 template<typename _MemPtr, typename _Arg> 01196 struct _Result_of_impl<true, false, _MemPtr, _Arg> 01197 : _Result_of_memobj<typename remove_reference<_MemPtr>::type, _Arg> 01198 { 01199 typedef typename _Result_of_memobj< 01200 typename remove_reference<_MemPtr>::type, _Arg>::__type 01201 __type; 01202 }; 01203 01204 template<typename _MemPtr, typename _Arg, typename... _ArgTypes> 01205 struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...> 01206 : _Result_of_memfun<typename remove_reference<_MemPtr>::type, _Arg, 01207 _ArgTypes...> 01208 { 01209 typedef typename _Result_of_memfun< 01210 typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type 01211 __type; 01212 }; 01213 01214 template<typename _Functor, typename... _ArgTypes> 01215 struct result_of<_Functor(_ArgTypes...)> 01216 : _Result_of_impl<is_member_object_pointer< 01217 typename remove_reference<_Functor>::type >::value, 01218 is_member_function_pointer< 01219 typename remove_reference<_Functor>::type >::value, 01220 _Functor, _ArgTypes...> 01221 { 01222 typedef typename _Result_of_impl< 01223 is_member_object_pointer< 01224 typename remove_reference<_Functor>::type >::value, 01225 is_member_function_pointer< 01226 typename remove_reference<_Functor>::type >::value, 01227 _Functor, _ArgTypes...>::__type 01228 type; 01229 }; 01230 01231 /** 01232 * Use SFINAE to determine if the type _Tp has a publicly-accessible 01233 * member type _NTYPE. 01234 */ 01235 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ 01236 template<typename _Tp> \ 01237 class __has_##_NTYPE##_helper \ 01238 : __sfinae_types \ 01239 { \ 01240 template<typename _Up> \ 01241 struct _Wrap_type \ 01242 { }; \ 01243 \ 01244 template<typename _Up> \ 01245 static __one __test(_Wrap_type<typename _Up::_NTYPE>*); \ 01246 \ 01247 template<typename _Up> \ 01248 static __two __test(...); \ 01249 \ 01250 public: \ 01251 static const bool value = sizeof(__test<_Tp>(0)) == 1; \ 01252 }; \ 01253 \ 01254 template<typename _Tp> \ 01255 struct __has_##_NTYPE \ 01256 : integral_constant<bool, __has_##_NTYPE##_helper \ 01257 <typename remove_cv<_Tp>::type>::value> \ 01258 { }; 01259 01260 #undef _DEFINE_SPEC_0_HELPER 01261 #undef _DEFINE_SPEC_1_HELPER 01262 #undef _DEFINE_SPEC_2_HELPER 01263 #undef _DEFINE_SPEC 01264 01265 // @} group metaprogramming 01266 _GLIBCXX_END_NAMESPACE_VERSION 01267 } // namespace 01268 01269 #endif // __GXX_EXPERIMENTAL_CXX0X__ 01270 01271 #endif // _GLIBCXX_TYPE_TRAITS