[llvm] [libc][NFC] split type_traits / utility in separate files (PR #65314)

Guillaume Chatelet via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 5 04:54:53 PDT 2023


https://github.com/gchatelet updated https://github.com/llvm/llvm-project/pull/65314:

>From 11d1be34fcdc8c306fc695b50c7e1f7e1083d09a Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Tue, 5 Sep 2023 11:18:45 +0000
Subject: [PATCH 1/3] [libc][NFC] split type_traits / utility in separate files

---
 libc/src/__support/CPP/functional.h           |  11 +-
 libc/src/__support/CPP/type_traits.h          | 391 +++---------------
 .../CPP/type_traits/add_lvalue_reference.h    |  28 ++
 .../__support/CPP/type_traits/add_pointer.h   |  28 ++
 .../CPP/type_traits/add_rvalue_reference.h    |  29 ++
 .../__support/CPP/type_traits/bool_constant.h |  20 +
 .../__support/CPP/type_traits/conditional.h   |  25 ++
 libc/src/__support/CPP/type_traits/decay.h    |  38 ++
 .../src/__support/CPP/type_traits/enable_if.h |  23 ++
 .../__support/CPP/type_traits/false_type.h    |  20 +
 .../CPP/type_traits/integral_constant.h       |  23 ++
 .../__support/CPP/type_traits/is_arithmetic.h |  27 ++
 libc/src/__support/CPP/type_traits/is_array.h |  28 ++
 .../__support/CPP/type_traits/is_base_of.h    |  44 ++
 libc/src/__support/CPP/type_traits/is_class.h |  29 ++
 libc/src/__support/CPP/type_traits/is_const.h |  25 ++
 .../CPP/type_traits/is_convertible.h          |  45 ++
 .../CPP/type_traits/is_destructible.h         |  65 +++
 libc/src/__support/CPP/type_traits/is_enum.h  |  23 ++
 .../CPP/type_traits/is_floating_point.h       |  35 ++
 .../__support/CPP/type_traits/is_function.h   |  33 ++
 .../__support/CPP/type_traits/is_integral.h   |  39 ++
 .../CPP/type_traits/is_lvalue_reference.h     |  33 ++
 .../CPP/type_traits/is_null_pointer.h         |  24 ++
 .../__support/CPP/type_traits/is_pointer.h    |  28 ++
 .../__support/CPP/type_traits/is_reference.h  |  29 ++
 .../CPP/type_traits/is_rvalue_reference.h     |  32 ++
 libc/src/__support/CPP/type_traits/is_same.h  |  25 ++
 .../src/__support/CPP/type_traits/is_signed.h |  28 ++
 .../type_traits/is_trivially_constructible.h  |  22 +
 .../CPP/type_traits/is_trivially_copyable.h   |  23 ++
 .../type_traits/is_trivially_destructible.h   |  35 ++
 libc/src/__support/CPP/type_traits/is_union.h |  23 ++
 .../__support/CPP/type_traits/is_unsigned.h   |  28 ++
 libc/src/__support/CPP/type_traits/is_void.h  |  24 ++
 .../__support/CPP/type_traits/make_signed.h   |  37 ++
 .../__support/CPP/type_traits/make_unsigned.h |  42 ++
 .../CPP/type_traits/remove_all_extents.h      |  34 ++
 .../src/__support/CPP/type_traits/remove_cv.h |  25 ++
 .../__support/CPP/type_traits/remove_cvref.h  |  24 ++
 .../__support/CPP/type_traits/remove_extent.h |  24 ++
 .../CPP/type_traits/remove_reference.h        |  24 ++
 .../src/__support/CPP/type_traits/true_type.h |  20 +
 .../__support/CPP/type_traits/type_identity.h |  20 +
 libc/src/__support/CPP/type_traits/void_t.h   |  26 ++
 libc/src/__support/CPP/utility.h              |  47 +--
 libc/src/__support/CPP/utility/declval.h      |  28 ++
 libc/src/__support/CPP/utility/forward.h      |  32 ++
 .../__support/CPP/utility/integer_sequence.h  |  37 ++
 libc/src/__support/CPP/utility/move.h         |  22 +
 .../llvm-project-overlay/libc/BUILD.bazel     |  56 ++-
 51 files changed, 1490 insertions(+), 391 deletions(-)
 create mode 100644 libc/src/__support/CPP/type_traits/add_lvalue_reference.h
 create mode 100644 libc/src/__support/CPP/type_traits/add_pointer.h
 create mode 100644 libc/src/__support/CPP/type_traits/add_rvalue_reference.h
 create mode 100644 libc/src/__support/CPP/type_traits/bool_constant.h
 create mode 100644 libc/src/__support/CPP/type_traits/conditional.h
 create mode 100644 libc/src/__support/CPP/type_traits/decay.h
 create mode 100644 libc/src/__support/CPP/type_traits/enable_if.h
 create mode 100644 libc/src/__support/CPP/type_traits/false_type.h
 create mode 100644 libc/src/__support/CPP/type_traits/integral_constant.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_arithmetic.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_array.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_base_of.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_class.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_const.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_convertible.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_destructible.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_enum.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_floating_point.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_function.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_integral.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_lvalue_reference.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_null_pointer.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_pointer.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_reference.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_rvalue_reference.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_same.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_signed.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_trivially_constructible.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_trivially_copyable.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_trivially_destructible.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_union.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_unsigned.h
 create mode 100644 libc/src/__support/CPP/type_traits/is_void.h
 create mode 100644 libc/src/__support/CPP/type_traits/make_signed.h
 create mode 100644 libc/src/__support/CPP/type_traits/make_unsigned.h
 create mode 100644 libc/src/__support/CPP/type_traits/remove_all_extents.h
 create mode 100644 libc/src/__support/CPP/type_traits/remove_cv.h
 create mode 100644 libc/src/__support/CPP/type_traits/remove_cvref.h
 create mode 100644 libc/src/__support/CPP/type_traits/remove_extent.h
 create mode 100644 libc/src/__support/CPP/type_traits/remove_reference.h
 create mode 100644 libc/src/__support/CPP/type_traits/true_type.h
 create mode 100644 libc/src/__support/CPP/type_traits/type_identity.h
 create mode 100644 libc/src/__support/CPP/type_traits/void_t.h
 create mode 100644 libc/src/__support/CPP/utility/declval.h
 create mode 100644 libc/src/__support/CPP/utility/forward.h
 create mode 100644 libc/src/__support/CPP/utility/integer_sequence.h
 create mode 100644 libc/src/__support/CPP/utility/move.h

diff --git a/libc/src/__support/CPP/functional.h b/libc/src/__support/CPP/functional.h
index e346011debab10c..ed5775d3fe64419 100644
--- a/libc/src/__support/CPP/functional.h
+++ b/libc/src/__support/CPP/functional.h
@@ -9,8 +9,12 @@
 #ifndef LLVM_LIBC_SRC_SUPPORT_CPP_FUNCTIONAL_H
 #define LLVM_LIBC_SRC_SUPPORT_CPP_FUNCTIONAL_H
 
-#include "src/__support/CPP/type_traits.h"
-#include "src/__support/CPP/utility.h"
+#include "src/__support/CPP/type_traits/enable_if.h"
+#include "src/__support/CPP/type_traits/is_convertible.h"
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/CPP/type_traits/is_void.h"
+#include "src/__support/CPP/type_traits/remove_cvref.h"
+#include "src/__support/CPP/type_traits/remove_reference.h"
 #include "src/__support/macros/attributes.h"
 
 #include <stdint.h>
@@ -42,8 +46,7 @@ template <typename Ret, typename... Params> class function<Ret(Params...)> {
   LIBC_INLINE function(
       Callable &&callable,
       // This is not the copy-constructor.
-      enable_if_t<!is_same<remove_cvref_t<Callable>, function>::value> * =
-          nullptr,
+      enable_if_t<!is_same_v<remove_cvref_t<Callable>, function>> * = nullptr,
       // Functor must be callable and return a suitable type.
       enable_if_t<is_void_v<Ret> ||
                   is_convertible_v<
diff --git a/libc/src/__support/CPP/type_traits.h b/libc/src/__support/CPP/type_traits.h
index aa0a6375e20200d..7794b39e0d8f4c3 100644
--- a/libc/src/__support/CPP/type_traits.h
+++ b/libc/src/__support/CPP/type_traits.h
@@ -1,4 +1,4 @@
-//===-- Self contained C++ type traits --------------------------*- C++ -*-===//
+//===-- Self contained C++ type_traits --------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,344 +6,51 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPETRAITS_H
-#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPETRAITS_H
-
-#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
-
-#include <stddef.h> // For size_t.
-
-namespace __llvm_libc {
-namespace cpp {
-
-template <typename T> struct type_identity {
-  using type = T;
-};
-
-template <bool B, typename T> struct enable_if;
-template <typename T> struct enable_if<true, T> : type_identity<T> {};
-template <bool B, typename T = void>
-using enable_if_t = typename enable_if<B, T>::type;
-
-template <typename T, T v> struct integral_constant {
-  using value_type = T;
-  LIBC_INLINE_VAR static constexpr T value = v;
-};
-using true_type = cpp::integral_constant<bool, true>;
-using false_type = cpp::integral_constant<bool, false>;
-
-template <bool V> using bool_constant = integral_constant<bool, V>;
-
-template <class T>
-struct is_trivially_copyable
-    : public integral_constant<bool, __is_trivially_copyable(T)> {};
-
-template <class T, class... Args>
-struct is_trivially_constructible
-    : integral_constant<bool, __is_trivially_constructible(T, Args...)> {};
-
-template <typename T, typename U> struct is_same : cpp::false_type {};
-template <typename T> struct is_same<T, T> : cpp::true_type {};
-template <typename T, typename U>
-LIBC_INLINE_VAR constexpr bool is_same_v = is_same<T, U>::value;
-
-template <class T> struct is_const : cpp::false_type {};
-template <class T> struct is_const<const T> : cpp::true_type {};
-template <class T>
-LIBC_INLINE_VAR constexpr bool is_const_v = is_const<T>::value;
-
-template <typename T> struct remove_cv : type_identity<T> {};
-template <typename T> struct remove_cv<const T> : type_identity<T> {};
-template <typename T> struct remove_cv<volatile T> : type_identity<T> {};
-template <typename T> struct remove_cv<const volatile T> : type_identity<T> {};
-template <typename T> using remove_cv_t = typename remove_cv<T>::type;
-
-template <typename T> struct remove_reference : type_identity<T> {};
-template <typename T> struct remove_reference<T &> : type_identity<T> {};
-template <typename T> struct remove_reference<T &&> : type_identity<T> {};
-template <typename T>
-using remove_reference_t = typename remove_reference<T>::type;
-
-template <typename T> struct add_rvalue_reference : type_identity<T &&> {};
-
-template <typename T> struct remove_cvref {
-  using type = remove_cv_t<remove_reference_t<T>>;
-};
-template <typename T> using remove_cvref_t = typename remove_cvref<T>::type;
-
-namespace details {
-template <typename T, typename... Args>
-LIBC_INLINE constexpr bool is_unqualified_any_of() {
-  return (... || is_same_v<remove_cv_t<T>, Args>);
-}
-} // namespace details
-
-template <typename T> struct is_integral {
-  LIBC_INLINE_VAR static constexpr bool value = details::is_unqualified_any_of<
-      T,
-#ifdef __SIZEOF_INT128__
-      __int128_t, __uint128_t,
-#endif
-      char, signed char, unsigned char, short, unsigned short, int,
-      unsigned int, long, unsigned long, long long, unsigned long long, bool>();
-};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_integral_v = is_integral<T>::value;
-
-template <typename T> struct is_enum {
-  LIBC_INLINE_VAR static constexpr bool value = __is_enum(T);
-};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_enum_v = is_enum<T>::value;
-
-template <typename T> struct is_pointer : cpp::false_type {};
-template <typename T> struct is_pointer<T *> : cpp::true_type {};
-template <typename T> struct is_pointer<T *const> : cpp::true_type {};
-template <typename T> struct is_pointer<T *volatile> : cpp::true_type {};
-template <typename T> struct is_pointer<T *const volatile> : cpp::true_type {};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_pointer_v = is_pointer<T>::value;
-
-template <typename T> struct is_floating_point {
-  LIBC_INLINE_VAR static constexpr bool value =
-      details::is_unqualified_any_of<T, float, double, long double>();
-};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_floating_point_v =
-    is_floating_point<T>::value;
-
-template <typename T> struct is_arithmetic {
-  LIBC_INLINE_VAR static constexpr bool value =
-      is_integral<T>::value || is_floating_point<T>::value;
-};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
-
-namespace details {
-template <typename T, bool = is_arithmetic<T>::value>
-struct is_signed : integral_constant<bool, (T(-1) < T(0))> {};
-template <typename T> struct is_signed<T, false> : false_type {};
-
-template <typename T, bool = is_arithmetic<T>::value>
-struct is_unsigned : integral_constant<bool, (T(-1) > T(0))> {};
-template <typename T> struct is_unsigned<T, false> : false_type {};
-} // namespace details
-
-template <typename T> struct is_signed {
-  LIBC_INLINE_VAR static constexpr bool value = details::is_signed<T>::value;
-  LIBC_INLINE constexpr operator bool() const { return value; }
-  LIBC_INLINE constexpr bool operator()() const { return value; }
-};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed<T>::value;
-
-template <typename T> struct is_unsigned {
-  LIBC_INLINE_VAR static constexpr bool value = details::is_unsigned<T>::value;
-  LIBC_INLINE constexpr operator bool() const { return value; }
-  LIBC_INLINE constexpr bool operator()() const { return value; }
-};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::value;
-
-template <typename T> struct make_unsigned;
-template <> struct make_unsigned<char> : type_identity<unsigned char> {};
-template <> struct make_unsigned<signed char> : type_identity<unsigned char> {};
-template <> struct make_unsigned<short> : type_identity<unsigned short> {};
-template <> struct make_unsigned<int> : type_identity<unsigned int> {};
-template <> struct make_unsigned<long> : type_identity<unsigned long> {};
-template <>
-struct make_unsigned<long long> : type_identity<unsigned long long> {};
-template <>
-struct make_unsigned<unsigned char> : type_identity<unsigned char> {};
-template <>
-struct make_unsigned<unsigned short> : type_identity<unsigned short> {};
-template <> struct make_unsigned<unsigned int> : type_identity<unsigned int> {};
-template <>
-struct make_unsigned<unsigned long> : type_identity<unsigned long> {};
-template <>
-struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {};
-#ifdef __SIZEOF_INT128__
-template <> struct make_unsigned<__int128_t> : type_identity<__uint128_t> {};
-template <> struct make_unsigned<__uint128_t> : type_identity<__uint128_t> {};
-#endif
-template <typename T> using make_unsigned_t = typename make_unsigned<T>::type;
-
-template <typename T> struct make_signed;
-template <> struct make_signed<char> : type_identity<char> {};
-template <> struct make_signed<signed char> : type_identity<char> {};
-template <> struct make_signed<short> : type_identity<short> {};
-template <> struct make_signed<int> : type_identity<int> {};
-template <> struct make_signed<long> : type_identity<long> {};
-template <> struct make_signed<long long> : type_identity<long long> {};
-template <> struct make_signed<unsigned char> : type_identity<char> {};
-template <> struct make_signed<unsigned short> : type_identity<short> {};
-template <> struct make_signed<unsigned int> : type_identity<int> {};
-template <> struct make_signed<unsigned long> : type_identity<long> {};
-template <>
-struct make_signed<unsigned long long> : type_identity<long long> {};
-#ifdef __SIZEOF_INT128__
-template <> struct make_signed<__int128_t> : type_identity<__int128_t> {};
-template <> struct make_signed<__uint128_t> : type_identity<__int128_t> {};
-#endif
-template <typename T> using make_signed_t = typename make_signed<T>::type;
-
-// Compile time type selection.
-template <bool B, typename T, typename F>
-struct conditional : type_identity<T> {};
-template <typename T, typename F>
-struct conditional<false, T, F> : type_identity<F> {};
-template <bool B, typename T, typename F>
-using conditional_t = typename conditional<B, T, F>::type;
-
-template <typename T>
-struct is_void : is_same<void, typename remove_cv<T>::type> {};
-template <typename T>
-LIBC_INLINE_VAR constexpr bool is_void_v = is_void<T>::value;
-template <class T> T declval();
-
-// Compile time checks on implicit conversions.
-namespace details {
-template <typename...> using void_t = void;
-template <typename T> void convertible_to_helper(T);
-} // namespace details
-
-template <typename F, typename T, typename = void>
-LIBC_INLINE_VAR constexpr bool is_convertible_v = false;
-
-// FIXME: This should use LIBC_INLINE_VAR, but clang buggily complains about
-// this when LIBC_INLINE_VAR uses [[clang::internal_linkage]].
-template <typename F, typename T>
-constexpr bool
-    is_convertible_v<F, T,
-                     details::void_t<decltype(details::convertible_to_helper<T>(
-                         declval<F>()))>> = true;
-
-namespace details {
-#if LIBC_HAS_BUILTIN(__is_lvalue_reference) &&                                 \
-    LIBC_HAS_BUILTIN(__is_rvalue_reference) &&                                 \
-    LIBC_HAS_BUILTIN(__is_reference)
-
-template <typename T>
-struct is_lvalue_reference : bool_constant<__is_lvalue_reference(T)> {};
-template <typename T>
-struct is_rvalue_reference : bool_constant<__is_rvalue_reference(T)> {};
-template <typename T> struct is_reference : bool_constant<__is_reference(T)> {};
-
-#else // LIBC_HAS_BUILTIN(__is_lvalue_reference) && etc...
-
-template <typename T> struct is_lvalue_reference : public false_type {};
-template <typename T> struct is_lvalue_reference<T &> : public true_type {};
-
-template <typename T> struct is_rvalue_reference : public false_type {};
-template <typename T> struct is_rvalue_reference<T &&> : public true_type {};
-
-template <typename T> struct is_reference : public false_type {};
-template <typename T> struct is_reference<T &> : public true_type {};
-template <typename T> struct is_reference<T &&> : public true_type {};
-
-#endif // LIBC_HAS_BUILTIN(__is_lvalue_reference) && etc...
-
-#if LIBC_HAS_BUILTIN(__remove_all_extents)
-template <typename T> using __remove_all_extents_t = __remove_all_extents(T);
-#else
-template <typename T> struct remove_all_extents {
-  typedef T type;
-};
-template <typename T> struct remove_all_extents<T[]> {
-  typedef typename remove_all_extents<T>::type type;
-};
-template <typename T, size_t _Np> struct remove_all_extents<T[_Np]> {
-  typedef typename remove_all_extents<T>::type type;
-};
-
-template <typename T>
-using __remove_all_extents_t = typename remove_all_extents<T>::type;
-#endif // LIBC_HAS_BUILTIN(__remove_all_extents)
-
-#if LIBC_HAS_BUILTIN(__is_function)
-
-template <typename T>
-struct is_function : integral_constant<bool, __is_function(T)> {};
-
-#else
-
-template <typename T>
-struct is_function
-    : public integral_constant<bool, !(is_reference<T>::value ||
-                                       is_const<const T>::value)> {};
-
-#endif // LIBC_HAS_BUILTIN(__is_function)
-
-#if LIBC_HAS_BUILTIN(__is_destructible)
-
-template <typename T>
-struct is_destructible : bool_constant<__is_destructible(T)> {};
-
-#else // LIBC_HAS_BUILTIN(__is_destructible)
-
-//  if it's a reference, return true
-//  if it's a function, return false
-//  if it's   void,     return false
-//  if it's an array of unknown bound, return false
-//  Otherwise, return "declval<T&>().~T()" is well-formed
-//    where T is remove_all_extents<T>::type
-
-template <typename> struct __is_destructible_apply {
-  typedef int type;
-};
-
-template <typename T> struct __is_destructor_wellformed {
-  template <typename T1>
-  static true_type __test(
-      typename __is_destructible_apply<decltype(declval<T1 &>().~T1())>::type);
-
-  template <typename T1> static false_type __test(...);
-
-  static const bool value = decltype(__test<T>(12))::value;
-};
-
-template <typename T, bool> struct __destructible_imp;
-
-template <typename T>
-struct __destructible_imp<T, false>
-    : public integral_constant<
-          bool, __is_destructor_wellformed<__remove_all_extents_t<T>>::value> {
-};
-
-template <typename T> struct __destructible_imp<T, true> : public true_type {};
-
-template <typename T, bool> struct __destructible_false;
-template <typename T>
-struct __destructible_false<T, false>
-    : public __destructible_imp<T, is_reference<T>::value> {};
-template <typename T>
-struct __destructible_false<T, true> : public false_type {};
-
-template <typename T>
-struct is_destructible : public __destructible_false<T, is_function<T>::value> {
-};
-template <typename T> struct is_destructible<T[]> : public false_type {};
-template <> struct is_destructible<void> : public false_type {};
-
-#endif // LIBC_HAS_BUILTIN(__is_destructible)
-} // namespace details
-
-#if LIBC_HAS_BUILTIN(__is_trivially_destructible)
-
-template <typename T>
-struct is_trivially_destructible
-    : public integral_constant<bool, __is_trivially_destructible(T)> {};
-
-#else
-template <typename T>
-struct is_trivially_destructible
-    : public integral_constant<
-          bool, __llvm_libc::cpp::details::is_destructible<T>::value
-                    &&__has_trivial_destructor(T)> {};
-#endif // LIBC_HAS_BUILTIN(__is_trivially_destructible)
-
-} // namespace cpp
-} // namespace __llvm_libc
-
-#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPETRAITS_H
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_H
+
+#include "src/__support/CPP/type_traits/add_lvalue_reference.h"
+#include "src/__support/CPP/type_traits/add_pointer.h"
+#include "src/__support/CPP/type_traits/add_rvalue_reference.h"
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/conditional.h"
+#include "src/__support/CPP/type_traits/decay.h"
+#include "src/__support/CPP/type_traits/enable_if.h"
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/integral_constant.h"
+#include "src/__support/CPP/type_traits/is_arithmetic.h"
+#include "src/__support/CPP/type_traits/is_array.h"
+#include "src/__support/CPP/type_traits/is_base_of.h"
+#include "src/__support/CPP/type_traits/is_class.h"
+#include "src/__support/CPP/type_traits/is_const.h"
+#include "src/__support/CPP/type_traits/is_convertible.h"
+#include "src/__support/CPP/type_traits/is_destructible.h"
+#include "src/__support/CPP/type_traits/is_enum.h"
+#include "src/__support/CPP/type_traits/is_floating_point.h"
+#include "src/__support/CPP/type_traits/is_function.h"
+#include "src/__support/CPP/type_traits/is_integral.h"
+#include "src/__support/CPP/type_traits/is_lvalue_reference.h"
+#include "src/__support/CPP/type_traits/is_null_pointer.h"
+#include "src/__support/CPP/type_traits/is_pointer.h"
+#include "src/__support/CPP/type_traits/is_reference.h"
+#include "src/__support/CPP/type_traits/is_rvalue_reference.h"
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/CPP/type_traits/is_signed.h"
+#include "src/__support/CPP/type_traits/is_trivially_constructible.h"
+#include "src/__support/CPP/type_traits/is_trivially_copyable.h"
+#include "src/__support/CPP/type_traits/is_trivially_destructible.h"
+#include "src/__support/CPP/type_traits/is_union.h"
+#include "src/__support/CPP/type_traits/is_unsigned.h"
+#include "src/__support/CPP/type_traits/is_void.h"
+#include "src/__support/CPP/type_traits/make_signed.h"
+#include "src/__support/CPP/type_traits/make_unsigned.h"
+#include "src/__support/CPP/type_traits/remove_all_extents.h"
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/CPP/type_traits/remove_cvref.h"
+#include "src/__support/CPP/type_traits/remove_extent.h"
+#include "src/__support/CPP/type_traits/remove_reference.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/CPP/type_traits/type_identity.h"
+#include "src/__support/CPP/type_traits/void_t.h"
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_H
diff --git a/libc/src/__support/CPP/type_traits/add_lvalue_reference.h b/libc/src/__support/CPP/type_traits/add_lvalue_reference.h
new file mode 100644
index 000000000000000..7cb22ac03bb033c
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/add_lvalue_reference.h
@@ -0,0 +1,28 @@
+//===-- add_lvalue_reference type_traits ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_LVALUE_REFERENCE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_LVALUE_REFERENCE_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// add_lvalue_reference
+namespace detail {
+template <class T> // Note that `cv void&` is a substitution failure
+auto try_add_lvalue_reference(int) -> cpp::type_identity<T &>;
+template <class T> // Handle T = cv void case
+auto try_add_lvalue_reference(...) -> cpp::type_identity<T>;
+} // namespace detail
+template <class T>
+struct add_lvalue_reference : decltype(detail::try_add_lvalue_reference<T>(0)) {
+};
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_LVALUE_REFERENCE_H
diff --git a/libc/src/__support/CPP/type_traits/add_pointer.h b/libc/src/__support/CPP/type_traits/add_pointer.h
new file mode 100644
index 000000000000000..543259ea1ca8f44
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/add_pointer.h
@@ -0,0 +1,28 @@
+//===-- add_pointer type_traits ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_POINTER_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_POINTER_H
+
+#include "src/__support/CPP/type_traits/remove_reference.h"
+#include "src/__support/CPP/type_traits/type_identity.h"
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// add_pointer
+namespace detail {
+template <class T>
+auto try_add_pointer(int) -> cpp::type_identity<cpp::remove_reference_t<T> *>;
+template <class T> auto try_add_pointer(...) -> cpp::type_identity<T>;
+} // namespace detail
+template <class T>
+struct add_pointer : decltype(detail::try_add_pointer<T>(0)) {};
+template <class T> using add_pointer_t = typename add_pointer<T>::type;
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_POINTER_H
diff --git a/libc/src/__support/CPP/type_traits/add_rvalue_reference.h b/libc/src/__support/CPP/type_traits/add_rvalue_reference.h
new file mode 100644
index 000000000000000..b912cef59b68f87
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/add_rvalue_reference.h
@@ -0,0 +1,29 @@
+//===-- add_rvalue_reference type_traits ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_RVALUE_REFERENCE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_RVALUE_REFERENCE_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// add_rvalue_reference
+namespace detail {
+template <class T>
+auto try_add_rvalue_reference(int) -> cpp::type_identity<T &&>;
+template <class T> auto try_add_rvalue_reference(...) -> cpp::type_identity<T>;
+} // namespace detail
+template <class T>
+struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference<T>(0)) {
+};
+template <class T>
+using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ADD_RVALUE_REFERENCE_H
diff --git a/libc/src/__support/CPP/type_traits/bool_constant.h b/libc/src/__support/CPP/type_traits/bool_constant.h
new file mode 100644
index 000000000000000..6fcfb8e82e4d803
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/bool_constant.h
@@ -0,0 +1,20 @@
+//===-- bool_constant type_traits -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_BOOL_CONSTANT_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_BOOL_CONSTANT_H
+
+#include "src/__support/CPP/type_traits/integral_constant.h"
+
+namespace __llvm_libc::cpp {
+
+// bool_constant
+template <bool V> using bool_constant = cpp::integral_constant<bool, V>;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_BOOL_CONSTANT_H
diff --git a/libc/src/__support/CPP/type_traits/conditional.h b/libc/src/__support/CPP/type_traits/conditional.h
new file mode 100644
index 000000000000000..f9917c2a7264cee
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/conditional.h
@@ -0,0 +1,25 @@
+//===-- conditional type_traits ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_CONDITIONAL_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_CONDITIONAL_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// conditional
+template <bool B, typename T, typename F>
+struct conditional : type_identity<T> {};
+template <typename T, typename F>
+struct conditional<false, T, F> : type_identity<F> {};
+template <bool B, typename T, typename F>
+using conditional_t = typename conditional<B, T, F>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_CONDITIONAL_H
diff --git a/libc/src/__support/CPP/type_traits/decay.h b/libc/src/__support/CPP/type_traits/decay.h
new file mode 100644
index 000000000000000..f3f9cfc5eaa006d
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/decay.h
@@ -0,0 +1,38 @@
+//===-- decay type_traits ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_DECAY_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_DECAY_H
+
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+#include "src/__support/CPP/type_traits/add_pointer.h"
+#include "src/__support/CPP/type_traits/conditional.h"
+#include "src/__support/CPP/type_traits/is_array.h"
+#include "src/__support/CPP/type_traits/is_function.h"
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/CPP/type_traits/remove_extent.h"
+#include "src/__support/CPP/type_traits/remove_reference.h"
+
+namespace __llvm_libc::cpp {
+
+// decay
+template <class T> class decay {
+  using U = cpp::remove_reference_t<T>;
+
+public:
+  using type = conditional_t<
+      cpp::is_array_v<U>, cpp::add_pointer_t<cpp::remove_extent_t<U>>,
+      cpp::conditional_t<cpp::is_function_v<U>, cpp::add_pointer_t<U>,
+                         cpp::remove_cv_t<U>>>;
+};
+template <class T> using decay_t = typename decay<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_DECAY_H
diff --git a/libc/src/__support/CPP/type_traits/enable_if.h b/libc/src/__support/CPP/type_traits/enable_if.h
new file mode 100644
index 000000000000000..51d7252fc3e48d8
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/enable_if.h
@@ -0,0 +1,23 @@
+//===-- enable_if type_traits -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ENABLE_IF_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ENABLE_IF_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// enable_if
+template <bool B, typename T> struct enable_if;
+template <typename T> struct enable_if<true, T> : type_identity<T> {};
+template <bool B, typename T = void>
+using enable_if_t = typename enable_if<B, T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ENABLE_IF_H
diff --git a/libc/src/__support/CPP/type_traits/false_type.h b/libc/src/__support/CPP/type_traits/false_type.h
new file mode 100644
index 000000000000000..8dc6fc66d288787
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/false_type.h
@@ -0,0 +1,20 @@
+//===-- false_type type_traits ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_FALSE_TYPE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_FALSE_TYPE_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+
+namespace __llvm_libc::cpp {
+
+// false_type
+using false_type = cpp::bool_constant<false>;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_FALSE_TYPE_H
diff --git a/libc/src/__support/CPP/type_traits/integral_constant.h b/libc/src/__support/CPP/type_traits/integral_constant.h
new file mode 100644
index 000000000000000..21bdbccf073a612
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/integral_constant.h
@@ -0,0 +1,23 @@
+//===-- integral_constant type_traits ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_INTEGRAL_CONSTANT_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_INTEGRAL_CONSTANT_H
+
+#include "src/__support/macros/attributes.h" // LIBC_INLINE_VAR
+
+namespace __llvm_libc::cpp {
+
+// integral_constant
+template <typename T, T v> struct integral_constant {
+  using value_type = T;
+  LIBC_INLINE_VAR static constexpr T value = v;
+};
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_INTEGRAL_CONSTANT_H
diff --git a/libc/src/__support/CPP/type_traits/is_arithmetic.h b/libc/src/__support/CPP/type_traits/is_arithmetic.h
new file mode 100644
index 000000000000000..cc651b11b204820
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_arithmetic.h
@@ -0,0 +1,27 @@
+//===-- is_arithmetic type_traits -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ARITHMETIC_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ARITHMETIC_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/is_floating_point.h"
+#include "src/__support/CPP/type_traits/is_integral.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_arithmetic
+template <typename T>
+struct is_arithmetic : cpp::bool_constant<(cpp::is_integral_v<T> ||
+                                           cpp::is_floating_point_v<T>)> {};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ARITHMETIC_H
diff --git a/libc/src/__support/CPP/type_traits/is_array.h b/libc/src/__support/CPP/type_traits/is_array.h
new file mode 100644
index 000000000000000..c04a2edb6c77ef9
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_array.h
@@ -0,0 +1,28 @@
+//===-- is_array type_traits ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ARRAY_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ARRAY_H
+
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/attributes.h"
+
+#include <stddef.h> // For size_t
+
+namespace __llvm_libc::cpp {
+
+// is_array
+template <class T> struct is_array : false_type {};
+template <class T> struct is_array<T[]> : true_type {};
+template <class T, size_t N> struct is_array<T[N]> : true_type {};
+template <class T>
+LIBC_INLINE_VAR constexpr bool is_array_v = is_array<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ARRAY_H
diff --git a/libc/src/__support/CPP/type_traits/is_base_of.h b/libc/src/__support/CPP/type_traits/is_base_of.h
new file mode 100644
index 000000000000000..7820c83f7cbcad4
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_base_of.h
@@ -0,0 +1,44 @@
+//===-- is_base_of type_traits ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_BASE_OF_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_BASE_OF_H
+
+#include "src/__support/CPP/type_traits/add_rvalue_reference.h"
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/is_class.h"
+#include "src/__support/CPP/type_traits/remove_all_extents.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_base_of
+namespace detail {
+template <typename B> cpp::true_type __test_ptr_conv(const volatile B *);
+template <typename> cpp::false_type __test_ptr_conv(const volatile void *);
+
+template <typename B, typename D>
+auto is_base_of(int) -> decltype(__test_ptr_conv<B>(static_cast<D *>(nullptr)));
+
+template <typename, typename>
+auto is_base_of(...) -> cpp::true_type; // private or ambiguous base
+
+} // namespace detail
+
+template <typename Base, typename Derived>
+struct is_base_of
+    : cpp::bool_constant<
+          cpp::is_class_v<Base> &&
+          cpp::is_class_v<Derived> &&decltype(detail::is_base_of<Base, Derived>(
+              0))::value> {};
+template <typename Base, typename Derived>
+LIBC_INLINE_VAR constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_BASE_OF_H
diff --git a/libc/src/__support/CPP/type_traits/is_class.h b/libc/src/__support/CPP/type_traits/is_class.h
new file mode 100644
index 000000000000000..93b3c3d5df33ed9
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_class.h
@@ -0,0 +1,29 @@
+//===-- is_class type_traits ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CLASS_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CLASS_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/is_union.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_class
+namespace detail {
+template <class T> cpp::bool_constant<!cpp::is_union_v<T>> test(int T::*);
+template <class> cpp::false_type test(...);
+} // namespace detail
+template <class T> struct is_class : decltype(detail::test<T>(nullptr)) {};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_class_v = is_class<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CLASS_H
diff --git a/libc/src/__support/CPP/type_traits/is_const.h b/libc/src/__support/CPP/type_traits/is_const.h
new file mode 100644
index 000000000000000..5434e2982d95cf4
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_const.h
@@ -0,0 +1,25 @@
+//===-- is_const type_traits ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CONST_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CONST_H
+
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_const
+template <class T> struct is_const : cpp::false_type {};
+template <class T> struct is_const<const T> : cpp::true_type {};
+template <class T>
+LIBC_INLINE_VAR constexpr bool is_const_v = is_const<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CONST_H
diff --git a/libc/src/__support/CPP/type_traits/is_convertible.h b/libc/src/__support/CPP/type_traits/is_convertible.h
new file mode 100644
index 000000000000000..a7292c3461d4841
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_convertible.h
@@ -0,0 +1,45 @@
+//===-- is_convertible type_traits ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CONVERTIBLE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CONVERTIBLE_H
+
+#include "src/__support/CPP/type_traits/is_void.h"
+#include "src/__support/CPP/utility/declval.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_convertible
+namespace detail {
+template <class T>
+auto test_returnable(int)
+    -> decltype(void(static_cast<T (*)()>(nullptr)), cpp::true_type{});
+template <class> auto test_returnable(...) -> cpp::false_type;
+
+template <class From, class To>
+auto test_implicitly_convertible(int)
+    -> decltype(void(cpp::declval<void (&)(To)>()(cpp::declval<From>())),
+                cpp::true_type{});
+template <class, class>
+auto test_implicitly_convertible(...) -> cpp::false_type;
+} // namespace detail
+
+template <class From, class To>
+struct is_convertible
+    : cpp::bool_constant<
+          (decltype(detail::test_returnable<To>(0))::value &&
+           decltype(detail::test_implicitly_convertible<From, To>(0))::value) ||
+          (cpp::is_void_v<From> && cpp::is_void_v<To>)> {};
+
+template <class From, class To>
+LIBC_INLINE_VAR constexpr bool is_convertible_v =
+    is_convertible<From, To>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_CONVERTIBLE_H
diff --git a/libc/src/__support/CPP/type_traits/is_destructible.h b/libc/src/__support/CPP/type_traits/is_destructible.h
new file mode 100644
index 000000000000000..38b64a90e4253a8
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_destructible.h
@@ -0,0 +1,65 @@
+//===-- is_destructible type_traits -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_DESTRUCTIBLE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_DESTRUCTIBLE_H
+
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/is_function.h"
+#include "src/__support/CPP/type_traits/is_reference.h"
+#include "src/__support/CPP/type_traits/remove_all_extents.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// is_destructible
+#if LIBC_HAS_BUILTIN(__is_destructible)
+template <typename T>
+struct is_destructible : bool_constant<__is_destructible(T)> {};
+#else
+//  if it's a   reference,              return true
+//  if it's a   function,               return false
+//  if it's     void,                   return false
+//  if it's an  array of unknown bound, return false
+//  Otherwise, return "declval<T&>().~T()" is well-formed
+//    where T is remove_all_extents<T>::type
+template <typename> struct __is_destructible_apply : cpp::type_identity<int> {};
+template <typename T> struct __is_destructor_wellformed {
+  template <typename T1>
+  static cpp::true_type __test(
+      typename __is_destructible_apply<decltype(declval<T1 &>().~T1())>::type);
+  template <typename T1> static cpp::false_type __test(...);
+  static const bool value = decltype(__test<T>(12))::value;
+};
+template <typename T, bool> struct __destructible_imp;
+template <typename T>
+struct __destructible_imp<T, false>
+    : public bool_constant<
+          __is_destructor_wellformed<cpp::remove_all_extents_t<T>>::value> {};
+template <typename T>
+struct __destructible_imp<T, true> : public cpp::true_type {};
+template <typename T, bool> struct __destructible_false;
+template <typename T>
+struct __destructible_false<T, false>
+    : public __destructible_imp<T, is_reference<T>::value> {};
+template <typename T>
+struct __destructible_false<T, true> : public cpp::false_type {};
+template <typename T>
+struct is_destructible : public __destructible_false<T, is_function<T>::value> {
+};
+template <typename T> struct is_destructible<T[]> : public false_type {};
+template <> struct is_destructible<void> : public false_type {};
+#endif
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_DESTRUCTIBLE_H
diff --git a/libc/src/__support/CPP/type_traits/is_enum.h b/libc/src/__support/CPP/type_traits/is_enum.h
new file mode 100644
index 000000000000000..4914df30c3cd11b
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_enum.h
@@ -0,0 +1,23 @@
+//===-- is_enum type_traits -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ENUM_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ENUM_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_enum
+template <typename T> struct is_enum : bool_constant<__is_enum(T)> {};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_enum_v = is_enum<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_ENUM_H
diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
new file mode 100644
index 000000000000000..746d0e36c92ebaa
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -0,0 +1,35 @@
+//===-- is_floating_point type_traits ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_FLOATING_POINT_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_FLOATING_POINT_H
+
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_floating_point
+template <typename T> struct is_floating_point {
+private:
+  template <typename Head, typename... Args>
+  LIBC_INLINE_VAR static constexpr bool __is_unqualified_any_of() {
+    return (... || is_same_v<remove_cv_t<Head>, Args>);
+  }
+
+public:
+  LIBC_INLINE_VAR static constexpr bool value =
+      __is_unqualified_any_of<T, float, double, long double>();
+};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_floating_point_v =
+    is_floating_point<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_FLOATING_POINT_H
diff --git a/libc/src/__support/CPP/type_traits/is_function.h b/libc/src/__support/CPP/type_traits/is_function.h
new file mode 100644
index 000000000000000..3a8b3486e8f3ad5
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_function.h
@@ -0,0 +1,33 @@
+//===-- is_function type_traits ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_FUNCTION_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_FUNCTION_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/is_const.h"
+#include "src/__support/CPP/type_traits/is_reference.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// is_function
+#if LIBC_HAS_BUILTIN(__is_function)
+template <typename T>
+struct is_function : integral_constant<bool, __is_function(T)> {};
+#else
+template <typename T>
+struct is_function
+    : public bool_constant<!(is_reference_v<T> || is_const_v<const T>)> {};
+#endif
+template <class T>
+LIBC_INLINE_VAR constexpr bool is_function_v = is_function<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_FUNCTION_H
diff --git a/libc/src/__support/CPP/type_traits/is_integral.h b/libc/src/__support/CPP/type_traits/is_integral.h
new file mode 100644
index 000000000000000..0113a5bf9113934
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_integral.h
@@ -0,0 +1,39 @@
+//===-- is_integral type_traits ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_INTEGRAL_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_INTEGRAL_H
+
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_integral
+template <typename T> struct is_integral {
+private:
+  template <typename Head, typename... Args>
+  LIBC_INLINE_VAR static constexpr bool __is_unqualified_any_of() {
+    return (... || is_same_v<remove_cv_t<Head>, Args>);
+  }
+
+public:
+  LIBC_INLINE_VAR static constexpr bool value = __is_unqualified_any_of<
+      T,
+#ifdef __SIZEOF_INT128__
+      __int128_t, __uint128_t,
+#endif
+      char, signed char, unsigned char, short, unsigned short, int,
+      unsigned int, long, unsigned long, long long, unsigned long long, bool>();
+};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_integral_v = is_integral<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_INTEGRAL_H
diff --git a/libc/src/__support/CPP/type_traits/is_lvalue_reference.h b/libc/src/__support/CPP/type_traits/is_lvalue_reference.h
new file mode 100644
index 000000000000000..fe7f4f7252530fe
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_lvalue_reference.h
@@ -0,0 +1,33 @@
+//===-- is_lvalue_reference type_traits -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_LVALUE_REFERENCE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_LVALUE_REFERENCE_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// is_lvalue_reference
+#if LIBC_HAS_BUILTIN(__is_lvalue_reference)
+template <typename T>
+struct is_lvalue_reference : bool_constant<__is_lvalue_reference(T)> {};
+#else
+template <typename T> struct is_lvalue_reference : public false_type {};
+template <typename T> struct is_lvalue_reference<T &> : public true_type {};
+#endif
+template <class T>
+LIBC_INLINE_VAR constexpr bool is_lvalue_reference_v =
+    is_lvalue_reference<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_LVALUE_REFERENCE_H
diff --git a/libc/src/__support/CPP/type_traits/is_null_pointer.h b/libc/src/__support/CPP/type_traits/is_null_pointer.h
new file mode 100644
index 000000000000000..e5c024b1b3898bc
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_null_pointer.h
@@ -0,0 +1,24 @@
+//===-- is_null_pointer type_traits -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_NULL_POINTER_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_NULL_POINTER_H
+
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_null_pointer
+using nullptr_t = decltype(nullptr);
+template <class T>
+struct is_null_pointer : cpp::is_same<cpp::nullptr_t, cpp::remove_cv_t<T>> {};
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_NULL_POINTER_H
diff --git a/libc/src/__support/CPP/type_traits/is_pointer.h b/libc/src/__support/CPP/type_traits/is_pointer.h
new file mode 100644
index 000000000000000..f7af8752e8d8998
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_pointer.h
@@ -0,0 +1,28 @@
+//===-- is_pointer type_traits ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_POINTER_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_POINTER_H
+
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_pointer
+template <typename T> struct is_pointer : cpp::false_type {};
+template <typename T> struct is_pointer<T *> : cpp::true_type {};
+template <typename T> struct is_pointer<T *const> : cpp::true_type {};
+template <typename T> struct is_pointer<T *volatile> : cpp::true_type {};
+template <typename T> struct is_pointer<T *const volatile> : cpp::true_type {};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_pointer_v = is_pointer<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_POINTER_H
diff --git a/libc/src/__support/CPP/type_traits/is_reference.h b/libc/src/__support/CPP/type_traits/is_reference.h
new file mode 100644
index 000000000000000..147b65ebfe7b780
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_reference.h
@@ -0,0 +1,29 @@
+//===-- is_reference type_traits --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_REFERENCE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_REFERENCE_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// is_reference
+#if LIBC_HAS_BUILTIN(__is_reference)
+template <typename T> struct is_reference : bool_constant<__is_reference(T)> {};
+#else
+template <typename T> struct is_reference : public false_type {};
+template <typename T> struct is_reference<T &> : public true_type {};
+template <typename T> struct is_reference<T &&> : public true_type {};
+#endif
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_REFERENCE_H
diff --git a/libc/src/__support/CPP/type_traits/is_rvalue_reference.h b/libc/src/__support/CPP/type_traits/is_rvalue_reference.h
new file mode 100644
index 000000000000000..33b2037df013810
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_rvalue_reference.h
@@ -0,0 +1,32 @@
+//===-- is_rvalue_reference type_traits -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_RVALUE_REFERENCE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_RVALUE_REFERENCE_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// is_rvalue_reference
+#if LIBC_HAS_BUILTIN(__is_rvalue_reference)
+template <typename T>
+struct is_rvalue_reference : bool_constant<__is_rvalue_reference(T)> {};
+#else
+template <typename T> struct is_rvalue_reference : public false_type {};
+template <typename T> struct is_rvalue_reference<T &&> : public true_type {};
+#endif
+template <class T>
+using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_RVALUE_REFERENCE_H
diff --git a/libc/src/__support/CPP/type_traits/is_same.h b/libc/src/__support/CPP/type_traits/is_same.h
new file mode 100644
index 000000000000000..f8fa7ed2f350c6c
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_same.h
@@ -0,0 +1,25 @@
+//===-- is_same type_traits -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_SAME_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_SAME_H
+
+#include "src/__support/CPP/type_traits/false_type.h"
+#include "src/__support/CPP/type_traits/true_type.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_same
+template <typename T, typename U> struct is_same : cpp::false_type {};
+template <typename T> struct is_same<T, T> : cpp::true_type {};
+template <typename T, typename U>
+LIBC_INLINE_VAR constexpr bool is_same_v = is_same<T, U>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_SAME_H
diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
new file mode 100644
index 000000000000000..a4e6dbcf3d62e7a
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -0,0 +1,28 @@
+//===-- is_signed type_traits -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/is_arithmetic.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_signed
+template <typename T>
+struct is_signed : bool_constant<(is_arithmetic_v<T> && (T(-1) < T(0)))> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H
diff --git a/libc/src/__support/CPP/type_traits/is_trivially_constructible.h b/libc/src/__support/CPP/type_traits/is_trivially_constructible.h
new file mode 100644
index 000000000000000..3053e7b9ac53b7e
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_trivially_constructible.h
@@ -0,0 +1,22 @@
+//===-- is_trivially_constructible type_traits ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_CONSTRUCTIBLE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_CONSTRUCTIBLE_H
+
+#include "src/__support/CPP/type_traits/integral_constant.h"
+
+namespace __llvm_libc::cpp {
+
+// is_trivially_constructible
+template <class T, class... Args>
+struct is_trivially_constructible
+    : integral_constant<bool, __is_trivially_constructible(T, Args...)> {};
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_CONSTRUCTIBLE_H
diff --git a/libc/src/__support/CPP/type_traits/is_trivially_copyable.h b/libc/src/__support/CPP/type_traits/is_trivially_copyable.h
new file mode 100644
index 000000000000000..a1b5a0cb26c5fcb
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_trivially_copyable.h
@@ -0,0 +1,23 @@
+//===-- is_trivially_copyable type_traits -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H
+
+#include "src/__support/CPP/type_traits/integral_constant.h"
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// is_trivially_copyable
+template <class T>
+struct is_trivially_copyable
+    : public integral_constant<bool, __is_trivially_copyable(T)> {};
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H
diff --git a/libc/src/__support/CPP/type_traits/is_trivially_destructible.h b/libc/src/__support/CPP/type_traits/is_trivially_destructible.h
new file mode 100644
index 000000000000000..5eab5aa08460436
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_trivially_destructible.h
@@ -0,0 +1,35 @@
+//===-- is_trivially_destructible type_traits -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_DESTRUCTIBLE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_DESTRUCTIBLE_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/is_destructible.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// is_trivially_destructible
+#if LIBC_HAS_BUILTIN(__is_trivially_destructible)
+template <typename T>
+struct is_trivially_destructible
+    : public bool_constant<__is_trivially_destructible(T)> {};
+#else
+template <typename T>
+struct is_trivially_destructible
+    : public bool_constant<cpp::is_destructible_v<T> &&__has_trivial_destructor(
+          T)> {};
+#endif // LIBC_HAS_BUILTIN(__is_trivially_destructible)
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_trivially_destructible_v =
+    is_trivially_destructible<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_TRIVIALLY_DESTRUCTIBLE_H
diff --git a/libc/src/__support/CPP/type_traits/is_union.h b/libc/src/__support/CPP/type_traits/is_union.h
new file mode 100644
index 000000000000000..354dbd160844b36
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_union.h
@@ -0,0 +1,23 @@
+//===-- is_union type_traits ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_UNION_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_UNION_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_union
+template <class T> struct is_union : bool_constant<__is_union(T)> {};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_union_v = is_union<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_UNION_H
diff --git a/libc/src/__support/CPP/type_traits/is_unsigned.h b/libc/src/__support/CPP/type_traits/is_unsigned.h
new file mode 100644
index 000000000000000..6510c1304cf344d
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -0,0 +1,28 @@
+//===-- is_unsigned type_traits ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/CPP/type_traits/is_arithmetic.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_unsigned
+template <typename T>
+struct is_unsigned : bool_constant<(is_arithmetic_v<T> && (T(-1) > T(0)))> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H
diff --git a/libc/src/__support/CPP/type_traits/is_void.h b/libc/src/__support/CPP/type_traits/is_void.h
new file mode 100644
index 000000000000000..be054f0860c26c6
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/is_void.h
@@ -0,0 +1,24 @@
+//===-- is_void type_traits -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_VOID_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_VOID_H
+
+#include "src/__support/CPP/type_traits/is_same.h"
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// is_void
+template <typename T> struct is_void : is_same<void, remove_cv_t<T>> {};
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_void_v = is_void<T>::value;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_VOID_H
diff --git a/libc/src/__support/CPP/type_traits/make_signed.h b/libc/src/__support/CPP/type_traits/make_signed.h
new file mode 100644
index 000000000000000..c896c4590232533
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/make_signed.h
@@ -0,0 +1,37 @@
+//===-- make_signed type_traits ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_MAKE_SIGNED_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_MAKE_SIGNED_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// make_signed
+template <typename T> struct make_signed;
+template <> struct make_signed<char> : type_identity<char> {};
+template <> struct make_signed<signed char> : type_identity<char> {};
+template <> struct make_signed<short> : type_identity<short> {};
+template <> struct make_signed<int> : type_identity<int> {};
+template <> struct make_signed<long> : type_identity<long> {};
+template <> struct make_signed<long long> : type_identity<long long> {};
+template <> struct make_signed<unsigned char> : type_identity<char> {};
+template <> struct make_signed<unsigned short> : type_identity<short> {};
+template <> struct make_signed<unsigned int> : type_identity<int> {};
+template <> struct make_signed<unsigned long> : type_identity<long> {};
+template <>
+struct make_signed<unsigned long long> : type_identity<long long> {};
+#ifdef __SIZEOF_INT128__
+template <> struct make_signed<__int128_t> : type_identity<__int128_t> {};
+template <> struct make_signed<__uint128_t> : type_identity<__int128_t> {};
+#endif
+template <typename T> using make_signed_t = typename make_signed<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_MAKE_SIGNED_H
diff --git a/libc/src/__support/CPP/type_traits/make_unsigned.h b/libc/src/__support/CPP/type_traits/make_unsigned.h
new file mode 100644
index 000000000000000..5cd7c3cd4c86395
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/make_unsigned.h
@@ -0,0 +1,42 @@
+//===-- make_unsigned type_traits -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_MAKE_UNSIGNED_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_MAKE_UNSIGNED_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// make_unsigned
+
+template <typename T> struct make_unsigned;
+template <> struct make_unsigned<char> : type_identity<unsigned char> {};
+template <> struct make_unsigned<signed char> : type_identity<unsigned char> {};
+template <> struct make_unsigned<short> : type_identity<unsigned short> {};
+template <> struct make_unsigned<int> : type_identity<unsigned int> {};
+template <> struct make_unsigned<long> : type_identity<unsigned long> {};
+template <>
+struct make_unsigned<long long> : type_identity<unsigned long long> {};
+template <>
+struct make_unsigned<unsigned char> : type_identity<unsigned char> {};
+template <>
+struct make_unsigned<unsigned short> : type_identity<unsigned short> {};
+template <> struct make_unsigned<unsigned int> : type_identity<unsigned int> {};
+template <>
+struct make_unsigned<unsigned long> : type_identity<unsigned long> {};
+template <>
+struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {};
+#ifdef __SIZEOF_INT128__
+template <> struct make_unsigned<__int128_t> : type_identity<__uint128_t> {};
+template <> struct make_unsigned<__uint128_t> : type_identity<__uint128_t> {};
+#endif
+template <typename T> using make_unsigned_t = typename make_unsigned<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_MAKE_UNSIGNED_H
diff --git a/libc/src/__support/CPP/type_traits/remove_all_extents.h b/libc/src/__support/CPP/type_traits/remove_all_extents.h
new file mode 100644
index 000000000000000..cea57ee8ccf09a5
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/remove_all_extents.h
@@ -0,0 +1,34 @@
+//===-- remove_all_extents type_traits --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
+
+#include "src/__support/macros/config.h"
+
+namespace __llvm_libc::cpp {
+
+// remove_all_extents
+#if LIBC_HAS_BUILTIN(__remove_all_extents)
+template <typename T> using remove_all_extents_t = __remove_all_extents(T);
+#else
+template <typename T> struct remove_all_extents {
+  using type = T;
+};
+template <typename T> struct remove_all_extents<T[]> {
+  using type = typename remove_all_extents<T>::type;
+};
+template <typename T, size_t _Np> struct remove_all_extents<T[_Np]> {
+  using type = typename remove_all_extents<T>::type;
+};
+#endif
+template <typename T>
+using remove_all_extents_t = typename remove_all_extents<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
diff --git a/libc/src/__support/CPP/type_traits/remove_cv.h b/libc/src/__support/CPP/type_traits/remove_cv.h
new file mode 100644
index 000000000000000..8ce41d64de277f3
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/remove_cv.h
@@ -0,0 +1,25 @@
+//===-- remove_cv type_traits -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_CV_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_CV_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// remove_cv
+template <class T> struct remove_cv : cpp::type_identity<T> {};
+template <class T> struct remove_cv<const T> : cpp::type_identity<T> {};
+template <class T> struct remove_cv<volatile T> : cpp::type_identity<T> {};
+template <class T>
+struct remove_cv<const volatile T> : cpp::type_identity<T> {};
+template <class T> using remove_cv_t = typename remove_cv<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_CV_H
diff --git a/libc/src/__support/CPP/type_traits/remove_cvref.h b/libc/src/__support/CPP/type_traits/remove_cvref.h
new file mode 100644
index 000000000000000..68eb479f548d4a0
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/remove_cvref.h
@@ -0,0 +1,24 @@
+//===-- remove_cvref type_traits --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_CVREF_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_CVREF_H
+
+#include "src/__support/CPP/type_traits/remove_cv.h"
+#include "src/__support/CPP/type_traits/remove_reference.h"
+
+namespace __llvm_libc::cpp {
+
+// remove_cvref
+template <typename T> struct remove_cvref {
+  using type = remove_cv_t<remove_reference_t<T>>;
+};
+template <typename T> using remove_cvref_t = typename remove_cvref<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_CVREF_H
diff --git a/libc/src/__support/CPP/type_traits/remove_extent.h b/libc/src/__support/CPP/type_traits/remove_extent.h
new file mode 100644
index 000000000000000..cc92f8fd080bf29
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/remove_extent.h
@@ -0,0 +1,24 @@
+//===-- remove_extent type_traits -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_EXTENT_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_EXTENT_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// remove_extent
+template <class T> struct remove_extent : cpp::type_identity<T> {};
+template <class T> struct remove_extent<T[]> : cpp::type_identity<T> {};
+template <class T, size_t N>
+struct remove_extent<T[N]> : cpp::type_identity<T> {};
+template <class T> using remove_extent_t = typename remove_extent<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_EXTENT_H
diff --git a/libc/src/__support/CPP/type_traits/remove_reference.h b/libc/src/__support/CPP/type_traits/remove_reference.h
new file mode 100644
index 000000000000000..b1cb17679273827
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/remove_reference.h
@@ -0,0 +1,24 @@
+//===-- remove_reference type_traits ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_REFERENCE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_REFERENCE_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// remove_reference
+template <class T> struct remove_reference : cpp::type_identity<T> {};
+template <class T> struct remove_reference<T &> : cpp::type_identity<T> {};
+template <class T> struct remove_reference<T &&> : cpp::type_identity<T> {};
+template <class T>
+using remove_reference_t = typename remove_reference<T>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_REFERENCE_H
diff --git a/libc/src/__support/CPP/type_traits/true_type.h b/libc/src/__support/CPP/type_traits/true_type.h
new file mode 100644
index 000000000000000..41f1fcadf189503
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/true_type.h
@@ -0,0 +1,20 @@
+//===-- true_type type_traits -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_TRUE_TYPE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_TRUE_TYPE_H
+
+#include "src/__support/CPP/type_traits/bool_constant.h"
+
+namespace __llvm_libc::cpp {
+
+// true_type
+using true_type = cpp::bool_constant<true>;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_TRUE_TYPE_H
diff --git a/libc/src/__support/CPP/type_traits/type_identity.h b/libc/src/__support/CPP/type_traits/type_identity.h
new file mode 100644
index 000000000000000..eaba0a9fbec47f4
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/type_identity.h
@@ -0,0 +1,20 @@
+//===-- type_identity type_traits -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_TYPE_IDENTITY_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_TYPE_IDENTITY_H
+
+namespace __llvm_libc::cpp {
+
+// type_identity
+template <typename T> struct type_identity {
+  using type = T;
+};
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_TYPE_IDENTITY_H
diff --git a/libc/src/__support/CPP/type_traits/void_t.h b/libc/src/__support/CPP/type_traits/void_t.h
new file mode 100644
index 000000000000000..237e7ce9744151b
--- /dev/null
+++ b/libc/src/__support/CPP/type_traits/void_t.h
@@ -0,0 +1,26 @@
+//===-- void_t type_traits --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_VOID_T_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_VOID_T_H
+
+#include "src/__support/CPP/type_traits/type_identity.h"
+
+namespace __llvm_libc::cpp {
+
+// void_t
+
+namespace detail {
+template <typename... Ts> struct make_void : cpp::type_identity<void> {};
+} // namespace detail
+
+template <typename... Ts>
+using void_t = typename detail::make_void<Ts...>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_VOID_T_H
diff --git a/libc/src/__support/CPP/utility.h b/libc/src/__support/CPP/utility.h
index 40455d5e61f8797..105d3a21dc2b00d 100644
--- a/libc/src/__support/CPP/utility.h
+++ b/libc/src/__support/CPP/utility.h
@@ -9,48 +9,9 @@
 #ifndef LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_H
 #define LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_H
 
-#include "src/__support/CPP/type_traits.h"
-#include "src/__support/macros/attributes.h"
-
-namespace __llvm_libc::cpp {
-
-template <typename T, T... Ints> struct integer_sequence {
-  static_assert(is_integral_v<T>);
-  template <T Next> using append = integer_sequence<T, Ints..., Next>;
-};
-
-namespace internal {
-
-template <typename T, int N> struct make_integer_sequence {
-  using type =
-      typename make_integer_sequence<T, N - 1>::type::template append<N>;
-};
-
-template <typename T> struct make_integer_sequence<T, -1> {
-  using type = integer_sequence<T>;
-};
-
-} // namespace internal
-
-template <typename T, int N>
-using make_integer_sequence =
-    typename internal::make_integer_sequence<T, N - 1>::type;
-
-template <typename T>
-LIBC_INLINE constexpr T &&forward(typename remove_reference<T>::type &value) {
-  return static_cast<T &&>(value);
-}
-
-template <typename T>
-LIBC_INLINE constexpr T &&forward(typename remove_reference<T>::type &&value) {
-  return static_cast<T &&>(value);
-}
-
-template <typename T>
-LIBC_INLINE constexpr typename remove_reference<T>::type &&move(T &&value) {
-  return static_cast<typename remove_reference<T>::type &&>(value);
-}
-
-} // namespace __llvm_libc::cpp
+#include "src/__support/CPP/utility/declval.h"
+#include "src/__support/CPP/utility/forward.h"
+#include "src/__support/CPP/utility/integer_sequence.h"
+#include "src/__support/CPP/utility/move.h"
 
 #endif // LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_H
diff --git a/libc/src/__support/CPP/utility/declval.h b/libc/src/__support/CPP/utility/declval.h
new file mode 100644
index 000000000000000..9261ceb9332d518
--- /dev/null
+++ b/libc/src/__support/CPP/utility/declval.h
@@ -0,0 +1,28 @@
+//===-- declval utility -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_DECLVAL_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_DECLVAL_H
+
+#include "src/__support/CPP/type_traits/add_rvalue_reference.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// declval
+namespace detail {
+template <typename T> LIBC_INLINE_VAR constexpr bool always_false = false;
+}
+
+template <typename T> cpp::add_rvalue_reference_t<T> declval() {
+  static_assert(detail::always_false<T>,
+                "declval not allowed in an evaluated context");
+}
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_DECLVAL_H
diff --git a/libc/src/__support/CPP/utility/forward.h b/libc/src/__support/CPP/utility/forward.h
new file mode 100644
index 000000000000000..a6698a589cb40e0
--- /dev/null
+++ b/libc/src/__support/CPP/utility/forward.h
@@ -0,0 +1,32 @@
+//===-- forward utility -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_FORWARD_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_FORWARD_H
+
+#include "src/__support/CPP/type_traits/is_lvalue_reference.h"
+#include "src/__support/CPP/type_traits/remove_reference.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc::cpp {
+
+// forward
+template <typename T>
+LIBC_INLINE constexpr T &&forward(remove_reference_t<T> &value) {
+  return static_cast<T &&>(value);
+}
+
+template <typename T>
+LIBC_INLINE constexpr T &&forward(remove_reference_t<T> &&value) {
+  static_assert(!is_lvalue_reference_v<T>,
+                "cannot forward an rvalue as an lvalue");
+  return static_cast<T &&>(value);
+}
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_FORWARD_H
diff --git a/libc/src/__support/CPP/utility/integer_sequence.h b/libc/src/__support/CPP/utility/integer_sequence.h
new file mode 100644
index 000000000000000..471567f714f882d
--- /dev/null
+++ b/libc/src/__support/CPP/utility/integer_sequence.h
@@ -0,0 +1,37 @@
+//===-- integer_sequence utility --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_INTEGER_SEQUENCE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_INTEGER_SEQUENCE_H
+
+#include "src/__support/CPP/type_traits/is_integral.h"
+
+namespace __llvm_libc::cpp {
+
+// integer_sequence
+template <typename T, T... Ints> struct integer_sequence {
+  static_assert(cpp::is_integral_v<T>);
+  template <T Next> using append = integer_sequence<T, Ints..., Next>;
+};
+
+namespace detail {
+template <typename T, int N> struct make_integer_sequence {
+  using type =
+      typename make_integer_sequence<T, N - 1>::type::template append<N>;
+};
+template <typename T> struct make_integer_sequence<T, -1> {
+  using type = integer_sequence<T>;
+};
+} // namespace detail
+
+template <typename T, int N>
+using make_integer_sequence =
+    typename detail::make_integer_sequence<T, N - 1>::type;
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_INTEGER_SEQUENCE_H
diff --git a/libc/src/__support/CPP/utility/move.h b/libc/src/__support/CPP/utility/move.h
new file mode 100644
index 000000000000000..3cc73c76ce9aff0
--- /dev/null
+++ b/libc/src/__support/CPP/utility/move.h
@@ -0,0 +1,22 @@
+//===-- move utility --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_MOVE_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_MOVE_H
+
+#include "src/__support/CPP/type_traits/remove_reference.h"
+
+namespace __llvm_libc::cpp {
+
+// move
+template <class T> constexpr cpp::remove_reference_t<T> &&move(T &&t) {
+  return static_cast<typename cpp::remove_reference_t<T> &&>(t);
+}
+
+} // namespace __llvm_libc::cpp
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_MOVE_H
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index a25e83691c98c1d..2957ff54882af81 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -280,7 +280,53 @@ libc_support_library(
 
 libc_support_library(
     name = "__support_cpp_type_traits",
-    hdrs = ["src/__support/CPP/type_traits.h"],
+    hdrs = [
+        "src/__support/CPP/type_traits.h",
+        "src/__support/CPP/type_traits/add_lvalue_reference.h",
+        "src/__support/CPP/type_traits/add_pointer.h",
+        "src/__support/CPP/type_traits/add_rvalue_reference.h",
+        "src/__support/CPP/type_traits/bool_constant.h",
+        "src/__support/CPP/type_traits/conditional.h",
+        "src/__support/CPP/type_traits/decay.h",
+        "src/__support/CPP/type_traits/enable_if.h",
+        "src/__support/CPP/type_traits/false_type.h",
+        "src/__support/CPP/type_traits/integral_constant.h",
+        "src/__support/CPP/type_traits/is_arithmetic.h",
+        "src/__support/CPP/type_traits/is_array.h",
+        "src/__support/CPP/type_traits/is_base_of.h",
+        "src/__support/CPP/type_traits/is_class.h",
+        "src/__support/CPP/type_traits/is_const.h",
+        "src/__support/CPP/type_traits/is_convertible.h",
+        "src/__support/CPP/type_traits/is_destructible.h",
+        "src/__support/CPP/type_traits/is_enum.h",
+        "src/__support/CPP/type_traits/is_floating_point.h",
+        "src/__support/CPP/type_traits/is_function.h",
+        "src/__support/CPP/type_traits/is_integral.h",
+        "src/__support/CPP/type_traits/is_lvalue_reference.h",
+        "src/__support/CPP/type_traits/is_null_pointer.h",
+        "src/__support/CPP/type_traits/is_pointer.h",
+        "src/__support/CPP/type_traits/is_reference.h",
+        "src/__support/CPP/type_traits/is_rvalue_reference.h",
+        "src/__support/CPP/type_traits/is_same.h",
+        "src/__support/CPP/type_traits/is_signed.h",
+        "src/__support/CPP/type_traits/is_trivially_constructible.h",
+        "src/__support/CPP/type_traits/is_trivially_copyable.h",
+        "src/__support/CPP/type_traits/is_trivially_destructible.h",
+        "src/__support/CPP/type_traits/is_union.h",
+        "src/__support/CPP/type_traits/is_unsigned.h",
+        "src/__support/CPP/type_traits/is_void.h",
+        "src/__support/CPP/type_traits/make_signed.h",
+        "src/__support/CPP/type_traits/make_unsigned.h",
+        "src/__support/CPP/type_traits/remove_all_extents.h",
+        "src/__support/CPP/type_traits/remove_cv.h",
+        "src/__support/CPP/type_traits/remove_cvref.h",
+        "src/__support/CPP/type_traits/remove_extent.h",
+        "src/__support/CPP/type_traits/remove_reference.h",
+        "src/__support/CPP/type_traits/true_type.h",
+        "src/__support/CPP/type_traits/type_identity.h",
+        "src/__support/CPP/type_traits/void_t.h",
+        "src/__support/CPP/utility/declval.h",
+    ],
     deps = [
         ":__support_macros_attributes",
         ":__support_macros_config",
@@ -290,7 +336,13 @@ libc_support_library(
 
 libc_support_library(
     name = "__support_cpp_utility",
-    hdrs = ["src/__support/CPP/utility.h"],
+    hdrs = [
+        "src/__support/CPP/utility.h",
+        "src/__support/CPP/utility/declval.h",
+        "src/__support/CPP/utility/forward.h",
+        "src/__support/CPP/utility/integer_sequence.h",
+        "src/__support/CPP/utility/move.h",
+    ],
     deps = [
         ":__support_cpp_type_traits",
         ":__support_macros_attributes",

>From 004ea55e08d628010198456636c022dfa72e807e Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Tue, 5 Sep 2023 11:49:35 +0000
Subject: [PATCH 2/3] Fix missing include in functional

---
 libc/src/__support/CPP/functional.h | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/CPP/functional.h b/libc/src/__support/CPP/functional.h
index ed5775d3fe64419..5ddb988d3312566 100644
--- a/libc/src/__support/CPP/functional.h
+++ b/libc/src/__support/CPP/functional.h
@@ -15,6 +15,7 @@
 #include "src/__support/CPP/type_traits/is_void.h"
 #include "src/__support/CPP/type_traits/remove_cvref.h"
 #include "src/__support/CPP/type_traits/remove_reference.h"
+#include "src/__support/CPP/utility/forward.h"
 #include "src/__support/macros/attributes.h"
 
 #include <stdint.h>
@@ -34,7 +35,7 @@ template <typename Ret, typename... Params> class function<Ret(Params...)> {
   template <typename Callable>
   LIBC_INLINE static Ret callback_fn(intptr_t callable, Params... params) {
     return (*reinterpret_cast<Callable *>(callable))(
-        forward<Params>(params)...);
+        cpp::forward<Params>(params)...);
   }
 
 public:
@@ -46,17 +47,18 @@ template <typename Ret, typename... Params> class function<Ret(Params...)> {
   LIBC_INLINE function(
       Callable &&callable,
       // This is not the copy-constructor.
-      enable_if_t<!is_same_v<remove_cvref_t<Callable>, function>> * = nullptr,
+      enable_if_t<!cpp::is_same_v<remove_cvref_t<Callable>, function>> * =
+          nullptr,
       // Functor must be callable and return a suitable type.
-      enable_if_t<is_void_v<Ret> ||
-                  is_convertible_v<
+      enable_if_t<cpp::is_void_v<Ret> ||
+                  cpp::is_convertible_v<
                       decltype(declval<Callable>()(declval<Params>()...)), Ret>>
           * = nullptr)
-      : callback(callback_fn<remove_reference_t<Callable>>),
+      : callback(callback_fn<cpp::remove_reference_t<Callable>>),
         callable(reinterpret_cast<intptr_t>(&callable)) {}
 
   LIBC_INLINE Ret operator()(Params... params) const {
-    return callback(callable, forward<Params>(params)...);
+    return callback(callable, cpp::forward<Params>(params)...);
   }
 
   LIBC_INLINE explicit operator bool() const { return callback; }

>From 67c294300f1f22cb67d0f0317ac5c8dfb05b4212 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Tue, 5 Sep 2023 11:49:58 +0000
Subject: [PATCH 3/3] fix remove_all_extents

---
 libc/src/__support/CPP/type_traits/remove_all_extents.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/CPP/type_traits/remove_all_extents.h b/libc/src/__support/CPP/type_traits/remove_all_extents.h
index cea57ee8ccf09a5..6e451a56375aed5 100644
--- a/libc/src/__support/CPP/type_traits/remove_all_extents.h
+++ b/libc/src/__support/CPP/type_traits/remove_all_extents.h
@@ -8,6 +8,7 @@
 #ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
 #define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_REMOVE_ALL_EXTENTS_H
 
+#include "src/__support/CPP/type_traits/bool_constant.h"
 #include "src/__support/macros/config.h"
 
 namespace __llvm_libc::cpp {
@@ -15,6 +16,8 @@ namespace __llvm_libc::cpp {
 // remove_all_extents
 #if LIBC_HAS_BUILTIN(__remove_all_extents)
 template <typename T> using remove_all_extents_t = __remove_all_extents(T);
+template <typename T>
+struct remove_all_extents : bool_constant<remove_all_extents_t<T>> {};
 #else
 template <typename T> struct remove_all_extents {
   using type = T;
@@ -25,9 +28,9 @@ template <typename T> struct remove_all_extents<T[]> {
 template <typename T, size_t _Np> struct remove_all_extents<T[_Np]> {
   using type = typename remove_all_extents<T>::type;
 };
-#endif
 template <typename T>
 using remove_all_extents_t = typename remove_all_extents<T>::type;
+#endif
 
 } // namespace __llvm_libc::cpp
 



More information about the llvm-commits mailing list