[libc++] Simplify type_traits and use more builtins

Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D127226
This commit is contained in:
Nikolas Klauser 2022-06-10 11:38:04 +02:00
parent 0ff51d5dde
commit 42f8f55798
16 changed files with 42 additions and 105 deletions

View File

@ -23,7 +23,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_abstract
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_abstract_v = is_abstract<_Tp>::value;
inline constexpr bool is_abstract_v = __is_abstract(_Tp);
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -24,7 +24,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS
is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {};
template <class _Tp>
inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value;
inline constexpr bool is_aggregate_v = __is_aggregate(_Tp);
#endif // _LIBCPP_STD_VER > 14

View File

@ -20,10 +20,19 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if __has_keyword(__is_arithmetic)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_arithmetic : integral_constant<bool, __is_arithmetic(_Tp)> {};
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic
: public integral_constant<bool, is_integral<_Tp>::value ||
is_floating_point<_Tp>::value> {};
#endif // __has_keyword(__is_arithmetic)
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;

View File

@ -24,7 +24,7 @@ struct _LIBCPP_TEMPLATE_VIS is_base_of
#if _LIBCPP_STD_VER > 14
template <class _Bp, class _Dp>
inline constexpr bool is_base_of_v = is_base_of<_Bp, _Dp>::value;
inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp);
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -20,27 +20,12 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if __has_feature(is_class) || defined(_LIBCPP_COMPILER_GCC)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class
: public integral_constant<bool, __is_class(_Tp)> {};
#else
namespace __is_class_imp
{
template <class _Tp> true_type __test(int _Tp::*);
template <class _Tp> false_type __test(...);
}
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class
: public integral_constant<bool, decltype(__is_class_imp::__test<_Tp>(0))::value && !is_union<_Tp>::value> {};
#endif
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_class_v = is_class<_Tp>::value;
inline constexpr bool is_class_v = __is_class(_Tp);
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -19,8 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// >= 11 because in C++03 nullptr isn't actually nullptr
#if __has_keyword(__is_compound) && !defined(_LIBCPP_CXX03_LANG)
#if __has_keyword(__is_compound)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };

View File

@ -18,38 +18,13 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if __has_feature(is_empty) || defined(_LIBCPP_COMPILER_GCC)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_empty
: public integral_constant<bool, __is_empty(_Tp)> {};
#else // __has_feature(is_empty)
template <class _Tp>
struct __is_empty1
: public _Tp
{
double __lx;
};
struct __is_empty2
{
double __lx;
};
template <class _Tp, bool = is_class<_Tp>::value>
struct __libcpp_empty : public integral_constant<bool, sizeof(__is_empty1<_Tp>) == sizeof(__is_empty2)> {};
template <class _Tp> struct __libcpp_empty<_Tp, false> : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_empty : public __libcpp_empty<_Tp> {};
#endif // __has_feature(is_empty)
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_empty_v = is_empty<_Tp>::value;
inline constexpr bool is_empty_v = __is_empty(_Tp);
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -19,8 +19,6 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
: public integral_constant<bool, __is_enum(_Tp)> {};
@ -29,27 +27,6 @@ template <class _Tp>
inline constexpr bool is_enum_v = __is_enum(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
: public integral_constant<bool, !is_void<_Tp>::value &&
!is_integral<_Tp>::value &&
!is_floating_point<_Tp>::value &&
!is_array<_Tp>::value &&
!is_pointer<_Tp>::value &&
!is_reference<_Tp>::value &&
!is_member_pointer<_Tp>::value &&
!is_union<_Tp>::value &&
!is_class<_Tp>::value &&
!is_function<_Tp>::value > {};
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_enum_v = is_enum<_Tp>::value;
#endif
#endif // __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___TYPE_TRAITS_IS_ENUM_H

View File

@ -28,7 +28,7 @@ is_final : public integral_constant<bool, __is_final(_Tp)> {};
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_final_v = is_final<_Tp>::value;
inline constexpr bool is_final_v = __is_final(_Tp);
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -19,6 +19,13 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if __has_keyword(__is_floating_point)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_floating_point : integral_constant<bool, __is_floating_point(_Tp)> {};
#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 {};
@ -27,6 +34,8 @@ template <> struct __libcpp_is_floating_point<long double> : public tru
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_floating_point
: public __libcpp_is_floating_point<typename remove_cv<_Tp>::type> {};
#endif // __has_keyword(__is_floating_point)
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;

View File

@ -20,15 +20,18 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_function
: public _BoolConstant<
#ifdef __clang__
__is_function(_Tp)
#else
!(is_reference<_Tp>::value || is_const<const _Tp>::value)
#endif
> {};
#if __has_keyword(__is_function)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_function : integral_constant<bool, __is_function(_Tp)> {};
#else
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_function
: public integral_constant<bool, !(is_reference<_Tp>::value || is_const<const _Tp>::value)> {};
#endif // __has_keyword(__is_function)
#if _LIBCPP_STD_VER > 14
template <class _Tp>

View File

@ -20,11 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// Before Clang 10, __is_fundamental didn't work for nullptr_t.
// In C++03 nullptr_t is library-provided but must still count as "fundamental."
#if __has_keyword(__is_fundamental) && \
!(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1000) && \
!defined(_LIBCPP_CXX03_LANG)
#if __has_keyword(__is_fundamental)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };

View File

@ -19,9 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// Before AppleClang 12.0.5, __is_pointer didn't work for Objective-C types.
#if __has_keyword(__is_pointer) && \
!(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1205)
#if __has_keyword(__is_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };

View File

@ -22,8 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// In C++03 nullptr_t is library-provided but must still count as "scalar."
#if __has_keyword(__is_scalar) && !defined(_LIBCPP_CXX03_LANG)
#if __has_keyword(__is_scalar)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };

View File

@ -19,22 +19,12 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if __has_feature(is_union) || defined(_LIBCPP_COMPILER_GCC)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union
: public integral_constant<bool, __is_union(_Tp)> {};
#else
template <class _Tp> struct __libcpp_union : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union
: public __libcpp_union<typename remove_cv<_Tp>::type> {};
#endif
#if _LIBCPP_STD_VER > 14
template <class _Tp>
inline constexpr bool is_union_v = is_union<_Tp>::value;
inline constexpr bool is_union_v = __is_union(_Tp);
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -20,11 +20,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// Before Clang 13, __is_unsigned returned true for enums with signed underlying type.
// No currently-released version of AppleClang contains the fixed intrinsic.
#if __has_keyword(__is_unsigned) && \
!(defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1300) && \
!defined(_LIBCPP_APPLE_CLANG_VER)
// Before AppleClang 14, __is_unsigned returned true for enums with signed underlying type.
#if __has_keyword(__is_unsigned) && !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1400)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };