1*e4b17023SJohn Marino// C++11 type_traits -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino// 5*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the 7*e4b17023SJohn Marino// terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option) 9*e4b17023SJohn Marino// any later version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino// GNU General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino/** @file include/type_traits 26*e4b17023SJohn Marino * This is a Standard C++ Library header. 27*e4b17023SJohn Marino */ 28*e4b17023SJohn Marino 29*e4b17023SJohn Marino#ifndef _GLIBCXX_TYPE_TRAITS 30*e4b17023SJohn Marino#define _GLIBCXX_TYPE_TRAITS 1 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino#pragma GCC system_header 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__ 35*e4b17023SJohn Marino# include <bits/c++0x_warning.h> 36*e4b17023SJohn Marino#else 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino#include <bits/c++config.h> 39*e4b17023SJohn Marino 40*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 41*e4b17023SJohn Marino{ 42*e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 43*e4b17023SJohn Marino 44*e4b17023SJohn Marino /** 45*e4b17023SJohn Marino * @defgroup metaprogramming Metaprogramming and type traits 46*e4b17023SJohn Marino * @ingroup utilities 47*e4b17023SJohn Marino * 48*e4b17023SJohn Marino * Template utilities for compile-time introspection and modification, 49*e4b17023SJohn Marino * including type classification traits, type property inspection traits 50*e4b17023SJohn Marino * and type transformation traits. 51*e4b17023SJohn Marino * 52*e4b17023SJohn Marino * @{ 53*e4b17023SJohn Marino */ 54*e4b17023SJohn Marino 55*e4b17023SJohn Marino /// integral_constant 56*e4b17023SJohn Marino template<typename _Tp, _Tp __v> 57*e4b17023SJohn Marino struct integral_constant 58*e4b17023SJohn Marino { 59*e4b17023SJohn Marino static constexpr _Tp value = __v; 60*e4b17023SJohn Marino typedef _Tp value_type; 61*e4b17023SJohn Marino typedef integral_constant<_Tp, __v> type; 62*e4b17023SJohn Marino constexpr operator value_type() { return value; } 63*e4b17023SJohn Marino }; 64*e4b17023SJohn Marino 65*e4b17023SJohn Marino /// The type used as a compile-time boolean with true value. 66*e4b17023SJohn Marino typedef integral_constant<bool, true> true_type; 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino /// The type used as a compile-time boolean with false value. 69*e4b17023SJohn Marino typedef integral_constant<bool, false> false_type; 70*e4b17023SJohn Marino 71*e4b17023SJohn Marino template<typename _Tp, _Tp __v> 72*e4b17023SJohn Marino constexpr _Tp integral_constant<_Tp, __v>::value; 73*e4b17023SJohn Marino 74*e4b17023SJohn Marino // Meta programming helper types. 75*e4b17023SJohn Marino 76*e4b17023SJohn Marino template<bool, typename, typename> 77*e4b17023SJohn Marino struct conditional; 78*e4b17023SJohn Marino 79*e4b17023SJohn Marino template<typename...> 80*e4b17023SJohn Marino struct __or_; 81*e4b17023SJohn Marino 82*e4b17023SJohn Marino template<> 83*e4b17023SJohn Marino struct __or_<> 84*e4b17023SJohn Marino : public false_type 85*e4b17023SJohn Marino { }; 86*e4b17023SJohn Marino 87*e4b17023SJohn Marino template<typename _B1> 88*e4b17023SJohn Marino struct __or_<_B1> 89*e4b17023SJohn Marino : public _B1 90*e4b17023SJohn Marino { }; 91*e4b17023SJohn Marino 92*e4b17023SJohn Marino template<typename _B1, typename _B2> 93*e4b17023SJohn Marino struct __or_<_B1, _B2> 94*e4b17023SJohn Marino : public conditional<_B1::value, _B1, _B2>::type 95*e4b17023SJohn Marino { }; 96*e4b17023SJohn Marino 97*e4b17023SJohn Marino template<typename _B1, typename _B2, typename _B3, typename... _Bn> 98*e4b17023SJohn Marino struct __or_<_B1, _B2, _B3, _Bn...> 99*e4b17023SJohn Marino : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type 100*e4b17023SJohn Marino { }; 101*e4b17023SJohn Marino 102*e4b17023SJohn Marino template<typename...> 103*e4b17023SJohn Marino struct __and_; 104*e4b17023SJohn Marino 105*e4b17023SJohn Marino template<> 106*e4b17023SJohn Marino struct __and_<> 107*e4b17023SJohn Marino : public true_type 108*e4b17023SJohn Marino { }; 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino template<typename _B1> 111*e4b17023SJohn Marino struct __and_<_B1> 112*e4b17023SJohn Marino : public _B1 113*e4b17023SJohn Marino { }; 114*e4b17023SJohn Marino 115*e4b17023SJohn Marino template<typename _B1, typename _B2> 116*e4b17023SJohn Marino struct __and_<_B1, _B2> 117*e4b17023SJohn Marino : public conditional<_B1::value, _B2, _B1>::type 118*e4b17023SJohn Marino { }; 119*e4b17023SJohn Marino 120*e4b17023SJohn Marino template<typename _B1, typename _B2, typename _B3, typename... _Bn> 121*e4b17023SJohn Marino struct __and_<_B1, _B2, _B3, _Bn...> 122*e4b17023SJohn Marino : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type 123*e4b17023SJohn Marino { }; 124*e4b17023SJohn Marino 125*e4b17023SJohn Marino template<typename _Pp> 126*e4b17023SJohn Marino struct __not_ 127*e4b17023SJohn Marino : public integral_constant<bool, !_Pp::value> 128*e4b17023SJohn Marino { }; 129*e4b17023SJohn Marino 130*e4b17023SJohn Marino struct __sfinae_types 131*e4b17023SJohn Marino { 132*e4b17023SJohn Marino typedef char __one; 133*e4b17023SJohn Marino typedef struct { char __arr[2]; } __two; 134*e4b17023SJohn Marino }; 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino // primary type categories. 137*e4b17023SJohn Marino 138*e4b17023SJohn Marino template<typename> 139*e4b17023SJohn Marino struct remove_cv; 140*e4b17023SJohn Marino 141*e4b17023SJohn Marino template<typename> 142*e4b17023SJohn Marino struct __is_void_helper 143*e4b17023SJohn Marino : public false_type { }; 144*e4b17023SJohn Marino 145*e4b17023SJohn Marino template<> 146*e4b17023SJohn Marino struct __is_void_helper<void> 147*e4b17023SJohn Marino : public true_type { }; 148*e4b17023SJohn Marino 149*e4b17023SJohn Marino /// is_void 150*e4b17023SJohn Marino template<typename _Tp> 151*e4b17023SJohn Marino struct is_void 152*e4b17023SJohn Marino : public integral_constant<bool, (__is_void_helper<typename 153*e4b17023SJohn Marino remove_cv<_Tp>::type>::value)> 154*e4b17023SJohn Marino { }; 155*e4b17023SJohn Marino 156*e4b17023SJohn Marino template<typename> 157*e4b17023SJohn Marino struct __is_integral_helper 158*e4b17023SJohn Marino : public false_type { }; 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino template<> 161*e4b17023SJohn Marino struct __is_integral_helper<bool> 162*e4b17023SJohn Marino : public true_type { }; 163*e4b17023SJohn Marino 164*e4b17023SJohn Marino template<> 165*e4b17023SJohn Marino struct __is_integral_helper<char> 166*e4b17023SJohn Marino : public true_type { }; 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino template<> 169*e4b17023SJohn Marino struct __is_integral_helper<signed char> 170*e4b17023SJohn Marino : public true_type { }; 171*e4b17023SJohn Marino 172*e4b17023SJohn Marino template<> 173*e4b17023SJohn Marino struct __is_integral_helper<unsigned char> 174*e4b17023SJohn Marino : public true_type { }; 175*e4b17023SJohn Marino 176*e4b17023SJohn Marino#ifdef _GLIBCXX_USE_WCHAR_T 177*e4b17023SJohn Marino template<> 178*e4b17023SJohn Marino struct __is_integral_helper<wchar_t> 179*e4b17023SJohn Marino : public true_type { }; 180*e4b17023SJohn Marino#endif 181*e4b17023SJohn Marino 182*e4b17023SJohn Marino template<> 183*e4b17023SJohn Marino struct __is_integral_helper<char16_t> 184*e4b17023SJohn Marino : public true_type { }; 185*e4b17023SJohn Marino 186*e4b17023SJohn Marino template<> 187*e4b17023SJohn Marino struct __is_integral_helper<char32_t> 188*e4b17023SJohn Marino : public true_type { }; 189*e4b17023SJohn Marino 190*e4b17023SJohn Marino template<> 191*e4b17023SJohn Marino struct __is_integral_helper<short> 192*e4b17023SJohn Marino : public true_type { }; 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino template<> 195*e4b17023SJohn Marino struct __is_integral_helper<unsigned short> 196*e4b17023SJohn Marino : public true_type { }; 197*e4b17023SJohn Marino 198*e4b17023SJohn Marino template<> 199*e4b17023SJohn Marino struct __is_integral_helper<int> 200*e4b17023SJohn Marino : public true_type { }; 201*e4b17023SJohn Marino 202*e4b17023SJohn Marino template<> 203*e4b17023SJohn Marino struct __is_integral_helper<unsigned int> 204*e4b17023SJohn Marino : public true_type { }; 205*e4b17023SJohn Marino 206*e4b17023SJohn Marino template<> 207*e4b17023SJohn Marino struct __is_integral_helper<long> 208*e4b17023SJohn Marino : public true_type { }; 209*e4b17023SJohn Marino 210*e4b17023SJohn Marino template<> 211*e4b17023SJohn Marino struct __is_integral_helper<unsigned long> 212*e4b17023SJohn Marino : public true_type { }; 213*e4b17023SJohn Marino 214*e4b17023SJohn Marino template<> 215*e4b17023SJohn Marino struct __is_integral_helper<long long> 216*e4b17023SJohn Marino : public true_type { }; 217*e4b17023SJohn Marino 218*e4b17023SJohn Marino template<> 219*e4b17023SJohn Marino struct __is_integral_helper<unsigned long long> 220*e4b17023SJohn Marino : public true_type { }; 221*e4b17023SJohn Marino 222*e4b17023SJohn Marino#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) 223*e4b17023SJohn Marino template<> 224*e4b17023SJohn Marino struct __is_integral_helper<__int128> 225*e4b17023SJohn Marino : public true_type { }; 226*e4b17023SJohn Marino 227*e4b17023SJohn Marino template<> 228*e4b17023SJohn Marino struct __is_integral_helper<unsigned __int128> 229*e4b17023SJohn Marino : public true_type { }; 230*e4b17023SJohn Marino#endif 231*e4b17023SJohn Marino 232*e4b17023SJohn Marino /// is_integral 233*e4b17023SJohn Marino template<typename _Tp> 234*e4b17023SJohn Marino struct is_integral 235*e4b17023SJohn Marino : public integral_constant<bool, (__is_integral_helper<typename 236*e4b17023SJohn Marino remove_cv<_Tp>::type>::value)> 237*e4b17023SJohn Marino { }; 238*e4b17023SJohn Marino 239*e4b17023SJohn Marino template<typename> 240*e4b17023SJohn Marino struct __is_floating_point_helper 241*e4b17023SJohn Marino : public false_type { }; 242*e4b17023SJohn Marino 243*e4b17023SJohn Marino template<> 244*e4b17023SJohn Marino struct __is_floating_point_helper<float> 245*e4b17023SJohn Marino : public true_type { }; 246*e4b17023SJohn Marino 247*e4b17023SJohn Marino template<> 248*e4b17023SJohn Marino struct __is_floating_point_helper<double> 249*e4b17023SJohn Marino : public true_type { }; 250*e4b17023SJohn Marino 251*e4b17023SJohn Marino template<> 252*e4b17023SJohn Marino struct __is_floating_point_helper<long double> 253*e4b17023SJohn Marino : public true_type { }; 254*e4b17023SJohn Marino 255*e4b17023SJohn Marino#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) 256*e4b17023SJohn Marino template<> 257*e4b17023SJohn Marino struct __is_floating_point_helper<__float128> 258*e4b17023SJohn Marino : public true_type { }; 259*e4b17023SJohn Marino#endif 260*e4b17023SJohn Marino 261*e4b17023SJohn Marino /// is_floating_point 262*e4b17023SJohn Marino template<typename _Tp> 263*e4b17023SJohn Marino struct is_floating_point 264*e4b17023SJohn Marino : public integral_constant<bool, (__is_floating_point_helper<typename 265*e4b17023SJohn Marino remove_cv<_Tp>::type>::value)> 266*e4b17023SJohn Marino { }; 267*e4b17023SJohn Marino 268*e4b17023SJohn Marino /// is_array 269*e4b17023SJohn Marino template<typename> 270*e4b17023SJohn Marino struct is_array 271*e4b17023SJohn Marino : public false_type { }; 272*e4b17023SJohn Marino 273*e4b17023SJohn Marino template<typename _Tp, std::size_t _Size> 274*e4b17023SJohn Marino struct is_array<_Tp[_Size]> 275*e4b17023SJohn Marino : public true_type { }; 276*e4b17023SJohn Marino 277*e4b17023SJohn Marino template<typename _Tp> 278*e4b17023SJohn Marino struct is_array<_Tp[]> 279*e4b17023SJohn Marino : public true_type { }; 280*e4b17023SJohn Marino 281*e4b17023SJohn Marino template<typename> 282*e4b17023SJohn Marino struct __is_pointer_helper 283*e4b17023SJohn Marino : public false_type { }; 284*e4b17023SJohn Marino 285*e4b17023SJohn Marino template<typename _Tp> 286*e4b17023SJohn Marino struct __is_pointer_helper<_Tp*> 287*e4b17023SJohn Marino : public true_type { }; 288*e4b17023SJohn Marino 289*e4b17023SJohn Marino /// is_pointer 290*e4b17023SJohn Marino template<typename _Tp> 291*e4b17023SJohn Marino struct is_pointer 292*e4b17023SJohn Marino : public integral_constant<bool, (__is_pointer_helper<typename 293*e4b17023SJohn Marino remove_cv<_Tp>::type>::value)> 294*e4b17023SJohn Marino { }; 295*e4b17023SJohn Marino 296*e4b17023SJohn Marino /// is_lvalue_reference 297*e4b17023SJohn Marino template<typename> 298*e4b17023SJohn Marino struct is_lvalue_reference 299*e4b17023SJohn Marino : public false_type { }; 300*e4b17023SJohn Marino 301*e4b17023SJohn Marino template<typename _Tp> 302*e4b17023SJohn Marino struct is_lvalue_reference<_Tp&> 303*e4b17023SJohn Marino : public true_type { }; 304*e4b17023SJohn Marino 305*e4b17023SJohn Marino /// is_rvalue_reference 306*e4b17023SJohn Marino template<typename> 307*e4b17023SJohn Marino struct is_rvalue_reference 308*e4b17023SJohn Marino : public false_type { }; 309*e4b17023SJohn Marino 310*e4b17023SJohn Marino template<typename _Tp> 311*e4b17023SJohn Marino struct is_rvalue_reference<_Tp&&> 312*e4b17023SJohn Marino : public true_type { }; 313*e4b17023SJohn Marino 314*e4b17023SJohn Marino template<typename> 315*e4b17023SJohn Marino struct is_function; 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino template<typename> 318*e4b17023SJohn Marino struct __is_member_object_pointer_helper 319*e4b17023SJohn Marino : public false_type { }; 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino template<typename _Tp, typename _Cp> 322*e4b17023SJohn Marino struct __is_member_object_pointer_helper<_Tp _Cp::*> 323*e4b17023SJohn Marino : public integral_constant<bool, !is_function<_Tp>::value> { }; 324*e4b17023SJohn Marino 325*e4b17023SJohn Marino /// is_member_object_pointer 326*e4b17023SJohn Marino template<typename _Tp> 327*e4b17023SJohn Marino struct is_member_object_pointer 328*e4b17023SJohn Marino : public integral_constant<bool, (__is_member_object_pointer_helper< 329*e4b17023SJohn Marino typename remove_cv<_Tp>::type>::value)> 330*e4b17023SJohn Marino { }; 331*e4b17023SJohn Marino 332*e4b17023SJohn Marino template<typename> 333*e4b17023SJohn Marino struct __is_member_function_pointer_helper 334*e4b17023SJohn Marino : public false_type { }; 335*e4b17023SJohn Marino 336*e4b17023SJohn Marino template<typename _Tp, typename _Cp> 337*e4b17023SJohn Marino struct __is_member_function_pointer_helper<_Tp _Cp::*> 338*e4b17023SJohn Marino : public integral_constant<bool, is_function<_Tp>::value> { }; 339*e4b17023SJohn Marino 340*e4b17023SJohn Marino /// is_member_function_pointer 341*e4b17023SJohn Marino template<typename _Tp> 342*e4b17023SJohn Marino struct is_member_function_pointer 343*e4b17023SJohn Marino : public integral_constant<bool, (__is_member_function_pointer_helper< 344*e4b17023SJohn Marino typename remove_cv<_Tp>::type>::value)> 345*e4b17023SJohn Marino { }; 346*e4b17023SJohn Marino 347*e4b17023SJohn Marino /// is_enum 348*e4b17023SJohn Marino template<typename _Tp> 349*e4b17023SJohn Marino struct is_enum 350*e4b17023SJohn Marino : public integral_constant<bool, __is_enum(_Tp)> 351*e4b17023SJohn Marino { }; 352*e4b17023SJohn Marino 353*e4b17023SJohn Marino /// is_union 354*e4b17023SJohn Marino template<typename _Tp> 355*e4b17023SJohn Marino struct is_union 356*e4b17023SJohn Marino : public integral_constant<bool, __is_union(_Tp)> 357*e4b17023SJohn Marino { }; 358*e4b17023SJohn Marino 359*e4b17023SJohn Marino /// is_class 360*e4b17023SJohn Marino template<typename _Tp> 361*e4b17023SJohn Marino struct is_class 362*e4b17023SJohn Marino : public integral_constant<bool, __is_class(_Tp)> 363*e4b17023SJohn Marino { }; 364*e4b17023SJohn Marino 365*e4b17023SJohn Marino /// is_function 366*e4b17023SJohn Marino template<typename> 367*e4b17023SJohn Marino struct is_function 368*e4b17023SJohn Marino : public false_type { }; 369*e4b17023SJohn Marino 370*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 371*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes...)> 372*e4b17023SJohn Marino : public true_type { }; 373*e4b17023SJohn Marino 374*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 375*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes......)> 376*e4b17023SJohn Marino : public true_type { }; 377*e4b17023SJohn Marino 378*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 379*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes...) const> 380*e4b17023SJohn Marino : public true_type { }; 381*e4b17023SJohn Marino 382*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 383*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes......) const> 384*e4b17023SJohn Marino : public true_type { }; 385*e4b17023SJohn Marino 386*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 387*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes...) volatile> 388*e4b17023SJohn Marino : public true_type { }; 389*e4b17023SJohn Marino 390*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 391*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes......) volatile> 392*e4b17023SJohn Marino : public true_type { }; 393*e4b17023SJohn Marino 394*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 395*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes...) const volatile> 396*e4b17023SJohn Marino : public true_type { }; 397*e4b17023SJohn Marino 398*e4b17023SJohn Marino template<typename _Res, typename... _ArgTypes> 399*e4b17023SJohn Marino struct is_function<_Res(_ArgTypes......) const volatile> 400*e4b17023SJohn Marino : public true_type { }; 401*e4b17023SJohn Marino 402*e4b17023SJohn Marino template<typename> 403*e4b17023SJohn Marino struct __is_nullptr_t_helper 404*e4b17023SJohn Marino : public false_type { }; 405*e4b17023SJohn Marino 406*e4b17023SJohn Marino template<> 407*e4b17023SJohn Marino struct __is_nullptr_t_helper<std::nullptr_t> 408*e4b17023SJohn Marino : public true_type { }; 409*e4b17023SJohn Marino 410*e4b17023SJohn Marino // __is_nullptr_t (extension). 411*e4b17023SJohn Marino template<typename _Tp> 412*e4b17023SJohn Marino struct __is_nullptr_t 413*e4b17023SJohn Marino : public integral_constant<bool, (__is_nullptr_t_helper<typename 414*e4b17023SJohn Marino remove_cv<_Tp>::type>::value)> 415*e4b17023SJohn Marino { }; 416*e4b17023SJohn Marino 417*e4b17023SJohn Marino // composite type categories. 418*e4b17023SJohn Marino 419*e4b17023SJohn Marino /// is_reference 420*e4b17023SJohn Marino template<typename _Tp> 421*e4b17023SJohn Marino struct is_reference 422*e4b17023SJohn Marino : public __or_<is_lvalue_reference<_Tp>, 423*e4b17023SJohn Marino is_rvalue_reference<_Tp>>::type 424*e4b17023SJohn Marino { }; 425*e4b17023SJohn Marino 426*e4b17023SJohn Marino /// is_arithmetic 427*e4b17023SJohn Marino template<typename _Tp> 428*e4b17023SJohn Marino struct is_arithmetic 429*e4b17023SJohn Marino : public __or_<is_integral<_Tp>, is_floating_point<_Tp>>::type 430*e4b17023SJohn Marino { }; 431*e4b17023SJohn Marino 432*e4b17023SJohn Marino /// is_fundamental 433*e4b17023SJohn Marino template<typename _Tp> 434*e4b17023SJohn Marino struct is_fundamental 435*e4b17023SJohn Marino : public __or_<is_arithmetic<_Tp>, is_void<_Tp>>::type 436*e4b17023SJohn Marino { }; 437*e4b17023SJohn Marino 438*e4b17023SJohn Marino /// is_object 439*e4b17023SJohn Marino template<typename _Tp> 440*e4b17023SJohn Marino struct is_object 441*e4b17023SJohn Marino : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>, 442*e4b17023SJohn Marino is_void<_Tp>>>::type 443*e4b17023SJohn Marino { }; 444*e4b17023SJohn Marino 445*e4b17023SJohn Marino template<typename> 446*e4b17023SJohn Marino struct is_member_pointer; 447*e4b17023SJohn Marino 448*e4b17023SJohn Marino /// is_scalar 449*e4b17023SJohn Marino template<typename _Tp> 450*e4b17023SJohn Marino struct is_scalar 451*e4b17023SJohn Marino : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>, 452*e4b17023SJohn Marino is_member_pointer<_Tp>, __is_nullptr_t<_Tp>>::type 453*e4b17023SJohn Marino { }; 454*e4b17023SJohn Marino 455*e4b17023SJohn Marino /// is_compound 456*e4b17023SJohn Marino template<typename _Tp> 457*e4b17023SJohn Marino struct is_compound 458*e4b17023SJohn Marino : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 459*e4b17023SJohn Marino 460*e4b17023SJohn Marino template<typename _Tp> 461*e4b17023SJohn Marino struct __is_member_pointer_helper 462*e4b17023SJohn Marino : public false_type { }; 463*e4b17023SJohn Marino 464*e4b17023SJohn Marino template<typename _Tp, typename _Cp> 465*e4b17023SJohn Marino struct __is_member_pointer_helper<_Tp _Cp::*> 466*e4b17023SJohn Marino : public true_type { }; 467*e4b17023SJohn Marino 468*e4b17023SJohn Marino /// is_member_pointer 469*e4b17023SJohn Marino template<typename _Tp> 470*e4b17023SJohn Marino struct is_member_pointer 471*e4b17023SJohn Marino : public integral_constant<bool, (__is_member_pointer_helper< 472*e4b17023SJohn Marino typename remove_cv<_Tp>::type>::value)> 473*e4b17023SJohn Marino { }; 474*e4b17023SJohn Marino 475*e4b17023SJohn Marino // type properties. 476*e4b17023SJohn Marino 477*e4b17023SJohn Marino /// is_const 478*e4b17023SJohn Marino template<typename> 479*e4b17023SJohn Marino struct is_const 480*e4b17023SJohn Marino : public false_type { }; 481*e4b17023SJohn Marino 482*e4b17023SJohn Marino template<typename _Tp> 483*e4b17023SJohn Marino struct is_const<_Tp const> 484*e4b17023SJohn Marino : public true_type { }; 485*e4b17023SJohn Marino 486*e4b17023SJohn Marino /// is_volatile 487*e4b17023SJohn Marino template<typename> 488*e4b17023SJohn Marino struct is_volatile 489*e4b17023SJohn Marino : public false_type { }; 490*e4b17023SJohn Marino 491*e4b17023SJohn Marino template<typename _Tp> 492*e4b17023SJohn Marino struct is_volatile<_Tp volatile> 493*e4b17023SJohn Marino : public true_type { }; 494*e4b17023SJohn Marino 495*e4b17023SJohn Marino /// is_trivial 496*e4b17023SJohn Marino template<typename _Tp> 497*e4b17023SJohn Marino struct is_trivial 498*e4b17023SJohn Marino : public integral_constant<bool, __is_trivial(_Tp)> 499*e4b17023SJohn Marino { }; 500*e4b17023SJohn Marino 501*e4b17023SJohn Marino // is_trivially_copyable (still unimplemented) 502*e4b17023SJohn Marino 503*e4b17023SJohn Marino /// is_standard_layout 504*e4b17023SJohn Marino template<typename _Tp> 505*e4b17023SJohn Marino struct is_standard_layout 506*e4b17023SJohn Marino : public integral_constant<bool, __is_standard_layout(_Tp)> 507*e4b17023SJohn Marino { }; 508*e4b17023SJohn Marino 509*e4b17023SJohn Marino /// is_pod 510*e4b17023SJohn Marino // Could use is_standard_layout && is_trivial instead of the builtin. 511*e4b17023SJohn Marino template<typename _Tp> 512*e4b17023SJohn Marino struct is_pod 513*e4b17023SJohn Marino : public integral_constant<bool, __is_pod(_Tp)> 514*e4b17023SJohn Marino { }; 515*e4b17023SJohn Marino 516*e4b17023SJohn Marino /// is_literal_type 517*e4b17023SJohn Marino template<typename _Tp> 518*e4b17023SJohn Marino struct is_literal_type 519*e4b17023SJohn Marino : public integral_constant<bool, __is_literal_type(_Tp)> 520*e4b17023SJohn Marino { }; 521*e4b17023SJohn Marino 522*e4b17023SJohn Marino /// is_empty 523*e4b17023SJohn Marino template<typename _Tp> 524*e4b17023SJohn Marino struct is_empty 525*e4b17023SJohn Marino : public integral_constant<bool, __is_empty(_Tp)> 526*e4b17023SJohn Marino { }; 527*e4b17023SJohn Marino 528*e4b17023SJohn Marino /// is_polymorphic 529*e4b17023SJohn Marino template<typename _Tp> 530*e4b17023SJohn Marino struct is_polymorphic 531*e4b17023SJohn Marino : public integral_constant<bool, __is_polymorphic(_Tp)> 532*e4b17023SJohn Marino { }; 533*e4b17023SJohn Marino 534*e4b17023SJohn Marino /// is_abstract 535*e4b17023SJohn Marino template<typename _Tp> 536*e4b17023SJohn Marino struct is_abstract 537*e4b17023SJohn Marino : public integral_constant<bool, __is_abstract(_Tp)> 538*e4b17023SJohn Marino { }; 539*e4b17023SJohn Marino 540*e4b17023SJohn Marino template<typename _Tp, 541*e4b17023SJohn Marino bool = is_integral<_Tp>::value, 542*e4b17023SJohn Marino bool = is_floating_point<_Tp>::value> 543*e4b17023SJohn Marino struct __is_signed_helper 544*e4b17023SJohn Marino : public false_type { }; 545*e4b17023SJohn Marino 546*e4b17023SJohn Marino template<typename _Tp> 547*e4b17023SJohn Marino struct __is_signed_helper<_Tp, false, true> 548*e4b17023SJohn Marino : public true_type { }; 549*e4b17023SJohn Marino 550*e4b17023SJohn Marino template<typename _Tp> 551*e4b17023SJohn Marino struct __is_signed_helper<_Tp, true, false> 552*e4b17023SJohn Marino : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))> 553*e4b17023SJohn Marino { }; 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino /// is_signed 556*e4b17023SJohn Marino template<typename _Tp> 557*e4b17023SJohn Marino struct is_signed 558*e4b17023SJohn Marino : public integral_constant<bool, __is_signed_helper<_Tp>::value> 559*e4b17023SJohn Marino { }; 560*e4b17023SJohn Marino 561*e4b17023SJohn Marino /// is_unsigned 562*e4b17023SJohn Marino template<typename _Tp> 563*e4b17023SJohn Marino struct is_unsigned 564*e4b17023SJohn Marino : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>::type 565*e4b17023SJohn Marino { }; 566*e4b17023SJohn Marino 567*e4b17023SJohn Marino 568*e4b17023SJohn Marino // destructible and constructible type properties 569*e4b17023SJohn Marino 570*e4b17023SJohn Marino template<typename> 571*e4b17023SJohn Marino struct add_rvalue_reference; 572*e4b17023SJohn Marino 573*e4b17023SJohn Marino /** 574*e4b17023SJohn Marino * @brief Utility to simplify expressions used in unevaluated operands 575*e4b17023SJohn Marino * @ingroup utilities 576*e4b17023SJohn Marino */ 577*e4b17023SJohn Marino template<typename _Tp> 578*e4b17023SJohn Marino typename add_rvalue_reference<_Tp>::type declval() noexcept; 579*e4b17023SJohn Marino 580*e4b17023SJohn Marino template<typename, unsigned = 0> 581*e4b17023SJohn Marino struct extent; 582*e4b17023SJohn Marino 583*e4b17023SJohn Marino template<typename> 584*e4b17023SJohn Marino struct remove_all_extents; 585*e4b17023SJohn Marino 586*e4b17023SJohn Marino template<typename _Tp> 587*e4b17023SJohn Marino struct __is_array_known_bounds 588*e4b17023SJohn Marino : public integral_constant<bool, (extent<_Tp>::value > 0)> 589*e4b17023SJohn Marino { }; 590*e4b17023SJohn Marino 591*e4b17023SJohn Marino template<typename _Tp> 592*e4b17023SJohn Marino struct __is_array_unknown_bounds 593*e4b17023SJohn Marino : public __and_<is_array<_Tp>, __not_<extent<_Tp>>>::type 594*e4b17023SJohn Marino { }; 595*e4b17023SJohn Marino 596*e4b17023SJohn Marino // In N3290 is_destructible does not say anything about function 597*e4b17023SJohn Marino // types and abstract types, see LWG 2049. This implementation 598*e4b17023SJohn Marino // describes function types as trivially nothrow destructible and 599*e4b17023SJohn Marino // abstract types as destructible, iff the explicit destructor 600*e4b17023SJohn Marino // call expression is wellformed. 601*e4b17023SJohn Marino struct __do_is_destructible_impl_1 602*e4b17023SJohn Marino { 603*e4b17023SJohn Marino template<typename _Up> 604*e4b17023SJohn Marino struct __w { _Up __u; }; 605*e4b17023SJohn Marino 606*e4b17023SJohn Marino template<typename _Tp, typename 607*e4b17023SJohn Marino = decltype(declval<__w<_Tp>&>().~__w<_Tp>())> 608*e4b17023SJohn Marino static true_type __test(int); 609*e4b17023SJohn Marino 610*e4b17023SJohn Marino template<typename> 611*e4b17023SJohn Marino static false_type __test(...); 612*e4b17023SJohn Marino }; 613*e4b17023SJohn Marino 614*e4b17023SJohn Marino template<typename _Tp> 615*e4b17023SJohn Marino struct __is_destructible_impl_1 616*e4b17023SJohn Marino : public __do_is_destructible_impl_1 617*e4b17023SJohn Marino { 618*e4b17023SJohn Marino typedef decltype(__test<_Tp>(0)) type; 619*e4b17023SJohn Marino }; 620*e4b17023SJohn Marino 621*e4b17023SJohn Marino // Special implementation for abstract types 622*e4b17023SJohn Marino struct __do_is_destructible_impl_2 623*e4b17023SJohn Marino { 624*e4b17023SJohn Marino template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())> 625*e4b17023SJohn Marino static true_type __test(int); 626*e4b17023SJohn Marino 627*e4b17023SJohn Marino template<typename> 628*e4b17023SJohn Marino static false_type __test(...); 629*e4b17023SJohn Marino }; 630*e4b17023SJohn Marino 631*e4b17023SJohn Marino template<typename _Tp> 632*e4b17023SJohn Marino struct __is_destructible_impl_2 633*e4b17023SJohn Marino : public __do_is_destructible_impl_2 634*e4b17023SJohn Marino { 635*e4b17023SJohn Marino typedef decltype(__test<_Tp>(0)) type; 636*e4b17023SJohn Marino }; 637*e4b17023SJohn Marino 638*e4b17023SJohn Marino template<typename _Tp, 639*e4b17023SJohn Marino bool = __or_<is_void<_Tp>, 640*e4b17023SJohn Marino __is_array_unknown_bounds<_Tp>>::value, 641*e4b17023SJohn Marino bool = __or_<is_reference<_Tp>, is_function<_Tp>>::value> 642*e4b17023SJohn Marino struct __is_destructible_safe; 643*e4b17023SJohn Marino 644*e4b17023SJohn Marino template<typename _Tp> 645*e4b17023SJohn Marino struct __is_destructible_safe<_Tp, false, false> 646*e4b17023SJohn Marino : public conditional<is_abstract<_Tp>::value, 647*e4b17023SJohn Marino __is_destructible_impl_2<_Tp>, 648*e4b17023SJohn Marino __is_destructible_impl_1<_Tp>>::type::type 649*e4b17023SJohn Marino { }; 650*e4b17023SJohn Marino 651*e4b17023SJohn Marino template<typename _Tp> 652*e4b17023SJohn Marino struct __is_destructible_safe<_Tp, true, false> 653*e4b17023SJohn Marino : public false_type { }; 654*e4b17023SJohn Marino 655*e4b17023SJohn Marino template<typename _Tp> 656*e4b17023SJohn Marino struct __is_destructible_safe<_Tp, false, true> 657*e4b17023SJohn Marino : public true_type { }; 658*e4b17023SJohn Marino 659*e4b17023SJohn Marino /// is_destructible 660*e4b17023SJohn Marino template<typename _Tp> 661*e4b17023SJohn Marino struct is_destructible 662*e4b17023SJohn Marino : public integral_constant<bool, (__is_destructible_safe<_Tp>::value)> 663*e4b17023SJohn Marino { }; 664*e4b17023SJohn Marino 665*e4b17023SJohn Marino struct __do_is_default_constructible_impl 666*e4b17023SJohn Marino { 667*e4b17023SJohn Marino template<typename _Tp, typename = decltype(_Tp())> 668*e4b17023SJohn Marino static true_type __test(int); 669*e4b17023SJohn Marino 670*e4b17023SJohn Marino template<typename> 671*e4b17023SJohn Marino static false_type __test(...); 672*e4b17023SJohn Marino }; 673*e4b17023SJohn Marino 674*e4b17023SJohn Marino template<typename _Tp> 675*e4b17023SJohn Marino struct __is_default_constructible_impl 676*e4b17023SJohn Marino : public __do_is_default_constructible_impl 677*e4b17023SJohn Marino { 678*e4b17023SJohn Marino typedef decltype(__test<_Tp>(0)) type; 679*e4b17023SJohn Marino }; 680*e4b17023SJohn Marino 681*e4b17023SJohn Marino template<typename _Tp> 682*e4b17023SJohn Marino struct __is_default_constructible_atom 683*e4b17023SJohn Marino : public __and_<__not_<is_void<_Tp>>, 684*e4b17023SJohn Marino __is_default_constructible_impl<_Tp>>::type 685*e4b17023SJohn Marino { }; 686*e4b17023SJohn Marino 687*e4b17023SJohn Marino template<typename _Tp, bool = is_array<_Tp>::value> 688*e4b17023SJohn Marino struct __is_default_constructible_safe; 689*e4b17023SJohn Marino 690*e4b17023SJohn Marino // The following technique is a workaround for a current core language 691*e4b17023SJohn Marino // restriction, which does not allow for array types to occur in 692*e4b17023SJohn Marino // functional casts of the form T(). Complete arrays can be default- 693*e4b17023SJohn Marino // constructed, if the element type is default-constructible, but 694*e4b17023SJohn Marino // arrays with unknown bounds are not. 695*e4b17023SJohn Marino template<typename _Tp> 696*e4b17023SJohn Marino struct __is_default_constructible_safe<_Tp, true> 697*e4b17023SJohn Marino : public __and_<__is_array_known_bounds<_Tp>, 698*e4b17023SJohn Marino __is_default_constructible_atom<typename 699*e4b17023SJohn Marino remove_all_extents<_Tp>::type>>::type 700*e4b17023SJohn Marino { }; 701*e4b17023SJohn Marino 702*e4b17023SJohn Marino template<typename _Tp> 703*e4b17023SJohn Marino struct __is_default_constructible_safe<_Tp, false> 704*e4b17023SJohn Marino : public __is_default_constructible_atom<_Tp>::type 705*e4b17023SJohn Marino { }; 706*e4b17023SJohn Marino 707*e4b17023SJohn Marino /// is_default_constructible 708*e4b17023SJohn Marino template<typename _Tp> 709*e4b17023SJohn Marino struct is_default_constructible 710*e4b17023SJohn Marino : public integral_constant<bool, (__is_default_constructible_safe< 711*e4b17023SJohn Marino _Tp>::value)> 712*e4b17023SJohn Marino { }; 713*e4b17023SJohn Marino 714*e4b17023SJohn Marino 715*e4b17023SJohn Marino // Implementation of is_constructible. 716*e4b17023SJohn Marino 717*e4b17023SJohn Marino // The hardest part of this trait is the binary direct-initialization 718*e4b17023SJohn Marino // case, because we hit into a functional cast of the form T(arg). 719*e4b17023SJohn Marino // This implementation uses different strategies depending on the 720*e4b17023SJohn Marino // target type to reduce the test overhead as much as possible: 721*e4b17023SJohn Marino // 722*e4b17023SJohn Marino // a) For a reference target type, we use a static_cast expression 723*e4b17023SJohn Marino // modulo its extra cases. 724*e4b17023SJohn Marino // 725*e4b17023SJohn Marino // b) For a non-reference target type we use a ::new expression. 726*e4b17023SJohn Marino struct __do_is_static_castable_impl 727*e4b17023SJohn Marino { 728*e4b17023SJohn Marino template<typename _From, typename _To, typename 729*e4b17023SJohn Marino = decltype(static_cast<_To>(declval<_From>()))> 730*e4b17023SJohn Marino static true_type __test(int); 731*e4b17023SJohn Marino 732*e4b17023SJohn Marino template<typename, typename> 733*e4b17023SJohn Marino static false_type __test(...); 734*e4b17023SJohn Marino }; 735*e4b17023SJohn Marino 736*e4b17023SJohn Marino template<typename _From, typename _To> 737*e4b17023SJohn Marino struct __is_static_castable_impl 738*e4b17023SJohn Marino : public __do_is_static_castable_impl 739*e4b17023SJohn Marino { 740*e4b17023SJohn Marino typedef decltype(__test<_From, _To>(0)) type; 741*e4b17023SJohn Marino }; 742*e4b17023SJohn Marino 743*e4b17023SJohn Marino template<typename _From, typename _To> 744*e4b17023SJohn Marino struct __is_static_castable_safe 745*e4b17023SJohn Marino : public __is_static_castable_impl<_From, _To>::type 746*e4b17023SJohn Marino { }; 747*e4b17023SJohn Marino 748*e4b17023SJohn Marino // __is_static_castable 749*e4b17023SJohn Marino template<typename _From, typename _To> 750*e4b17023SJohn Marino struct __is_static_castable 751*e4b17023SJohn Marino : public integral_constant<bool, (__is_static_castable_safe< 752*e4b17023SJohn Marino _From, _To>::value)> 753*e4b17023SJohn Marino { }; 754*e4b17023SJohn Marino 755*e4b17023SJohn Marino // Implementation for non-reference types. To meet the proper 756*e4b17023SJohn Marino // variable definition semantics, we also need to test for 757*e4b17023SJohn Marino // is_destructible in this case. 758*e4b17023SJohn Marino // This form should be simplified by a single expression: 759*e4b17023SJohn Marino // ::delete ::new _Tp(declval<_Arg>()), see c++/51222. 760*e4b17023SJohn Marino struct __do_is_direct_constructible_impl 761*e4b17023SJohn Marino { 762*e4b17023SJohn Marino template<typename _Tp, typename _Arg, typename 763*e4b17023SJohn Marino = decltype(::new _Tp(declval<_Arg>()))> 764*e4b17023SJohn Marino static true_type __test(int); 765*e4b17023SJohn Marino 766*e4b17023SJohn Marino template<typename, typename> 767*e4b17023SJohn Marino static false_type __test(...); 768*e4b17023SJohn Marino }; 769*e4b17023SJohn Marino 770*e4b17023SJohn Marino template<typename _Tp, typename _Arg> 771*e4b17023SJohn Marino struct __is_direct_constructible_impl 772*e4b17023SJohn Marino : public __do_is_direct_constructible_impl 773*e4b17023SJohn Marino { 774*e4b17023SJohn Marino typedef decltype(__test<_Tp, _Arg>(0)) type; 775*e4b17023SJohn Marino }; 776*e4b17023SJohn Marino 777*e4b17023SJohn Marino template<typename _Tp, typename _Arg> 778*e4b17023SJohn Marino struct __is_direct_constructible_new_safe 779*e4b17023SJohn Marino : public __and_<is_destructible<_Tp>, 780*e4b17023SJohn Marino __is_direct_constructible_impl<_Tp, _Arg>>::type 781*e4b17023SJohn Marino { }; 782*e4b17023SJohn Marino 783*e4b17023SJohn Marino template<typename, typename> 784*e4b17023SJohn Marino struct is_same; 785*e4b17023SJohn Marino 786*e4b17023SJohn Marino template<typename, typename> 787*e4b17023SJohn Marino struct is_base_of; 788*e4b17023SJohn Marino 789*e4b17023SJohn Marino template<typename> 790*e4b17023SJohn Marino struct remove_reference; 791*e4b17023SJohn Marino 792*e4b17023SJohn Marino template<typename _From, typename _To, bool 793*e4b17023SJohn Marino = __not_<__or_<is_void<_From>, 794*e4b17023SJohn Marino is_function<_From>>>::value> 795*e4b17023SJohn Marino struct __is_base_to_derived_ref; 796*e4b17023SJohn Marino 797*e4b17023SJohn Marino // Detect whether we have a downcast situation during 798*e4b17023SJohn Marino // reference binding. 799*e4b17023SJohn Marino template<typename _From, typename _To> 800*e4b17023SJohn Marino struct __is_base_to_derived_ref<_From, _To, true> 801*e4b17023SJohn Marino { 802*e4b17023SJohn Marino typedef typename remove_cv<typename remove_reference<_From 803*e4b17023SJohn Marino >::type>::type __src_t; 804*e4b17023SJohn Marino typedef typename remove_cv<typename remove_reference<_To 805*e4b17023SJohn Marino >::type>::type __dst_t; 806*e4b17023SJohn Marino typedef __and_<__not_<is_same<__src_t, __dst_t>>, 807*e4b17023SJohn Marino is_base_of<__src_t, __dst_t>> type; 808*e4b17023SJohn Marino static constexpr bool value = type::value; 809*e4b17023SJohn Marino }; 810*e4b17023SJohn Marino 811*e4b17023SJohn Marino template<typename _From, typename _To> 812*e4b17023SJohn Marino struct __is_base_to_derived_ref<_From, _To, false> 813*e4b17023SJohn Marino : public false_type 814*e4b17023SJohn Marino { }; 815*e4b17023SJohn Marino 816*e4b17023SJohn Marino template<typename _From, typename _To, bool 817*e4b17023SJohn Marino = __and_<is_lvalue_reference<_From>, 818*e4b17023SJohn Marino is_rvalue_reference<_To>>::value> 819*e4b17023SJohn Marino struct __is_lvalue_to_rvalue_ref; 820*e4b17023SJohn Marino 821*e4b17023SJohn Marino // Detect whether we have an lvalue of non-function type 822*e4b17023SJohn Marino // bound to a reference-compatible rvalue-reference. 823*e4b17023SJohn Marino template<typename _From, typename _To> 824*e4b17023SJohn Marino struct __is_lvalue_to_rvalue_ref<_From, _To, true> 825*e4b17023SJohn Marino { 826*e4b17023SJohn Marino typedef typename remove_cv<typename remove_reference< 827*e4b17023SJohn Marino _From>::type>::type __src_t; 828*e4b17023SJohn Marino typedef typename remove_cv<typename remove_reference< 829*e4b17023SJohn Marino _To>::type>::type __dst_t; 830*e4b17023SJohn Marino typedef __and_<__not_<is_function<__src_t>>, 831*e4b17023SJohn Marino __or_<is_same<__src_t, __dst_t>, 832*e4b17023SJohn Marino is_base_of<__dst_t, __src_t>>> type; 833*e4b17023SJohn Marino static constexpr bool value = type::value; 834*e4b17023SJohn Marino }; 835*e4b17023SJohn Marino 836*e4b17023SJohn Marino template<typename _From, typename _To> 837*e4b17023SJohn Marino struct __is_lvalue_to_rvalue_ref<_From, _To, false> 838*e4b17023SJohn Marino : public false_type 839*e4b17023SJohn Marino { }; 840*e4b17023SJohn Marino 841*e4b17023SJohn Marino // Here we handle direct-initialization to a reference type as 842*e4b17023SJohn Marino // equivalent to a static_cast modulo overshooting conversions. 843*e4b17023SJohn Marino // These are restricted to the following conversions: 844*e4b17023SJohn Marino // a) A base class value to a derived class reference 845*e4b17023SJohn Marino // b) An lvalue to an rvalue-reference of reference-compatible 846*e4b17023SJohn Marino // types that are not functions 847*e4b17023SJohn Marino template<typename _Tp, typename _Arg> 848*e4b17023SJohn Marino struct __is_direct_constructible_ref_cast 849*e4b17023SJohn Marino : public __and_<__is_static_castable<_Arg, _Tp>, 850*e4b17023SJohn Marino __not_<__or_<__is_base_to_derived_ref<_Arg, _Tp>, 851*e4b17023SJohn Marino __is_lvalue_to_rvalue_ref<_Arg, _Tp> 852*e4b17023SJohn Marino >>>::type 853*e4b17023SJohn Marino { }; 854*e4b17023SJohn Marino 855*e4b17023SJohn Marino template<typename _Tp, typename _Arg> 856*e4b17023SJohn Marino struct __is_direct_constructible_new 857*e4b17023SJohn Marino : public conditional<is_reference<_Tp>::value, 858*e4b17023SJohn Marino __is_direct_constructible_ref_cast<_Tp, _Arg>, 859*e4b17023SJohn Marino __is_direct_constructible_new_safe<_Tp, _Arg> 860*e4b17023SJohn Marino >::type 861*e4b17023SJohn Marino { }; 862*e4b17023SJohn Marino 863*e4b17023SJohn Marino template<typename _Tp, typename _Arg> 864*e4b17023SJohn Marino struct __is_direct_constructible 865*e4b17023SJohn Marino : public integral_constant<bool, (__is_direct_constructible_new< 866*e4b17023SJohn Marino _Tp, _Arg>::value)> 867*e4b17023SJohn Marino { }; 868*e4b17023SJohn Marino 869*e4b17023SJohn Marino // Since default-construction and binary direct-initialization have 870*e4b17023SJohn Marino // been handled separately, the implementation of the remaining 871*e4b17023SJohn Marino // n-ary construction cases is rather straightforward. We can use 872*e4b17023SJohn Marino // here a functional cast, because array types are excluded anyway 873*e4b17023SJohn Marino // and this form is never interpreted as a C cast. 874*e4b17023SJohn Marino struct __do_is_nary_constructible_impl 875*e4b17023SJohn Marino { 876*e4b17023SJohn Marino template<typename _Tp, typename... _Args, typename 877*e4b17023SJohn Marino = decltype(_Tp(declval<_Args>()...))> 878*e4b17023SJohn Marino static true_type __test(int); 879*e4b17023SJohn Marino 880*e4b17023SJohn Marino template<typename, typename...> 881*e4b17023SJohn Marino static false_type __test(...); 882*e4b17023SJohn Marino }; 883*e4b17023SJohn Marino 884*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 885*e4b17023SJohn Marino struct __is_nary_constructible_impl 886*e4b17023SJohn Marino : public __do_is_nary_constructible_impl 887*e4b17023SJohn Marino { 888*e4b17023SJohn Marino typedef decltype(__test<_Tp, _Args...>(0)) type; 889*e4b17023SJohn Marino }; 890*e4b17023SJohn Marino 891*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 892*e4b17023SJohn Marino struct __is_nary_constructible 893*e4b17023SJohn Marino : public __is_nary_constructible_impl<_Tp, _Args...>::type 894*e4b17023SJohn Marino { 895*e4b17023SJohn Marino static_assert(sizeof...(_Args) > 1, 896*e4b17023SJohn Marino "Only useful for > 1 arguments"); 897*e4b17023SJohn Marino }; 898*e4b17023SJohn Marino 899*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 900*e4b17023SJohn Marino struct __is_constructible_impl 901*e4b17023SJohn Marino : public __is_nary_constructible<_Tp, _Args...> 902*e4b17023SJohn Marino { }; 903*e4b17023SJohn Marino 904*e4b17023SJohn Marino template<typename _Tp, typename _Arg> 905*e4b17023SJohn Marino struct __is_constructible_impl<_Tp, _Arg> 906*e4b17023SJohn Marino : public __is_direct_constructible<_Tp, _Arg> 907*e4b17023SJohn Marino { }; 908*e4b17023SJohn Marino 909*e4b17023SJohn Marino template<typename _Tp> 910*e4b17023SJohn Marino struct __is_constructible_impl<_Tp> 911*e4b17023SJohn Marino : public is_default_constructible<_Tp> 912*e4b17023SJohn Marino { }; 913*e4b17023SJohn Marino 914*e4b17023SJohn Marino /// is_constructible 915*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 916*e4b17023SJohn Marino struct is_constructible 917*e4b17023SJohn Marino : public integral_constant<bool, (__is_constructible_impl<_Tp, 918*e4b17023SJohn Marino _Args...>::value)> 919*e4b17023SJohn Marino { }; 920*e4b17023SJohn Marino 921*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 922*e4b17023SJohn Marino struct __is_copy_constructible_impl; 923*e4b17023SJohn Marino 924*e4b17023SJohn Marino template<typename _Tp> 925*e4b17023SJohn Marino struct __is_copy_constructible_impl<_Tp, true> 926*e4b17023SJohn Marino : public false_type { }; 927*e4b17023SJohn Marino 928*e4b17023SJohn Marino template<typename _Tp> 929*e4b17023SJohn Marino struct __is_copy_constructible_impl<_Tp, false> 930*e4b17023SJohn Marino : public is_constructible<_Tp, const _Tp&> 931*e4b17023SJohn Marino { }; 932*e4b17023SJohn Marino 933*e4b17023SJohn Marino /// is_copy_constructible 934*e4b17023SJohn Marino template<typename _Tp> 935*e4b17023SJohn Marino struct is_copy_constructible 936*e4b17023SJohn Marino : public __is_copy_constructible_impl<_Tp> 937*e4b17023SJohn Marino { }; 938*e4b17023SJohn Marino 939*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 940*e4b17023SJohn Marino struct __is_move_constructible_impl; 941*e4b17023SJohn Marino 942*e4b17023SJohn Marino template<typename _Tp> 943*e4b17023SJohn Marino struct __is_move_constructible_impl<_Tp, true> 944*e4b17023SJohn Marino : public false_type { }; 945*e4b17023SJohn Marino 946*e4b17023SJohn Marino template<typename _Tp> 947*e4b17023SJohn Marino struct __is_move_constructible_impl<_Tp, false> 948*e4b17023SJohn Marino : public is_constructible<_Tp, _Tp&&> 949*e4b17023SJohn Marino { }; 950*e4b17023SJohn Marino 951*e4b17023SJohn Marino /// is_move_constructible 952*e4b17023SJohn Marino template<typename _Tp> 953*e4b17023SJohn Marino struct is_move_constructible 954*e4b17023SJohn Marino : public __is_move_constructible_impl<_Tp> 955*e4b17023SJohn Marino { }; 956*e4b17023SJohn Marino 957*e4b17023SJohn Marino template<typename _Tp> 958*e4b17023SJohn Marino struct __is_nt_default_constructible_atom 959*e4b17023SJohn Marino : public integral_constant<bool, noexcept(_Tp())> 960*e4b17023SJohn Marino { }; 961*e4b17023SJohn Marino 962*e4b17023SJohn Marino template<typename _Tp, bool = is_array<_Tp>::value> 963*e4b17023SJohn Marino struct __is_nt_default_constructible_impl; 964*e4b17023SJohn Marino 965*e4b17023SJohn Marino template<typename _Tp> 966*e4b17023SJohn Marino struct __is_nt_default_constructible_impl<_Tp, true> 967*e4b17023SJohn Marino : public __and_<__is_array_known_bounds<_Tp>, 968*e4b17023SJohn Marino __is_nt_default_constructible_atom<typename 969*e4b17023SJohn Marino remove_all_extents<_Tp>::type>>::type 970*e4b17023SJohn Marino { }; 971*e4b17023SJohn Marino 972*e4b17023SJohn Marino template<typename _Tp> 973*e4b17023SJohn Marino struct __is_nt_default_constructible_impl<_Tp, false> 974*e4b17023SJohn Marino : public __is_nt_default_constructible_atom<_Tp> 975*e4b17023SJohn Marino { }; 976*e4b17023SJohn Marino 977*e4b17023SJohn Marino /// is_nothrow_default_constructible 978*e4b17023SJohn Marino template<typename _Tp> 979*e4b17023SJohn Marino struct is_nothrow_default_constructible 980*e4b17023SJohn Marino : public __and_<is_default_constructible<_Tp>, 981*e4b17023SJohn Marino __is_nt_default_constructible_impl<_Tp>>::type 982*e4b17023SJohn Marino { }; 983*e4b17023SJohn Marino 984*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 985*e4b17023SJohn Marino struct __is_nt_constructible_impl 986*e4b17023SJohn Marino : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> 987*e4b17023SJohn Marino { }; 988*e4b17023SJohn Marino 989*e4b17023SJohn Marino template<typename _Tp, typename _Arg> 990*e4b17023SJohn Marino struct __is_nt_constructible_impl<_Tp, _Arg> 991*e4b17023SJohn Marino : public integral_constant<bool, 992*e4b17023SJohn Marino noexcept(static_cast<_Tp>(declval<_Arg>()))> 993*e4b17023SJohn Marino { }; 994*e4b17023SJohn Marino 995*e4b17023SJohn Marino template<typename _Tp> 996*e4b17023SJohn Marino struct __is_nt_constructible_impl<_Tp> 997*e4b17023SJohn Marino : public is_nothrow_default_constructible<_Tp> 998*e4b17023SJohn Marino { }; 999*e4b17023SJohn Marino 1000*e4b17023SJohn Marino /// is_nothrow_constructible 1001*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 1002*e4b17023SJohn Marino struct is_nothrow_constructible 1003*e4b17023SJohn Marino : public __and_<is_constructible<_Tp, _Args...>, 1004*e4b17023SJohn Marino __is_nt_constructible_impl<_Tp, _Args...>>::type 1005*e4b17023SJohn Marino { }; 1006*e4b17023SJohn Marino 1007*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 1008*e4b17023SJohn Marino struct __is_nothrow_copy_constructible_impl; 1009*e4b17023SJohn Marino 1010*e4b17023SJohn Marino template<typename _Tp> 1011*e4b17023SJohn Marino struct __is_nothrow_copy_constructible_impl<_Tp, true> 1012*e4b17023SJohn Marino : public false_type { }; 1013*e4b17023SJohn Marino 1014*e4b17023SJohn Marino template<typename _Tp> 1015*e4b17023SJohn Marino struct __is_nothrow_copy_constructible_impl<_Tp, false> 1016*e4b17023SJohn Marino : public is_nothrow_constructible<_Tp, const _Tp&> 1017*e4b17023SJohn Marino { }; 1018*e4b17023SJohn Marino 1019*e4b17023SJohn Marino /// is_nothrow_copy_constructible 1020*e4b17023SJohn Marino template<typename _Tp> 1021*e4b17023SJohn Marino struct is_nothrow_copy_constructible 1022*e4b17023SJohn Marino : public __is_nothrow_copy_constructible_impl<_Tp> 1023*e4b17023SJohn Marino { }; 1024*e4b17023SJohn Marino 1025*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 1026*e4b17023SJohn Marino struct __is_nothrow_move_constructible_impl; 1027*e4b17023SJohn Marino 1028*e4b17023SJohn Marino template<typename _Tp> 1029*e4b17023SJohn Marino struct __is_nothrow_move_constructible_impl<_Tp, true> 1030*e4b17023SJohn Marino : public false_type { }; 1031*e4b17023SJohn Marino 1032*e4b17023SJohn Marino template<typename _Tp> 1033*e4b17023SJohn Marino struct __is_nothrow_move_constructible_impl<_Tp, false> 1034*e4b17023SJohn Marino : public is_nothrow_constructible<_Tp, _Tp&&> 1035*e4b17023SJohn Marino { }; 1036*e4b17023SJohn Marino 1037*e4b17023SJohn Marino /// is_nothrow_move_constructible 1038*e4b17023SJohn Marino template<typename _Tp> 1039*e4b17023SJohn Marino struct is_nothrow_move_constructible 1040*e4b17023SJohn Marino : public __is_nothrow_move_constructible_impl<_Tp> 1041*e4b17023SJohn Marino { }; 1042*e4b17023SJohn Marino 1043*e4b17023SJohn Marino template<typename _Tp, typename _Up> 1044*e4b17023SJohn Marino class __is_assignable_helper 1045*e4b17023SJohn Marino : public __sfinae_types 1046*e4b17023SJohn Marino { 1047*e4b17023SJohn Marino template<typename _Tp1, typename _Up1> 1048*e4b17023SJohn Marino static decltype(declval<_Tp1>() = declval<_Up1>(), __one()) 1049*e4b17023SJohn Marino __test(int); 1050*e4b17023SJohn Marino 1051*e4b17023SJohn Marino template<typename, typename> 1052*e4b17023SJohn Marino static __two __test(...); 1053*e4b17023SJohn Marino 1054*e4b17023SJohn Marino public: 1055*e4b17023SJohn Marino static constexpr bool value = sizeof(__test<_Tp, _Up>(0)) == 1; 1056*e4b17023SJohn Marino }; 1057*e4b17023SJohn Marino 1058*e4b17023SJohn Marino /// is_assignable 1059*e4b17023SJohn Marino template<typename _Tp, typename _Up> 1060*e4b17023SJohn Marino struct is_assignable 1061*e4b17023SJohn Marino : public integral_constant<bool, 1062*e4b17023SJohn Marino __is_assignable_helper<_Tp, _Up>::value> 1063*e4b17023SJohn Marino { }; 1064*e4b17023SJohn Marino 1065*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 1066*e4b17023SJohn Marino struct __is_copy_assignable_impl; 1067*e4b17023SJohn Marino 1068*e4b17023SJohn Marino template<typename _Tp> 1069*e4b17023SJohn Marino struct __is_copy_assignable_impl<_Tp, true> 1070*e4b17023SJohn Marino : public false_type { }; 1071*e4b17023SJohn Marino 1072*e4b17023SJohn Marino template<typename _Tp> 1073*e4b17023SJohn Marino struct __is_copy_assignable_impl<_Tp, false> 1074*e4b17023SJohn Marino : public is_assignable<_Tp&, const _Tp&> 1075*e4b17023SJohn Marino { }; 1076*e4b17023SJohn Marino 1077*e4b17023SJohn Marino /// is_copy_assignable 1078*e4b17023SJohn Marino template<typename _Tp> 1079*e4b17023SJohn Marino struct is_copy_assignable 1080*e4b17023SJohn Marino : public __is_copy_assignable_impl<_Tp> 1081*e4b17023SJohn Marino { }; 1082*e4b17023SJohn Marino 1083*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 1084*e4b17023SJohn Marino struct __is_move_assignable_impl; 1085*e4b17023SJohn Marino 1086*e4b17023SJohn Marino template<typename _Tp> 1087*e4b17023SJohn Marino struct __is_move_assignable_impl<_Tp, true> 1088*e4b17023SJohn Marino : public false_type { }; 1089*e4b17023SJohn Marino 1090*e4b17023SJohn Marino template<typename _Tp> 1091*e4b17023SJohn Marino struct __is_move_assignable_impl<_Tp, false> 1092*e4b17023SJohn Marino : public is_assignable<_Tp&, _Tp&&> 1093*e4b17023SJohn Marino { }; 1094*e4b17023SJohn Marino 1095*e4b17023SJohn Marino /// is_move_assignable 1096*e4b17023SJohn Marino template<typename _Tp> 1097*e4b17023SJohn Marino struct is_move_assignable 1098*e4b17023SJohn Marino : public __is_move_assignable_impl<_Tp> 1099*e4b17023SJohn Marino { }; 1100*e4b17023SJohn Marino 1101*e4b17023SJohn Marino template<typename _Tp, typename _Up> 1102*e4b17023SJohn Marino struct __is_nt_assignable_impl 1103*e4b17023SJohn Marino : public integral_constant<bool, noexcept(declval<_Tp>() = declval<_Up>())> 1104*e4b17023SJohn Marino { }; 1105*e4b17023SJohn Marino 1106*e4b17023SJohn Marino /// is_nothrow_assignable 1107*e4b17023SJohn Marino template<typename _Tp, typename _Up> 1108*e4b17023SJohn Marino struct is_nothrow_assignable 1109*e4b17023SJohn Marino : public __and_<is_assignable<_Tp, _Up>, 1110*e4b17023SJohn Marino __is_nt_assignable_impl<_Tp, _Up>>::type 1111*e4b17023SJohn Marino { }; 1112*e4b17023SJohn Marino 1113*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 1114*e4b17023SJohn Marino struct __is_nt_copy_assignable_impl; 1115*e4b17023SJohn Marino 1116*e4b17023SJohn Marino template<typename _Tp> 1117*e4b17023SJohn Marino struct __is_nt_copy_assignable_impl<_Tp, true> 1118*e4b17023SJohn Marino : public false_type { }; 1119*e4b17023SJohn Marino 1120*e4b17023SJohn Marino template<typename _Tp> 1121*e4b17023SJohn Marino struct __is_nt_copy_assignable_impl<_Tp, false> 1122*e4b17023SJohn Marino : public is_nothrow_assignable<_Tp&, const _Tp&> 1123*e4b17023SJohn Marino { }; 1124*e4b17023SJohn Marino 1125*e4b17023SJohn Marino /// is_nothrow_copy_assignable 1126*e4b17023SJohn Marino template<typename _Tp> 1127*e4b17023SJohn Marino struct is_nothrow_copy_assignable 1128*e4b17023SJohn Marino : public __is_nt_copy_assignable_impl<_Tp> 1129*e4b17023SJohn Marino { }; 1130*e4b17023SJohn Marino 1131*e4b17023SJohn Marino template<typename _Tp, bool = is_void<_Tp>::value> 1132*e4b17023SJohn Marino struct __is_nt_move_assignable_impl; 1133*e4b17023SJohn Marino 1134*e4b17023SJohn Marino template<typename _Tp> 1135*e4b17023SJohn Marino struct __is_nt_move_assignable_impl<_Tp, true> 1136*e4b17023SJohn Marino : public false_type { }; 1137*e4b17023SJohn Marino 1138*e4b17023SJohn Marino template<typename _Tp> 1139*e4b17023SJohn Marino struct __is_nt_move_assignable_impl<_Tp, false> 1140*e4b17023SJohn Marino : public is_nothrow_assignable<_Tp&, _Tp&&> 1141*e4b17023SJohn Marino { }; 1142*e4b17023SJohn Marino 1143*e4b17023SJohn Marino /// is_nothrow_move_assignable 1144*e4b17023SJohn Marino template<typename _Tp> 1145*e4b17023SJohn Marino struct is_nothrow_move_assignable 1146*e4b17023SJohn Marino : public __is_nt_move_assignable_impl<_Tp> 1147*e4b17023SJohn Marino { }; 1148*e4b17023SJohn Marino 1149*e4b17023SJohn Marino /// has_trivial_default_constructor 1150*e4b17023SJohn Marino template<typename _Tp> 1151*e4b17023SJohn Marino struct has_trivial_default_constructor 1152*e4b17023SJohn Marino : public integral_constant<bool, __has_trivial_constructor(_Tp)> 1153*e4b17023SJohn Marino { }; 1154*e4b17023SJohn Marino 1155*e4b17023SJohn Marino /// has_trivial_copy_constructor 1156*e4b17023SJohn Marino template<typename _Tp> 1157*e4b17023SJohn Marino struct has_trivial_copy_constructor 1158*e4b17023SJohn Marino : public integral_constant<bool, __has_trivial_copy(_Tp)> 1159*e4b17023SJohn Marino { }; 1160*e4b17023SJohn Marino 1161*e4b17023SJohn Marino /// has_trivial_copy_assign 1162*e4b17023SJohn Marino template<typename _Tp> 1163*e4b17023SJohn Marino struct has_trivial_copy_assign 1164*e4b17023SJohn Marino : public integral_constant<bool, __has_trivial_assign(_Tp)> 1165*e4b17023SJohn Marino { }; 1166*e4b17023SJohn Marino 1167*e4b17023SJohn Marino /// has_trivial_destructor 1168*e4b17023SJohn Marino template<typename _Tp> 1169*e4b17023SJohn Marino struct has_trivial_destructor 1170*e4b17023SJohn Marino : public integral_constant<bool, __has_trivial_destructor(_Tp)> 1171*e4b17023SJohn Marino { }; 1172*e4b17023SJohn Marino 1173*e4b17023SJohn Marino /// has_virtual_destructor 1174*e4b17023SJohn Marino template<typename _Tp> 1175*e4b17023SJohn Marino struct has_virtual_destructor 1176*e4b17023SJohn Marino : public integral_constant<bool, __has_virtual_destructor(_Tp)> 1177*e4b17023SJohn Marino { }; 1178*e4b17023SJohn Marino 1179*e4b17023SJohn Marino 1180*e4b17023SJohn Marino // type property queries. 1181*e4b17023SJohn Marino 1182*e4b17023SJohn Marino /// alignment_of 1183*e4b17023SJohn Marino template<typename _Tp> 1184*e4b17023SJohn Marino struct alignment_of 1185*e4b17023SJohn Marino : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 1186*e4b17023SJohn Marino 1187*e4b17023SJohn Marino /// rank 1188*e4b17023SJohn Marino template<typename> 1189*e4b17023SJohn Marino struct rank 1190*e4b17023SJohn Marino : public integral_constant<std::size_t, 0> { }; 1191*e4b17023SJohn Marino 1192*e4b17023SJohn Marino template<typename _Tp, std::size_t _Size> 1193*e4b17023SJohn Marino struct rank<_Tp[_Size]> 1194*e4b17023SJohn Marino : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 1195*e4b17023SJohn Marino 1196*e4b17023SJohn Marino template<typename _Tp> 1197*e4b17023SJohn Marino struct rank<_Tp[]> 1198*e4b17023SJohn Marino : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 1199*e4b17023SJohn Marino 1200*e4b17023SJohn Marino /// extent 1201*e4b17023SJohn Marino template<typename, unsigned _Uint> 1202*e4b17023SJohn Marino struct extent 1203*e4b17023SJohn Marino : public integral_constant<std::size_t, 0> { }; 1204*e4b17023SJohn Marino 1205*e4b17023SJohn Marino template<typename _Tp, unsigned _Uint, std::size_t _Size> 1206*e4b17023SJohn Marino struct extent<_Tp[_Size], _Uint> 1207*e4b17023SJohn Marino : public integral_constant<std::size_t, 1208*e4b17023SJohn Marino _Uint == 0 ? _Size : extent<_Tp, 1209*e4b17023SJohn Marino _Uint - 1>::value> 1210*e4b17023SJohn Marino { }; 1211*e4b17023SJohn Marino 1212*e4b17023SJohn Marino template<typename _Tp, unsigned _Uint> 1213*e4b17023SJohn Marino struct extent<_Tp[], _Uint> 1214*e4b17023SJohn Marino : public integral_constant<std::size_t, 1215*e4b17023SJohn Marino _Uint == 0 ? 0 : extent<_Tp, 1216*e4b17023SJohn Marino _Uint - 1>::value> 1217*e4b17023SJohn Marino { }; 1218*e4b17023SJohn Marino 1219*e4b17023SJohn Marino 1220*e4b17023SJohn Marino // type relations. 1221*e4b17023SJohn Marino 1222*e4b17023SJohn Marino /// is_same 1223*e4b17023SJohn Marino template<typename, typename> 1224*e4b17023SJohn Marino struct is_same 1225*e4b17023SJohn Marino : public false_type { }; 1226*e4b17023SJohn Marino 1227*e4b17023SJohn Marino template<typename _Tp> 1228*e4b17023SJohn Marino struct is_same<_Tp, _Tp> 1229*e4b17023SJohn Marino : public true_type { }; 1230*e4b17023SJohn Marino 1231*e4b17023SJohn Marino /// is_base_of 1232*e4b17023SJohn Marino template<typename _Base, typename _Derived> 1233*e4b17023SJohn Marino struct is_base_of 1234*e4b17023SJohn Marino : public integral_constant<bool, __is_base_of(_Base, _Derived)> 1235*e4b17023SJohn Marino { }; 1236*e4b17023SJohn Marino 1237*e4b17023SJohn Marino template<typename _From, typename _To, 1238*e4b17023SJohn Marino bool = __or_<is_void<_From>, is_function<_To>, 1239*e4b17023SJohn Marino is_array<_To>>::value> 1240*e4b17023SJohn Marino struct __is_convertible_helper 1241*e4b17023SJohn Marino { static constexpr bool value = is_void<_To>::value; }; 1242*e4b17023SJohn Marino 1243*e4b17023SJohn Marino template<typename _From, typename _To> 1244*e4b17023SJohn Marino class __is_convertible_helper<_From, _To, false> 1245*e4b17023SJohn Marino : public __sfinae_types 1246*e4b17023SJohn Marino { 1247*e4b17023SJohn Marino template<typename _To1> 1248*e4b17023SJohn Marino static void __test_aux(_To1); 1249*e4b17023SJohn Marino 1250*e4b17023SJohn Marino template<typename _From1, typename _To1> 1251*e4b17023SJohn Marino static decltype(__test_aux<_To1>(std::declval<_From1>()), __one()) 1252*e4b17023SJohn Marino __test(int); 1253*e4b17023SJohn Marino 1254*e4b17023SJohn Marino template<typename, typename> 1255*e4b17023SJohn Marino static __two __test(...); 1256*e4b17023SJohn Marino 1257*e4b17023SJohn Marino public: 1258*e4b17023SJohn Marino static constexpr bool value = sizeof(__test<_From, _To>(0)) == 1; 1259*e4b17023SJohn Marino }; 1260*e4b17023SJohn Marino 1261*e4b17023SJohn Marino /// is_convertible 1262*e4b17023SJohn Marino template<typename _From, typename _To> 1263*e4b17023SJohn Marino struct is_convertible 1264*e4b17023SJohn Marino : public integral_constant<bool, 1265*e4b17023SJohn Marino __is_convertible_helper<_From, _To>::value> 1266*e4b17023SJohn Marino { }; 1267*e4b17023SJohn Marino 1268*e4b17023SJohn Marino /// is_explicitly_convertible 1269*e4b17023SJohn Marino template<typename _From, typename _To> 1270*e4b17023SJohn Marino struct is_explicitly_convertible 1271*e4b17023SJohn Marino : public is_constructible<_To, _From> 1272*e4b17023SJohn Marino { }; 1273*e4b17023SJohn Marino 1274*e4b17023SJohn Marino 1275*e4b17023SJohn Marino // const-volatile modifications. 1276*e4b17023SJohn Marino 1277*e4b17023SJohn Marino /// remove_const 1278*e4b17023SJohn Marino template<typename _Tp> 1279*e4b17023SJohn Marino struct remove_const 1280*e4b17023SJohn Marino { typedef _Tp type; }; 1281*e4b17023SJohn Marino 1282*e4b17023SJohn Marino template<typename _Tp> 1283*e4b17023SJohn Marino struct remove_const<_Tp const> 1284*e4b17023SJohn Marino { typedef _Tp type; }; 1285*e4b17023SJohn Marino 1286*e4b17023SJohn Marino /// remove_volatile 1287*e4b17023SJohn Marino template<typename _Tp> 1288*e4b17023SJohn Marino struct remove_volatile 1289*e4b17023SJohn Marino { typedef _Tp type; }; 1290*e4b17023SJohn Marino 1291*e4b17023SJohn Marino template<typename _Tp> 1292*e4b17023SJohn Marino struct remove_volatile<_Tp volatile> 1293*e4b17023SJohn Marino { typedef _Tp type; }; 1294*e4b17023SJohn Marino 1295*e4b17023SJohn Marino /// remove_cv 1296*e4b17023SJohn Marino template<typename _Tp> 1297*e4b17023SJohn Marino struct remove_cv 1298*e4b17023SJohn Marino { 1299*e4b17023SJohn Marino typedef typename 1300*e4b17023SJohn Marino remove_const<typename remove_volatile<_Tp>::type>::type type; 1301*e4b17023SJohn Marino }; 1302*e4b17023SJohn Marino 1303*e4b17023SJohn Marino /// add_const 1304*e4b17023SJohn Marino template<typename _Tp> 1305*e4b17023SJohn Marino struct add_const 1306*e4b17023SJohn Marino { typedef _Tp const type; }; 1307*e4b17023SJohn Marino 1308*e4b17023SJohn Marino /// add_volatile 1309*e4b17023SJohn Marino template<typename _Tp> 1310*e4b17023SJohn Marino struct add_volatile 1311*e4b17023SJohn Marino { typedef _Tp volatile type; }; 1312*e4b17023SJohn Marino 1313*e4b17023SJohn Marino /// add_cv 1314*e4b17023SJohn Marino template<typename _Tp> 1315*e4b17023SJohn Marino struct add_cv 1316*e4b17023SJohn Marino { 1317*e4b17023SJohn Marino typedef typename 1318*e4b17023SJohn Marino add_const<typename add_volatile<_Tp>::type>::type type; 1319*e4b17023SJohn Marino }; 1320*e4b17023SJohn Marino 1321*e4b17023SJohn Marino 1322*e4b17023SJohn Marino // Reference transformations. 1323*e4b17023SJohn Marino 1324*e4b17023SJohn Marino /// remove_reference 1325*e4b17023SJohn Marino template<typename _Tp> 1326*e4b17023SJohn Marino struct remove_reference 1327*e4b17023SJohn Marino { typedef _Tp type; }; 1328*e4b17023SJohn Marino 1329*e4b17023SJohn Marino template<typename _Tp> 1330*e4b17023SJohn Marino struct remove_reference<_Tp&> 1331*e4b17023SJohn Marino { typedef _Tp type; }; 1332*e4b17023SJohn Marino 1333*e4b17023SJohn Marino template<typename _Tp> 1334*e4b17023SJohn Marino struct remove_reference<_Tp&&> 1335*e4b17023SJohn Marino { typedef _Tp type; }; 1336*e4b17023SJohn Marino 1337*e4b17023SJohn Marino template<typename _Tp, 1338*e4b17023SJohn Marino bool = __and_<__not_<is_reference<_Tp>>, 1339*e4b17023SJohn Marino __not_<is_void<_Tp>>>::value, 1340*e4b17023SJohn Marino bool = is_rvalue_reference<_Tp>::value> 1341*e4b17023SJohn Marino struct __add_lvalue_reference_helper 1342*e4b17023SJohn Marino { typedef _Tp type; }; 1343*e4b17023SJohn Marino 1344*e4b17023SJohn Marino template<typename _Tp> 1345*e4b17023SJohn Marino struct __add_lvalue_reference_helper<_Tp, true, false> 1346*e4b17023SJohn Marino { typedef _Tp& type; }; 1347*e4b17023SJohn Marino 1348*e4b17023SJohn Marino template<typename _Tp> 1349*e4b17023SJohn Marino struct __add_lvalue_reference_helper<_Tp, false, true> 1350*e4b17023SJohn Marino { typedef typename remove_reference<_Tp>::type& type; }; 1351*e4b17023SJohn Marino 1352*e4b17023SJohn Marino /// add_lvalue_reference 1353*e4b17023SJohn Marino template<typename _Tp> 1354*e4b17023SJohn Marino struct add_lvalue_reference 1355*e4b17023SJohn Marino : public __add_lvalue_reference_helper<_Tp> 1356*e4b17023SJohn Marino { }; 1357*e4b17023SJohn Marino 1358*e4b17023SJohn Marino template<typename _Tp, 1359*e4b17023SJohn Marino bool = __and_<__not_<is_reference<_Tp>>, 1360*e4b17023SJohn Marino __not_<is_void<_Tp>>>::value> 1361*e4b17023SJohn Marino struct __add_rvalue_reference_helper 1362*e4b17023SJohn Marino { typedef _Tp type; }; 1363*e4b17023SJohn Marino 1364*e4b17023SJohn Marino template<typename _Tp> 1365*e4b17023SJohn Marino struct __add_rvalue_reference_helper<_Tp, true> 1366*e4b17023SJohn Marino { typedef _Tp&& type; }; 1367*e4b17023SJohn Marino 1368*e4b17023SJohn Marino /// add_rvalue_reference 1369*e4b17023SJohn Marino template<typename _Tp> 1370*e4b17023SJohn Marino struct add_rvalue_reference 1371*e4b17023SJohn Marino : public __add_rvalue_reference_helper<_Tp> 1372*e4b17023SJohn Marino { }; 1373*e4b17023SJohn Marino 1374*e4b17023SJohn Marino 1375*e4b17023SJohn Marino // sign modifications. 1376*e4b17023SJohn Marino 1377*e4b17023SJohn Marino // Utility for constructing identically cv-qualified types. 1378*e4b17023SJohn Marino template<typename _Unqualified, bool _IsConst, bool _IsVol> 1379*e4b17023SJohn Marino struct __cv_selector; 1380*e4b17023SJohn Marino 1381*e4b17023SJohn Marino template<typename _Unqualified> 1382*e4b17023SJohn Marino struct __cv_selector<_Unqualified, false, false> 1383*e4b17023SJohn Marino { typedef _Unqualified __type; }; 1384*e4b17023SJohn Marino 1385*e4b17023SJohn Marino template<typename _Unqualified> 1386*e4b17023SJohn Marino struct __cv_selector<_Unqualified, false, true> 1387*e4b17023SJohn Marino { typedef volatile _Unqualified __type; }; 1388*e4b17023SJohn Marino 1389*e4b17023SJohn Marino template<typename _Unqualified> 1390*e4b17023SJohn Marino struct __cv_selector<_Unqualified, true, false> 1391*e4b17023SJohn Marino { typedef const _Unqualified __type; }; 1392*e4b17023SJohn Marino 1393*e4b17023SJohn Marino template<typename _Unqualified> 1394*e4b17023SJohn Marino struct __cv_selector<_Unqualified, true, true> 1395*e4b17023SJohn Marino { typedef const volatile _Unqualified __type; }; 1396*e4b17023SJohn Marino 1397*e4b17023SJohn Marino template<typename _Qualified, typename _Unqualified, 1398*e4b17023SJohn Marino bool _IsConst = is_const<_Qualified>::value, 1399*e4b17023SJohn Marino bool _IsVol = is_volatile<_Qualified>::value> 1400*e4b17023SJohn Marino class __match_cv_qualifiers 1401*e4b17023SJohn Marino { 1402*e4b17023SJohn Marino typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; 1403*e4b17023SJohn Marino 1404*e4b17023SJohn Marino public: 1405*e4b17023SJohn Marino typedef typename __match::__type __type; 1406*e4b17023SJohn Marino }; 1407*e4b17023SJohn Marino 1408*e4b17023SJohn Marino // Utility for finding the unsigned versions of signed integral types. 1409*e4b17023SJohn Marino template<typename _Tp> 1410*e4b17023SJohn Marino struct __make_unsigned 1411*e4b17023SJohn Marino { typedef _Tp __type; }; 1412*e4b17023SJohn Marino 1413*e4b17023SJohn Marino template<> 1414*e4b17023SJohn Marino struct __make_unsigned<char> 1415*e4b17023SJohn Marino { typedef unsigned char __type; }; 1416*e4b17023SJohn Marino 1417*e4b17023SJohn Marino template<> 1418*e4b17023SJohn Marino struct __make_unsigned<signed char> 1419*e4b17023SJohn Marino { typedef unsigned char __type; }; 1420*e4b17023SJohn Marino 1421*e4b17023SJohn Marino template<> 1422*e4b17023SJohn Marino struct __make_unsigned<short> 1423*e4b17023SJohn Marino { typedef unsigned short __type; }; 1424*e4b17023SJohn Marino 1425*e4b17023SJohn Marino template<> 1426*e4b17023SJohn Marino struct __make_unsigned<int> 1427*e4b17023SJohn Marino { typedef unsigned int __type; }; 1428*e4b17023SJohn Marino 1429*e4b17023SJohn Marino template<> 1430*e4b17023SJohn Marino struct __make_unsigned<long> 1431*e4b17023SJohn Marino { typedef unsigned long __type; }; 1432*e4b17023SJohn Marino 1433*e4b17023SJohn Marino template<> 1434*e4b17023SJohn Marino struct __make_unsigned<long long> 1435*e4b17023SJohn Marino { typedef unsigned long long __type; }; 1436*e4b17023SJohn Marino 1437*e4b17023SJohn Marino#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) 1438*e4b17023SJohn Marino template<> 1439*e4b17023SJohn Marino struct __make_unsigned<__int128> 1440*e4b17023SJohn Marino { typedef unsigned __int128 __type; }; 1441*e4b17023SJohn Marino#endif 1442*e4b17023SJohn Marino 1443*e4b17023SJohn Marino // Select between integral and enum: not possible to be both. 1444*e4b17023SJohn Marino template<typename _Tp, 1445*e4b17023SJohn Marino bool _IsInt = is_integral<_Tp>::value, 1446*e4b17023SJohn Marino bool _IsEnum = is_enum<_Tp>::value> 1447*e4b17023SJohn Marino class __make_unsigned_selector; 1448*e4b17023SJohn Marino 1449*e4b17023SJohn Marino template<typename _Tp> 1450*e4b17023SJohn Marino class __make_unsigned_selector<_Tp, true, false> 1451*e4b17023SJohn Marino { 1452*e4b17023SJohn Marino typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt; 1453*e4b17023SJohn Marino typedef typename __unsignedt::__type __unsigned_type; 1454*e4b17023SJohn Marino typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; 1455*e4b17023SJohn Marino 1456*e4b17023SJohn Marino public: 1457*e4b17023SJohn Marino typedef typename __cv_unsigned::__type __type; 1458*e4b17023SJohn Marino }; 1459*e4b17023SJohn Marino 1460*e4b17023SJohn Marino template<typename _Tp> 1461*e4b17023SJohn Marino class __make_unsigned_selector<_Tp, false, true> 1462*e4b17023SJohn Marino { 1463*e4b17023SJohn Marino // With -fshort-enums, an enum may be as small as a char. 1464*e4b17023SJohn Marino typedef unsigned char __smallest; 1465*e4b17023SJohn Marino static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 1466*e4b17023SJohn Marino static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); 1467*e4b17023SJohn Marino static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); 1468*e4b17023SJohn Marino typedef conditional<__b2, unsigned int, unsigned long> __cond2; 1469*e4b17023SJohn Marino typedef typename __cond2::type __cond2_type; 1470*e4b17023SJohn Marino typedef conditional<__b1, unsigned short, __cond2_type> __cond1; 1471*e4b17023SJohn Marino typedef typename __cond1::type __cond1_type; 1472*e4b17023SJohn Marino 1473*e4b17023SJohn Marino public: 1474*e4b17023SJohn Marino typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 1475*e4b17023SJohn Marino }; 1476*e4b17023SJohn Marino 1477*e4b17023SJohn Marino // Given an integral/enum type, return the corresponding unsigned 1478*e4b17023SJohn Marino // integer type. 1479*e4b17023SJohn Marino // Primary template. 1480*e4b17023SJohn Marino /// make_unsigned 1481*e4b17023SJohn Marino template<typename _Tp> 1482*e4b17023SJohn Marino struct make_unsigned 1483*e4b17023SJohn Marino { typedef typename __make_unsigned_selector<_Tp>::__type type; }; 1484*e4b17023SJohn Marino 1485*e4b17023SJohn Marino // Integral, but don't define. 1486*e4b17023SJohn Marino template<> 1487*e4b17023SJohn Marino struct make_unsigned<bool>; 1488*e4b17023SJohn Marino 1489*e4b17023SJohn Marino 1490*e4b17023SJohn Marino // Utility for finding the signed versions of unsigned integral types. 1491*e4b17023SJohn Marino template<typename _Tp> 1492*e4b17023SJohn Marino struct __make_signed 1493*e4b17023SJohn Marino { typedef _Tp __type; }; 1494*e4b17023SJohn Marino 1495*e4b17023SJohn Marino template<> 1496*e4b17023SJohn Marino struct __make_signed<char> 1497*e4b17023SJohn Marino { typedef signed char __type; }; 1498*e4b17023SJohn Marino 1499*e4b17023SJohn Marino template<> 1500*e4b17023SJohn Marino struct __make_signed<unsigned char> 1501*e4b17023SJohn Marino { typedef signed char __type; }; 1502*e4b17023SJohn Marino 1503*e4b17023SJohn Marino template<> 1504*e4b17023SJohn Marino struct __make_signed<unsigned short> 1505*e4b17023SJohn Marino { typedef signed short __type; }; 1506*e4b17023SJohn Marino 1507*e4b17023SJohn Marino template<> 1508*e4b17023SJohn Marino struct __make_signed<unsigned int> 1509*e4b17023SJohn Marino { typedef signed int __type; }; 1510*e4b17023SJohn Marino 1511*e4b17023SJohn Marino template<> 1512*e4b17023SJohn Marino struct __make_signed<unsigned long> 1513*e4b17023SJohn Marino { typedef signed long __type; }; 1514*e4b17023SJohn Marino 1515*e4b17023SJohn Marino template<> 1516*e4b17023SJohn Marino struct __make_signed<unsigned long long> 1517*e4b17023SJohn Marino { typedef signed long long __type; }; 1518*e4b17023SJohn Marino 1519*e4b17023SJohn Marino#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) 1520*e4b17023SJohn Marino template<> 1521*e4b17023SJohn Marino struct __make_signed<unsigned __int128> 1522*e4b17023SJohn Marino { typedef __int128 __type; }; 1523*e4b17023SJohn Marino#endif 1524*e4b17023SJohn Marino 1525*e4b17023SJohn Marino // Select between integral and enum: not possible to be both. 1526*e4b17023SJohn Marino template<typename _Tp, 1527*e4b17023SJohn Marino bool _IsInt = is_integral<_Tp>::value, 1528*e4b17023SJohn Marino bool _IsEnum = is_enum<_Tp>::value> 1529*e4b17023SJohn Marino class __make_signed_selector; 1530*e4b17023SJohn Marino 1531*e4b17023SJohn Marino template<typename _Tp> 1532*e4b17023SJohn Marino class __make_signed_selector<_Tp, true, false> 1533*e4b17023SJohn Marino { 1534*e4b17023SJohn Marino typedef __make_signed<typename remove_cv<_Tp>::type> __signedt; 1535*e4b17023SJohn Marino typedef typename __signedt::__type __signed_type; 1536*e4b17023SJohn Marino typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; 1537*e4b17023SJohn Marino 1538*e4b17023SJohn Marino public: 1539*e4b17023SJohn Marino typedef typename __cv_signed::__type __type; 1540*e4b17023SJohn Marino }; 1541*e4b17023SJohn Marino 1542*e4b17023SJohn Marino template<typename _Tp> 1543*e4b17023SJohn Marino class __make_signed_selector<_Tp, false, true> 1544*e4b17023SJohn Marino { 1545*e4b17023SJohn Marino // With -fshort-enums, an enum may be as small as a char. 1546*e4b17023SJohn Marino typedef signed char __smallest; 1547*e4b17023SJohn Marino static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 1548*e4b17023SJohn Marino static const bool __b1 = sizeof(_Tp) <= sizeof(signed short); 1549*e4b17023SJohn Marino static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); 1550*e4b17023SJohn Marino typedef conditional<__b2, signed int, signed long> __cond2; 1551*e4b17023SJohn Marino typedef typename __cond2::type __cond2_type; 1552*e4b17023SJohn Marino typedef conditional<__b1, signed short, __cond2_type> __cond1; 1553*e4b17023SJohn Marino typedef typename __cond1::type __cond1_type; 1554*e4b17023SJohn Marino 1555*e4b17023SJohn Marino public: 1556*e4b17023SJohn Marino typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 1557*e4b17023SJohn Marino }; 1558*e4b17023SJohn Marino 1559*e4b17023SJohn Marino // Given an integral/enum type, return the corresponding signed 1560*e4b17023SJohn Marino // integer type. 1561*e4b17023SJohn Marino // Primary template. 1562*e4b17023SJohn Marino /// make_signed 1563*e4b17023SJohn Marino template<typename _Tp> 1564*e4b17023SJohn Marino struct make_signed 1565*e4b17023SJohn Marino { typedef typename __make_signed_selector<_Tp>::__type type; }; 1566*e4b17023SJohn Marino 1567*e4b17023SJohn Marino // Integral, but don't define. 1568*e4b17023SJohn Marino template<> 1569*e4b17023SJohn Marino struct make_signed<bool>; 1570*e4b17023SJohn Marino 1571*e4b17023SJohn Marino 1572*e4b17023SJohn Marino // array modifications. 1573*e4b17023SJohn Marino 1574*e4b17023SJohn Marino /// remove_extent 1575*e4b17023SJohn Marino template<typename _Tp> 1576*e4b17023SJohn Marino struct remove_extent 1577*e4b17023SJohn Marino { typedef _Tp type; }; 1578*e4b17023SJohn Marino 1579*e4b17023SJohn Marino template<typename _Tp, std::size_t _Size> 1580*e4b17023SJohn Marino struct remove_extent<_Tp[_Size]> 1581*e4b17023SJohn Marino { typedef _Tp type; }; 1582*e4b17023SJohn Marino 1583*e4b17023SJohn Marino template<typename _Tp> 1584*e4b17023SJohn Marino struct remove_extent<_Tp[]> 1585*e4b17023SJohn Marino { typedef _Tp type; }; 1586*e4b17023SJohn Marino 1587*e4b17023SJohn Marino /// remove_all_extents 1588*e4b17023SJohn Marino template<typename _Tp> 1589*e4b17023SJohn Marino struct remove_all_extents 1590*e4b17023SJohn Marino { typedef _Tp type; }; 1591*e4b17023SJohn Marino 1592*e4b17023SJohn Marino template<typename _Tp, std::size_t _Size> 1593*e4b17023SJohn Marino struct remove_all_extents<_Tp[_Size]> 1594*e4b17023SJohn Marino { typedef typename remove_all_extents<_Tp>::type type; }; 1595*e4b17023SJohn Marino 1596*e4b17023SJohn Marino template<typename _Tp> 1597*e4b17023SJohn Marino struct remove_all_extents<_Tp[]> 1598*e4b17023SJohn Marino { typedef typename remove_all_extents<_Tp>::type type; }; 1599*e4b17023SJohn Marino 1600*e4b17023SJohn Marino 1601*e4b17023SJohn Marino // pointer modifications. 1602*e4b17023SJohn Marino 1603*e4b17023SJohn Marino template<typename _Tp, typename> 1604*e4b17023SJohn Marino struct __remove_pointer_helper 1605*e4b17023SJohn Marino { typedef _Tp type; }; 1606*e4b17023SJohn Marino 1607*e4b17023SJohn Marino template<typename _Tp, typename _Up> 1608*e4b17023SJohn Marino struct __remove_pointer_helper<_Tp, _Up*> 1609*e4b17023SJohn Marino { typedef _Up type; }; 1610*e4b17023SJohn Marino 1611*e4b17023SJohn Marino /// remove_pointer 1612*e4b17023SJohn Marino template<typename _Tp> 1613*e4b17023SJohn Marino struct remove_pointer 1614*e4b17023SJohn Marino : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> 1615*e4b17023SJohn Marino { }; 1616*e4b17023SJohn Marino 1617*e4b17023SJohn Marino /// add_pointer 1618*e4b17023SJohn Marino template<typename _Tp> 1619*e4b17023SJohn Marino struct add_pointer 1620*e4b17023SJohn Marino { typedef typename remove_reference<_Tp>::type* type; }; 1621*e4b17023SJohn Marino 1622*e4b17023SJohn Marino 1623*e4b17023SJohn Marino template<std::size_t _Len> 1624*e4b17023SJohn Marino struct __aligned_storage_msa 1625*e4b17023SJohn Marino { 1626*e4b17023SJohn Marino union __type 1627*e4b17023SJohn Marino { 1628*e4b17023SJohn Marino unsigned char __data[_Len]; 1629*e4b17023SJohn Marino struct __attribute__((__aligned__)) { } __align; 1630*e4b17023SJohn Marino }; 1631*e4b17023SJohn Marino }; 1632*e4b17023SJohn Marino 1633*e4b17023SJohn Marino /** 1634*e4b17023SJohn Marino * @brief Alignment type. 1635*e4b17023SJohn Marino * 1636*e4b17023SJohn Marino * The value of _Align is a default-alignment which shall be the 1637*e4b17023SJohn Marino * most stringent alignment requirement for any C++ object type 1638*e4b17023SJohn Marino * whose size is no greater than _Len (3.9). The member typedef 1639*e4b17023SJohn Marino * type shall be a POD type suitable for use as uninitialized 1640*e4b17023SJohn Marino * storage for any object whose size is at most _Len and whose 1641*e4b17023SJohn Marino * alignment is a divisor of _Align. 1642*e4b17023SJohn Marino */ 1643*e4b17023SJohn Marino template<std::size_t _Len, std::size_t _Align = 1644*e4b17023SJohn Marino __alignof__(typename __aligned_storage_msa<_Len>::__type)> 1645*e4b17023SJohn Marino struct aligned_storage 1646*e4b17023SJohn Marino { 1647*e4b17023SJohn Marino union type 1648*e4b17023SJohn Marino { 1649*e4b17023SJohn Marino unsigned char __data[_Len]; 1650*e4b17023SJohn Marino struct __attribute__((__aligned__((_Align)))) { } __align; 1651*e4b17023SJohn Marino }; 1652*e4b17023SJohn Marino }; 1653*e4b17023SJohn Marino 1654*e4b17023SJohn Marino 1655*e4b17023SJohn Marino // Decay trait for arrays and functions, used for perfect forwarding 1656*e4b17023SJohn Marino // in make_pair, make_tuple, etc. 1657*e4b17023SJohn Marino template<typename _Up, 1658*e4b17023SJohn Marino bool _IsArray = is_array<_Up>::value, 1659*e4b17023SJohn Marino bool _IsFunction = is_function<_Up>::value> 1660*e4b17023SJohn Marino struct __decay_selector; 1661*e4b17023SJohn Marino 1662*e4b17023SJohn Marino // NB: DR 705. 1663*e4b17023SJohn Marino template<typename _Up> 1664*e4b17023SJohn Marino struct __decay_selector<_Up, false, false> 1665*e4b17023SJohn Marino { typedef typename remove_cv<_Up>::type __type; }; 1666*e4b17023SJohn Marino 1667*e4b17023SJohn Marino template<typename _Up> 1668*e4b17023SJohn Marino struct __decay_selector<_Up, true, false> 1669*e4b17023SJohn Marino { typedef typename remove_extent<_Up>::type* __type; }; 1670*e4b17023SJohn Marino 1671*e4b17023SJohn Marino template<typename _Up> 1672*e4b17023SJohn Marino struct __decay_selector<_Up, false, true> 1673*e4b17023SJohn Marino { typedef typename add_pointer<_Up>::type __type; }; 1674*e4b17023SJohn Marino 1675*e4b17023SJohn Marino /// decay 1676*e4b17023SJohn Marino template<typename _Tp> 1677*e4b17023SJohn Marino class decay 1678*e4b17023SJohn Marino { 1679*e4b17023SJohn Marino typedef typename remove_reference<_Tp>::type __remove_type; 1680*e4b17023SJohn Marino 1681*e4b17023SJohn Marino public: 1682*e4b17023SJohn Marino typedef typename __decay_selector<__remove_type>::__type type; 1683*e4b17023SJohn Marino }; 1684*e4b17023SJohn Marino 1685*e4b17023SJohn Marino template<typename _Tp> 1686*e4b17023SJohn Marino class reference_wrapper; 1687*e4b17023SJohn Marino 1688*e4b17023SJohn Marino // Helper which adds a reference to a type when given a reference_wrapper 1689*e4b17023SJohn Marino template<typename _Tp> 1690*e4b17023SJohn Marino struct __strip_reference_wrapper 1691*e4b17023SJohn Marino { 1692*e4b17023SJohn Marino typedef _Tp __type; 1693*e4b17023SJohn Marino }; 1694*e4b17023SJohn Marino 1695*e4b17023SJohn Marino template<typename _Tp> 1696*e4b17023SJohn Marino struct __strip_reference_wrapper<reference_wrapper<_Tp> > 1697*e4b17023SJohn Marino { 1698*e4b17023SJohn Marino typedef _Tp& __type; 1699*e4b17023SJohn Marino }; 1700*e4b17023SJohn Marino 1701*e4b17023SJohn Marino template<typename _Tp> 1702*e4b17023SJohn Marino struct __strip_reference_wrapper<const reference_wrapper<_Tp> > 1703*e4b17023SJohn Marino { 1704*e4b17023SJohn Marino typedef _Tp& __type; 1705*e4b17023SJohn Marino }; 1706*e4b17023SJohn Marino 1707*e4b17023SJohn Marino template<typename _Tp> 1708*e4b17023SJohn Marino struct __decay_and_strip 1709*e4b17023SJohn Marino { 1710*e4b17023SJohn Marino typedef typename __strip_reference_wrapper< 1711*e4b17023SJohn Marino typename decay<_Tp>::type>::__type __type; 1712*e4b17023SJohn Marino }; 1713*e4b17023SJohn Marino 1714*e4b17023SJohn Marino 1715*e4b17023SJohn Marino // Primary template. 1716*e4b17023SJohn Marino /// Define a member typedef @c type only if a boolean constant is true. 1717*e4b17023SJohn Marino template<bool, typename _Tp = void> 1718*e4b17023SJohn Marino struct enable_if 1719*e4b17023SJohn Marino { }; 1720*e4b17023SJohn Marino 1721*e4b17023SJohn Marino // Partial specialization for true. 1722*e4b17023SJohn Marino template<typename _Tp> 1723*e4b17023SJohn Marino struct enable_if<true, _Tp> 1724*e4b17023SJohn Marino { typedef _Tp type; }; 1725*e4b17023SJohn Marino 1726*e4b17023SJohn Marino 1727*e4b17023SJohn Marino // Primary template. 1728*e4b17023SJohn Marino /// Define a member typedef @c type to one of two argument types. 1729*e4b17023SJohn Marino template<bool _Cond, typename _Iftrue, typename _Iffalse> 1730*e4b17023SJohn Marino struct conditional 1731*e4b17023SJohn Marino { typedef _Iftrue type; }; 1732*e4b17023SJohn Marino 1733*e4b17023SJohn Marino // Partial specialization for false. 1734*e4b17023SJohn Marino template<typename _Iftrue, typename _Iffalse> 1735*e4b17023SJohn Marino struct conditional<false, _Iftrue, _Iffalse> 1736*e4b17023SJohn Marino { typedef _Iffalse type; }; 1737*e4b17023SJohn Marino 1738*e4b17023SJohn Marino 1739*e4b17023SJohn Marino /// common_type 1740*e4b17023SJohn Marino template<typename... _Tp> 1741*e4b17023SJohn Marino struct common_type; 1742*e4b17023SJohn Marino 1743*e4b17023SJohn Marino template<typename _Tp> 1744*e4b17023SJohn Marino struct common_type<_Tp> 1745*e4b17023SJohn Marino { typedef _Tp type; }; 1746*e4b17023SJohn Marino 1747*e4b17023SJohn Marino template<typename _Tp, typename _Up> 1748*e4b17023SJohn Marino struct common_type<_Tp, _Up> 1749*e4b17023SJohn Marino { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; }; 1750*e4b17023SJohn Marino 1751*e4b17023SJohn Marino template<typename _Tp, typename _Up, typename... _Vp> 1752*e4b17023SJohn Marino struct common_type<_Tp, _Up, _Vp...> 1753*e4b17023SJohn Marino { 1754*e4b17023SJohn Marino typedef typename 1755*e4b17023SJohn Marino common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; 1756*e4b17023SJohn Marino }; 1757*e4b17023SJohn Marino 1758*e4b17023SJohn Marino /// The underlying type of an enum. 1759*e4b17023SJohn Marino template<typename _Tp> 1760*e4b17023SJohn Marino struct underlying_type 1761*e4b17023SJohn Marino { 1762*e4b17023SJohn Marino typedef __underlying_type(_Tp) type; 1763*e4b17023SJohn Marino }; 1764*e4b17023SJohn Marino 1765*e4b17023SJohn Marino template<typename _Tp> 1766*e4b17023SJohn Marino struct __declval_protector 1767*e4b17023SJohn Marino { 1768*e4b17023SJohn Marino static const bool __stop = false; 1769*e4b17023SJohn Marino static typename add_rvalue_reference<_Tp>::type __delegate(); 1770*e4b17023SJohn Marino }; 1771*e4b17023SJohn Marino 1772*e4b17023SJohn Marino template<typename _Tp> 1773*e4b17023SJohn Marino inline typename add_rvalue_reference<_Tp>::type 1774*e4b17023SJohn Marino declval() noexcept 1775*e4b17023SJohn Marino { 1776*e4b17023SJohn Marino static_assert(__declval_protector<_Tp>::__stop, 1777*e4b17023SJohn Marino "declval() must not be used!"); 1778*e4b17023SJohn Marino return __declval_protector<_Tp>::__delegate(); 1779*e4b17023SJohn Marino } 1780*e4b17023SJohn Marino 1781*e4b17023SJohn Marino /// result_of 1782*e4b17023SJohn Marino template<typename _Signature> 1783*e4b17023SJohn Marino class result_of; 1784*e4b17023SJohn Marino 1785*e4b17023SJohn Marino template<typename _MemPtr, typename _Arg> 1786*e4b17023SJohn Marino struct _Result_of_memobj; 1787*e4b17023SJohn Marino 1788*e4b17023SJohn Marino template<typename _Res, typename _Class, typename _Arg> 1789*e4b17023SJohn Marino struct _Result_of_memobj<_Res _Class::*, _Arg> 1790*e4b17023SJohn Marino { 1791*e4b17023SJohn Marino private: 1792*e4b17023SJohn Marino typedef _Res _Class::* _Func; 1793*e4b17023SJohn Marino 1794*e4b17023SJohn Marino template<typename _Tp> 1795*e4b17023SJohn Marino static _Tp _S_get(const _Class&); 1796*e4b17023SJohn Marino template<typename _Tp> 1797*e4b17023SJohn Marino static decltype(*std::declval<_Tp>()) _S_get(...); 1798*e4b17023SJohn Marino 1799*e4b17023SJohn Marino public: 1800*e4b17023SJohn Marino typedef 1801*e4b17023SJohn Marino decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) 1802*e4b17023SJohn Marino __type; 1803*e4b17023SJohn Marino }; 1804*e4b17023SJohn Marino 1805*e4b17023SJohn Marino template<typename _MemPtr, typename _Arg, typename... _ArgTypes> 1806*e4b17023SJohn Marino struct _Result_of_memfun; 1807*e4b17023SJohn Marino 1808*e4b17023SJohn Marino template<typename _Res, typename _Class, typename _Arg, typename... _Args> 1809*e4b17023SJohn Marino struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...> 1810*e4b17023SJohn Marino { 1811*e4b17023SJohn Marino private: 1812*e4b17023SJohn Marino typedef _Res _Class::* _Func; 1813*e4b17023SJohn Marino 1814*e4b17023SJohn Marino template<typename _Tp> 1815*e4b17023SJohn Marino static _Tp _S_get(const _Class&); 1816*e4b17023SJohn Marino template<typename _Tp> 1817*e4b17023SJohn Marino static decltype(*std::declval<_Tp>()) _S_get(...); 1818*e4b17023SJohn Marino 1819*e4b17023SJohn Marino public: 1820*e4b17023SJohn Marino typedef 1821*e4b17023SJohn Marino decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) 1822*e4b17023SJohn Marino (std::declval<_Args>()...) ) 1823*e4b17023SJohn Marino __type; 1824*e4b17023SJohn Marino }; 1825*e4b17023SJohn Marino 1826*e4b17023SJohn Marino template<bool, bool, typename _Functor, typename... _ArgTypes> 1827*e4b17023SJohn Marino struct _Result_of_impl; 1828*e4b17023SJohn Marino 1829*e4b17023SJohn Marino template<typename _Functor, typename... _ArgTypes> 1830*e4b17023SJohn Marino struct _Result_of_impl<false, false, _Functor, _ArgTypes...> 1831*e4b17023SJohn Marino { 1832*e4b17023SJohn Marino typedef 1833*e4b17023SJohn Marino decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) ) 1834*e4b17023SJohn Marino __type; 1835*e4b17023SJohn Marino }; 1836*e4b17023SJohn Marino 1837*e4b17023SJohn Marino template<typename _MemPtr, typename _Arg> 1838*e4b17023SJohn Marino struct _Result_of_impl<true, false, _MemPtr, _Arg> 1839*e4b17023SJohn Marino : _Result_of_memobj<typename remove_reference<_MemPtr>::type, _Arg> 1840*e4b17023SJohn Marino { 1841*e4b17023SJohn Marino typedef typename _Result_of_memobj< 1842*e4b17023SJohn Marino typename remove_reference<_MemPtr>::type, _Arg>::__type 1843*e4b17023SJohn Marino __type; 1844*e4b17023SJohn Marino }; 1845*e4b17023SJohn Marino 1846*e4b17023SJohn Marino template<typename _MemPtr, typename _Arg, typename... _ArgTypes> 1847*e4b17023SJohn Marino struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...> 1848*e4b17023SJohn Marino : _Result_of_memfun<typename remove_reference<_MemPtr>::type, _Arg, 1849*e4b17023SJohn Marino _ArgTypes...> 1850*e4b17023SJohn Marino { 1851*e4b17023SJohn Marino typedef typename _Result_of_memfun< 1852*e4b17023SJohn Marino typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type 1853*e4b17023SJohn Marino __type; 1854*e4b17023SJohn Marino }; 1855*e4b17023SJohn Marino 1856*e4b17023SJohn Marino template<typename _Functor, typename... _ArgTypes> 1857*e4b17023SJohn Marino struct result_of<_Functor(_ArgTypes...)> 1858*e4b17023SJohn Marino : _Result_of_impl<is_member_object_pointer< 1859*e4b17023SJohn Marino typename remove_reference<_Functor>::type >::value, 1860*e4b17023SJohn Marino is_member_function_pointer< 1861*e4b17023SJohn Marino typename remove_reference<_Functor>::type >::value, 1862*e4b17023SJohn Marino _Functor, _ArgTypes...> 1863*e4b17023SJohn Marino { 1864*e4b17023SJohn Marino typedef typename _Result_of_impl< 1865*e4b17023SJohn Marino is_member_object_pointer< 1866*e4b17023SJohn Marino typename remove_reference<_Functor>::type >::value, 1867*e4b17023SJohn Marino is_member_function_pointer< 1868*e4b17023SJohn Marino typename remove_reference<_Functor>::type >::value, 1869*e4b17023SJohn Marino _Functor, _ArgTypes...>::__type 1870*e4b17023SJohn Marino type; 1871*e4b17023SJohn Marino }; 1872*e4b17023SJohn Marino 1873*e4b17023SJohn Marino /** 1874*e4b17023SJohn Marino * Use SFINAE to determine if the type _Tp has a publicly-accessible 1875*e4b17023SJohn Marino * member type _NTYPE. 1876*e4b17023SJohn Marino */ 1877*e4b17023SJohn Marino#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ 1878*e4b17023SJohn Marino template<typename _Tp> \ 1879*e4b17023SJohn Marino class __has_##_NTYPE##_helper \ 1880*e4b17023SJohn Marino : __sfinae_types \ 1881*e4b17023SJohn Marino { \ 1882*e4b17023SJohn Marino template<typename _Up> \ 1883*e4b17023SJohn Marino struct _Wrap_type \ 1884*e4b17023SJohn Marino { }; \ 1885*e4b17023SJohn Marino \ 1886*e4b17023SJohn Marino template<typename _Up> \ 1887*e4b17023SJohn Marino static __one __test(_Wrap_type<typename _Up::_NTYPE>*); \ 1888*e4b17023SJohn Marino \ 1889*e4b17023SJohn Marino template<typename _Up> \ 1890*e4b17023SJohn Marino static __two __test(...); \ 1891*e4b17023SJohn Marino \ 1892*e4b17023SJohn Marino public: \ 1893*e4b17023SJohn Marino static constexpr bool value = sizeof(__test<_Tp>(0)) == 1; \ 1894*e4b17023SJohn Marino }; \ 1895*e4b17023SJohn Marino \ 1896*e4b17023SJohn Marino template<typename _Tp> \ 1897*e4b17023SJohn Marino struct __has_##_NTYPE \ 1898*e4b17023SJohn Marino : integral_constant<bool, __has_##_NTYPE##_helper \ 1899*e4b17023SJohn Marino <typename remove_cv<_Tp>::type>::value> \ 1900*e4b17023SJohn Marino { }; 1901*e4b17023SJohn Marino 1902*e4b17023SJohn Marino /// @} group metaprogramming 1903*e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 1904*e4b17023SJohn Marino} // namespace 1905*e4b17023SJohn Marino 1906*e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__ 1907*e4b17023SJohn Marino 1908*e4b17023SJohn Marino#endif // _GLIBCXX_TYPE_TRAITS 1909