Map the absl::is_trivially_* functions to their std impl

There's no point redefining these functions if they are supported by the compiler and the version of libstdc++. Also, some of the builtins used by the absl implementation of these functions (e.g. __has_trivial_destructor) have been deprecated in Clang 15.

PiperOrigin-RevId: 465554125
Change-Id: I8674c3a5270ce3c654cdf58ae7dbd9d2bda8faa5
diff --git a/absl/base/config.h b/absl/base/config.h
index 94f7fcb..2faed85 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -273,6 +273,17 @@
 #define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
 #endif
 
+// ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
+//
+// Checks whether `std::is_trivially_copyable<T>` is supported.
+//
+// Notes: Clang 15+ with libc++ supports these features, GCC hasn't been tested.
+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE)
+#error ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set
+#elif defined(__clang__) && (__clang_major__ >= 15)
+#define ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1
+#endif
+
 // ABSL_HAVE_THREAD_LOCAL
 //
 // Checks whether C++11's `thread_local` storage duration specifier is
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index d886cb3..46b7690 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -298,8 +298,12 @@
 // https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits.
 template <typename T>
 struct is_trivially_destructible
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
+    : std::is_trivially_destructible<T> {
+#else
     : std::integral_constant<bool, __has_trivial_destructor(T) &&
                                    std::is_destructible<T>::value> {
+#endif
 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
  private:
   static constexpr bool compliant = std::is_trivially_destructible<T>::value ==
@@ -347,9 +351,13 @@
 // Nontrivially destructible types will cause the expression to be nontrivial.
 template <typename T>
 struct is_trivially_default_constructible
+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE)
+    : std::is_trivially_default_constructible<T> {
+#else
     : std::integral_constant<bool, __has_trivial_constructor(T) &&
                                    std::is_default_constructible<T>::value &&
                                    is_trivially_destructible<T>::value> {
+#endif
 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
     !defined(                                            \
         ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
@@ -381,10 +389,14 @@
 // expression to be nontrivial.
 template <typename T>
 struct is_trivially_move_constructible
+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE)
+    : std::is_trivially_move_constructible<T> {
+#else
     : std::conditional<
           std::is_object<T>::value && !std::is_array<T>::value,
           type_traits_internal::IsTriviallyMoveConstructibleObject<T>,
           std::is_reference<T>>::type::type {
+#endif
 #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \
     !defined(                                            \
         ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION)
@@ -490,9 +502,13 @@
 // `is_trivially_assignable<T&, const T&>`.
 template <typename T>
 struct is_trivially_copy_assignable
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
+    : std::is_trivially_copy_assignable<T> {
+#else
     : std::integral_constant<
           bool, __has_trivial_assign(typename std::remove_reference<T>::type) &&
                     absl::is_copy_assignable<T>::value> {
+#endif
 #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
  private:
   static constexpr bool compliant =
@@ -544,6 +560,11 @@
 // destructible. Arrays of trivially copyable types are trivially copyable.
 //
 // We expose this metafunction only for internal use within absl.
+
+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE)
+template <typename T>
+struct is_trivially_copyable : std::is_trivially_copyable<T> {};
+#else
 template <typename T>
 class is_trivially_copyable_impl {
   using ExtentsRemoved = typename std::remove_all_extents<T>::type;
@@ -569,6 +590,7 @@
 struct is_trivially_copyable
     : std::integral_constant<
           bool, type_traits_internal::is_trivially_copyable_impl<T>::kValue> {};
+#endif
 }  // namespace type_traits_internal
 
 // -----------------------------------------------------------------------------
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index 0ef5b66..fe96554 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -336,6 +336,7 @@
 
 struct NonCopyableOrMovable {
   NonCopyableOrMovable() = default;
+  virtual ~NonCopyableOrMovable() = default;
   NonCopyableOrMovable(const NonCopyableOrMovable&) = delete;
   NonCopyableOrMovable(NonCopyableOrMovable&&) = delete;
   NonCopyableOrMovable& operator=(const NonCopyableOrMovable&) = delete;