[libc++] Use builtin type traits whenever possible

This patch updates <type_traits> to use builtin type traits whenever
possible to improve compile times.

Differential Revision: https://reviews.llvm.org/D67900
This commit is contained in:
zoecarver 2020-03-19 09:54:53 -07:00
parent 88bf9b3d26
commit 5ade17e0ca
2 changed files with 396 additions and 6 deletions

View File

@ -544,6 +544,18 @@ template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp
// is_same
#if __has_keyword(__is_same)
template <class _Tp, class _Up>
struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v = __is_same(_Tp, _Up);
#endif
#else
template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};
@ -553,6 +565,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v
= is_same<_Tp, _Up>::value;
#endif
#endif // __is_same
template <class _Tp, class _Up>
using _IsSame = _BoolConstant<
#ifdef __clang__
@ -656,6 +670,18 @@ struct __two {char __lx[2];};
// is_const
#if __has_keyword(__is_const)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v = __is_const(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
@ -665,8 +691,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v
= is_const<_Tp>::value;
#endif
#endif // __has_keyword(__is_const)
// is_volatile
#if __has_keyword(__is_volatile)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v = __is_volatile(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
@ -676,37 +716,87 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v
= is_volatile<_Tp>::value;
#endif
#endif // __has_keyword(__is_volatile)
// remove_const
#if __has_keyword(__remove_const)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_const {typedef __remove_const(_Tp) type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_const_t = __remove_const(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;
#endif
#endif // __has_keyword(__remove_const)
// remove_volatile
#if __has_keyword(__remove_volatile)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef __remove_volatile(_Tp) type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_volatile_t = __remove_volatile(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;
#endif
#endif // __has_keyword(__remove_volatile)
// remove_cv
#if __has_keyword(__remove_cv)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_cv {typedef __remove_cv(_Tp) type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_cv_t = __remove_cv(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
{typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;
#endif
#endif // __has_keyword(__remove_cv)
// is_void
template <class _Tp> struct __libcpp_is_void : public false_type {};
template <> struct __libcpp_is_void<void> : public true_type {};
#if __has_keyword(__is_void)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v = __is_void(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void
: public __libcpp_is_void<typename remove_cv<_Tp>::type> {};
: public is_same<typename remove_cv<_Tp::type, void> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
@ -714,6 +804,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v
= is_void<_Tp>::value;
#endif
#endif // __has_keyword(__is_void)
// __is_nullptr_t
template <class _Tp> struct __is_nullptr_t_impl : public false_type {};
@ -735,6 +827,18 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_null_pointer_v
// is_integral
#if __has_keyword(__is_integral)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { };
#if _LIBCPP_STD_VER > 14
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v = __is_integral(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral
: public _BoolConstant<__libcpp_is_integral<typename remove_cv<_Tp>::type>::value> {};
@ -744,8 +848,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v
= is_integral<_Tp>::value;
#endif
#endif // __has_keyword(__is_integral)
// is_floating_point
#if __has_keyword(__is_floating_point)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_floating_point : _BoolConstant<__is_floating_point(_Tp)> { };
#if _LIBCPP_STD_VER > 14
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_floating_point_v = __is_floating_point(_Tp);
#endif
#else
template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
template <> struct __libcpp_is_floating_point<float> : public true_type {};
template <> struct __libcpp_is_floating_point<double> : public true_type {};
@ -760,8 +878,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_floating_point_v
= is_floating_point<_Tp>::value;
#endif
#endif // __has_keyword(__is_floating_point)
// is_array
#if __has_keyword(__is_array)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v = __is_array(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array
: public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]>
@ -775,6 +907,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v
= is_array<_Tp>::value;
#endif
#endif // __has_keyword(__is_array)
// is_pointer
template <class _Tp> struct __libcpp_is_pointer : public false_type {};
@ -788,6 +922,18 @@ template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing>
template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; };
#endif
#if __has_keyword(__is_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v = __is_pointer(_Tp);
#endif
#else // __has_keyword(__is_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer
: public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<typename remove_cv<_Tp>::type>::type> {};
@ -797,8 +943,36 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v
= is_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_pointer)
// is_reference
#if __has_keyword(__is_lvalue_reference) && \
__has_keyword(__is_rvalue_reference) && \
__has_keyword(__is_reference)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { };
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { };
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v = __is_reference(_Tp);
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
#endif
#else // __has_keyword(__is_lvalue_reference) && etc...
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
@ -822,6 +996,9 @@ template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v
= is_rvalue_reference<_Tp>::value;
#endif
#endif // __has_keyword(__is_lvalue_reference) && etc...
// is_union
#if __has_feature(is_union) || defined(_LIBCPP_COMPILER_GCC)
@ -902,6 +1079,19 @@ template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
};
};
#if __has_keyword(__is_member_function_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
: _BoolConstant<__is_member_function_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v
= __is_member_function_pointer(_Tp);
#endif
#else // __has_keyword(__is_member_function_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {};
@ -912,8 +1102,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v
= is_member_function_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_member_function_pointer)
// is_member_pointer
#if __has_keyword(__is_member_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v = __is_member_pointer(_Tp);
#endif
#else // __has_keyword(__is_member_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {};
@ -923,8 +1127,24 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v
= is_member_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_member_pointer)
// is_member_object_pointer
#if __has_keyword(__is_member_object_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
: _BoolConstant<__is_member_object_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
= __is_member_object_pointer(_Tp);
#endif
#else // __has_keyword(__is_member_object_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj > {};
@ -934,6 +1154,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
= is_member_object_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_member_object_pointer)
// is_enum
#if __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
@ -941,6 +1163,11 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
: public integral_constant<bool, __is_enum(_Tp)> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_enum_v = __is_enum(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
@ -955,16 +1182,28 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
!is_class<_Tp>::value &&
!is_function<_Tp>::value > {};
#endif
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_enum_v
= is_enum<_Tp>::value;
#endif
#endif // __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
// is_arithmetic
#if __has_keyword(__is_arithmetic)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_arithmetic : _BoolConstant<__is_arithmetic(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_arithmetic_v = __is_arithmetic(_Tp);
#endif
#else // __has_keyword(__is_arithmetic)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic
: public integral_constant<bool, is_integral<_Tp>::value ||
is_floating_point<_Tp>::value> {};
@ -975,8 +1214,23 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_arithmetic_v
= is_arithmetic<_Tp>::value;
#endif
#endif // __has_keyword(__is_arithmetic)
// is_fundamental
// In clang 9 and lower, this builtin did not work for nullptr_t
#if __has_keyword(__is_fundamental) && _LIBCPP_CLANG_VER > 900
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v = __is_fundamental(_Tp);
#endif
#else // __has_keyword(__is_fundamental)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental
: public integral_constant<bool, is_void<_Tp>::value ||
__is_nullptr_t<_Tp>::value ||
@ -988,8 +1242,23 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v
= is_fundamental<_Tp>::value;
#endif
#endif // __has_keyword(__is_fundamental)
// is_scalar
// >= 11 because in C++03 nullptr isn't actually nullptr
#if __has_keyword(__is_scalar) && !defined(_LIBCPP_CXX03_LANG)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_scalar_v = __is_scalar(_Tp);
#endif
#else // __has_keyword(__is_scalar)
template <class _Tp> struct __is_block : false_type {};
#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {};
@ -1011,8 +1280,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_scalar_v
= is_scalar<_Tp>::value;
#endif
#endif // __has_keyword(__is_scalar)
// is_object
#if __has_keyword(__is_object)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_object_v = __is_object(_Tp);
#endif
#else // __has_keyword(__is_object)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
: public integral_constant<bool, is_scalar<_Tp>::value ||
is_array<_Tp>::value ||
@ -1025,8 +1308,23 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_object_v
= is_object<_Tp>::value;
#endif
#endif // __has_keyword(__is_object)
// is_compound
// >= 11 because in C++03 nullptr isn't actually nullptr
#if __has_keyword(__is_compound) && !defined(_LIBCPP_CXX03_LANG)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_compound_v = __is_compound(_Tp);
#endif
#else // __has_keyword(__is_compound)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound
: public integral_constant<bool, !is_fundamental<_Tp>::value> {};
@ -1036,6 +1334,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_compound_v
= is_compound<_Tp>::value;
#endif
#endif // __has_keyword(__is_compound)
// __is_referenceable [defns.referenceable]
@ -1080,6 +1379,13 @@ template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
// remove_reference
#if __has_keyword(__remove_reference)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_reference { typedef __remove_reference(_Tp) type; };
#else // __has_keyword(__remove_reference)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
@ -1088,6 +1394,8 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typede
template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;
#endif
#endif // __has_keyword(__remove_reference)
// add_lvalue_reference
template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
@ -1195,6 +1503,19 @@ template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
// is_signed
// In clang 9 and earlier, this builtin did not work for floating points or enums
#if __has_keyword(__is_signed) && _LIBCPP_CLANG_VER > 900
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v = __is_signed(_Tp);
#endif
#else // __has_keyword(__is_signed)
template <class _Tp, bool = is_integral<_Tp>::value>
struct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {};
@ -1214,8 +1535,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v
= is_signed<_Tp>::value;
#endif
#endif // __has_keyword(__is_signed)
// is_unsigned
#if __has_keyword(__is_unsigned)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v = __is_unsigned(_Tp);
#endif
#else // __has_keyword(__is_unsigned)
template <class _Tp, bool = is_integral<_Tp>::value>
struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {};
@ -1235,6 +1570,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v
= is_unsigned<_Tp>::value;
#endif
#endif // __has_keyword(__is_unsigned)
// rank
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank
@ -1252,6 +1589,19 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t rank_v
// extent
#if __has_keyword(__array_extent)
template<class _Tp, size_t _Dim = 0>
struct _LIBCPP_TEMPLATE_VIS extent
: integral_constant<size_t, __array_extent(_Tp, _Dim)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, unsigned _Ip = 0>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t extent_v = __array_extent(_Tp, _Ip);
#endif
#else // __has_keyword(__array_extent)
template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent
: public integral_constant<size_t, 0> {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0>
@ -1269,6 +1619,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t extent_v
= extent<_Tp, _Ip>::value;
#endif
#endif // __has_keyword(__array_extent)
// remove_extent
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent
@ -2114,6 +2466,18 @@ template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type
template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
#if __has_keyword(__is_assignable)
template<class _Tp, class _Up>
struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Arg>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v = __is_assignable(_Tp, _Arg);
#endif
#else // __has_keyword(__is_assignable)
template <class _Tp, class _Arg>
typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type
__is_assignable_test(int);
@ -2142,6 +2506,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v
= is_assignable<_Tp, _Arg>::value;
#endif
#endif // __has_keyword(__is_assignable)
// is_copy_assignable
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_assignable
@ -2168,6 +2534,18 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_assignable_v
// is_destructible
#if __has_keyword(__is_destructible)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v = __is_destructible(_Tp);
#endif
#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 +2608,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v
= is_destructible<_Tp>::value;
#endif
#endif // __has_keyword(__is_destructible)
// move
template <class _Tp>
@ -3859,7 +4239,6 @@ struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
#endif
template <class _Tp, bool = is_enum<_Tp>::value>
struct __sfinae_underlying_type
{

View File

@ -50,6 +50,14 @@ void test_is_not_same()
static_assert((!std::is_same<T, U>::value), "");
}
template <class T>
struct OverloadTest
{
void fn(std::is_same<T, int>) { }
void fn(std::false_type) { }
void x() { fn(std::false_type()); }
};
class Class
{
public:
@ -70,5 +78,8 @@ int main(int, char**)
test_is_not_same<int*, int&>();
test_is_not_same<int&, int>();
OverloadTest<char> t;
(void)t;
return 0;
}