1 // C++0x type_traits -*- C++ -*- 2 3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file include/type_traits 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_TYPE_TRAITS 30 #define _GLIBCXX_TYPE_TRAITS 1 31 32 #pragma GCC system_header 33 34 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 35 # include <c++0x_warning.h> 36 #else 37 38 #if defined(_GLIBCXX_INCLUDE_AS_TR1) 39 # error C++0x header cannot be included from TR1 header 40 #endif 41 42 #include <cstddef> 43 44 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X) 45 # include <tr1_impl/type_traits> 46 #else 47 # define _GLIBCXX_INCLUDE_AS_CXX0X 48 # define _GLIBCXX_BEGIN_NAMESPACE_TR1 49 # define _GLIBCXX_END_NAMESPACE_TR1 50 # define _GLIBCXX_TR1 51 # include <tr1_impl/type_traits> 52 # undef _GLIBCXX_TR1 53 # undef _GLIBCXX_END_NAMESPACE_TR1 54 # undef _GLIBCXX_BEGIN_NAMESPACE_TR1 55 # undef _GLIBCXX_INCLUDE_AS_CXX0X 56 #endif 57 58 namespace std 59 { 60 /** @addtogroup metaprogramming 61 * @{ 62 */ 63 64 // Primary classification traits. 65 66 /// is_lvalue_reference 67 template<typename> 68 struct is_lvalue_reference 69 : public false_type { }; 70 71 template<typename _Tp> 72 struct is_lvalue_reference<_Tp&> 73 : public true_type { }; 74 75 /// is_rvalue_reference 76 template<typename> 77 struct is_rvalue_reference 78 : public false_type { }; 79 80 template<typename _Tp> 81 struct is_rvalue_reference<_Tp&&> 82 : public true_type { }; 83 84 // Secondary classification traits. 85 86 /// is_reference 87 template<typename _Tp> 88 struct is_reference 89 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value 90 || is_rvalue_reference<_Tp>::value)> 91 { }; 92 93 // Reference transformations. 94 95 /// remove_reference 96 template<typename _Tp> 97 struct remove_reference 98 { typedef _Tp type; }; 99 100 template<typename _Tp> 101 struct remove_reference<_Tp&> 102 { typedef _Tp type; }; 103 104 template<typename _Tp> 105 struct remove_reference<_Tp&&> 106 { typedef _Tp type; }; 107 108 template<typename _Tp, 109 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value, 110 bool = is_rvalue_reference<_Tp>::value> 111 struct __add_lvalue_reference_helper 112 { typedef _Tp type; }; 113 114 template<typename _Tp> 115 struct __add_lvalue_reference_helper<_Tp, true, false> 116 { typedef _Tp& type; }; 117 118 template<typename _Tp> 119 struct __add_lvalue_reference_helper<_Tp, false, true> 120 { typedef typename remove_reference<_Tp>::type& type; }; 121 122 /// add_lvalue_reference 123 template<typename _Tp> 124 struct add_lvalue_reference 125 : public __add_lvalue_reference_helper<_Tp> 126 { }; 127 128 template<typename _Tp, 129 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value> 130 struct __add_rvalue_reference_helper 131 { typedef _Tp type; }; 132 133 template<typename _Tp> 134 struct __add_rvalue_reference_helper<_Tp, true> 135 { typedef _Tp&& type; }; 136 137 /// add_rvalue_reference 138 template<typename _Tp> 139 struct add_rvalue_reference 140 : public __add_rvalue_reference_helper<_Tp> 141 { }; 142 143 // Scalar properties and transformations. 144 145 template<typename _Tp, 146 bool = is_integral<_Tp>::value, 147 bool = is_floating_point<_Tp>::value> 148 struct __is_signed_helper 149 : public false_type { }; 150 151 template<typename _Tp> 152 struct __is_signed_helper<_Tp, false, true> 153 : public true_type { }; 154 155 template<typename _Tp> 156 struct __is_signed_helper<_Tp, true, false> 157 : public integral_constant<bool, _Tp(-1) < _Tp(0)> 158 { }; 159 160 /// is_signed 161 template<typename _Tp> 162 struct is_signed 163 : public integral_constant<bool, __is_signed_helper<_Tp>::value> 164 { }; 165 166 /// is_unsigned 167 template<typename _Tp> 168 struct is_unsigned 169 : public integral_constant<bool, (is_arithmetic<_Tp>::value 170 && !is_signed<_Tp>::value)> 171 { }; 172 173 // Member introspection. 174 175 /// is_pod 176 template<typename _Tp> 177 struct is_pod 178 : public integral_constant<bool, __is_pod(_Tp)> 179 { }; 180 181 /// has_trivial_default_constructor 182 template<typename _Tp> 183 struct has_trivial_default_constructor 184 : public integral_constant<bool, __has_trivial_constructor(_Tp)> 185 { }; 186 187 /// has_trivial_copy_constructor 188 template<typename _Tp> 189 struct has_trivial_copy_constructor 190 : public integral_constant<bool, __has_trivial_copy(_Tp)> 191 { }; 192 193 /// has_trivial_assign 194 template<typename _Tp> 195 struct has_trivial_assign 196 : public integral_constant<bool, __has_trivial_assign(_Tp)> 197 { }; 198 199 /// has_trivial_destructor 200 template<typename _Tp> 201 struct has_trivial_destructor 202 : public integral_constant<bool, __has_trivial_destructor(_Tp)> 203 { }; 204 205 /// has_nothrow_default_constructor 206 template<typename _Tp> 207 struct has_nothrow_default_constructor 208 : public integral_constant<bool, __has_nothrow_constructor(_Tp)> 209 { }; 210 211 /// has_nothrow_copy_constructor 212 template<typename _Tp> 213 struct has_nothrow_copy_constructor 214 : public integral_constant<bool, __has_nothrow_copy(_Tp)> 215 { }; 216 217 /// has_nothrow_assign 218 template<typename _Tp> 219 struct has_nothrow_assign 220 : public integral_constant<bool, __has_nothrow_assign(_Tp)> 221 { }; 222 223 /// is_base_of 224 template<typename _Base, typename _Derived> 225 struct is_base_of 226 : public integral_constant<bool, __is_base_of(_Base, _Derived)> 227 { }; 228 229 // Relationships between types. 230 template<typename _From, typename _To> 231 struct __is_convertible_simple 232 : public __sfinae_types 233 { 234 private: 235 static __one __test(_To); 236 static __two __test(...); 237 static _From __makeFrom(); 238 239 public: 240 static const bool __value = sizeof(__test(__makeFrom())) == 1; 241 }; 242 243 template<typename _Tp> 244 struct __is_int_or_cref 245 { 246 typedef typename remove_reference<_Tp>::type __rr_Tp; 247 static const bool __value = (is_integral<_Tp>::value 248 || (is_integral<__rr_Tp>::value 249 && is_const<__rr_Tp>::value 250 && !is_volatile<__rr_Tp>::value)); 251 }; 252 253 template<typename _From, typename _To, 254 bool = (is_void<_From>::value || is_void<_To>::value 255 || is_function<_To>::value || is_array<_To>::value 256 // This special case is here only to avoid warnings. 257 || (is_floating_point<typename 258 remove_reference<_From>::type>::value 259 && __is_int_or_cref<_To>::__value))> 260 struct __is_convertible_helper 261 { 262 // "An imaginary lvalue of type From...". 263 static const bool __value = (__is_convertible_simple<typename 264 add_lvalue_reference<_From>::type, 265 _To>::__value); 266 }; 267 268 template<typename _From, typename _To> 269 struct __is_convertible_helper<_From, _To, true> 270 { static const bool __value = (is_void<_To>::value 271 || (__is_int_or_cref<_To>::__value 272 && !is_void<_From>::value)); }; 273 274 // XXX FIXME 275 // The C++0x specifications are different, see N2255. 276 /// is_convertible 277 template<typename _From, typename _To> 278 struct is_convertible 279 : public integral_constant<bool, 280 __is_convertible_helper<_From, _To>::__value> 281 { }; 282 283 template<std::size_t _Len> 284 struct __aligned_storage_msa 285 { 286 union __type 287 { 288 unsigned char __data[_Len]; 289 struct __attribute__((__aligned__)) { } __align; 290 }; 291 }; 292 293 /** 294 * @brief Alignment type. 295 * 296 * The value of _Align is a default-alignment which shall be the 297 * most stringent alignment requirement for any C++ object type 298 * whose size is no greater than _Len (3.9). The member typedef 299 * type shall be a POD type suitable for use as uninitialized 300 * storage for any object whose size is at most _Len and whose 301 * alignment is a divisor of _Align. 302 */ 303 template<std::size_t _Len, std::size_t _Align = 304 __alignof__(typename __aligned_storage_msa<_Len>::__type)> 305 struct aligned_storage 306 { 307 union type 308 { 309 unsigned char __data[_Len]; 310 struct __attribute__((__aligned__((_Align)))) { } __align; 311 }; 312 }; 313 314 315 // Define a nested type if some predicate holds. 316 // Primary template. 317 /// enable_if 318 template<bool, typename _Tp = void> 319 struct enable_if 320 { }; 321 322 // Partial specialization for true. 323 template<typename _Tp> 324 struct enable_if<true, _Tp> 325 { typedef _Tp type; }; 326 327 328 // A conditional expression, but for types. If true, first, if false, second. 329 // Primary template. 330 /// conditional 331 template<bool _Cond, typename _Iftrue, typename _Iffalse> 332 struct conditional 333 { typedef _Iftrue type; }; 334 335 // Partial specialization for false. 336 template<typename _Iftrue, typename _Iffalse> 337 struct conditional<false, _Iftrue, _Iffalse> 338 { typedef _Iffalse type; }; 339 340 341 // Decay trait for arrays and functions, used for perfect forwarding 342 // in make_pair, make_tuple, etc. 343 template<typename _Up, 344 bool _IsArray = is_array<_Up>::value, 345 bool _IsFunction = is_function<_Up>::value> 346 struct __decay_selector; 347 348 // NB: DR 705. 349 template<typename _Up> 350 struct __decay_selector<_Up, false, false> 351 { typedef typename remove_cv<_Up>::type __type; }; 352 353 template<typename _Up> 354 struct __decay_selector<_Up, true, false> 355 { typedef typename remove_extent<_Up>::type* __type; }; 356 357 template<typename _Up> 358 struct __decay_selector<_Up, false, true> 359 { typedef typename add_pointer<_Up>::type __type; }; 360 361 /// decay 362 template<typename _Tp> 363 struct decay 364 { 365 private: 366 typedef typename remove_reference<_Tp>::type __remove_type; 367 368 public: 369 typedef typename __decay_selector<__remove_type>::__type type; 370 }; 371 372 373 // Utility for constructing identically cv-qualified types. 374 template<typename _Unqualified, bool _IsConst, bool _IsVol> 375 struct __cv_selector; 376 377 template<typename _Unqualified> 378 struct __cv_selector<_Unqualified, false, false> 379 { typedef _Unqualified __type; }; 380 381 template<typename _Unqualified> 382 struct __cv_selector<_Unqualified, false, true> 383 { typedef volatile _Unqualified __type; }; 384 385 template<typename _Unqualified> 386 struct __cv_selector<_Unqualified, true, false> 387 { typedef const _Unqualified __type; }; 388 389 template<typename _Unqualified> 390 struct __cv_selector<_Unqualified, true, true> 391 { typedef const volatile _Unqualified __type; }; 392 393 template<typename _Qualified, typename _Unqualified, 394 bool _IsConst = is_const<_Qualified>::value, 395 bool _IsVol = is_volatile<_Qualified>::value> 396 struct __match_cv_qualifiers 397 { 398 private: 399 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; 400 401 public: 402 typedef typename __match::__type __type; 403 }; 404 405 406 // Utility for finding the unsigned versions of signed integral types. 407 template<typename _Tp> 408 struct __make_unsigned 409 { typedef _Tp __type; }; 410 411 template<> 412 struct __make_unsigned<char> 413 { typedef unsigned char __type; }; 414 415 template<> 416 struct __make_unsigned<signed char> 417 { typedef unsigned char __type; }; 418 419 template<> 420 struct __make_unsigned<short> 421 { typedef unsigned short __type; }; 422 423 template<> 424 struct __make_unsigned<int> 425 { typedef unsigned int __type; }; 426 427 template<> 428 struct __make_unsigned<long> 429 { typedef unsigned long __type; }; 430 431 template<> 432 struct __make_unsigned<long long> 433 { typedef unsigned long long __type; }; 434 435 436 // Select between integral and enum: not possible to be both. 437 template<typename _Tp, 438 bool _IsInt = is_integral<_Tp>::value, 439 bool _IsEnum = is_enum<_Tp>::value> 440 struct __make_unsigned_selector; 441 442 template<typename _Tp> 443 struct __make_unsigned_selector<_Tp, true, false> 444 { 445 private: 446 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt; 447 typedef typename __unsignedt::__type __unsigned_type; 448 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; 449 450 public: 451 typedef typename __cv_unsigned::__type __type; 452 }; 453 454 template<typename _Tp> 455 struct __make_unsigned_selector<_Tp, false, true> 456 { 457 private: 458 // With -fshort-enums, an enum may be as small as a char. 459 typedef unsigned char __smallest; 460 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 461 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); 462 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); 463 typedef conditional<__b2, unsigned int, unsigned long> __cond2; 464 typedef typename __cond2::type __cond2_type; 465 typedef conditional<__b1, unsigned short, __cond2_type> __cond1; 466 typedef typename __cond1::type __cond1_type; 467 468 public: 469 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 470 }; 471 472 // Given an integral/enum type, return the corresponding unsigned 473 // integer type. 474 // Primary template. 475 /// make_unsigned 476 template<typename _Tp> 477 struct make_unsigned 478 { typedef typename __make_unsigned_selector<_Tp>::__type type; }; 479 480 // Integral, but don't define. 481 template<> 482 struct make_unsigned<bool>; 483 484 485 // Utility for finding the signed versions of unsigned integral types. 486 template<typename _Tp> 487 struct __make_signed 488 { typedef _Tp __type; }; 489 490 template<> 491 struct __make_signed<char> 492 { typedef signed char __type; }; 493 494 template<> 495 struct __make_signed<unsigned char> 496 { typedef signed char __type; }; 497 498 template<> 499 struct __make_signed<unsigned short> 500 { typedef signed short __type; }; 501 502 template<> 503 struct __make_signed<unsigned int> 504 { typedef signed int __type; }; 505 506 template<> 507 struct __make_signed<unsigned long> 508 { typedef signed long __type; }; 509 510 template<> 511 struct __make_signed<unsigned long long> 512 { typedef signed long long __type; }; 513 514 515 // Select between integral and enum: not possible to be both. 516 template<typename _Tp, 517 bool _IsInt = is_integral<_Tp>::value, 518 bool _IsEnum = is_enum<_Tp>::value> 519 struct __make_signed_selector; 520 521 template<typename _Tp> 522 struct __make_signed_selector<_Tp, true, false> 523 { 524 private: 525 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt; 526 typedef typename __signedt::__type __signed_type; 527 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; 528 529 public: 530 typedef typename __cv_signed::__type __type; 531 }; 532 533 template<typename _Tp> 534 struct __make_signed_selector<_Tp, false, true> 535 { 536 private: 537 // With -fshort-enums, an enum may be as small as a char. 538 typedef signed char __smallest; 539 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 540 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short); 541 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); 542 typedef conditional<__b2, signed int, signed long> __cond2; 543 typedef typename __cond2::type __cond2_type; 544 typedef conditional<__b1, signed short, __cond2_type> __cond1; 545 typedef typename __cond1::type __cond1_type; 546 547 public: 548 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 549 }; 550 551 // Given an integral/enum type, return the corresponding signed 552 // integer type. 553 // Primary template. 554 /// make_signed 555 template<typename _Tp> 556 struct make_signed 557 { typedef typename __make_signed_selector<_Tp>::__type type; }; 558 559 // Integral, but don't define. 560 template<> 561 struct make_signed<bool>; 562 563 /// common_type 564 template<typename... _Tp> 565 struct common_type; 566 567 template<typename _Tp> 568 struct common_type<_Tp> 569 { 570 static_assert(sizeof(_Tp) > 0, "must be complete type"); 571 typedef _Tp type; 572 }; 573 574 template<typename _Tp, typename _Up> 575 class common_type<_Tp, _Up> 576 { 577 static_assert(sizeof(_Tp) > 0, "must be complete type"); 578 static_assert(sizeof(_Up) > 0, "must be complete type"); 579 580 static _Tp&& __t(); 581 static _Up&& __u(); 582 583 // HACK: Prevents optimization of ?: in the decltype 584 // expression when the condition is the literal, "true". 585 // See, PR36628. 586 static bool __true_or_false(); 587 588 public: 589 typedef decltype(__true_or_false() ? __t() : __u()) type; 590 }; 591 592 template<typename _Tp, typename _Up, typename... _Vp> 593 struct common_type<_Tp, _Up, _Vp...> 594 { 595 typedef typename 596 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; 597 }; 598 599 // @} group metaprogramming 600 } 601 602 #endif // __GXX_EXPERIMENTAL_CXX0X__ 603 604 #endif // _GLIBCXX_TYPE_TRAITS 605 606