diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -544,9 +544,18 @@ // is_same +#if __has_keyword(__is_same) + +template +using is_same = _BoolConstant<__is_same(_Tp, _Up)>; + +#else + template struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {}; template struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {}; +#endif // __is_same + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v @@ -645,9 +654,18 @@ // is_const +#if __has_keyword(__is_const) + +template +using is_const = _BoolConstant<__is_const(_Tp)>; + +#else + template struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {}; template struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {}; +#endif // __has_keyword(__is_const) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v @@ -656,9 +674,18 @@ // is_volatile +#if __has_keyword(__is_volatile) + +template +using is_volatile = _BoolConstant<__is_volatile(_Tp)>; + +#else + template struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {}; template struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {}; +#endif // __has_keyword(__is_volatile) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v @@ -667,36 +694,79 @@ // remove_const +#if __has_keyword(__remove_const) + +template +struct _LIBCPP_TEMPLATE_VIS remove_const {typedef __remove_const(_Tp) type;}; + +#else + template struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;}; template struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;}; + +#endif // __has_keyword(__remove_const) + #if _LIBCPP_STD_VER > 11 template using remove_const_t = typename remove_const<_Tp>::type; #endif // remove_volatile +#if __has_keyword(__remove_volatile) + +template +struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef __remove_volatile(_Tp) type;}; + +#else + template struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;}; template struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;}; + +#endif // __has_keyword(__remove_volatile) + #if _LIBCPP_STD_VER > 11 template using remove_volatile_t = typename remove_volatile<_Tp>::type; #endif // remove_cv +#if __has_keyword(__remove_cv) + +template +struct _LIBCPP_TEMPLATE_VIS remove_cv {typedef __remove_cv(_Tp) type;}; + +#else + template struct _LIBCPP_TEMPLATE_VIS remove_cv {typedef typename remove_volatile::type>::type type;}; + +#endif // __has_keyword(__remove_cv) + #if _LIBCPP_STD_VER > 11 template using remove_cv_t = typename remove_cv<_Tp>::type; #endif // is_void +#if __has_keyword(__is_void) + +template +using is_void = _BoolConstant<__is_void(_Tp)>; + +// This is never used but, we define it anyway for consistency. +template +using __libcpp_is_void = _BoolConstant<__is_void(_Tp)>; + +#else + template struct __libcpp_is_void : public false_type {}; template <> struct __libcpp_is_void : public true_type {}; template struct _LIBCPP_TEMPLATE_VIS is_void : public __libcpp_is_void::type> {}; +#endif // __has_keyword(__is_void) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v @@ -750,6 +820,18 @@ template <> struct __libcpp_is_integral<__uint128_t> : public true_type {}; #endif +#if __has_keyword(__is_integral) + +template +using is_integral = _BoolConstant<__is_integral(_Tp)>; + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v = __is_integral(_Tp); +#endif + +#else + template struct _LIBCPP_TEMPLATE_VIS is_integral : public __libcpp_is_integral::type> {}; @@ -759,6 +841,8 @@ = is_integral<_Tp>::value; #endif +#endif // __has_keyword(__is_integral) + // is_floating_point template struct __libcpp_is_floating_point : public false_type {}; @@ -766,6 +850,18 @@ template <> struct __libcpp_is_floating_point : public true_type {}; template <> struct __libcpp_is_floating_point : public true_type {}; +#if __has_keyword(__is_floating_point) + +template +using is_floating_point = _BoolConstant<__is_floating_point(_Tp)>; + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_floating_point_v = __is_floating_point(_Tp); +#endif + +#else + template struct _LIBCPP_TEMPLATE_VIS is_floating_point : public __libcpp_is_floating_point::type> {}; @@ -775,8 +871,17 @@ = is_floating_point<_Tp>::value; #endif +#endif // __has_keyword(__is_floating_point) + // is_array +#if __has_keyword(__is_array) + +template +using is_array = _BoolConstant<__is_array(_Tp)>; + +#else + template struct _LIBCPP_TEMPLATE_VIS is_array : public false_type {}; template struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]> @@ -784,6 +889,8 @@ template struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]> : public true_type {}; +#endif // __has_keyword(__is_array) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v @@ -803,9 +910,18 @@ template struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; }; #endif +#if __has_keyword(__is_pointer) + +template +using is_pointer = _BoolConstant<__is_pointer(_Tp)>; + +#else // __has_keyword(__is_pointer) + template struct _LIBCPP_TEMPLATE_VIS is_pointer : public __libcpp_is_pointer::type>::type> {}; +#endif // __has_keyword(__is_pointer) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v @@ -814,6 +930,21 @@ // is_reference +#if __has_keyword(__is_lvalue_reference) && \ + __has_keyword(is_rvalue_reference) && \ + __has_keyword(is_reference) + +template +using is_lvalue_reference = _BoolConstant<__is_lvalue_reference(_Tp)>; + +template +using is_rvalue_reference = _BoolConstant<__is_rvalue_reference(_Tp)>; + +template +using is_reference = _BoolConstant<__is_reference(_Tp)>; + +#else // __has_keyword(__is_lvalue_reference) && etc... + template struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {}; template struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {}; @@ -824,6 +955,8 @@ template struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {}; template struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {}; +#endif // __has_keyword(__is_lvalue_reference) && etc... + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v @@ -837,6 +970,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value; #endif + // is_union #if __has_feature(is_union) || defined(_LIBCPP_COMPILER_GCC) @@ -917,10 +1051,18 @@ }; }; +#if __has_keyword(__is_member_function_pointer) + +template +using is_member_function_pointer = _BoolConstant<__is_member_function_pointer(_Tp)>; + +#else // __has_keyword(__is_member_function_pointer) template struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer : public _BoolConstant< __libcpp_is_member_pointer::type>::__is_func > {}; +#endif // __has_keyword(__is_member_function_pointer) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v @@ -929,9 +1071,18 @@ // is_member_pointer +#if __has_keyword(__is_member_pointer) + +template +using is_member_pointer = _BoolConstant<__is_member_pointer(_Tp)>; + +#else // __has_keyword(__is_member_pointer) + template struct _LIBCPP_TEMPLATE_VIS is_member_pointer : public _BoolConstant< __libcpp_is_member_pointer::type>::__is_member > {}; + #endif // __has_keyword(__is_member_pointer) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v @@ -940,9 +1091,18 @@ // is_member_object_pointer +#if __has_keyword(__is_member_object_pointer) + +template +using is_member_object_pointer = _BoolConstant<__is_member_object_pointer(_Tp)>; + +#else // __has_keyword(__is_member_object_pointer) + template struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer : public _BoolConstant< __libcpp_is_member_pointer::type>::__is_obj > {}; +#endif // __has_keyword(__is_member_object_pointer) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v @@ -980,10 +1140,19 @@ // is_arithmetic +#if __has_keyword(__is_arithmetic) + +template +using is_arithmetic = _BoolConstant<__is_arithmetic(_Tp)>; + +#else // __has_keyword(__is_arithmetic) + template struct _LIBCPP_TEMPLATE_VIS is_arithmetic : public integral_constant::value || is_floating_point<_Tp>::value> {}; +#endif // __has_keyword(__is_arithmetic) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_arithmetic_v @@ -992,11 +1161,20 @@ // is_fundamental +#if __has_keyword(__is_fundamental) && false // TODO: see D67899 + +template +using is_fundamental = _BoolConstant<__is_fundamental(_Tp)>; + +#else // __has_keyword(__is_fundamental) + template struct _LIBCPP_TEMPLATE_VIS is_fundamental : public integral_constant::value || __is_nullptr_t<_Tp>::value || is_arithmetic<_Tp>::value> {}; +#endif // __has_keyword(__is_fundamental) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v @@ -1005,6 +1183,13 @@ // is_scalar +#if __has_keyword(__is_scalar) + +template +using is_scalar = _BoolConstant<__is_scalar(_Tp)>; + +#else // __has_keyword(__is_scalar) + template struct _LIBCPP_TEMPLATE_VIS is_scalar : public integral_constant::value || is_member_pointer<_Tp>::value || @@ -1014,6 +1199,8 @@ template <> struct _LIBCPP_TEMPLATE_VIS is_scalar : public true_type {}; +#endif // __has_keyword(__is_scalar) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_scalar_v @@ -1022,12 +1209,21 @@ // is_object +#if __has_keyword(__is_object) + +template +using is_object = _BoolConstant<__is_object(_Tp)>; + +#else // __has_keyword(__is_object) + template struct _LIBCPP_TEMPLATE_VIS is_object : public integral_constant::value || is_array<_Tp>::value || is_union<_Tp>::value || is_class<_Tp>::value > {}; +#endif // __has_keyword(__is_object) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_object_v @@ -1036,9 +1232,18 @@ // is_compound +#if __has_keyword(__is_compound) + +template +using is_compound = _BoolConstant<__is_compound(_Tp)>; + +#else // __has_keyword(__is_compound) + template struct _LIBCPP_TEMPLATE_VIS is_compound : public integral_constant::value> {}; +#endif // __has_keyword(__is_compound) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_compound_v @@ -1089,32 +1294,61 @@ // remove_reference +#if __has_keyword(__remove_reference) + +template +struct remove_reference { typedef __remove_reference(_Tp) type; }; + +#else // __has_keyword(__remove_reference) + template struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; template struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; template struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; +#endif // __has_keyword(__remove_reference) + #if _LIBCPP_STD_VER > 11 template using remove_reference_t = typename remove_reference<_Tp>::type; #endif // add_lvalue_reference +#if __has_keyword(__add_lvalue_reference) + +template +struct add_lvalue_reference { typedef __add_lvalue_reference(_Tp) type; }; + +#else // __has_keyword(__add_lvalue_reference) + template ::value> struct __add_lvalue_reference_impl { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; template struct __add_lvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; }; template struct _LIBCPP_TEMPLATE_VIS add_lvalue_reference {typedef _LIBCPP_NODEBUG_TYPE typename __add_lvalue_reference_impl<_Tp>::type type;}; +#endif // __has_keyword(__add_lvalue_reference) + #if _LIBCPP_STD_VER > 11 template using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; #endif +// add_rvalue_reference + +#if __has_keyword(__add_rvalue_reference) + +template +struct add_rvalue_reference { typedef __add_rvalue_reference(_Tp) type; }; + +#else // __has_keyword(__add_rvalue_reference) + template ::value> struct __add_rvalue_reference_impl { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; template struct __add_rvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG_TYPE _Tp&& type; }; template struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference {typedef _LIBCPP_NODEBUG_TYPE typename __add_rvalue_reference_impl<_Tp>::type type;}; +#endif // __has_keyword(__add_rvalue_reference) + #if _LIBCPP_STD_VER > 11 template using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; #endif @@ -1200,6 +1434,13 @@ // is_signed +#if __has_keyword(__is_signed) && false // TODO: see D67897 + +template +using is_signed = _BoolConstant<__is_signed(_Tp)>; + +#else // __has_keyword(__is_signed) + template ::value> struct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {}; @@ -1213,6 +1454,8 @@ template struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {}; +#endif // __has_keyword(__is_signed) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v @@ -1221,6 +1464,13 @@ // is_unsigned +#if __has_keyword(__is_unsigned) + +template +using is_unsigned = _BoolConstant<__is_unsigned(_Tp)>; + +#else // __has_keyword(__is_unsigned) + template ::value> struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {}; @@ -1234,6 +1484,8 @@ template struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {}; +#endif // __has_keyword(__is_unsigned) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v @@ -1242,6 +1494,13 @@ // rank +#if __has_keyword(__array_rank) && false // TODO: investigate why this breaks clang + +template +using rank = integral_constant; + +#else // __has_keyword(__array_rank) + template struct _LIBCPP_TEMPLATE_VIS rank : public integral_constant {}; template struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]> @@ -1249,6 +1508,8 @@ template struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]> : public integral_constant::value + 1> {}; +#endif // __has_keyword(__array_rank) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t rank_v @@ -1257,6 +1518,13 @@ // extent +#if __has_keyword(__array_extent) + +template +using extent = integral_constant; + +#else // __has_keyword(__array_extent) + template struct _LIBCPP_TEMPLATE_VIS extent : public integral_constant {}; template struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0> @@ -1268,6 +1536,8 @@ template struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip> : public integral_constant::value> {}; +#endif // __has_keyword(__array_extent) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t extent_v @@ -2120,6 +2390,13 @@ template struct __select_2nd { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; +#if __has_keyword(__is_assignable) + +template +using is_assignable = _BoolConstant<__is_assignable(_Tp, _Up)>; + +#else // __has_keyword(__is_assignable) + template typename __select_2nd() = _VSTD::declval<_Arg>())), true_type>::type __is_assignable_test(int); @@ -2142,6 +2419,8 @@ struct is_assignable : public __is_assignable_imp<_Tp, _Arg> {}; +#endif // __has_keyword(__is_assignable) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v @@ -2174,6 +2453,13 @@ // is_destructible +#if __has_keyword(__is_destructible) + +template +using is_destructible = _BoolConstant<__is_destructible(_Tp)>; + +#else // __has_keyword(__is_destructible) + // if it's a reference, return true // if it's a function, return false // if it's void, return false @@ -2230,6 +2516,8 @@ struct is_destructible : public _VSTD::false_type {}; +#endif // __has_keyword(__is_destructible) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v