Revert "[libc++] Simplify type_traits and use more builtins"
authorManoj Gupta <manojgupta@google.com>
Sat, 25 Jun 2022 16:51:00 +0000 (09:51 -0700)
committerManoj Gupta <manojgupta@google.com>
Sat, 25 Jun 2022 19:38:05 +0000 (12:38 -0700)
This reverts commit 42f8f557989741434d7b7b4439b3eef3e68b2ab5.

Breaks float128 usage, test case provided in D127226.

Differential Revision: https://reviews.llvm.org/D128587

16 files changed:
libcxx/include/__type_traits/is_abstract.h
libcxx/include/__type_traits/is_aggregate.h
libcxx/include/__type_traits/is_arithmetic.h
libcxx/include/__type_traits/is_base_of.h
libcxx/include/__type_traits/is_class.h
libcxx/include/__type_traits/is_compound.h
libcxx/include/__type_traits/is_empty.h
libcxx/include/__type_traits/is_enum.h
libcxx/include/__type_traits/is_final.h
libcxx/include/__type_traits/is_floating_point.h
libcxx/include/__type_traits/is_function.h
libcxx/include/__type_traits/is_fundamental.h
libcxx/include/__type_traits/is_pointer.h
libcxx/include/__type_traits/is_scalar.h
libcxx/include/__type_traits/is_union.h
libcxx/include/__type_traits/is_unsigned.h

index c74b328..0480118 100644 (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);
+inline constexpr bool is_abstract_v = is_abstract<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
index ea9de84..f32aec8 100644 (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);
+inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value;
 
 #endif // _LIBCPP_STD_VER > 14
 
index cfe2fff..6d631f4 100644 (file)
 
 _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;
index 0e6dec0..b944a65 100644 (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);
+inline constexpr bool is_base_of_v = is_base_of<_Bp, _Dp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
index cddaeae..8e07a5e 100644 (file)
 
 _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);
+inline constexpr bool is_class_v = is_class<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
index 643edd7..f055155 100644 (file)
@@ -19,7 +19,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_keyword(__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)> { };
index 042b4e6..e81c6f7 100644 (file)
 
 _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);
+inline constexpr bool is_empty_v = is_empty<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
index bf6921c..ac160da 100644 (file)
@@ -19,6 +19,8 @@
 
 _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)> {};
 
@@ -27,6 +29,27 @@ 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
index 74ced23..f2d9b5b 100644 (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);
+inline constexpr bool is_final_v = is_final<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
index d6211af..d93e5d9 100644 (file)
 
 _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 {};
@@ -34,8 +27,6 @@ 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;
index bce980c..23ba9cb 100644 (file)
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_keyword(__is_function)
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_function : integral_constant<bool, __is_function(_Tp)> {};
-
+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
+    > {};
 
-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>
index aaa7063..859cfde 100644 (file)
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_keyword(__is_fundamental)
+// 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)
 
 template<class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
index 2139b03..ab66989 100644 (file)
@@ -19,7 +19,9 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_keyword(__is_pointer)
+// 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)
 
 template<class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
index 0ca34c7..f745bf5 100644 (file)
@@ -22,7 +22,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if __has_keyword(__is_scalar)
+// In C++03 nullptr_t is library-provided but must still count as "scalar."
+#if __has_keyword(__is_scalar) && !defined(_LIBCPP_CXX03_LANG)
 
 template<class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
index 3e8cffe..d02931f 100644 (file)
 
 _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);
+inline constexpr bool is_union_v = is_union<_Tp>::value;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD
index bb279fd..b052281 100644 (file)
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// 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)
+// 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)
 
 template<class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };