[libcxx-commits] [libcxx] [libc++] Optimize `text_encoding::environment_is()` for UTF-8, ASCII, Windows1252 and ISOLatin1 (PR #225136)

William Tran-Viet via libcxx-commits libcxx-commits at lists.llvm.org
Mon Sep 21 10:48:48 PDT 2026


https://github.com/smallp-o-p updated https://github.com/llvm/llvm-project/pull/225136

>From b9397300045282fabda08ec91e0e773147046d0d Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Mon, 21 Sep 2026 12:04:53 -0400
Subject: [PATCH 1/2] Optimize environment_is() for UTF-8, ASCII, Windows1252
 and ISOLatin1

---
 libcxx/include/text_encoding | 48 +++++++++++++++++++++++++++++++++---
 libcxx/src/text_encoding.cpp |  4 +++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/text_encoding b/libcxx/include/text_encoding
index c0708e3af05f7f..e21f83b9fadde3 100644
--- a/libcxx/include/text_encoding
+++ b/libcxx/include/text_encoding
@@ -70,6 +70,7 @@ struct text_encoding
 
 #    include <__algorithm/find_if.h>
 #    include <__algorithm/lower_bound.h>
+#    include <__algorithm/ranges_any_of.h>
 #    include <__cstddef/ptrdiff_t.h>
 #    include <__functional/hash.h>
 #    include <__iterator/iterator_traits.h>
@@ -77,6 +78,7 @@ struct text_encoding
 #    include <__ranges/view_interface.h>
 #    include <climits>
 #    include <cstdint>
+#    include <initializer_list>
 #    include <string_view>
 #    include <version>
 
@@ -85,6 +87,8 @@ struct text_encoding;
 
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
+_LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT _LIBCPP_HIDDEN const char* __get_environment_encoding_name() noexcept;
+
 _LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT _LIBCPP_EXPORTED_FROM_ABI text_encoding
 __get_locale_encoding(const char* __name);
 
@@ -606,12 +610,50 @@ public:
 
   template <id _Id>
   [[nodiscard]] _LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT static bool environment_is() {
-    // TODO: It may be worthwhile to implement an optimization for popular encodings, e.g. UTF-8,
-    // to allow checking the environment text encoding without needing to use the data tables.
-
 #      if defined(__ANDROID__)
     return _Id == std::text_encoding::id::UTF8;
 #      else
+    const char* __env_name = __get_environment_encoding_name();
+
+    auto __predicate = [__env_name](auto __str) { return __comp_name(__str, __env_name); };
+
+    if constexpr (_Id == id::UTF8) {
+      return std::ranges::any_of(initializer_list<const char*>{"UTF-8, csUTF8"}, __predicate);
+    }
+    if constexpr (_Id == id::ASCII) {
+      return std::ranges::any_of(
+          initializer_list<const char*>{
+              "US-ASCII",
+              "ANSI_X3.4-1968",
+              "ANSI_X3.4-1986",
+              "IBM367",
+              "ISO646-US",
+              "ISO_646.irv:1991",
+              "cp367",
+              "csASCII",
+              "ASCII",
+              "iso-ir-6",
+              "us"},
+          __predicate);
+    }
+    if constexpr (_Id == id::windows1252) {
+      return std::ranges::any_of(initializer_list<const char*>{"windows-1252, cswindows1252"}, __predicate);
+    }
+    if constexpr (_Id == id::ISOLatin1) {
+      return std::ranges::any_of(
+          initializer_list<const char*>{
+              "ISO-8859-1",
+              "ISO_8859-1:1987",
+              "CP819",
+              "IBM819",
+              "ISO_8859-1",
+              "csISOLatin1",
+              "iso-ir-100",
+              "l1",
+              "latin1"},
+          __predicate);
+    }
+
     return environment() == _Id;
 #      endif
   }
diff --git a/libcxx/src/text_encoding.cpp b/libcxx/src/text_encoding.cpp
index 0804c3457f1e66..eb0d3b59202d4d 100644
--- a/libcxx/src/text_encoding.cpp
+++ b/libcxx/src/text_encoding.cpp
@@ -14,6 +14,10 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
+const char* __get_environment_encoding_name() noexcept {
+  return __locale::__get_locale_encoding(static_cast<__locale::__locale_t>(0));
+}
+
 #if defined(__ANDROID__)
 // UTF-8 is the always the environment encoding on Android.
 std::text_encoding __get_locale_encoding([[maybe_unused]] const char* __name) { return std::text_encoding::id::UTF8; }

>From 65631f343570bf1bfc2ebd0e5ae107eaa152de4c Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Mon, 21 Sep 2026 13:48:29 -0400
Subject: [PATCH 2/2] (Unfortunately) Add a symbol to the ABI

---
 libcxx/include/text_encoding                                   | 3 ++-
 ...nown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/text_encoding b/libcxx/include/text_encoding
index e21f83b9fadde3..849f1c54efaa48 100644
--- a/libcxx/include/text_encoding
+++ b/libcxx/include/text_encoding
@@ -87,7 +87,8 @@ struct text_encoding;
 
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
-_LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT _LIBCPP_HIDDEN const char* __get_environment_encoding_name() noexcept;
+_LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT _LIBCPP_EXPORTED_FROM_ABI const char*
+__get_environment_encoding_name() noexcept;
 
 _LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT _LIBCPP_EXPORTED_FROM_ABI text_encoding
 __get_locale_encoding(const char* __name);
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index c727c028d21e60..50f36962e69c02 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1234,6 +1234,7 @@
 {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__131__get_environment_encoding_nameEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}



More information about the libcxx-commits mailing list