1 // TR1 type_traits -*- C++ -*- 2 3 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 /** @file tr1/type_traits 27 * This is a TR1 C++ Library header. 28 */ 29 30 #ifndef _GLIBCXX_TR1_TYPE_TRAITS 31 #define _GLIBCXX_TR1_TYPE_TRAITS 1 32 33 #pragma GCC system_header 34 35 #include <bits/c++config.h> 36 37 namespace std _GLIBCXX_VISIBILITY(default) 38 { 39 namespace tr1 40 { 41 _GLIBCXX_BEGIN_NAMESPACE_VERSION 42 43 /** 44 * @addtogroup metaprogramming 45 * @{ 46 */ 47 48 struct __sfinae_types 49 { 50 typedef char __one; 51 typedef struct { char __arr[2]; } __two; 52 }; 53 54 #define _DEFINE_SPEC_0_HELPER \ 55 template<> 56 57 #define _DEFINE_SPEC_1_HELPER \ 58 template<typename _Tp> 59 60 #define _DEFINE_SPEC_2_HELPER \ 61 template<typename _Tp, typename _Cp> 62 63 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ 64 _DEFINE_SPEC_##_Order##_HELPER \ 65 struct _Trait<_Type> \ 66 : public integral_constant<bool, _Value> { }; 67 68 // helper classes [4.3]. 69 70 /// integral_constant 71 template<typename _Tp, _Tp __v> 72 struct integral_constant 73 { 74 static const _Tp value = __v; 75 typedef _Tp value_type; 76 typedef integral_constant<_Tp, __v> type; 77 }; 78 79 /// typedef for true_type 80 typedef integral_constant<bool, true> true_type; 81 82 /// typedef for false_type 83 typedef integral_constant<bool, false> false_type; 84 85 template<typename _Tp, _Tp __v> 86 const _Tp integral_constant<_Tp, __v>::value; 87 88 /// remove_cv 89 template<typename> 90 struct remove_cv; 91 92 template<typename> 93 struct __is_void_helper 94 : public false_type { }; 95 _DEFINE_SPEC(0, __is_void_helper, void, true) 96 97 // primary type categories [4.5.1]. 98 99 /// is_void 100 template<typename _Tp> 101 struct is_void 102 : public integral_constant<bool, (__is_void_helper<typename 103 remove_cv<_Tp>::type>::value)> 104 { }; 105 106 template<typename> 107 struct __is_integral_helper 108 : public false_type { }; 109 _DEFINE_SPEC(0, __is_integral_helper, bool, true) 110 _DEFINE_SPEC(0, __is_integral_helper, char, true) 111 _DEFINE_SPEC(0, __is_integral_helper, signed char, true) 112 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) 113 #ifdef _GLIBCXX_USE_WCHAR_T 114 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) 115 #endif 116 _DEFINE_SPEC(0, __is_integral_helper, short, true) 117 _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true) 118 _DEFINE_SPEC(0, __is_integral_helper, int, true) 119 _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true) 120 _DEFINE_SPEC(0, __is_integral_helper, long, true) 121 _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true) 122 _DEFINE_SPEC(0, __is_integral_helper, long long, true) 123 _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true) 124 125 /// is_integral 126 template<typename _Tp> 127 struct is_integral 128 : public integral_constant<bool, (__is_integral_helper<typename 129 remove_cv<_Tp>::type>::value)> 130 { }; 131 132 template<typename> 133 struct __is_floating_point_helper 134 : public false_type { }; 135 _DEFINE_SPEC(0, __is_floating_point_helper, float, true) 136 _DEFINE_SPEC(0, __is_floating_point_helper, double, true) 137 _DEFINE_SPEC(0, __is_floating_point_helper, long double, true) 138 139 /// is_floating_point 140 template<typename _Tp> 141 struct is_floating_point 142 : public integral_constant<bool, (__is_floating_point_helper<typename 143 remove_cv<_Tp>::type>::value)> 144 { }; 145 146 /// is_array 147 template<typename> 148 struct is_array 149 : public false_type { }; 150 151 template<typename _Tp, std::size_t _Size> 152 struct is_array<_Tp[_Size]> 153 : public true_type { }; 154 155 template<typename _Tp> 156 struct is_array<_Tp[]> 157 : public true_type { }; 158 159 template<typename> 160 struct __is_pointer_helper 161 : public false_type { }; 162 _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true) 163 164 /// is_pointer 165 template<typename _Tp> 166 struct is_pointer 167 : public integral_constant<bool, (__is_pointer_helper<typename 168 remove_cv<_Tp>::type>::value)> 169 { }; 170 171 /// is_reference 172 template<typename _Tp> 173 struct is_reference; 174 175 /// is_function 176 template<typename _Tp> 177 struct is_function; 178 179 template<typename> 180 struct __is_member_object_pointer_helper 181 : public false_type { }; 182 _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*, 183 !is_function<_Tp>::value) 184 185 /// is_member_object_pointer 186 template<typename _Tp> 187 struct is_member_object_pointer 188 : public integral_constant<bool, (__is_member_object_pointer_helper< 189 typename remove_cv<_Tp>::type>::value)> 190 { }; 191 192 template<typename> 193 struct __is_member_function_pointer_helper 194 : public false_type { }; 195 _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*, 196 is_function<_Tp>::value) 197 198 /// is_member_function_pointer 199 template<typename _Tp> 200 struct is_member_function_pointer 201 : public integral_constant<bool, (__is_member_function_pointer_helper< 202 typename remove_cv<_Tp>::type>::value)> 203 { }; 204 205 /// is_enum 206 template<typename _Tp> 207 struct is_enum 208 : public integral_constant<bool, __is_enum(_Tp)> 209 { }; 210 211 /// is_union 212 template<typename _Tp> 213 struct is_union 214 : public integral_constant<bool, __is_union(_Tp)> 215 { }; 216 217 /// is_class 218 template<typename _Tp> 219 struct is_class 220 : public integral_constant<bool, __is_class(_Tp)> 221 { }; 222 223 /// is_function 224 template<typename> 225 struct is_function 226 : public false_type { }; 227 template<typename _Res, typename... _ArgTypes> 228 struct is_function<_Res(_ArgTypes...)> 229 : public true_type { }; 230 template<typename _Res, typename... _ArgTypes> 231 struct is_function<_Res(_ArgTypes......)> 232 : public true_type { }; 233 template<typename _Res, typename... _ArgTypes> 234 struct is_function<_Res(_ArgTypes...) const> 235 : public true_type { }; 236 template<typename _Res, typename... _ArgTypes> 237 struct is_function<_Res(_ArgTypes......) const> 238 : public true_type { }; 239 template<typename _Res, typename... _ArgTypes> 240 struct is_function<_Res(_ArgTypes...) volatile> 241 : public true_type { }; 242 template<typename _Res, typename... _ArgTypes> 243 struct is_function<_Res(_ArgTypes......) volatile> 244 : public true_type { }; 245 template<typename _Res, typename... _ArgTypes> 246 struct is_function<_Res(_ArgTypes...) const volatile> 247 : public true_type { }; 248 template<typename _Res, typename... _ArgTypes> 249 struct is_function<_Res(_ArgTypes......) const volatile> 250 : public true_type { }; 251 252 // composite type traits [4.5.2]. 253 254 /// is_arithmetic 255 template<typename _Tp> 256 struct is_arithmetic 257 : public integral_constant<bool, (is_integral<_Tp>::value 258 || is_floating_point<_Tp>::value)> 259 { }; 260 261 /// is_fundamental 262 template<typename _Tp> 263 struct is_fundamental 264 : public integral_constant<bool, (is_arithmetic<_Tp>::value 265 || is_void<_Tp>::value)> 266 { }; 267 268 /// is_object 269 template<typename _Tp> 270 struct is_object 271 : public integral_constant<bool, !(is_function<_Tp>::value 272 || is_reference<_Tp>::value 273 || is_void<_Tp>::value)> 274 { }; 275 276 /// is_member_pointer 277 template<typename _Tp> 278 struct is_member_pointer; 279 280 /// is_scalar 281 template<typename _Tp> 282 struct is_scalar 283 : public integral_constant<bool, (is_arithmetic<_Tp>::value 284 || is_enum<_Tp>::value 285 || is_pointer<_Tp>::value 286 || is_member_pointer<_Tp>::value)> 287 { }; 288 289 /// is_compound 290 template<typename _Tp> 291 struct is_compound 292 : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 293 294 /// is_member_pointer 295 template<typename _Tp> 296 struct __is_member_pointer_helper 297 : public false_type { }; 298 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) 299 300 template<typename _Tp> 301 struct is_member_pointer 302 : public integral_constant<bool, (__is_member_pointer_helper< 303 typename remove_cv<_Tp>::type>::value)> 304 { }; 305 306 // type properties [4.5.3]. 307 /// is_const 308 template<typename> 309 struct is_const 310 : public false_type { }; 311 312 template<typename _Tp> 313 struct is_const<_Tp const> 314 : public true_type { }; 315 316 /// is_volatile 317 template<typename> 318 struct is_volatile 319 : public false_type { }; 320 321 template<typename _Tp> 322 struct is_volatile<_Tp volatile> 323 : public true_type { }; 324 325 /// is_empty 326 template<typename _Tp> 327 struct is_empty 328 : public integral_constant<bool, __is_empty(_Tp)> 329 { }; 330 331 /// is_polymorphic 332 template<typename _Tp> 333 struct is_polymorphic 334 : public integral_constant<bool, __is_polymorphic(_Tp)> 335 { }; 336 337 /// is_abstract 338 template<typename _Tp> 339 struct is_abstract 340 : public integral_constant<bool, __is_abstract(_Tp)> 341 { }; 342 343 /// has_virtual_destructor 344 template<typename _Tp> 345 struct has_virtual_destructor 346 : public integral_constant<bool, __has_virtual_destructor(_Tp)> 347 { }; 348 349 /// alignment_of 350 template<typename _Tp> 351 struct alignment_of 352 : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 353 354 /// rank 355 template<typename> 356 struct rank 357 : public integral_constant<std::size_t, 0> { }; 358 359 template<typename _Tp, std::size_t _Size> 360 struct rank<_Tp[_Size]> 361 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 362 363 template<typename _Tp> 364 struct rank<_Tp[]> 365 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 366 367 /// extent 368 template<typename, unsigned _Uint = 0> 369 struct extent 370 : public integral_constant<std::size_t, 0> { }; 371 372 template<typename _Tp, unsigned _Uint, std::size_t _Size> 373 struct extent<_Tp[_Size], _Uint> 374 : public integral_constant<std::size_t, 375 _Uint == 0 ? _Size : extent<_Tp, 376 _Uint - 1>::value> 377 { }; 378 379 template<typename _Tp, unsigned _Uint> 380 struct extent<_Tp[], _Uint> 381 : public integral_constant<std::size_t, 382 _Uint == 0 ? 0 : extent<_Tp, 383 _Uint - 1>::value> 384 { }; 385 386 // relationships between types [4.6]. 387 388 /// is_same 389 template<typename, typename> 390 struct is_same 391 : public false_type { }; 392 393 template<typename _Tp> 394 struct is_same<_Tp, _Tp> 395 : public true_type { }; 396 397 // const-volatile modifications [4.7.1]. 398 399 /// remove_const 400 template<typename _Tp> 401 struct remove_const 402 { typedef _Tp type; }; 403 404 template<typename _Tp> 405 struct remove_const<_Tp const> 406 { typedef _Tp type; }; 407 408 /// remove_volatile 409 template<typename _Tp> 410 struct remove_volatile 411 { typedef _Tp type; }; 412 413 template<typename _Tp> 414 struct remove_volatile<_Tp volatile> 415 { typedef _Tp type; }; 416 417 /// remove_cv 418 template<typename _Tp> 419 struct remove_cv 420 { 421 typedef typename 422 remove_const<typename remove_volatile<_Tp>::type>::type type; 423 }; 424 425 /// add_const 426 template<typename _Tp> 427 struct add_const 428 { typedef _Tp const type; }; 429 430 /// add_volatile 431 template<typename _Tp> 432 struct add_volatile 433 { typedef _Tp volatile type; }; 434 435 /// add_cv 436 template<typename _Tp> 437 struct add_cv 438 { 439 typedef typename 440 add_const<typename add_volatile<_Tp>::type>::type type; 441 }; 442 443 // array modifications [4.7.3]. 444 445 /// remove_extent 446 template<typename _Tp> 447 struct remove_extent 448 { typedef _Tp type; }; 449 450 template<typename _Tp, std::size_t _Size> 451 struct remove_extent<_Tp[_Size]> 452 { typedef _Tp type; }; 453 454 template<typename _Tp> 455 struct remove_extent<_Tp[]> 456 { typedef _Tp type; }; 457 458 /// remove_all_extents 459 template<typename _Tp> 460 struct remove_all_extents 461 { typedef _Tp type; }; 462 463 template<typename _Tp, std::size_t _Size> 464 struct remove_all_extents<_Tp[_Size]> 465 { typedef typename remove_all_extents<_Tp>::type type; }; 466 467 template<typename _Tp> 468 struct remove_all_extents<_Tp[]> 469 { typedef typename remove_all_extents<_Tp>::type type; }; 470 471 // pointer modifications [4.7.4]. 472 473 template<typename _Tp, typename> 474 struct __remove_pointer_helper 475 { typedef _Tp type; }; 476 477 template<typename _Tp, typename _Up> 478 struct __remove_pointer_helper<_Tp, _Up*> 479 { typedef _Up type; }; 480 481 /// remove_pointer 482 template<typename _Tp> 483 struct remove_pointer 484 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> 485 { }; 486 487 template<typename> 488 struct remove_reference; 489 490 /// add_pointer 491 template<typename _Tp> 492 struct add_pointer 493 { typedef typename remove_reference<_Tp>::type* type; }; 494 495 template<typename> 496 struct is_reference 497 : public false_type { }; 498 499 template<typename _Tp> 500 struct is_reference<_Tp&> 501 : public true_type { }; 502 503 template<typename _Tp> 504 struct is_pod 505 : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value> 506 { }; 507 508 template<typename _Tp> 509 struct has_trivial_constructor 510 : public integral_constant<bool, is_pod<_Tp>::value> 511 { }; 512 513 template<typename _Tp> 514 struct has_trivial_copy 515 : public integral_constant<bool, is_pod<_Tp>::value> 516 { }; 517 518 template<typename _Tp> 519 struct has_trivial_assign 520 : public integral_constant<bool, is_pod<_Tp>::value> 521 { }; 522 523 template<typename _Tp> 524 struct has_trivial_destructor 525 : public integral_constant<bool, is_pod<_Tp>::value> 526 { }; 527 528 template<typename _Tp> 529 struct has_nothrow_constructor 530 : public integral_constant<bool, is_pod<_Tp>::value> 531 { }; 532 533 template<typename _Tp> 534 struct has_nothrow_copy 535 : public integral_constant<bool, is_pod<_Tp>::value> 536 { }; 537 538 template<typename _Tp> 539 struct has_nothrow_assign 540 : public integral_constant<bool, is_pod<_Tp>::value> 541 { }; 542 543 template<typename> 544 struct __is_signed_helper 545 : public false_type { }; 546 _DEFINE_SPEC(0, __is_signed_helper, signed char, true) 547 _DEFINE_SPEC(0, __is_signed_helper, short, true) 548 _DEFINE_SPEC(0, __is_signed_helper, int, true) 549 _DEFINE_SPEC(0, __is_signed_helper, long, true) 550 _DEFINE_SPEC(0, __is_signed_helper, long long, true) 551 552 template<typename _Tp> 553 struct is_signed 554 : public integral_constant<bool, (__is_signed_helper<typename 555 remove_cv<_Tp>::type>::value)> 556 { }; 557 558 template<typename> 559 struct __is_unsigned_helper 560 : public false_type { }; 561 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned char, true) 562 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned short, true) 563 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned int, true) 564 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long, true) 565 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long long, true) 566 567 template<typename _Tp> 568 struct is_unsigned 569 : public integral_constant<bool, (__is_unsigned_helper<typename 570 remove_cv<_Tp>::type>::value)> 571 { }; 572 573 template<typename _Base, typename _Derived> 574 struct __is_base_of_helper 575 { 576 typedef typename remove_cv<_Base>::type _NoCv_Base; 577 typedef typename remove_cv<_Derived>::type _NoCv_Derived; 578 static const bool __value = (is_same<_Base, _Derived>::value 579 || (__is_base_of(_Base, _Derived) 580 && !is_same<_NoCv_Base, 581 _NoCv_Derived>::value)); 582 }; 583 584 template<typename _Base, typename _Derived> 585 struct is_base_of 586 : public integral_constant<bool, 587 __is_base_of_helper<_Base, _Derived>::__value> 588 { }; 589 590 template<typename _From, typename _To> 591 struct __is_convertible_simple 592 : public __sfinae_types 593 { 594 private: 595 static __one __test(_To); 596 static __two __test(...); 597 static _From __makeFrom(); 598 599 public: 600 static const bool __value = sizeof(__test(__makeFrom())) == 1; 601 }; 602 603 template<typename _Tp> 604 struct add_reference; 605 606 template<typename _Tp> 607 struct __is_int_or_cref 608 { 609 typedef typename remove_reference<_Tp>::type __rr_Tp; 610 static const bool __value = (is_integral<_Tp>::value 611 || (is_integral<__rr_Tp>::value 612 && is_const<__rr_Tp>::value 613 && !is_volatile<__rr_Tp>::value)); 614 }; 615 616 template<typename _From, typename _To, 617 bool = (is_void<_From>::value || is_void<_To>::value 618 || is_function<_To>::value || is_array<_To>::value 619 // This special case is here only to avoid warnings. 620 || (is_floating_point<typename 621 remove_reference<_From>::type>::value 622 && __is_int_or_cref<_To>::__value))> 623 struct __is_convertible_helper 624 { 625 // "An imaginary lvalue of type From...". 626 static const bool __value = (__is_convertible_simple<typename 627 add_reference<_From>::type, _To>::__value); 628 }; 629 630 template<typename _From, typename _To> 631 struct __is_convertible_helper<_From, _To, true> 632 { static const bool __value = (is_void<_To>::value 633 || (__is_int_or_cref<_To>::__value 634 && !is_void<_From>::value)); }; 635 636 template<typename _From, typename _To> 637 struct is_convertible 638 : public integral_constant<bool, 639 __is_convertible_helper<_From, _To>::__value> 640 { }; 641 642 // reference modifications [4.7.2]. 643 template<typename _Tp> 644 struct remove_reference 645 { typedef _Tp type; }; 646 647 template<typename _Tp> 648 struct remove_reference<_Tp&> 649 { typedef _Tp type; }; 650 651 // NB: Careful with reference to void. 652 template<typename _Tp, bool = (is_void<_Tp>::value 653 || is_reference<_Tp>::value)> 654 struct __add_reference_helper 655 { typedef _Tp& type; }; 656 657 template<typename _Tp> 658 struct __add_reference_helper<_Tp, true> 659 { typedef _Tp type; }; 660 661 template<typename _Tp> 662 struct add_reference 663 : public __add_reference_helper<_Tp> 664 { }; 665 666 // other transformations [4.8]. 667 template<std::size_t _Len, std::size_t _Align> 668 struct aligned_storage 669 { 670 union type 671 { 672 unsigned char __data[_Len]; 673 struct __attribute__((__aligned__((_Align)))) { } __align; 674 }; 675 }; 676 677 #undef _DEFINE_SPEC_0_HELPER 678 #undef _DEFINE_SPEC_1_HELPER 679 #undef _DEFINE_SPEC_2_HELPER 680 #undef _DEFINE_SPEC 681 682 /// @} group metaprogramming 683 684 _GLIBCXX_END_NAMESPACE_VERSION 685 } 686 } 687 688 #endif // _GLIBCXX_TR1_TYPE_TRAITS 689