1// C++0x type_traits -*- C++ -*- 2 3// Copyright (C) 2007, 2008, 2009, 2010 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 <bits/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 58namespace std 59{ 60 /** 61 * @addtogroup metaprogramming 62 * @{ 63 */ 64 65 // Primary classification traits. 66 67 /// is_lvalue_reference 68 template<typename> 69 struct is_lvalue_reference 70 : public false_type { }; 71 72 template<typename _Tp> 73 struct is_lvalue_reference<_Tp&> 74 : public true_type { }; 75 76 /// is_rvalue_reference 77 template<typename> 78 struct is_rvalue_reference 79 : public false_type { }; 80 81 template<typename _Tp> 82 struct is_rvalue_reference<_Tp&&> 83 : public true_type { }; 84 85 // Secondary classification traits. 86 87 /// is_reference 88 template<typename _Tp> 89 struct is_reference 90 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value 91 || is_rvalue_reference<_Tp>::value)> 92 { }; 93 94 // Reference transformations. 95 96 /// remove_reference 97 template<typename _Tp> 98 struct remove_reference 99 { typedef _Tp type; }; 100 101 template<typename _Tp> 102 struct remove_reference<_Tp&> 103 { typedef _Tp type; }; 104 105 template<typename _Tp> 106 struct remove_reference<_Tp&&> 107 { typedef _Tp type; }; 108 109 template<typename _Tp, 110 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value, 111 bool = is_rvalue_reference<_Tp>::value> 112 struct __add_lvalue_reference_helper 113 { typedef _Tp type; }; 114 115 template<typename _Tp> 116 struct __add_lvalue_reference_helper<_Tp, true, false> 117 { typedef _Tp& type; }; 118 119 template<typename _Tp> 120 struct __add_lvalue_reference_helper<_Tp, false, true> 121 { typedef typename remove_reference<_Tp>::type& type; }; 122 123 /// add_lvalue_reference 124 template<typename _Tp> 125 struct add_lvalue_reference 126 : public __add_lvalue_reference_helper<_Tp> 127 { }; 128 129 template<typename _Tp, 130 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value> 131 struct __add_rvalue_reference_helper 132 { typedef _Tp type; }; 133 134 template<typename _Tp> 135 struct __add_rvalue_reference_helper<_Tp, true> 136 { typedef _Tp&& type; }; 137 138 /// add_rvalue_reference 139 template<typename _Tp> 140 struct add_rvalue_reference 141 : public __add_rvalue_reference_helper<_Tp> 142 { }; 143 144 // Scalar properties and transformations. 145 146 template<typename _Tp, 147 bool = is_integral<_Tp>::value, 148 bool = is_floating_point<_Tp>::value> 149 struct __is_signed_helper 150 : public false_type { }; 151 152 template<typename _Tp> 153 struct __is_signed_helper<_Tp, false, true> 154 : public true_type { }; 155 156 template<typename _Tp> 157 struct __is_signed_helper<_Tp, true, false> 158 : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))> 159 { }; 160 161 /// is_signed 162 template<typename _Tp> 163 struct is_signed 164 : public integral_constant<bool, __is_signed_helper<_Tp>::value> 165 { }; 166 167 /// is_unsigned 168 template<typename _Tp> 169 struct is_unsigned 170 : public integral_constant<bool, (is_arithmetic<_Tp>::value 171 && !is_signed<_Tp>::value)> 172 { }; 173 174 // Member introspection. 175 176 /// is_trivial 177 template<typename _Tp> 178 struct is_trivial 179 : public integral_constant<bool, __is_trivial(_Tp)> 180 { }; 181 182 /// is_standard_layout 183 template<typename _Tp> 184 struct is_standard_layout 185 : public integral_constant<bool, __is_standard_layout(_Tp)> 186 { }; 187 188 /// is_pod 189 // Could use is_standard_layout && is_trivial instead of the builtin. 190 template<typename _Tp> 191 struct is_pod 192 : public integral_constant<bool, __is_pod(_Tp)> 193 { }; 194 195 template<typename _Tp> 196 typename add_rvalue_reference<_Tp>::type declval(); 197 198 template<typename _Tp, typename... _Args> 199 class __is_constructible_helper 200 : public __sfinae_types 201 { 202 template<typename _Tp1, typename... _Args1> 203 static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int); 204 205 template<typename, typename...> 206 static __two __test(...); 207 208 public: 209 static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1; 210 }; 211 212 template<typename _Tp, typename _Arg> 213 class __is_constructible_helper<_Tp, _Arg> 214 : public __sfinae_types 215 { 216 template<typename _Tp1, typename _Arg1> 217 static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one()) 218 __test(int); 219 220 template<typename, typename> 221 static __two __test(...); 222 223 public: 224 static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1; 225 }; 226 227 /// is_constructible 228 // XXX FIXME 229 // The C++0x specifications require front-end support, see N2255. 230 template<typename _Tp, typename... _Args> 231 struct is_constructible 232 : public integral_constant<bool, 233 __is_constructible_helper<_Tp, 234 _Args...>::__value> 235 { }; 236 237 /// has_trivial_default_constructor 238 template<typename _Tp> 239 struct has_trivial_default_constructor 240 : public integral_constant<bool, __has_trivial_constructor(_Tp)> 241 { }; 242 243 /// has_trivial_copy_constructor 244 template<typename _Tp> 245 struct has_trivial_copy_constructor 246 : public integral_constant<bool, __has_trivial_copy(_Tp)> 247 { }; 248 249 /// has_trivial_assign 250 template<typename _Tp> 251 struct has_trivial_assign 252 : public integral_constant<bool, __has_trivial_assign(_Tp)> 253 { }; 254 255 /// has_trivial_destructor 256 template<typename _Tp> 257 struct has_trivial_destructor 258 : public integral_constant<bool, __has_trivial_destructor(_Tp)> 259 { }; 260 261 /// has_nothrow_default_constructor 262 template<typename _Tp> 263 struct has_nothrow_default_constructor 264 : public integral_constant<bool, __has_nothrow_constructor(_Tp)> 265 { }; 266 267 /// has_nothrow_copy_constructor 268 template<typename _Tp> 269 struct has_nothrow_copy_constructor 270 : public integral_constant<bool, __has_nothrow_copy(_Tp)> 271 { }; 272 273 /// has_nothrow_assign 274 template<typename _Tp> 275 struct has_nothrow_assign 276 : public integral_constant<bool, __has_nothrow_assign(_Tp)> 277 { }; 278 279 // Relationships between types. 280 281 /// is_base_of 282 template<typename _Base, typename _Derived> 283 struct is_base_of 284 : public integral_constant<bool, __is_base_of(_Base, _Derived)> 285 { }; 286 287 template<typename _From, typename _To, 288 bool = (is_void<_From>::value || is_void<_To>::value 289 || is_function<_To>::value || is_array<_To>::value)> 290 struct __is_convertible_helper 291 { static const bool __value = (is_void<_From>::value 292 && is_void<_To>::value); }; 293 294 template<typename _From, typename _To> 295 class __is_convertible_helper<_From, _To, false> 296 : public __sfinae_types 297 { 298 static __one __test(_To); 299 static __two __test(...); 300 301 public: 302 static const bool __value = sizeof(__test(declval<_From>())) == 1; 303 }; 304 305 /// is_convertible 306 // XXX FIXME 307 // The C++0x specifications require front-end support, see N2255. 308 template<typename _From, typename _To> 309 struct is_convertible 310 : public integral_constant<bool, 311 __is_convertible_helper<_From, _To>::__value> 312 { }; 313 314 /// is_explicitly_convertible 315 template<typename _From, typename _To> 316 struct is_explicitly_convertible 317 : public is_constructible<_To, _From> 318 { }; 319 320 template<std::size_t _Len> 321 struct __aligned_storage_msa 322 { 323 union __type 324 { 325 unsigned char __data[_Len]; 326 struct __attribute__((__aligned__)) { } __align; 327 }; 328 }; 329 330 /** 331 * @brief Alignment type. 332 * 333 * The value of _Align is a default-alignment which shall be the 334 * most stringent alignment requirement for any C++ object type 335 * whose size is no greater than _Len (3.9). The member typedef 336 * type shall be a POD type suitable for use as uninitialized 337 * storage for any object whose size is at most _Len and whose 338 * alignment is a divisor of _Align. 339 */ 340 template<std::size_t _Len, std::size_t _Align = 341 __alignof__(typename __aligned_storage_msa<_Len>::__type)> 342 struct aligned_storage 343 { 344 union type 345 { 346 unsigned char __data[_Len]; 347 struct __attribute__((__aligned__((_Align)))) { } __align; 348 }; 349 }; 350 351 352 // Define a nested type if some predicate holds. 353 // Primary template. 354 /// enable_if 355 template<bool, typename _Tp = void> 356 struct enable_if 357 { }; 358 359 // Partial specialization for true. 360 template<typename _Tp> 361 struct enable_if<true, _Tp> 362 { typedef _Tp type; }; 363 364 365 // A conditional expression, but for types. If true, first, if false, second. 366 // Primary template. 367 /// conditional 368 template<bool _Cond, typename _Iftrue, typename _Iffalse> 369 struct conditional 370 { typedef _Iftrue type; }; 371 372 // Partial specialization for false. 373 template<typename _Iftrue, typename _Iffalse> 374 struct conditional<false, _Iftrue, _Iffalse> 375 { typedef _Iffalse type; }; 376 377 378 // Decay trait for arrays and functions, used for perfect forwarding 379 // in make_pair, make_tuple, etc. 380 template<typename _Up, 381 bool _IsArray = is_array<_Up>::value, 382 bool _IsFunction = is_function<_Up>::value> 383 struct __decay_selector; 384 385 // NB: DR 705. 386 template<typename _Up> 387 struct __decay_selector<_Up, false, false> 388 { typedef typename remove_cv<_Up>::type __type; }; 389 390 template<typename _Up> 391 struct __decay_selector<_Up, true, false> 392 { typedef typename remove_extent<_Up>::type* __type; }; 393 394 template<typename _Up> 395 struct __decay_selector<_Up, false, true> 396 { typedef typename add_pointer<_Up>::type __type; }; 397 398 /// decay 399 template<typename _Tp> 400 class decay 401 { 402 typedef typename remove_reference<_Tp>::type __remove_type; 403 404 public: 405 typedef typename __decay_selector<__remove_type>::__type type; 406 }; 407 408 409 // Utility for constructing identically cv-qualified types. 410 template<typename _Unqualified, bool _IsConst, bool _IsVol> 411 struct __cv_selector; 412 413 template<typename _Unqualified> 414 struct __cv_selector<_Unqualified, false, false> 415 { typedef _Unqualified __type; }; 416 417 template<typename _Unqualified> 418 struct __cv_selector<_Unqualified, false, true> 419 { typedef volatile _Unqualified __type; }; 420 421 template<typename _Unqualified> 422 struct __cv_selector<_Unqualified, true, false> 423 { typedef const _Unqualified __type; }; 424 425 template<typename _Unqualified> 426 struct __cv_selector<_Unqualified, true, true> 427 { typedef const volatile _Unqualified __type; }; 428 429 template<typename _Qualified, typename _Unqualified, 430 bool _IsConst = is_const<_Qualified>::value, 431 bool _IsVol = is_volatile<_Qualified>::value> 432 class __match_cv_qualifiers 433 { 434 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; 435 436 public: 437 typedef typename __match::__type __type; 438 }; 439 440 441 // Utility for finding the unsigned versions of signed integral types. 442 template<typename _Tp> 443 struct __make_unsigned 444 { typedef _Tp __type; }; 445 446 template<> 447 struct __make_unsigned<char> 448 { typedef unsigned char __type; }; 449 450 template<> 451 struct __make_unsigned<signed char> 452 { typedef unsigned char __type; }; 453 454 template<> 455 struct __make_unsigned<short> 456 { typedef unsigned short __type; }; 457 458 template<> 459 struct __make_unsigned<int> 460 { typedef unsigned int __type; }; 461 462 template<> 463 struct __make_unsigned<long> 464 { typedef unsigned long __type; }; 465 466 template<> 467 struct __make_unsigned<long long> 468 { typedef unsigned long long __type; }; 469 470 471 // Select between integral and enum: not possible to be both. 472 template<typename _Tp, 473 bool _IsInt = is_integral<_Tp>::value, 474 bool _IsEnum = is_enum<_Tp>::value> 475 class __make_unsigned_selector; 476 477 template<typename _Tp> 478 class __make_unsigned_selector<_Tp, true, false> 479 { 480 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt; 481 typedef typename __unsignedt::__type __unsigned_type; 482 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; 483 484 public: 485 typedef typename __cv_unsigned::__type __type; 486 }; 487 488 template<typename _Tp> 489 class __make_unsigned_selector<_Tp, false, true> 490 { 491 // With -fshort-enums, an enum may be as small as a char. 492 typedef unsigned char __smallest; 493 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 494 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); 495 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); 496 typedef conditional<__b2, unsigned int, unsigned long> __cond2; 497 typedef typename __cond2::type __cond2_type; 498 typedef conditional<__b1, unsigned short, __cond2_type> __cond1; 499 typedef typename __cond1::type __cond1_type; 500 501 public: 502 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 503 }; 504 505 // Given an integral/enum type, return the corresponding unsigned 506 // integer type. 507 // Primary template. 508 /// make_unsigned 509 template<typename _Tp> 510 struct make_unsigned 511 { typedef typename __make_unsigned_selector<_Tp>::__type type; }; 512 513 // Integral, but don't define. 514 template<> 515 struct make_unsigned<bool>; 516 517 518 // Utility for finding the signed versions of unsigned integral types. 519 template<typename _Tp> 520 struct __make_signed 521 { typedef _Tp __type; }; 522 523 template<> 524 struct __make_signed<char> 525 { typedef signed char __type; }; 526 527 template<> 528 struct __make_signed<unsigned char> 529 { typedef signed char __type; }; 530 531 template<> 532 struct __make_signed<unsigned short> 533 { typedef signed short __type; }; 534 535 template<> 536 struct __make_signed<unsigned int> 537 { typedef signed int __type; }; 538 539 template<> 540 struct __make_signed<unsigned long> 541 { typedef signed long __type; }; 542 543 template<> 544 struct __make_signed<unsigned long long> 545 { typedef signed long long __type; }; 546 547 548 // Select between integral and enum: not possible to be both. 549 template<typename _Tp, 550 bool _IsInt = is_integral<_Tp>::value, 551 bool _IsEnum = is_enum<_Tp>::value> 552 class __make_signed_selector; 553 554 template<typename _Tp> 555 class __make_signed_selector<_Tp, true, false> 556 { 557 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt; 558 typedef typename __signedt::__type __signed_type; 559 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; 560 561 public: 562 typedef typename __cv_signed::__type __type; 563 }; 564 565 template<typename _Tp> 566 class __make_signed_selector<_Tp, false, true> 567 { 568 // With -fshort-enums, an enum may be as small as a char. 569 typedef signed char __smallest; 570 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 571 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short); 572 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); 573 typedef conditional<__b2, signed int, signed long> __cond2; 574 typedef typename __cond2::type __cond2_type; 575 typedef conditional<__b1, signed short, __cond2_type> __cond1; 576 typedef typename __cond1::type __cond1_type; 577 578 public: 579 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 580 }; 581 582 // Given an integral/enum type, return the corresponding signed 583 // integer type. 584 // Primary template. 585 /// make_signed 586 template<typename _Tp> 587 struct make_signed 588 { typedef typename __make_signed_selector<_Tp>::__type type; }; 589 590 // Integral, but don't define. 591 template<> 592 struct make_signed<bool>; 593 594 /// common_type 595 template<typename... _Tp> 596 struct common_type; 597 598 template<typename _Tp> 599 struct common_type<_Tp> 600 { typedef _Tp type; }; 601 602 template<typename _Tp, typename _Up> 603 struct common_type<_Tp, _Up> 604 { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; }; 605 606 template<typename _Tp, typename _Up, typename... _Vp> 607 struct common_type<_Tp, _Up, _Vp...> 608 { 609 typedef typename 610 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; 611 }; 612 // @} group metaprogramming 613 614 /// declval 615 template<typename _Tp> 616 struct __declval_protector 617 { 618 static const bool __stop = false; 619 static typename add_rvalue_reference<_Tp>::type __delegate(); 620 }; 621 622 template<typename _Tp> 623 inline typename add_rvalue_reference<_Tp>::type 624 declval() 625 { 626 static_assert(__declval_protector<_Tp>::__stop, 627 "declval() must not be used!"); 628 return __declval_protector<_Tp>::__delegate(); 629 } 630} 631 632#endif // __GXX_EXPERIMENTAL_CXX0X__ 633 634#endif // _GLIBCXX_TYPE_TRAITS 635