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