[libc-commits] [libc] [libc] Handle charNN_t cpp::is_integral (PR #177463)

Roland McGrath via libc-commits libc-commits at lists.llvm.org
Thu Jan 22 12:46:24 PST 2026


https://github.com/frobtech created https://github.com/llvm/llvm-project/pull/177463

In C++20, char8_t is a distinct type from unsigned char, but is
still an integral type.  char16_t and char32_t are integral types
in both C++17 and C++20.

This also reverts the change in PR #177421, which is not needed
when cpp::is_integral_v<char8_t> works correctly in all modes.


>From 61f5b9a5b7e1a6beb304b932a03fff632f1550a1 Mon Sep 17 00:00:00 2001
From: Roland McGrath <mcgrathr at google.com>
Date: Thu, 22 Jan 2026 12:36:12 -0800
Subject: [PATCH] [libc] Handle charNN_t cpp::is_integral

In C++20, char8_t is a distinct type from unsigned char, but is
still an integral type.  char16_t and char32_t are integral types
in both C++17 and C++20.

This also reverts the change in PR #177421, which is not needed
when cpp::is_integral_v<char8_t> works correctly in all modes.
---
 libc/src/__support/CPP/type_traits/is_integral.h | 15 ++++++++++-----
 libc/src/__support/wchar/character_converter.h   |  3 +--
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_integral.h b/libc/src/__support/CPP/type_traits/is_integral.h
index 96ba09a07ddc6..09047cb00bf75 100644
--- a/libc/src/__support/CPP/type_traits/is_integral.h
+++ b/libc/src/__support/CPP/type_traits/is_integral.h
@@ -26,13 +26,18 @@ template <typename T> struct is_integral {
   }
 
 public:
-  LIBC_INLINE_VAR static constexpr bool value = __is_unqualified_any_of<
-      T,
+  LIBC_INLINE_VAR static constexpr bool value =
+      __is_unqualified_any_of<T,
 #ifdef LIBC_TYPES_HAS_INT128
-      __int128_t, __uint128_t,
+                              __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>();
+#ifdef __cpp_char8_t
+                              char8_t,
+#endif
+                              char16_t, char32_t, 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;
diff --git a/libc/src/__support/wchar/character_converter.h b/libc/src/__support/wchar/character_converter.h
index d0a942ecb3bb1..e7300166556ac 100644
--- a/libc/src/__support/wchar/character_converter.h
+++ b/libc/src/__support/wchar/character_converter.h
@@ -77,8 +77,7 @@ LIBC_INLINE bool CharacterConverter::isValidState() {
 }
 
 LIBC_INLINE int CharacterConverter::push(char8_t utf8_byte) {
-  uint8_t num_ones =
-      static_cast<uint8_t>(cpp::countl_one(static_cast<uint8_t>(utf8_byte)));
+  uint8_t num_ones = static_cast<uint8_t>(cpp::countl_one(utf8_byte));
   // Checking the first byte if first push
   if (isEmpty()) {
     // UTF-8 char has 1 byte total



More information about the libc-commits mailing list