1169691Skan// TR1 type_traits -*- C++ -*- 2169691Skan 3169691Skan// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 4169691Skan// 5169691Skan// This file is part of the GNU ISO C++ Library. This library is free 6169691Skan// software; you can redistribute it and/or modify it under the 7169691Skan// terms of the GNU General Public License as published by the 8169691Skan// Free Software Foundation; either version 2, or (at your option) 9169691Skan// any later version. 10169691Skan 11169691Skan// This library is distributed in the hope that it will be useful, 12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169691Skan// GNU General Public License for more details. 15169691Skan 16169691Skan// You should have received a copy of the GNU General Public License along 17169691Skan// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19169691Skan// USA. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free software 22169691Skan// library without restriction. Specifically, if other files instantiate 23169691Skan// templates or use macros or inline functions from this file, or you compile 24169691Skan// this file and link it with other files to produce an executable, this 25169691Skan// file does not by itself cause the resulting executable to be covered by 26169691Skan// the GNU General Public License. This exception does not however 27169691Skan// invalidate any other reasons why the executable file might be covered by 28169691Skan// the GNU General Public License. 29169691Skan 30169691Skan/** @file tr1/type_traits 31169691Skan * This is a TR1 C++ Library header. 32169691Skan */ 33169691Skan 34169691Skan#ifndef _TR1_TYPE_TRAITS 35169691Skan#define _TR1_TYPE_TRAITS 1 36169691Skan 37169691Skan#include <bits/c++config.h> 38169691Skan#include <tr1/type_traits_fwd.h> 39169691Skan 40169691Skan// namespace std::tr1 41169691Skannamespace std 42169691Skan{ 43169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1) 44169691Skan 45169691Skan // For use in __in_array and elsewhere. 46169691Skan struct __sfinae_types 47169691Skan { 48169691Skan typedef char __one; 49169691Skan typedef struct { char __arr[2]; } __two; 50169691Skan }; 51169691Skan 52169691Skan template<typename _Tp> 53169691Skan struct __in_array 54169691Skan : public __sfinae_types 55169691Skan { 56169691Skan private: 57169691Skan template<typename _Up> 58169691Skan static __one __test(_Up(*)[1]); 59169691Skan template<typename> 60169691Skan static __two __test(...); 61169691Skan 62169691Skan public: 63169691Skan static const bool __value = sizeof(__test<_Tp>(0)) == 1; 64169691Skan }; 65169691Skan 66169691Skan#define _DEFINE_SPEC_BODY(_Value) \ 67169691Skan : public integral_constant<bool, _Value> { }; 68169691Skan 69169691Skan#define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \ 70169691Skan template<> \ 71169691Skan struct _Spec \ 72169691Skan _DEFINE_SPEC_BODY(_Value) 73169691Skan 74169691Skan#define _DEFINE_SPEC_1_HELPER(_Spec, _Value) \ 75169691Skan template<typename _Tp> \ 76169691Skan struct _Spec \ 77169691Skan _DEFINE_SPEC_BODY(_Value) 78169691Skan 79169691Skan#define _DEFINE_SPEC_2_HELPER(_Spec, _Value) \ 80169691Skan template<typename _Tp, typename _Cp> \ 81169691Skan struct _Spec \ 82169691Skan _DEFINE_SPEC_BODY(_Value) 83169691Skan 84169691Skan#define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ 85169691Skan _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \ 86169691Skan _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \ 87169691Skan _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \ 88169691Skan _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value) 89169691Skan 90169691Skan /// @brief helper classes [4.3]. 91169691Skan template<typename _Tp, _Tp __v> 92169691Skan struct integral_constant 93169691Skan { 94169691Skan static const _Tp value = __v; 95169691Skan typedef _Tp value_type; 96169691Skan typedef integral_constant<_Tp, __v> type; 97169691Skan }; 98169691Skan typedef integral_constant<bool, true> true_type; 99169691Skan typedef integral_constant<bool, false> false_type; 100169691Skan 101169691Skan template<typename _Tp, _Tp __v> 102169691Skan const _Tp integral_constant<_Tp, __v>::value; 103169691Skan 104169691Skan /// @brief primary type categories [4.5.1]. 105169691Skan template<typename> 106169691Skan struct is_void 107169691Skan : public false_type { }; 108169691Skan _DEFINE_SPEC(0, is_void, void, true) 109169691Skan 110169691Skan template<typename> 111169691Skan struct is_integral 112169691Skan : public false_type { }; 113169691Skan _DEFINE_SPEC(0, is_integral, bool, true) 114169691Skan _DEFINE_SPEC(0, is_integral, char, true) 115169691Skan _DEFINE_SPEC(0, is_integral, signed char, true) 116169691Skan _DEFINE_SPEC(0, is_integral, unsigned char, true) 117169691Skan#ifdef _GLIBCXX_USE_WCHAR_T 118169691Skan _DEFINE_SPEC(0, is_integral, wchar_t, true) 119169691Skan#endif 120169691Skan _DEFINE_SPEC(0, is_integral, short, true) 121169691Skan _DEFINE_SPEC(0, is_integral, unsigned short, true) 122169691Skan _DEFINE_SPEC(0, is_integral, int, true) 123169691Skan _DEFINE_SPEC(0, is_integral, unsigned int, true) 124169691Skan _DEFINE_SPEC(0, is_integral, long, true) 125169691Skan _DEFINE_SPEC(0, is_integral, unsigned long, true) 126169691Skan _DEFINE_SPEC(0, is_integral, long long, true) 127169691Skan _DEFINE_SPEC(0, is_integral, unsigned long long, true) 128169691Skan 129169691Skan template<typename> 130169691Skan struct is_floating_point 131169691Skan : public false_type { }; 132169691Skan _DEFINE_SPEC(0, is_floating_point, float, true) 133169691Skan _DEFINE_SPEC(0, is_floating_point, double, true) 134169691Skan _DEFINE_SPEC(0, is_floating_point, long double, true) 135169691Skan 136169691Skan template<typename> 137169691Skan struct is_array 138169691Skan : public false_type { }; 139169691Skan 140169691Skan template<typename _Tp, std::size_t _Size> 141169691Skan struct is_array<_Tp[_Size]> 142169691Skan : public true_type { }; 143169691Skan 144169691Skan template<typename _Tp> 145169691Skan struct is_array<_Tp[]> 146169691Skan : public true_type { }; 147169691Skan 148169691Skan template<typename> 149169691Skan struct is_pointer 150169691Skan : public false_type { }; 151169691Skan _DEFINE_SPEC(1, is_pointer, _Tp*, true) 152169691Skan 153169691Skan template<typename> 154169691Skan struct is_reference 155169691Skan : public false_type { }; 156169691Skan 157169691Skan template<typename _Tp> 158169691Skan struct is_reference<_Tp&> 159169691Skan : public true_type { }; 160169691Skan 161169691Skan template<typename> 162169691Skan struct is_member_object_pointer 163169691Skan : public false_type { }; 164169691Skan _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*, 165169691Skan !is_function<_Tp>::value) 166169691Skan 167169691Skan template<typename> 168169691Skan struct is_member_function_pointer 169169691Skan : public false_type { }; 170169691Skan _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*, 171169691Skan is_function<_Tp>::value) 172169691Skan 173169691Skan template<typename _Tp> 174169691Skan struct is_enum 175169691Skan : public integral_constant<bool, !(is_fundamental<_Tp>::value 176169691Skan || is_array<_Tp>::value 177169691Skan || is_pointer<_Tp>::value 178169691Skan || is_reference<_Tp>::value 179169691Skan || is_member_pointer<_Tp>::value 180169691Skan || is_function<_Tp>::value 181169691Skan || __is_union_or_class<_Tp>::value)> 182169691Skan { }; 183169691Skan 184169691Skan template<typename> 185169691Skan struct is_union { }; 186169691Skan 187169691Skan template<typename> 188169691Skan struct is_class { }; 189169691Skan 190169691Skan template<typename _Tp> 191169691Skan struct is_function 192169691Skan : public integral_constant<bool, !(__in_array<_Tp>::__value 193169691Skan || __is_union_or_class<_Tp>::value 194169691Skan || is_reference<_Tp>::value 195169691Skan || is_void<_Tp>::value)> 196169691Skan { }; 197169691Skan 198169691Skan /// @brief composite type traits [4.5.2]. 199169691Skan template<typename _Tp> 200169691Skan struct is_arithmetic 201169691Skan : public integral_constant<bool, (is_integral<_Tp>::value 202169691Skan || is_floating_point<_Tp>::value)> 203169691Skan { }; 204169691Skan 205169691Skan template<typename _Tp> 206169691Skan struct is_fundamental 207169691Skan : public integral_constant<bool, (is_arithmetic<_Tp>::value 208169691Skan || is_void<_Tp>::value)> 209169691Skan { }; 210169691Skan 211169691Skan template<typename _Tp> 212169691Skan struct is_object 213169691Skan : public integral_constant<bool, !(is_function<_Tp>::value 214169691Skan || is_reference<_Tp>::value 215169691Skan || is_void<_Tp>::value)> 216169691Skan { }; 217169691Skan 218169691Skan template<typename _Tp> 219169691Skan struct is_scalar 220169691Skan : public integral_constant<bool, (is_arithmetic<_Tp>::value 221169691Skan || is_enum<_Tp>::value 222169691Skan || is_pointer<_Tp>::value 223169691Skan || is_member_pointer<_Tp>::value)> 224169691Skan { }; 225169691Skan 226169691Skan template<typename _Tp> 227169691Skan struct is_compound 228169691Skan : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 229169691Skan 230169691Skan template<typename _Tp> 231169691Skan struct is_member_pointer 232169691Skan : public integral_constant<bool, 233169691Skan (is_member_object_pointer<_Tp>::value 234169691Skan || is_member_function_pointer<_Tp>::value)> 235169691Skan { }; 236169691Skan 237169691Skan template<typename _Tp> 238169691Skan struct __is_union_or_class_helper 239169691Skan : public __sfinae_types 240169691Skan { 241169691Skan private: 242169691Skan template<typename _Up> 243169691Skan static __one __test(int _Up::*); 244169691Skan template<typename> 245169691Skan static __two __test(...); 246169691Skan 247169691Skan public: 248169691Skan static const bool __value = sizeof(__test<_Tp>(0)) == 1; 249169691Skan }; 250169691Skan 251169691Skan // Extension. 252169691Skan template<typename _Tp> 253169691Skan struct __is_union_or_class 254169691Skan : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value> 255169691Skan { }; 256169691Skan 257169691Skan /// @brief type properties [4.5.3]. 258169691Skan template<typename> 259169691Skan struct is_const 260169691Skan : public false_type { }; 261169691Skan 262169691Skan template<typename _Tp> 263169691Skan struct is_const<_Tp const> 264169691Skan : public true_type { }; 265169691Skan 266169691Skan template<typename> 267169691Skan struct is_volatile 268169691Skan : public false_type { }; 269169691Skan 270169691Skan template<typename _Tp> 271169691Skan struct is_volatile<_Tp volatile> 272169691Skan : public true_type { }; 273169691Skan 274169691Skan template<typename _Tp> 275169691Skan struct is_pod 276169691Skan : public integral_constant<bool, (is_void<_Tp>::value 277169691Skan || is_scalar<typename 278169691Skan remove_all_extents<_Tp>::type>::value)> 279169691Skan { }; 280169691Skan 281169691Skan // NB: Without compiler support we cannot tell union from class types, 282169691Skan // and is_empty and is_polymorphic don't work at all with the former. 283169691Skan template<typename _Tp, bool = !__is_union_or_class<_Tp>::value> 284169691Skan struct __is_empty_helper 285169691Skan { 286169691Skan private: 287169691Skan template<typename> 288169691Skan struct __first { }; 289169691Skan template<typename _Up> 290169691Skan struct __second 291169691Skan : public _Up { }; 292169691Skan 293169691Skan public: 294169691Skan static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>); 295169691Skan }; 296169691Skan 297169691Skan template<typename _Tp> 298169691Skan struct __is_empty_helper<_Tp, true> 299169691Skan { static const bool __value = false; }; 300169691Skan 301169691Skan template<typename _Tp> 302169691Skan struct is_empty 303169691Skan : public integral_constant<bool, __is_empty_helper<_Tp>::__value> 304169691Skan { }; 305169691Skan 306169691Skan template<typename _Tp, bool = !__is_union_or_class<_Tp>::value> 307169691Skan struct __is_polymorphic_helper 308169691Skan { 309169691Skan private: 310169691Skan template<typename _Up> 311169691Skan struct __first 312169691Skan : public _Up { }; 313169691Skan template<typename _Up> 314169691Skan struct __second 315169691Skan : public _Up 316169691Skan { 317169691Skan virtual void __dummy(); 318169691Skan virtual ~__second() throw(); 319169691Skan }; 320169691Skan 321169691Skan public: 322169691Skan static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>); 323169691Skan }; 324169691Skan 325169691Skan template<typename _Tp> 326169691Skan struct __is_polymorphic_helper<_Tp, true> 327169691Skan { static const bool __value = false; }; 328169691Skan 329169691Skan template<typename _Tp> 330169691Skan struct is_polymorphic 331169691Skan : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value> 332169691Skan { }; 333169691Skan 334169691Skan // Exploit the resolution DR core/337. 335169691Skan template<typename _Tp> 336169691Skan struct is_abstract 337169691Skan : public integral_constant<bool, (!__in_array<_Tp>::__value 338169691Skan && __is_union_or_class<_Tp>::value)> { }; 339169691Skan 340169691Skan template<typename _Tp> 341169691Skan struct has_trivial_constructor 342169691Skan : public integral_constant<bool, is_pod<_Tp>::value> { }; 343169691Skan 344169691Skan template<typename _Tp> 345169691Skan struct has_trivial_copy 346169691Skan : public integral_constant<bool, is_pod<_Tp>::value> { }; 347169691Skan 348169691Skan template<typename _Tp> 349169691Skan struct has_trivial_assign 350169691Skan : public integral_constant<bool, is_pod<_Tp>::value> { }; 351169691Skan 352169691Skan template<typename _Tp> 353169691Skan struct has_trivial_destructor 354169691Skan : public integral_constant<bool, is_pod<_Tp>::value> { }; 355169691Skan 356169691Skan template<typename _Tp> 357169691Skan struct has_nothrow_constructor 358169691Skan : public integral_constant<bool, is_pod<_Tp>::value> { }; 359169691Skan 360169691Skan template<typename _Tp> 361169691Skan struct has_nothrow_copy 362169691Skan : public integral_constant<bool, is_pod<_Tp>::value> { }; 363169691Skan 364169691Skan template<typename _Tp> 365169691Skan struct has_nothrow_assign 366169691Skan : public integral_constant<bool, is_pod<_Tp>::value> { }; 367169691Skan 368169691Skan template<typename> 369169691Skan struct has_virtual_destructor 370169691Skan : public false_type { }; 371169691Skan 372169691Skan template<typename> 373169691Skan struct is_signed 374169691Skan : public false_type { }; 375169691Skan _DEFINE_SPEC(0, is_signed, signed char, true) 376169691Skan _DEFINE_SPEC(0, is_signed, short, true) 377169691Skan _DEFINE_SPEC(0, is_signed, int, true) 378169691Skan _DEFINE_SPEC(0, is_signed, long, true) 379169691Skan _DEFINE_SPEC(0, is_signed, long long, true) 380169691Skan 381169691Skan template<typename> 382169691Skan struct is_unsigned 383169691Skan : public false_type { }; 384169691Skan _DEFINE_SPEC(0, is_unsigned, unsigned char, true) 385169691Skan _DEFINE_SPEC(0, is_unsigned, unsigned short, true) 386169691Skan _DEFINE_SPEC(0, is_unsigned, unsigned int, true) 387169691Skan _DEFINE_SPEC(0, is_unsigned, unsigned long, true) 388169691Skan _DEFINE_SPEC(0, is_unsigned, unsigned long long, true) 389169691Skan 390169691Skan template<typename _Tp> 391169691Skan struct alignment_of 392169691Skan : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 393169691Skan 394169691Skan template<typename> 395169691Skan struct rank 396169691Skan : public integral_constant<std::size_t, 0> { }; 397169691Skan 398169691Skan template<typename _Tp, std::size_t _Size> 399169691Skan struct rank<_Tp[_Size]> 400169691Skan : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 401169691Skan 402169691Skan template<typename _Tp> 403169691Skan struct rank<_Tp[]> 404169691Skan : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 405169691Skan 406169691Skan template<typename, unsigned> 407169691Skan struct extent 408169691Skan : public integral_constant<std::size_t, 0> { }; 409169691Skan 410169691Skan template<typename _Tp, unsigned _Uint, std::size_t _Size> 411169691Skan struct extent<_Tp[_Size], _Uint> 412169691Skan : public integral_constant<std::size_t, 413169691Skan _Uint == 0 ? _Size : extent<_Tp, 414169691Skan _Uint - 1>::value> 415169691Skan { }; 416169691Skan 417169691Skan template<typename _Tp, unsigned _Uint> 418169691Skan struct extent<_Tp[], _Uint> 419169691Skan : public integral_constant<std::size_t, 420169691Skan _Uint == 0 ? 0 : extent<_Tp, 421169691Skan _Uint - 1>::value> 422169691Skan { }; 423169691Skan 424169691Skan /// @brief relationships between types [4.6]. 425169691Skan template<typename, typename> 426169691Skan struct is_same 427169691Skan : public false_type { }; 428169691Skan 429169691Skan template<typename _Tp> 430169691Skan struct is_same<_Tp, _Tp> 431169691Skan : public true_type { }; 432169691Skan 433169691Skan // See Daveed Vandevoorde explanation in http://tinyurl.com/502f. 434169691Skan // Also see Rani Sharoni in http://tinyurl.com/6jvyq. 435169691Skan template<typename _Base, typename _Derived, 436169691Skan bool = (!__is_union_or_class<_Base>::value 437169691Skan || !__is_union_or_class<_Derived>::value 438169691Skan || is_same<_Base, _Derived>::value)> 439169691Skan struct __is_base_of_helper 440169691Skan : public __sfinae_types 441169691Skan { 442169691Skan private: 443169691Skan typedef typename remove_cv<_Base>::type _NoCv_Base; 444169691Skan typedef typename remove_cv<_Derived>::type _NoCv_Derived; 445169691Skan 446169691Skan template<typename _Up> 447169691Skan static __one __test(_NoCv_Derived&, _Up); 448169691Skan static __two __test(_NoCv_Base&, int); 449169691Skan 450169691Skan struct _Conv 451169691Skan { 452169691Skan operator _NoCv_Derived&(); 453169691Skan operator _NoCv_Base&() const; 454169691Skan }; 455169691Skan 456169691Skan public: 457169691Skan static const bool __value = sizeof(__test(_Conv(), 0)) == 1; 458169691Skan }; 459169691Skan 460169691Skan template<typename _Base, typename _Derived> 461169691Skan struct __is_base_of_helper<_Base, _Derived, true> 462169691Skan { static const bool __value = is_same<_Base, _Derived>::value; }; 463169691Skan 464169691Skan template<typename _Base, typename _Derived> 465169691Skan struct is_base_of 466169691Skan : public integral_constant<bool, 467169691Skan __is_base_of_helper<_Base, _Derived>::__value> 468169691Skan { }; 469169691Skan 470169691Skan template<typename _From, typename _To> 471169691Skan struct __is_convertible_simple 472169691Skan : public __sfinae_types 473169691Skan { 474169691Skan private: 475169691Skan static __one __test(_To); 476169691Skan static __two __test(...); 477169691Skan static _From __makeFrom(); 478169691Skan 479169691Skan public: 480169691Skan static const bool __value = sizeof(__test(__makeFrom())) == 1; 481169691Skan }; 482169691Skan 483169691Skan template<typename _Tp> 484169691Skan struct __is_int_or_cref 485169691Skan { 486169691Skan typedef typename remove_reference<_Tp>::type __rr_Tp; 487169691Skan static const bool __value = (is_integral<_Tp>::value 488169691Skan || (is_integral<__rr_Tp>::value 489169691Skan && is_const<__rr_Tp>::value 490169691Skan && !is_volatile<__rr_Tp>::value)); 491169691Skan }; 492169691Skan 493169691Skan template<typename _From, typename _To, 494169691Skan bool = (is_void<_From>::value || is_void<_To>::value 495169691Skan || is_function<_To>::value || is_array<_To>::value 496169691Skan // This special case is here only to avoid warnings. 497169691Skan || (is_floating_point<typename 498169691Skan remove_reference<_From>::type>::value 499169691Skan && __is_int_or_cref<_To>::__value))> 500169691Skan struct __is_convertible_helper 501169691Skan { 502169691Skan // "An imaginary lvalue of type From...". 503169691Skan static const bool __value = (__is_convertible_simple<typename 504169691Skan add_reference<_From>::type, _To>::__value); 505169691Skan }; 506169691Skan 507169691Skan template<typename _From, typename _To> 508169691Skan struct __is_convertible_helper<_From, _To, true> 509169691Skan { static const bool __value = (is_void<_To>::value 510169691Skan || (__is_int_or_cref<_To>::__value 511169691Skan && !is_void<_From>::value)); }; 512169691Skan 513169691Skan template<typename _From, typename _To> 514169691Skan struct is_convertible 515169691Skan : public integral_constant<bool, 516169691Skan __is_convertible_helper<_From, _To>::__value> 517169691Skan { }; 518169691Skan 519169691Skan /// @brief const-volatile modifications [4.7.1]. 520169691Skan template<typename _Tp> 521169691Skan struct remove_const 522169691Skan { typedef _Tp type; }; 523169691Skan 524169691Skan template<typename _Tp> 525169691Skan struct remove_const<_Tp const> 526169691Skan { typedef _Tp type; }; 527169691Skan 528169691Skan template<typename _Tp> 529169691Skan struct remove_volatile 530169691Skan { typedef _Tp type; }; 531169691Skan 532169691Skan template<typename _Tp> 533169691Skan struct remove_volatile<_Tp volatile> 534169691Skan { typedef _Tp type; }; 535169691Skan 536169691Skan template<typename _Tp> 537169691Skan struct remove_cv 538169691Skan { 539169691Skan typedef typename 540169691Skan remove_const<typename remove_volatile<_Tp>::type>::type type; 541169691Skan }; 542169691Skan 543169691Skan template<typename _Tp> 544169691Skan struct add_const 545169691Skan { typedef _Tp const type; }; 546169691Skan 547169691Skan template<typename _Tp> 548169691Skan struct add_volatile 549169691Skan { typedef _Tp volatile type; }; 550169691Skan 551169691Skan template<typename _Tp> 552169691Skan struct add_cv 553169691Skan { 554169691Skan typedef typename 555169691Skan add_const<typename add_volatile<_Tp>::type>::type type; 556169691Skan }; 557169691Skan 558169691Skan /// @brief reference modifications [4.7.2]. 559169691Skan template<typename _Tp> 560169691Skan struct remove_reference 561169691Skan { typedef _Tp type; }; 562169691Skan 563169691Skan template<typename _Tp> 564169691Skan struct remove_reference<_Tp&> 565169691Skan { typedef _Tp type; }; 566169691Skan 567169691Skan // NB: Careful with reference to void. 568169691Skan template<typename _Tp, bool = (is_void<_Tp>::value 569169691Skan || is_reference<_Tp>::value)> 570169691Skan struct __add_reference_helper 571169691Skan { typedef _Tp& type; }; 572169691Skan 573169691Skan template<typename _Tp> 574169691Skan struct __add_reference_helper<_Tp, true> 575169691Skan { typedef _Tp type; }; 576169691Skan 577169691Skan template<typename _Tp> 578169691Skan struct add_reference 579169691Skan : public __add_reference_helper<_Tp> 580169691Skan { }; 581169691Skan 582169691Skan /// @brief array modifications [4.7.3]. 583169691Skan template<typename _Tp> 584169691Skan struct remove_extent 585169691Skan { typedef _Tp type; }; 586169691Skan 587169691Skan template<typename _Tp, std::size_t _Size> 588169691Skan struct remove_extent<_Tp[_Size]> 589169691Skan { typedef _Tp type; }; 590169691Skan 591169691Skan template<typename _Tp> 592169691Skan struct remove_extent<_Tp[]> 593169691Skan { typedef _Tp type; }; 594169691Skan 595169691Skan template<typename _Tp> 596169691Skan struct remove_all_extents 597169691Skan { typedef _Tp type; }; 598169691Skan 599169691Skan template<typename _Tp, std::size_t _Size> 600169691Skan struct remove_all_extents<_Tp[_Size]> 601169691Skan { typedef typename remove_all_extents<_Tp>::type type; }; 602169691Skan 603169691Skan template<typename _Tp> 604169691Skan struct remove_all_extents<_Tp[]> 605169691Skan { typedef typename remove_all_extents<_Tp>::type type; }; 606169691Skan 607169691Skan /// @brief pointer modifications [4.7.4]. 608169691Skan#undef _DEFINE_SPEC_BODY 609169691Skan#define _DEFINE_SPEC_BODY(_Value) \ 610169691Skan { typedef _Tp type; }; 611169691Skan 612169691Skan template<typename _Tp> 613169691Skan struct remove_pointer 614169691Skan { typedef _Tp type; }; 615169691Skan _DEFINE_SPEC(1, remove_pointer, _Tp*, false) 616169691Skan 617169691Skan template<typename _Tp> 618169691Skan struct add_pointer 619169691Skan { typedef typename remove_reference<_Tp>::type* type; }; 620169691Skan 621169691Skan /// @brief other transformations [4.8]. 622169691Skan 623169691Skan // Due to c++/19163 and c++/17743, for the time being we cannot use 624169691Skan // the correct, neat implementation :-( 625169691Skan // 626169691Skan // template<std::size_t _Len, std::size_t _Align> 627169691Skan // struct aligned_storage 628169691Skan // { typedef char type[_Len] __attribute__((__aligned__(_Align))); } 629169691Skan // 630169691Skan // Temporary workaround, useful for Align up to 32: 631169691Skan template<std::size_t, std::size_t> 632169691Skan struct aligned_storage { }; 633169691Skan 634169691Skan template<std::size_t _Len> 635169691Skan struct aligned_storage<_Len, 1> 636169691Skan { 637169691Skan union type 638169691Skan { 639169691Skan unsigned char __data[_Len]; 640169691Skan char __align __attribute__((__aligned__(1))); 641169691Skan }; 642169691Skan }; 643169691Skan 644169691Skan template<std::size_t _Len> 645169691Skan struct aligned_storage<_Len, 2> 646169691Skan { 647169691Skan union type 648169691Skan { 649169691Skan unsigned char __data[_Len]; 650169691Skan char __align __attribute__((__aligned__(2))); 651169691Skan }; 652169691Skan }; 653169691Skan 654169691Skan template<std::size_t _Len> 655169691Skan struct aligned_storage<_Len, 4> 656169691Skan { 657169691Skan union type 658169691Skan { 659169691Skan unsigned char __data[_Len]; 660169691Skan char __align __attribute__((__aligned__(4))); 661169691Skan }; 662169691Skan }; 663169691Skan 664169691Skan template<std::size_t _Len> 665169691Skan struct aligned_storage<_Len, 8> 666169691Skan { 667169691Skan union type 668169691Skan { 669169691Skan unsigned char __data[_Len]; 670169691Skan char __align __attribute__((__aligned__(8))); 671169691Skan }; 672169691Skan }; 673169691Skan 674169691Skan template<std::size_t _Len> 675169691Skan struct aligned_storage<_Len, 16> 676169691Skan { 677169691Skan union type 678169691Skan { 679169691Skan unsigned char __data[_Len]; 680169691Skan char __align __attribute__((__aligned__(16))); 681169691Skan }; 682169691Skan }; 683169691Skan 684169691Skan template<std::size_t _Len> 685169691Skan struct aligned_storage<_Len, 32> 686169691Skan { 687169691Skan union type 688169691Skan { 689169691Skan unsigned char __data[_Len]; 690169691Skan char __align __attribute__((__aligned__(32))); 691169691Skan }; 692169691Skan }; 693169691Skan 694169691Skan#undef _DEFINE_SPEC_0_HELPER 695169691Skan#undef _DEFINE_SPEC_1_HELPER 696169691Skan#undef _DEFINE_SPEC_2_HELPER 697169691Skan#undef _DEFINE_SPEC 698169691Skan#undef _DEFINE_SPEC_BODY 699169691Skan 700169691Skan_GLIBCXX_END_NAMESPACE 701169691Skan} 702169691Skan 703169691Skan#endif 704