[libcxx-commits] [libcxx] [libc++] Implement our own is{, x}digit functions for the C locale (PR #165467)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Oct 28 12:38:46 PDT 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/165467
The C locale is defined by the C standard, so we know exactly which digits classify as (x)digits. Instead of going through the locale base API we can simply implement functions which determine whether a charachter is one ourselves, and probably improve code gen significantly as well that way.
>From 4f59971aea2dc1bb390b79a30393daec0b7e97a2 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 28 Oct 2025 20:37:15 +0100
Subject: [PATCH] [libc++] Implement our own is{,x}digit functions for the C
locale
---
libcxx/include/__locale_dir/locale_base_api.h | 5 -----
libcxx/include/__locale_dir/num.h | 13 +++++++++++--
libcxx/include/__locale_dir/support/bsd_like.h | 4 ----
libcxx/include/__locale_dir/support/linux.h | 4 ----
.../__locale_dir/support/no_locale/characters.h | 4 ----
libcxx/include/__locale_dir/support/windows.h | 4 ----
6 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 9f3ce02a3af20..152eccee1cdda 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -64,8 +64,6 @@
// Character manipulation functions
// --------------------------------
// namespace __locale {
-// int __isdigit(int, __locale_t); // required by the headers
-// int __isxdigit(int, __locale_t); // required by the headers
// int __toupper(int, __locale_t);
// int __tolower(int, __locale_t);
// int __strcoll(const char*, const char*, __locale_t);
@@ -204,9 +202,6 @@ __strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); }
-
# if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
return strcoll_l(__s1, __s2, __loc);
diff --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h
index 7ca8ffe348959..224d7b9d2c668 100644
--- a/libcxx/include/__locale_dir/num.h
+++ b/libcxx/include/__locale_dir/num.h
@@ -748,6 +748,15 @@ void __num_put<_CharT>::__widen_and_group_int(
__op = __ob + (__np - __nb);
}
+_LIBCPP_HIDE_FROM_ABI inline bool __isdigit(char __c) {
+ return __c >= '0' && __c <= '9';
+}
+
+_LIBCPP_HIDE_FROM_ABI inline bool __isxdigit(char __c) {
+ auto __lower = __c | 0x20;
+ return std::__isdigit(__c) || (__lower >= 'a' && __lower <= 'f');
+}
+
template <class _CharT>
void __num_put<_CharT>::__widen_and_group_float(
char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) {
@@ -763,11 +772,11 @@ void __num_put<_CharT>::__widen_and_group_float(
*__oe++ = __ct.widen(*__nf++);
*__oe++ = __ct.widen(*__nf++);
for (__ns = __nf; __ns < __ne; ++__ns)
- if (!__locale::__isxdigit(*__ns, _LIBCPP_GET_C_LOCALE))
+ if (!std::__isxdigit(*__ns))
break;
} else {
for (__ns = __nf; __ns < __ne; ++__ns)
- if (!__locale::__isdigit(*__ns, _LIBCPP_GET_C_LOCALE))
+ if (!std::__isdigit(*__ns))
break;
}
if (__grouping.empty()) {
diff --git a/libcxx/include/__locale_dir/support/bsd_like.h b/libcxx/include/__locale_dir/support/bsd_like.h
index ac402924709e5..568cc17993cf8 100644
--- a/libcxx/include/__locale_dir/support/bsd_like.h
+++ b/libcxx/include/__locale_dir/support/bsd_like.h
@@ -89,10 +89,6 @@ __strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return ::isdigit_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return ::isxdigit_l(__c, __loc); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::toupper_l(__c, __loc); }
diff --git a/libcxx/include/__locale_dir/support/linux.h b/libcxx/include/__locale_dir/support/linux.h
index 23bcf44c31dbf..94a2ecb9a940d 100644
--- a/libcxx/include/__locale_dir/support/linux.h
+++ b/libcxx/include/__locale_dir/support/linux.h
@@ -116,10 +116,6 @@ __strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return isdigit_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return isxdigit_l(__c, __loc); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); }
diff --git a/libcxx/include/__locale_dir/support/no_locale/characters.h b/libcxx/include/__locale_dir/support/no_locale/characters.h
index 1281b8bd13094..73eba3ec542c7 100644
--- a/libcxx/include/__locale_dir/support/no_locale/characters.h
+++ b/libcxx/include/__locale_dir/support/no_locale/characters.h
@@ -29,10 +29,6 @@ namespace __locale {
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t) { return std::isdigit(__c); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t) { return std::isxdigit(__c); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t) { return std::toupper(__c); }
diff --git a/libcxx/include/__locale_dir/support/windows.h b/libcxx/include/__locale_dir/support/windows.h
index 0df8709f118d0..edd8a66c23e80 100644
--- a/libcxx/include/__locale_dir/support/windows.h
+++ b/libcxx/include/__locale_dir/support/windows.h
@@ -197,10 +197,6 @@ __strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
//
// Character manipulation functions
//
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return _isdigit_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return _isxdigit_l(__c, __loc); }
-
#if defined(_LIBCPP_BUILDING_LIBRARY)
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::_toupper_l(__c, __loc); }
More information about the libcxx-commits
mailing list