[libcxx-commits] [libcxx] 8a531c3 - [libc++] Implement P1885R12: `<text_encoding>` (#141312)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jun 24 16:46:16 PDT 2026
Author: William Tran-Viet
Date: 2026-06-25T07:46:11+08:00
New Revision: 8a531c3608c722ad529be448d6ecef06ba107228
URL: https://github.com/llvm/llvm-project/commit/8a531c3608c722ad529be448d6ecef06ba107228
DIFF: https://github.com/llvm/llvm-project/commit/8a531c3608c722ad529be448d6ecef06ba107228.diff
LOG: [libc++] Implement P1885R12: `<text_encoding>` (#141312)
Resolves #105373, resolves #118371 and resolves #105332
- Implements `<text_encoding>`
- Adds availability macros for LLVM 23.
- The data is stored in three tables:
- One giant string split by null-terminators to represent the aliases
- An index table which stores indexes into the string, each entry
representing the first character of an alias
- Text encoding data, which stores an index to the index table, the MIB,
and the number of aliases the encoding has.
Storing it in the above manner allows us to make significant savings in
binary file size and required runtime storage for the data.
As required by the LLVM Project's AI use policy:
- The implementation for `__get_locale_encoding(const char*)` for
Windows has been developed with the assistance of AI.
---------
Co-authored-by: A. Jiang <de34 at live.cn>
Added:
libcxx/include/text_encoding
libcxx/src/text_encoding.cpp
libcxx/test/libcxx/text/text_encoding/environment.android.pass.cpp
libcxx/test/libcxx/text/text_encoding/environment.pass.cpp
libcxx/test/libcxx/text/text_encoding/environment.windows.pass.cpp
libcxx/test/libcxx/text/text_encoding/nodiscard.verify.cpp
libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.id.pass.cpp
libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.string_view.pass.cpp
libcxx/test/libcxx/text/text_encoding/text_encoding.members/environment.delete.verify.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/text_encoding.version.compile.pass.cpp
libcxx/test/std/localization/locales/locale/locale.members/encoding.pass.cpp
libcxx/test/std/text/text_encoding/test_text_encoding.h
libcxx/test/std/text/text_encoding/text_encoding.ctor/default.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.ctor/id.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.ctor/string_view.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.eq/equal.id.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.eq/equal.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.hash/enabled_hash.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.hash/hash.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/aliases.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/aliases_view.compile.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/environment.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/id.compile.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/literal.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/begin.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/empty.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/end.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/front.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/index.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/iterator.pass.cpp
libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/operator-bool.pass.cpp
libcxx/test/std/text/text_encoding/trivially_copyable.compile.pass.cpp
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/docs/ReleaseNotes/23.rst
libcxx/docs/Status/Cxx26Issues.csv
libcxx/docs/Status/Cxx26Papers.csv
libcxx/include/CMakeLists.txt
libcxx/include/__configuration/availability.h
libcxx/include/__locale
libcxx/include/__locale_dir/locale_base_api.h
libcxx/include/__locale_dir/support/aix.h
libcxx/include/__locale_dir/support/bsd_like.h
libcxx/include/__locale_dir/support/linux.h
libcxx/include/__locale_dir/support/newlib.h
libcxx/include/__locale_dir/support/windows.h
libcxx/include/module.modulemap.in
libcxx/include/version
libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
libcxx/modules/std.compat.cppm.in
libcxx/modules/std.cppm.in
libcxx/modules/std/text_encoding.inc
libcxx/src/CMakeLists.txt
libcxx/src/support/win32/locale_win32.cpp
libcxx/test/libcxx/localization/nodiscard.verify.cpp
libcxx/test/libcxx/transitive_includes/cxx03.csv
libcxx/test/libcxx/transitive_includes/cxx11.csv
libcxx/test/libcxx/transitive_includes/cxx14.csv
libcxx/test/libcxx/transitive_includes/cxx17.csv
libcxx/test/libcxx/transitive_includes/cxx20.csv
libcxx/test/libcxx/transitive_includes/cxx23.csv
libcxx/test/libcxx/transitive_includes/cxx26.csv
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
libcxx/utils/generate_feature_test_macro_components.py
libcxx/utils/libcxx/header_information.py
libcxx/utils/libcxx/test/features/availability.py
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 47f10324e2523..f8719f1f74c6d 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -536,7 +536,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_submdspan`` *unimplemented*
---------------------------------------------------------- -----------------
- ``__cpp_lib_text_encoding`` *unimplemented*
+ ``__cpp_lib_text_encoding`` ``202306L``
---------------------------------------------------------- -----------------
``__cpp_lib_to_chars`` *unimplemented*
---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index a491306a3cffb..1abe4f7c3b9e4 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -39,7 +39,9 @@ Implemented Papers
------------------
- P2440R1: ``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right`` (`Github <https://llvm.org/PR105184>`__)
+- P1885R12: Naming Text Encodings to Demystify Them (`Github <https://llvm.org/PR105373>`__)
- P1899R3: ``stride_view`` (`Github <https://llvm.org/PR105198>`__)
+- P2862R1: ``text_encoding::name()`` should never return null values (`Github <https://llvm.org/PR118371>`__)
- P3936R1: Safer ``atomic_ref::address`` (`Github <https://llvm.org/PR189594>`__)
- P3953R3: Rename ``std::runtime_format`` (`Github <https://llvm.org/PR189624>`__)
- P4052R0: Renaming saturation arithmetic functions (`Github <https://llvm.org/PR189589>`__)
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index 419e5755ed4a8..d4f7a44910e00 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -56,7 +56,7 @@
"`LWG4035 <https://wg21.link/LWG4035>`__","``single_view`` should provide ``empty``","2024-03 (Tokyo)","|Complete|","19","`#105328 <https://github.com/llvm/llvm-project/issues/105328>`__",""
"`LWG4036 <https://wg21.link/LWG4036>`__","``__alignof_is_defined`` is only implicitly specified in C++ and not yet deprecated","2024-03 (Tokyo)","","","`#105329 <https://github.com/llvm/llvm-project/issues/105329>`__",""
"`LWG4037 <https://wg21.link/LWG4037>`__","Static data members of ``ctype_base`` are not yet required to be usable in constant expressions","2024-03 (Tokyo)","","","`#105330 <https://github.com/llvm/llvm-project/issues/105330>`__",""
-"`LWG4038 <https://wg21.link/LWG4038>`__","``std::text_encoding::aliases_view`` should have constexpr iterators","2024-03 (Tokyo)","","","`#105332 <https://github.com/llvm/llvm-project/issues/105332>`__",""
+"`LWG4038 <https://wg21.link/LWG4038>`__","``std::text_encoding::aliases_view`` should have constexpr iterators","2024-03 (Tokyo)","|Complete|","23","`#105332 <https://github.com/llvm/llvm-project/issues/105332>`__",""
"`LWG4043 <https://wg21.link/LWG4043>`__","""ASCII"" is not a registered character encoding","2024-03 (Tokyo)","|Nothing To Do|","","`#105335 <https://github.com/llvm/llvm-project/issues/105335>`__",""
"`LWG4045 <https://wg21.link/LWG4045>`__","``tuple`` can create dangling references from ``tuple-like``","2024-03 (Tokyo)","","","`#105337 <https://github.com/llvm/llvm-project/issues/105337>`__",""
"`LWG4053 <https://wg21.link/LWG4053>`__","Unary call to ``std::views::repeat`` does not decay the argument","2024-03 (Tokyo)","|Complete|","19","`#105338 <https://github.com/llvm/llvm-project/issues/105338>`__",""
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index a951ac4c6c833..9744940459bcd 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -13,7 +13,7 @@
"`P2013R5 <https://wg21.link/P2013R5>`__","Freestanding Language: Optional ``::operator new``","2023-06 (Varna)","","","`#105370 <https://github.com/llvm/llvm-project/issues/105370>`__",""
"`P2363R5 <https://wg21.link/P2363R5>`__","Extending associative containers with the remaining heterogeneous overloads","2023-06 (Varna)","","","`#105371 <https://github.com/llvm/llvm-project/issues/105371>`__",""
"`P1901R2 <https://wg21.link/P1901R2>`__","Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers","2023-06 (Varna)","","","`#105372 <https://github.com/llvm/llvm-project/issues/105372>`__",""
-"`P1885R12 <https://wg21.link/P1885R12>`__","Naming Text Encodings to Demystify Them","2023-06 (Varna)","","","`#105373 <https://github.com/llvm/llvm-project/issues/105373>`__",""
+"`P1885R12 <https://wg21.link/P1885R12>`__","Naming Text Encodings to Demystify Them","2023-06 (Varna)","|Complete|","23","`#105373 <https://github.com/llvm/llvm-project/issues/105373>`__",""
"`P0792R14 <https://wg21.link/P0792R14>`__","``function_ref``: a type-erased callable reference","2023-06 (Varna)","","","`#105376 <https://github.com/llvm/llvm-project/issues/105376>`__",""
"`P2874R2 <https://wg21.link/P2874R2>`__","P2874R2: Mandating Annex D Require No More","2023-06 (Varna)","|Complete|","12","`#105377 <https://github.com/llvm/llvm-project/issues/105377>`__",""
"`P2757R3 <https://wg21.link/P2757R3>`__","Type-checking format args","2023-06 (Varna)","","","`#105378 <https://github.com/llvm/llvm-project/issues/105378>`__",""
@@ -79,7 +79,7 @@
"`P3136R1 <https://wg21.link/P3136R1>`__","Retiring niebloids","2024-11 (Wrocław)","|Complete|","14","`#118133 <https://github.com/llvm/llvm-project/issues/118133>`__",""
"`P3138R5 <https://wg21.link/P3138R5>`__","``views::cache_latest``","2024-11 (Wrocław)","","","`#118134 <https://github.com/llvm/llvm-project/issues/118134>`__",""
"`P3379R0 <https://wg21.link/P3379R0>`__","Constrain ``std::expected`` equality operators","2024-11 (Wrocław)","|Complete|","21","`#118135 <https://github.com/llvm/llvm-project/issues/118135>`__",""
-"`P2862R1 <https://wg21.link/P2862R1>`__","``text_encoding::name()`` should never return null values","2024-11 (Wrocław)","","","`#118371 <https://github.com/llvm/llvm-project/issues/118371>`__",""
+"`P2862R1 <https://wg21.link/P2862R1>`__","``text_encoding::name()`` should never return null values","2024-11 (Wrocław)","|Complete|","23","`#118371 <https://github.com/llvm/llvm-project/issues/118371>`__",""
"`P2897R7 <https://wg21.link/P2897R7>`__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","|Complete|","21","`#118372 <https://github.com/llvm/llvm-project/issues/118372>`__",""
"`P3355R2 <https://wg21.link/P3355R2>`__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","","`#118373 <https://github.com/llvm/llvm-project/issues/118373>`__",""
"`P3222R0 <https://wg21.link/P3222R0>`__","Fix C++26 by adding transposed special cases for P2642 layouts","2024-11 (Wrocław)","","","`#118374 <https://github.com/llvm/llvm-project/issues/118374>`__",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cb7ae820bc012..618686c685bee 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -1090,6 +1090,7 @@ set(files
strstream
syncstream
system_error
+ text_encoding
tgmath.h
thread
tuple
diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h
index d0788083c0128..735af5d431cb1 100644
--- a/libcxx/include/__configuration/availability.h
+++ b/libcxx/include/__configuration/availability.h
@@ -38,6 +38,8 @@
// When availability annotations are disabled, we take for granted that features introduced
// in all versions of the library are available.
#if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
+# define _LIBCPP_INTRODUCED_IN_LLVM_23 1
+# define _LIBCPP_INTRODUCED_IN_LLVM_23_ATTRIBUTE /* nothing */
# define _LIBCPP_INTRODUCED_IN_LLVM_23 1
# define _LIBCPP_INTRODUCED_IN_LLVM_23_ATTRIBUTE /* nothing */
@@ -323,6 +325,10 @@
# define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 0
#endif
+// Controls whether the implementation for text_encoding::environment() is available
+#define _LIBCPP_AVAILABILITY_HAS_TEXT_ENCODING_ENVIRONMENT _LIBCPP_INTRODUCED_IN_LLVM_23
+#define _LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT _LIBCPP_INTRODUCED_IN_LLVM_23_ATTRIBUTE
+
// Only define a bunch of symbols in the dylib if we need to be compatible with LLVM 7 headers or older
# if defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 8
# define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index 33b1924db67c1..99d29c167f29a 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -11,6 +11,7 @@
#define _LIBCPP___LOCALE
#include <__config>
+#include <__configuration/availability.h>
#if _LIBCPP_HAS_LOCALIZATION
@@ -26,6 +27,7 @@
# include <cstdint>
# include <cstdlib>
# include <string>
+# include <text_encoding>
// Some platforms require more includes than others. Keep the includes on all plaforms for now.
# include <cstddef>
@@ -109,6 +111,13 @@ public:
return std::use_facet<std::collate<_CharT> >(*this).compare(
__x.data(), __x.data() + __x.size(), __y.data(), __y.data() + __y.size()) < 0;
}
+# if _LIBCPP_STD_VER >= 26
+ [[nodiscard]] _LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT
+ _LIBCPP_HIDE_FROM_ABI std::text_encoding encoding() const {
+ std::string __name = name();
+ return std::__get_locale_encoding(__name.c_str());
+ }
+# endif
// global locale objects:
static locale global(const locale&);
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index e1e60e18fd7c6..f973d95ef244d 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -102,6 +102,8 @@
//
// int __snprintf(char*, size_t, __locale_t, const char*, ...); // required by the headers
// int __asprintf(char**, __locale_t, const char*, ...); // required by the headers
+//
+// const char* __get_locale_encoding(__locale_t);
// }
#if _LIBCPP_HAS_LOCALIZATION
@@ -139,6 +141,7 @@
# include <__cstddef/size_t.h>
# include <__utility/forward.h>
# include <ctype.h>
+# include <langinfo.h>
# include <string.h>
# include <time.h>
# if _LIBCPP_HAS_WIDE_CHARACTERS
@@ -268,7 +271,12 @@ __mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps,
return __libcpp_mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
}
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
-# endif // _LIBCPP_BUILDING_LIBRARY
+
+inline _LIBCPP_HIDE_FROM_ABI const char* __get_locale_encoding(__locale_t __loc) {
+ return ::nl_langinfo_l(CODESET, __loc);
+}
+
+# endif // _LIBCPP_BUILDING_LIBRARY
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")
diff --git a/libcxx/include/__locale_dir/support/aix.h b/libcxx/include/__locale_dir/support/aix.h
index 8e1a4843900da..4ab52793ae3c1 100644
--- a/libcxx/include/__locale_dir/support/aix.h
+++ b/libcxx/include/__locale_dir/support/aix.h
@@ -17,6 +17,7 @@
#include <cstdio>
#include <cstdlib>
#include <ctype.h>
+#include <langinfo.h>
#include <string.h>
#include <time.h>
#if _LIBCPP_HAS_WIDE_CHARACTERS
@@ -79,6 +80,10 @@ inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
__locale_guard __current(__loc);
return std::localeconv();
}
+
+inline _LIBCPP_HIDE_FROM_ABI const char* __get_locale_encoding(__locale_t __loc) {
+ return ::nl_langinfo_l(CODESET, __loc);
+}
#endif // _LIBCPP_BUILDING_LIBRARY
// The following structure is a quick-and-dirty workaround for routines that AIX
diff --git a/libcxx/include/__locale_dir/support/bsd_like.h b/libcxx/include/__locale_dir/support/bsd_like.h
index 1a84c351eb9d1..6632ca51e1eaa 100644
--- a/libcxx/include/__locale_dir/support/bsd_like.h
+++ b/libcxx/include/__locale_dir/support/bsd_like.h
@@ -15,6 +15,7 @@
#include <__utility/forward.h>
#include <clocale> // std::lconv
#include <ctype.h>
+#include <langinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -180,7 +181,11 @@ __mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps,
return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
}
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
-#endif // _LIBCPP_BUILDING_LIBRARY
+
+inline _LIBCPP_HIDE_FROM_ABI const char* __get_locale_encoding(__locale_t __loc) {
+ return ::nl_langinfo_l(CODESET, __loc);
+}
+#endif // _LIBCPP_BUILDING_LIBRARY
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")
diff --git a/libcxx/include/__locale_dir/support/linux.h b/libcxx/include/__locale_dir/support/linux.h
index 2fe3f6bb8124f..6a91a001c239c 100644
--- a/libcxx/include/__locale_dir/support/linux.h
+++ b/libcxx/include/__locale_dir/support/linux.h
@@ -17,6 +17,7 @@
#include <cstdio>
#include <cstdlib>
#include <ctype.h>
+#include <langinfo.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
@@ -211,7 +212,15 @@ __mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps,
return std::mbsrtowcs(__dest, __src, __len, __ps);
}
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
-#endif // _LIBCPP_BUILDING_LIBRARY
+
+inline _LIBCPP_HIDE_FROM_ABI const char* __get_locale_encoding([[maybe_unused]] __locale_t __loc) {
+# if defined(__ANDROID__)
+ return "UTF-8";
+# else
+ return ::nl_langinfo_l(CODESET, __loc);
+# endif
+}
+#endif // _LIBCPP_BUILDING_LIBRARY
#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs
_LIBCPP_HIDE_FROM_ABI
diff --git a/libcxx/include/__locale_dir/support/newlib.h b/libcxx/include/__locale_dir/support/newlib.h
index 6ea12c3bc3e1f..7fe48572b4587 100644
--- a/libcxx/include/__locale_dir/support/newlib.h
+++ b/libcxx/include/__locale_dir/support/newlib.h
@@ -16,6 +16,7 @@
#include <cstdio>
#include <cstdlib>
#include <ctype.h>
+#include <langinfo.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
@@ -76,6 +77,10 @@ inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
__locale_guard __current(__loc);
return std::localeconv();
}
+
+inline _LIBCPP_HIDE_FROM_ABI const char* __get_locale_encoding(__locale_t __loc) {
+ return ::nl_langinfo_l(CODESET, __loc);
+}
#endif // _LIBCPP_BUILDING_LIBRARY
//
diff --git a/libcxx/include/__locale_dir/support/windows.h b/libcxx/include/__locale_dir/support/windows.h
index c9ea500bc0b12..6675cfb740b29 100644
--- a/libcxx/include/__locale_dir/support/windows.h
+++ b/libcxx/include/__locale_dir/support/windows.h
@@ -164,6 +164,7 @@ inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, const char* __loc
return __new_locale;
}
_LIBCPP_EXPORTED_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc);
+_LIBCPP_EXPORTED_FROM_ABI const char* __get_locale_encoding(__locale_t __loc);
#endif // _LIBCPP_BUILDING_LIBRARY
//
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index b11055940a82c..d70d0fce52460 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2125,6 +2125,11 @@ module std [system] {
export *
}
+ module text_encoding {
+ header "text_encoding"
+ export *
+ }
+
module thread {
module formatter { header "__thread/formatter.h" }
module id { header "__thread/id.h" }
diff --git a/libcxx/include/text_encoding b/libcxx/include/text_encoding
new file mode 100644
index 0000000000000..da39be92c3dfa
--- /dev/null
+++ b/libcxx/include/text_encoding
@@ -0,0 +1,835 @@
+// -*- 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 _LIBCPP_TEXT_ENCODING
+#define _LIBCPP_TEXT_ENCODING
+
+/* text_encoding synopsis
+namespace std {
+
+struct text_encoding;
+
+// [text.encoding.hash], hash support
+template<class T> struct hash;
+template<> struct hash<text_encoding>;
+
+struct text_encoding
+{
+ static constexpr size_t max_name_length = 63;
+
+ // [text.encoding.id], enumeration text_encoding::id
+ enum class id : int_least32_t {
+ see below
+ };
+ using enum id;
+
+ constexpr text_encoding() = default;
+ constexpr explicit text_encoding(string_view enc) noexcept;
+ constexpr text_encoding(id i) noexcept;
+
+ constexpr id mib() const noexcept;
+ constexpr const char* name() const noexcept;
+
+ // [text.encoding.aliases], class text_encoding::aliases_view
+ // struct aliases_view;
+ constexpr aliases_view aliases() const noexcept;
+
+ friend constexpr bool operator==(const text_encoding& a,
+ const text_encoding& b) noexcept;
+ friend constexpr bool operator==(const text_encoding& encoding, id i) noexcept;
+
+ static consteval text_encoding literal() noexcept;
+ static text_encoding environment();
+ template<id i> static bool environment_is();
+
+ private:
+ id mib_ = id::unknown; // exposition only
+ char name_[max_name_length + 1] = {0}; // exposition only
+ static constexpr bool comp-name(string_view a, string_view b); // exposition only
+};
+}
+
+*/
+
+#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
+# include <__cxx03/__config>
+#else
+# include <__config>
+
+# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+# endif
+
+# if _LIBCPP_STD_VER >= 26
+
+# include <__algorithm/count.h>
+# include <__algorithm/find_if.h>
+# include <__algorithm/lower_bound.h>
+# include <__cstddef/ptr
diff _t.h>
+# include <__functional/hash.h>
+# include <__iterator/iterator_traits.h>
+# include <__ranges/enable_borrowed_range.h>
+# include <__ranges/view_interface.h>
+# include <climits>
+# include <cstdint>
+# include <string_view>
+# include <version>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+struct text_encoding;
+
+_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
+
+_LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT _LIBCPP_EXPORTED_FROM_ABI text_encoding
+__get_locale_encoding(const char* __name);
+
+_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
+
+struct text_encoding {
+ static_assert(CHAR_BIT == 8, "libc++ only supports platforms where CHAR_BIT == 8");
+ enum class id : int_least32_t {
+ other = 1,
+ unknown = 2,
+ ASCII = 3,
+ ISOLatin1 = 4,
+ ISOLatin2 = 5,
+ ISOLatin3 = 6,
+ ISOLatin4 = 7,
+ ISOLatinCyrillic = 8,
+ ISOLatinArabic = 9,
+ ISOLatinGreek = 10,
+ ISOLatinHebrew = 11,
+ ISOLatin5 = 12,
+ ISOLatin6 = 13,
+ ISOTextComm = 14,
+ HalfWidthKatakana = 15,
+ JISEncoding = 16,
+ ShiftJIS = 17,
+ EUCPkdFmtJapanese = 18,
+ EUCFixWidJapanese = 19,
+ ISO4UnitedKingdom = 20,
+ ISO11SwedishForNames = 21,
+ ISO15Italian = 22,
+ ISO17Spanish = 23,
+ ISO21German = 24,
+ ISO60DanishNorwegian = 25,
+ ISO69French = 26,
+ ISO10646UTF1 = 27,
+ ISO646basic1983 = 28,
+ INVARIANT = 29,
+ ISO2IntlRefVersion = 30,
+ NATSSEFI = 31,
+ NATSSEFIADD = 32, // NATS-DANO (33) and NATS-DANO-ADD (34) are omitted by the standard.
+ ISO10Swedish = 35,
+ KSC56011987 = 36,
+ ISO2022KR = 37,
+ EUCKR = 38,
+ ISO2022JP = 39,
+ ISO2022JP2 = 40,
+ ISO13JISC6220jp = 41,
+ ISO14JISC6220ro = 42,
+ ISO16Portuguese = 43,
+ ISO18Greek7Old = 44,
+ ISO19LatinGreek = 45,
+ ISO25French = 46,
+ ISO27LatinGreek1 = 47,
+ ISO5427Cyrillic = 48,
+ ISO42JISC62261978 = 49,
+ ISO47BSViewdata = 50,
+ ISO49INIS = 51,
+ ISO50INIS8 = 52,
+ ISO51INISCyrillic = 53,
+ ISO54271981 = 54,
+ ISO5428Greek = 55,
+ ISO57GB1988 = 56,
+ ISO58GB231280 = 57,
+ ISO61Norwegian2 = 58,
+ ISO70VideotexSupp1 = 59,
+ ISO84Portuguese2 = 60,
+ ISO85Spanish2 = 61,
+ ISO86Hungarian = 62,
+ ISO87JISX0208 = 63,
+ ISO88Greek7 = 64,
+ ISO89ASMO449 = 65,
+ ISO90 = 66,
+ ISO91JISC62291984a = 67,
+ ISO92JISC62991984b = 68,
+ ISO93JIS62291984badd = 69,
+ ISO94JIS62291984hand = 70,
+ ISO95JIS62291984handadd = 71,
+ ISO96JISC62291984kana = 72,
+ ISO2033 = 73,
+ ISO99NAPLPS = 74,
+ ISO102T617bit = 75,
+ ISO103T618bit = 76,
+ ISO111ECMACyrillic = 77,
+ ISO121Canadian1 = 78,
+ ISO122Canadian2 = 79,
+ ISO123CSAZ24341985gr = 80,
+ ISO88596E = 81,
+ ISO88596I = 82,
+ ISO128T101G2 = 83,
+ ISO88598E = 84,
+ ISO88598I = 85,
+ ISO139CSN369103 = 86,
+ ISO141JUSIB1002 = 87,
+ ISO143IECP271 = 88,
+ ISO146Serbian = 89,
+ ISO147Macedonian = 90,
+ ISO150 = 91,
+ ISO151Cuba = 92,
+ ISO6937Add = 93,
+ ISO153GOST1976874 = 94,
+ ISO8859Supp = 95,
+ ISO10367Box = 96,
+ ISO158Lap = 97,
+ ISO159JISX02121990 = 98,
+ ISO646Danish = 99,
+ USDK = 100,
+ DKUS = 101,
+ KSC5636 = 102,
+ Unicode11UTF7 = 103,
+ ISO2022CN = 104,
+ ISO2022CNEXT = 105,
+ UTF8 = 106,
+ ISO885913 = 109,
+ ISO885914 = 110,
+ ISO885915 = 111,
+ ISO885916 = 112,
+ GBK = 113,
+ GB18030 = 114,
+ OSDEBCDICDF0415 = 115,
+ OSDEBCDICDF03IRV = 116,
+ OSDEBCDICDF041 = 117,
+ ISO115481 = 118,
+ KZ1048 = 119,
+ UCS2 = 1000,
+ UCS4 = 1001,
+ UnicodeASCII = 1002,
+ UnicodeLatin1 = 1003,
+ UnicodeJapanese = 1004,
+ UnicodeIBM1261 = 1005,
+ UnicodeIBM1268 = 1006,
+ UnicodeIBM1276 = 1007,
+ UnicodeIBM1264 = 1008,
+ UnicodeIBM1265 = 1009,
+ Unicode11 = 1010,
+ SCSU = 1011,
+ UTF7 = 1012,
+ UTF16BE = 1013,
+ UTF16LE = 1014,
+ UTF16 = 1015,
+ CESU8 = 1016,
+ UTF32 = 1017,
+ UTF32BE = 1018,
+ UTF32LE = 1019,
+ BOCU1 = 1020,
+ UTF7IMAP = 1021,
+ Windows30Latin1 = 2000,
+ Windows31Latin1 = 2001,
+ Windows31Latin2 = 2002,
+ Windows31Latin5 = 2003,
+ HPRoman8 = 2004,
+ AdobeStandardEncoding = 2005,
+ VenturaUS = 2006,
+ VenturaInternational = 2007,
+ DECMCS = 2008,
+ PC850Multilingual = 2009,
+ PC8DanishNorwegian = 2012,
+ PC862LatinHebrew = 2013,
+ PC8Turkish = 2014,
+ IBMSymbols = 2015,
+ IBMThai = 2016,
+ HPLegal = 2017,
+ HPPiFont = 2018,
+ HPMath8 = 2019,
+ HPPSMath = 2020,
+ HPDesktop = 2021,
+ VenturaMath = 2022,
+ MicrosoftPublishing = 2023,
+ Windows31J = 2024,
+ GB2312 = 2025,
+ Big5 = 2026,
+ Macintosh = 2027,
+ IBM037 = 2028,
+ IBM038 = 2029,
+ IBM273 = 2030,
+ IBM274 = 2031,
+ IBM275 = 2032,
+ IBM277 = 2033,
+ IBM278 = 2034,
+ IBM280 = 2035,
+ IBM281 = 2036,
+ IBM284 = 2037,
+ IBM285 = 2038,
+ IBM290 = 2039,
+ IBM297 = 2040,
+ IBM420 = 2041,
+ IBM423 = 2042,
+ IBM424 = 2043,
+ PC8CodePage437 = 2011,
+ IBM500 = 2044,
+ IBM851 = 2045,
+ PCp852 = 2010,
+ IBM855 = 2046,
+ IBM857 = 2047,
+ IBM860 = 2048,
+ IBM861 = 2049,
+ IBM863 = 2050,
+ IBM864 = 2051,
+ IBM865 = 2052,
+ IBM868 = 2053,
+ IBM869 = 2054,
+ IBM870 = 2055,
+ IBM871 = 2056,
+ IBM880 = 2057,
+ IBM891 = 2058,
+ IBM903 = 2059,
+ IBM904 = 2060,
+ IBM905 = 2061,
+ IBM918 = 2062,
+ IBM1026 = 2063,
+ IBMEBCDICATDE = 2064,
+ EBCDICATDEA = 2065,
+ EBCDICCAFR = 2066,
+ EBCDICDKNO = 2067,
+ EBCDICDKNOA = 2068,
+ EBCDICFISE = 2069,
+ EBCDICFISEA = 2070,
+ EBCDICFR = 2071,
+ EBCDICIT = 2072,
+ EBCDICPT = 2073,
+ EBCDICES = 2074,
+ EBCDICESA = 2075,
+ EBCDICESS = 2076,
+ EBCDICUK = 2077,
+ EBCDICUS = 2078,
+ Unknown8BiT = 2079,
+ Mnemonic = 2080,
+ Mnem = 2081,
+ VISCII = 2082,
+ VIQR = 2083,
+ KOI8R = 2084,
+ HZGB2312 = 2085,
+ IBM866 = 2086,
+ PC775Baltic = 2087,
+ KOI8U = 2088,
+ IBM00858 = 2089,
+ IBM00924 = 2090,
+ IBM01140 = 2091,
+ IBM01141 = 2092,
+ IBM01142 = 2093,
+ IBM01143 = 2094,
+ IBM01144 = 2095,
+ IBM01145 = 2096,
+ IBM01146 = 2097,
+ IBM01147 = 2098,
+ IBM01148 = 2099,
+ IBM01149 = 2100,
+ Big5HKSCS = 2101,
+ IBM1047 = 2102,
+ PTCP154 = 2103,
+ Amiga1251 = 2104,
+ KOI7switched = 2105,
+ BRF = 2106,
+ TSCII = 2107,
+ CP51932 = 2108,
+ windows874 = 2109,
+ windows1250 = 2250,
+ windows1251 = 2251,
+ windows1252 = 2252,
+ windows1253 = 2253,
+ windows1254 = 2254,
+ windows1255 = 2255,
+ windows1256 = 2256,
+ windows1257 = 2257,
+ windows1258 = 2258,
+ TIS620 = 2259,
+ CP50220 = 2260
+ };
+
+private:
+ static constexpr int __nats_dano_ = 33;
+ static constexpr int __nats_dano_add_ = 34;
+
+ // A __te_data structure stores:
+ // Index into a table of offsets in the giant aliases string
+ // The MIB of that text encoding
+ // Number of aliases the current MIB holds
+ // We only need 6 bytes of information to store this information.
+
+ // The data is structured in three
diff erent locations:
+ // The mib table (array of __te_data)
+ // Aliases string
+ // Table of offsets into the aliases string
+
+ // All of the alias strings were transformed from an array of char* into one giant string split by '\0'.
+ // This allows us to reduce runtime memory footprint by not only removing the need to store ~884 pointers, it also
+ // significantly reduces the disk space taken by removing the need for relocation data for those pointers.
+ // We also know ahead of time that the total number of characters of all of these aliases combined can fit into 2
+ // bytes, so we can also save even more memory by using 2 byte offsets rather than a full pointer into the aliases
+ // string.
+
+ struct __te_data {
+ unsigned short __first_alias_index_;
+ unsigned short __mib_rep_;
+ unsigned char __num_aliases_;
+
+ friend constexpr bool operator<(const __te_data& __enc, id __i) noexcept {
+ return __enc.__mib_rep_ < static_cast<unsigned short>(__i);
+ }
+ };
+
+ static constexpr bool __comp_name(string_view __a, string_view __b) noexcept {
+ if (__a.empty() || __b.empty()) {
+ return false;
+ }
+
+ // Map any non-alphanumeric character to 255, skip prefix 0s, else get tolower(__n).
+ auto __map_char = [](char __n, bool& __in_number) -> unsigned char {
+ if (__n == '0') {
+ return __in_number ? '0' : 255;
+ }
+ __in_number = __n >= '1' && __n <= '9';
+
+ if ((__n >= '1' && __n <= '9') || (__n >= 'a' && __n <= 'z')) {
+ return __n;
+ }
+ if (__n >= 'A' && __n <= 'Z') {
+ return __n + ('a' - 'A'); // tolower
+ }
+
+ return 255;
+ };
+
+ auto __a_ptr = __a.begin(), __b_ptr = __b.begin();
+ bool __a_in_number = false, __b_in_number = false;
+
+ unsigned char __a_val = 255, __b_val = 255;
+ for (;; __a_ptr++, __b_ptr++) {
+ while (__a_ptr != __a.end() && (__a_val = __map_char(*__a_ptr, __a_in_number)) == 255)
+ __a_ptr++;
+ while (__b_ptr != __b.end() && (__b_val = __map_char(*__b_ptr, __b_in_number)) == 255)
+ __b_ptr++;
+
+ if (__a_ptr == __a.end())
+ return __b_ptr == __b.end();
+ if (__b_ptr == __b.end())
+ return false;
+ if (__a_val != __b_val)
+ return false;
+ }
+ return true;
+ }
+
+ static constexpr unsigned short __find_data_idx(string_view __a) noexcept {
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__a.size() <= max_name_length, "input string_view must have size <= 63");
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(!__a.contains('\0'), "input string_view must not contain '\\0'");
+
+ auto __pred = [&__a](const __te_data& __entry) -> bool {
+ // Search aliases of text encoding for string
+ aliases_view __aliases(__entry);
+ return std::find_if(__aliases.begin(), __aliases.end(), [&__a](auto __alias) {
+ return __comp_name(__a, __alias);
+ }) != __aliases.end();
+ };
+
+ const __te_data* __found = std::find_if(__entries + 2, std::end(__entries), __pred);
+ if (__found == std::end(__entries)) {
+ return __other_idx_; // other
+ }
+
+ return __found - __entries;
+ }
+
+ static constexpr unsigned short __find_data_idx_by_id(id __i) noexcept {
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__i >= id::other, "invalid text_encoding::id passed");
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__i <= id::CP50220, "invalid text_encoding::id passed");
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(int_least32_t(__i) != __nats_dano_, "Mib for NATS-DANO used");
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(int_least32_t(__i) != __nats_dano_add_, "Mib for NATS-DANO-ADD used");
+ auto __found = std::lower_bound(std::begin(__entries), std::end(__entries), __i);
+
+ if (__found == std::end(__entries)) {
+ return __unknown_idx_; // unknown
+ }
+
+ return __found - __entries;
+ }
+
+public:
+ using enum id;
+ static constexpr size_t max_name_length = 63;
+
+ // [text.encoding.aliases], class text_encoding::aliases_view
+ struct aliases_view : ranges::view_interface<aliases_view> {
+ struct __iterator {
+ using iterator_concept = random_access_iterator_tag;
+ using iterator_category = random_access_iterator_tag;
+ using value_type = const char*;
+ using reference = const char*;
+ using
diff erence_type = int;
+
+ constexpr __iterator() noexcept = default;
+
+ [[nodiscard]] constexpr reference operator*() const noexcept {
+ return __get_alias_from_offset_table(__current_idx_);
+ }
+
+ [[nodiscard]] constexpr reference operator[](
diff erence_type __n) const noexcept {
+ auto __it = *this;
+ return *(__it + __n);
+ }
+
+ [[nodiscard]] friend constexpr __iterator operator+(__iterator __it,
diff erence_type __n) noexcept {
+ __it += __n;
+ return __it;
+ }
+
+ [[nodiscard]] friend constexpr __iterator operator+(
diff erence_type __n, __iterator __it) noexcept {
+ __it += __n;
+ return __it;
+ }
+
+ [[nodiscard]] friend constexpr __iterator operator-(__iterator __it,
diff erence_type __n) noexcept {
+ __it -= __n;
+ return __it;
+ }
+
+ [[nodiscard]] constexpr
diff erence_type operator-(const __iterator& __other) const noexcept {
+ return __current_idx_ - __other.__current_idx_;
+ }
+
+ constexpr __iterator& operator++() noexcept {
+ __current_idx_++;
+ return *this;
+ }
+
+ constexpr __iterator operator++(int) noexcept {
+ auto __old = *this;
+ __current_idx_++;
+ return __old;
+ }
+
+ constexpr __iterator& operator--() noexcept {
+ __current_idx_--;
+ return *this;
+ }
+
+ constexpr __iterator operator--(int) noexcept {
+ auto __old = *this;
+ __current_idx_--;
+ return __old;
+ }
+
+ constexpr __iterator& operator+=(
diff erence_type __n) noexcept {
+ __current_idx_ += __n;
+ return *this;
+ }
+
+ constexpr __iterator& operator-=(
diff erence_type __n) noexcept { return (*this += -__n); }
+
+ friend constexpr auto operator<=>(const __iterator& __it, const __iterator& __it2) noexcept = default;
+
+ private:
+ friend struct aliases_view;
+
+ constexpr __iterator(unsigned short __enc_d) noexcept : __current_idx_(__enc_d) {}
+
+ unsigned short __current_idx_;
+ }; // __iterator
+
+ [[nodiscard]] constexpr __iterator begin() const noexcept { return __iterator(__first_idx_); }
+
+ [[nodiscard]] constexpr __iterator end() const noexcept { return __iterator(__last_idx_); }
+
+ private:
+ friend struct text_encoding;
+
+ constexpr aliases_view(const __te_data& __d)
+ : __first_idx_(__d.__first_alias_index_), __last_idx_(__d.__first_alias_index_ + __d.__num_aliases_) {}
+
+ unsigned short __first_idx_;
+ unsigned short __last_idx_;
+ }; // aliases_view
+
+ constexpr text_encoding() = default;
+
+ constexpr explicit text_encoding(string_view __enc) noexcept : __encoding_idx_(__find_data_idx(__enc)) {
+ __enc.copy(__name_, max_name_length, 0);
+ }
+
+ constexpr text_encoding(id __i) noexcept : __encoding_idx_(__find_data_idx_by_id(__i)) {
+ const char* __alias = __get_alias_from_offset_table(__get().__first_alias_index_);
+ if (__alias[0] != '\0') {
+ string_view(__alias).copy(__name_, max_name_length);
+ }
+ }
+
+ [[nodiscard]] constexpr id mib() const noexcept { return id(__get().__mib_rep_); }
+
+ [[nodiscard]] constexpr const char* name() const noexcept { return __name_; }
+
+ [[nodiscard]] constexpr aliases_view aliases() const noexcept { return aliases_view(__get()); }
+
+ friend constexpr bool operator==(const text_encoding& __a, const text_encoding& __b) noexcept {
+ return __a.mib() == id::other && __b.mib() == id::other
+ ? __comp_name(__a.__name_, __b.__name_)
+ : __a.mib() == __b.mib();
+ }
+
+ friend constexpr bool operator==(const text_encoding& __encoding, id __i) noexcept { return __encoding.mib() == __i; }
+
+ [[nodiscard]] static consteval text_encoding literal() noexcept {
+ // TODO: Remove this branch once we have __GNUC_EXECUTION_CHARSET_NAME or __clang_literal_encoding__ unconditionally
+# ifdef __GNUC_EXECUTION_CHARSET_NAME
+ return text_encoding(__GNUC_EXECUTION_CHARSET_NAME);
+# elif defined(__clang_literal_encoding__)
+ return text_encoding(__clang_literal_encoding__);
+# else
+ return text_encoding();
+# endif
+ }
+
+# if _LIBCPP_HAS_LOCALIZATION
+ [[nodiscard]] _LIBCPP_AVAILABILITY_TEXT_ENCODING_ENVIRONMENT static text_encoding environment() {
+# if defined(_LIBCPP_WIN32API)
+ return __get_locale_encoding(nullptr);
+# else
+ return __get_locale_encoding("");
+# endif
+ }
+
+ 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
+ return environment() == _Id;
+# endif
+ }
+# else
+ static text_encoding environment() = delete;
+
+ template <id>
+ static bool environment_is() = delete;
+# endif
+
+private:
+ constexpr const __te_data& __get() const { return __entries[__encoding_idx_]; }
+
+ static constexpr char const* __get_alias_from_offset_table(unsigned short __idx) {
+ return __aliases_string + __alias_offsets.__table[__idx];
+ }
+
+ static constexpr auto __other_idx_ = 0u;
+ static constexpr auto __unknown_idx_ = 1u;
+
+ char __name_[max_name_length + 1]{};
+ unsigned short __encoding_idx_{1u};
+
+ static constexpr __te_data __entries[] = {
+ {0, 1, 0}, {1, 2, 0}, {2, 3, 11}, {13, 4, 9}, {22, 5, 7}, {29, 6, 7}, {36, 7, 7},
+ {43, 8, 6}, {49, 9, 8}, {57, 10, 9}, {66, 11, 6}, {72, 12, 7}, {79, 13, 6}, {85, 14, 3},
+ {88, 15, 3}, {91, 16, 2}, {93, 17, 3}, {96, 18, 3}, {99, 19, 2}, {101, 20, 6}, {107, 21, 5},
+ {112, 22, 4}, {116, 23, 4}, {120, 24, 5}, {125, 25, 6}, {131, 26, 5}, {136, 27, 2}, {138, 28, 3},
+ {141, 29, 2}, {143, 30, 4}, {147, 31, 3}, {150, 32, 3}, {153, 35, 7}, {160, 36, 6}, {166, 37, 2},
+ {168, 38, 2}, {170, 39, 2}, {172, 40, 2}, {174, 41, 6}, {180, 42, 5}, {185, 43, 4}, {189, 44, 3},
+ {192, 45, 3}, {195, 46, 4}, {199, 47, 3}, {202, 48, 3}, {205, 49, 3}, {208, 50, 3}, {211, 51, 3},
+ {214, 52, 3}, {217, 53, 3}, {220, 54, 4}, {224, 55, 3}, {227, 56, 5}, {232, 57, 4}, {236, 58, 5},
+ {241, 59, 3}, {244, 60, 4}, {248, 61, 4}, {252, 62, 5}, {257, 63, 5}, {262, 64, 3}, {265, 65, 5},
+ {270, 66, 2}, {272, 67, 4}, {276, 68, 5}, {281, 69, 4}, {285, 70, 4}, {289, 71, 4}, {293, 72, 3},
+ {296, 73, 4}, {300, 74, 5}, {305, 75, 3}, {308, 76, 4}, {312, 77, 4}, {316, 78, 7}, {323, 79, 6},
+ {329, 80, 3}, {332, 81, 3}, {335, 82, 3}, {338, 83, 3}, {341, 84, 3}, {344, 85, 3}, {347, 86, 3},
+ {350, 87, 6}, {356, 88, 3}, {359, 89, 4}, {363, 90, 4}, {367, 91, 4}, {371, 92, 5}, {376, 93, 3},
+ {379, 94, 4}, {383, 95, 4}, {387, 96, 3}, {390, 97, 4}, {394, 98, 4}, {398, 99, 5}, {403, 100, 2},
+ {405, 101, 2}, {407, 102, 3}, {410, 103, 2}, {412, 104, 2}, {414, 105, 2}, {416, 106, 2}, {418, 109, 2},
+ {420, 110, 8}, {428, 111, 4}, {432, 112, 7}, {439, 113, 5}, {444, 114, 2}, {446, 115, 2}, {448, 116, 2},
+ {450, 117, 2}, {452, 118, 4}, {456, 119, 4}, {460, 1000, 2}, {462, 1001, 2}, {464, 1002, 2}, {466, 1003, 3},
+ {469, 1004, 2}, {471, 1005, 2}, {473, 1006, 2}, {475, 1007, 2}, {477, 1008, 2}, {479, 1009, 2}, {481, 1010, 2},
+ {483, 1011, 2}, {485, 1012, 2}, {487, 1013, 2}, {489, 1014, 2}, {491, 1015, 2}, {493, 1016, 3}, {496, 1017, 2},
+ {498, 1018, 2}, {500, 1019, 2}, {502, 1020, 3}, {505, 1021, 2}, {507, 2000, 2}, {509, 2001, 2}, {511, 2002, 2},
+ {513, 2003, 2}, {515, 2004, 4}, {519, 2005, 2}, {521, 2006, 2}, {523, 2007, 2}, {525, 2008, 3}, {528, 2009, 4},
+ {532, 2010, 4}, {536, 2011, 4}, {540, 2012, 2}, {542, 2013, 4}, {546, 2014, 2}, {548, 2015, 2}, {550, 2016, 2},
+ {552, 2017, 2}, {554, 2018, 2}, {556, 2019, 2}, {558, 2020, 2}, {560, 2021, 2}, {562, 2022, 2}, {564, 2023, 2},
+ {566, 2024, 2}, {568, 2025, 2}, {570, 2026, 2}, {572, 2027, 3}, {575, 2028, 7}, {582, 2029, 4}, {586, 2030, 3},
+ {589, 2031, 4}, {593, 2032, 4}, {597, 2033, 4}, {601, 2034, 5}, {606, 2035, 4}, {610, 2036, 4}, {614, 2037, 4},
+ {618, 2038, 4}, {622, 2039, 4}, {626, 2040, 4}, {630, 2041, 4}, {634, 2042, 4}, {638, 2043, 4}, {642, 2044, 5},
+ {647, 2045, 4}, {651, 2046, 4}, {655, 2047, 4}, {659, 2048, 4}, {663, 2049, 5}, {668, 2050, 4}, {672, 2051, 3},
+ {675, 2052, 4}, {679, 2053, 4}, {683, 2054, 5}, {688, 2055, 5}, {693, 2056, 4}, {697, 2057, 4}, {701, 2058, 3},
+ {704, 2059, 3}, {707, 2060, 4}, {711, 2061, 4}, {715, 2062, 4}, {719, 2063, 3}, {722, 2064, 2}, {724, 2065, 2},
+ {726, 2066, 2}, {728, 2067, 2}, {730, 2068, 2}, {732, 2069, 2}, {734, 2070, 2}, {736, 2071, 2}, {738, 2072, 2},
+ {740, 2073, 2}, {742, 2074, 2}, {744, 2075, 2}, {746, 2076, 2}, {748, 2077, 2}, {750, 2078, 2}, {752, 2079, 2},
+ {754, 2080, 2}, {756, 2081, 2}, {758, 2082, 2}, {760, 2083, 2}, {762, 2084, 2}, {764, 2085, 1}, {765, 2086, 4},
+ {769, 2087, 3}, {772, 2088, 2}, {774, 2089, 5}, {779, 2090, 5}, {784, 2091, 5}, {789, 2092, 5}, {794, 2093, 6},
+ {800, 2094, 6}, {806, 2095, 5}, {811, 2096, 5}, {816, 2097, 5}, {821, 2098, 5}, {826, 2099, 5}, {831, 2100, 5},
+ {836, 2101, 2}, {838, 2102, 3}, {841, 2103, 5}, {846, 2104, 5}, {851, 2105, 2}, {853, 2106, 2}, {855, 2107, 2},
+ {857, 2108, 2}, {859, 2109, 2}, {861, 2250, 2}, {863, 2251, 2}, {865, 2252, 2}, {867, 2253, 2}, {869, 2254, 2},
+ {871, 2255, 2}, {873, 2256, 2}, {875, 2257, 2}, {877, 2258, 2}, {879, 2259, 3}, {882, 2260, 2}};
+
+ static constexpr char __aliases_string[] =
+ "US-ASCII\0iso-ir-6\0ANSI_X3.4-1968\0ANSI_X3.4-1986\0ISO_646.irv:1991\0ISO646-"
+ "US\0us\0IBM367\0cp367\0csASCII\0ASCII\0ISO_8859-1:1987\0iso-ir-100\0ISO_8859-1\0ISO-8859-"
+ "1\0latin1\0l1\0IBM819\0CP819\0csISOLatin1\0ISO_8859-2:1987\0iso-ir-101\0ISO_8859-2\0ISO-8859-"
+ "2\0latin2\0l2\0csISOLatin2\0ISO_8859-3:1988\0iso-ir-109\0ISO_8859-3\0ISO-8859-3\0latin3\0l3\0csISOLatin3\0ISO_"
+ "8859-4:1988\0iso-ir-110\0ISO_8859-4\0ISO-8859-4\0latin4\0l4\0csISOLatin4\0ISO_8859-5:1988\0iso-ir-144\0ISO_8859-"
+ "5\0ISO-8859-5\0cyrillic\0csISOLatinCyrillic\0ISO_8859-6:1987\0iso-ir-127\0ISO_8859-6\0ISO-8859-6\0ECMA-"
+ "114\0ASMO-708\0arabic\0csISOLatinArabic\0ISO_8859-7:1987\0iso-ir-126\0ISO_8859-7\0ISO-8859-7\0ELOT_928\0ECMA-"
+ "118\0greek\0greek8\0csISOLatinGreek\0ISO_8859-8:1988\0iso-ir-138\0ISO_8859-8\0ISO-8859-"
+ "8\0hebrew\0csISOLatinHebrew\0ISO_8859-9:1989\0iso-ir-148\0ISO_8859-9\0ISO-8859-9\0latin5\0l5\0csISOLatin5\0ISO-"
+ "8859-10\0iso-ir-157\0l6\0ISO_8859-10:1992\0csISOLatin6\0latin6\0ISO_6937-2-add\0iso-ir-142\0csISOTextComm\0JIS_"
+ "X0201\0X0201\0csHalfWidthKatakana\0JIS_Encoding\0csJISEncoding\0Shift_JIS\0MS_Kanji\0csShiftJIS\0Extended_UNIX_"
+ "Code_Packed_Format_for_Japanese\0csEUCPkdFmtJapanese\0EUC-JP\0Extended_UNIX_Code_Fixed_Width_for_"
+ "Japanese\0csEUCFixWidJapanese\0BS_4730\0iso-ir-4\0ISO646-GB\0gb\0uk\0csISO4UnitedKingdom\0SEN_850200_C\0iso-ir-"
+ "11\0ISO646-SE2\0se2\0csISO11SwedishForNames\0IT\0iso-ir-15\0ISO646-IT\0csISO15Italian\0ES\0iso-ir-17\0ISO646-"
+ "ES\0csISO17Spanish\0DIN_66003\0iso-ir-21\0de\0ISO646-DE\0csISO21German\0NS_4551-1\0iso-ir-60\0ISO646-"
+ "NO\0no\0csISO60DanishNorwegian\0csISO60Norwegian1\0NF_Z_62-010\0iso-ir-69\0ISO646-FR\0fr\0csISO69French\0ISO-"
+ "10646-UTF-1\0csISO10646UTF1\0ISO_646.basic:1983\0ref\0csISO646basic1983\0INVARIANT\0csINVARIANT\0ISO_646.irv:"
+ "1983\0iso-ir-2\0irv\0csISO2IntlRefVersion\0NATS-SEFI\0iso-ir-8-1\0csNATSSEFI\0NATS-SEFI-ADD\0iso-ir-8-"
+ "2\0csNATSSEFIADD\0SEN_850200_B\0iso-ir-10\0FI\0ISO646-FI\0ISO646-SE\0se\0csISO10Swedish\0KS_C_5601-1987\0iso-ir-"
+ "149\0KS_C_5601-1989\0KSC_5601\0korean\0csKSC56011987\0ISO-2022-KR\0csISO2022KR\0EUC-KR\0csEUCKR\0ISO-2022-"
+ "JP\0csISO2022JP\0ISO-2022-JP-2\0csISO2022JP2\0JIS_C6220-1969-jp\0JIS_C6220-1969\0iso-ir-13\0katakana\0x0201-"
+ "7\0csISO13JISC6220jp\0JIS_C6220-1969-ro\0iso-ir-14\0jp\0ISO646-JP\0csISO14JISC6220ro\0PT\0iso-ir-16\0ISO646-"
+ "PT\0csISO16Portuguese\0greek7-old\0iso-ir-18\0csISO18Greek7Old\0latin-greek\0iso-ir-19\0csISO19LatinGreek\0NF_Z_"
+ "62-010_(1973)\0iso-ir-25\0ISO646-FR1\0csISO25French\0Latin-greek-1\0iso-ir-27\0csISO27LatinGreek1\0ISO_"
+ "5427\0iso-ir-37\0csISO5427Cyrillic\0JIS_C6226-1978\0iso-ir-42\0csISO42JISC62261978\0BS_viewdata\0iso-ir-"
+ "47\0csISO47BSViewdata\0INIS\0iso-ir-49\0csISO49INIS\0INIS-8\0iso-ir-50\0csISO50INIS8\0INIS-cyrillic\0iso-ir-"
+ "51\0csISO51INISCyrillic\0ISO_5427:1981\0iso-ir-54\0ISO5427Cyrillic1981\0csISO54271981\0ISO_5428:1980\0iso-ir-"
+ "55\0csISO5428Greek\0GB_1988-80\0iso-ir-57\0cn\0ISO646-CN\0csISO57GB1988\0GB_2312-80\0iso-ir-"
+ "58\0chinese\0csISO58GB231280\0NS_4551-2\0ISO646-NO2\0iso-ir-61\0no2\0csISO61Norwegian2\0videotex-suppl\0iso-ir-"
+ "70\0csISO70VideotexSupp1\0PT2\0iso-ir-84\0ISO646-PT2\0csISO84Portuguese2\0ES2\0iso-ir-85\0ISO646-"
+ "ES2\0csISO85Spanish2\0MSZ_7795.3\0iso-ir-86\0ISO646-HU\0hu\0csISO86Hungarian\0JIS_C6226-1983\0iso-ir-"
+ "87\0x0208\0JIS_X0208-1983\0csISO87JISX0208\0greek7\0iso-ir-88\0csISO88Greek7\0ASMO_449\0ISO_9036\0arabic7\0iso-"
+ "ir-89\0csISO89ASMO449\0iso-ir-90\0csISO90\0JIS_C6229-1984-a\0iso-ir-91\0jp-ocr-a\0csISO91JISC62291984a\0JIS_"
+ "C6229-1984-b\0iso-ir-92\0ISO646-JP-OCR-B\0jp-ocr-b\0csISO92JISC62991984b\0JIS_C6229-1984-b-add\0iso-ir-93\0jp-"
+ "ocr-b-add\0csISO93JIS62291984badd\0JIS_C6229-1984-hand\0iso-ir-94\0jp-ocr-hand\0csISO94JIS62291984hand\0JIS_"
+ "C6229-1984-hand-add\0iso-ir-95\0jp-ocr-hand-add\0csISO95JIS62291984handadd\0JIS_C6229-1984-kana\0iso-ir-"
+ "96\0csISO96JISC62291984kana\0ISO_2033-1983\0iso-ir-98\0e13b\0csISO2033\0ANSI_X3.110-1983\0iso-ir-99\0CSA_T500-"
+ "1983\0NAPLPS\0csISO99NAPLPS\0T.61-7bit\0iso-ir-102\0csISO102T617bit\0T.61-8bit\0T.61\0iso-ir-"
+ "103\0csISO103T618bit\0ECMA-cyrillic\0iso-ir-111\0KOI8-E\0csISO111ECMACyrillic\0CSA_Z243.4-1985-1\0iso-ir-"
+ "121\0ISO646-CA\0csa7-1\0csa71\0ca\0csISO121Canadian1\0CSA_Z243.4-1985-2\0iso-ir-122\0ISO646-CA2\0csa7-"
+ "2\0csa72\0csISO122Canadian2\0CSA_Z243.4-1985-gr\0iso-ir-123\0csISO123CSAZ24341985gr\0ISO_8859-6-"
+ "E\0csISO88596E\0ISO-8859-6-E\0ISO_8859-6-I\0csISO88596I\0ISO-8859-6-I\0T.101-G2\0iso-ir-"
+ "128\0csISO128T101G2\0ISO_8859-8-E\0csISO88598E\0ISO-8859-8-E\0ISO_8859-8-I\0csISO88598I\0ISO-8859-8-I\0CSN_"
+ "369103\0iso-ir-139\0csISO139CSN369103\0JUS_I.B1.002\0iso-ir-141\0ISO646-YU\0js\0yu\0csISO141JUSIB1002\0IEC_P27-"
+ "1\0iso-ir-143\0csISO143IECP271\0JUS_I.B1.003-serb\0iso-ir-146\0serbian\0csISO146Serbian\0JUS_I.B1.003-"
+ "mac\0macedonian\0iso-ir-147\0csISO147Macedonian\0greek-ccitt\0iso-ir-150\0csISO150\0csISO150GreekCCITT\0NC_NC00-"
+ "10:81\0cuba\0iso-ir-151\0ISO646-CU\0csISO151Cuba\0ISO_6937-2-25\0iso-ir-152\0csISO6937Add\0GOST_19768-74\0ST_"
+ "SEV_358-88\0iso-ir-153\0csISO153GOST1976874\0ISO_8859-supp\0iso-ir-154\0latin1-2-5\0csISO8859Supp\0ISO_10367-"
+ "box\0iso-ir-155\0csISO10367Box\0latin-lap\0lap\0iso-ir-158\0csISO158Lap\0JIS_X0212-1990\0x0212\0iso-ir-"
+ "159\0csISO159JISX02121990\0DS_2089\0DS2089\0ISO646-DK\0dk\0csISO646Danish\0us-dk\0csUSDK\0dk-"
+ "us\0csDKUS\0KSC5636\0ISO646-KR\0csKSC5636\0UNICODE-1-1-UTF-7\0csUnicode11UTF7\0ISO-2022-CN\0csISO2022CN\0ISO-"
+ "2022-CN-EXT\0csISO2022CNEXT\0UTF-8\0csUTF8\0ISO-8859-13\0csISO885913\0ISO-8859-14\0iso-ir-199\0ISO_8859-14:"
+ "1998\0ISO_8859-14\0latin8\0iso-celtic\0l8\0csISO885914\0ISO-8859-15\0ISO_8859-15\0Latin-9\0csISO885915\0ISO-"
+ "8859-16\0iso-ir-226\0ISO_8859-16:2001\0ISO_8859-16\0latin10\0l10\0csISO885916\0GBK\0CP936\0MS936\0windows-"
+ "936\0csGBK\0GB18030\0csGB18030\0OSD_EBCDIC_DF04_15\0csOSDEBCDICDF0415\0OSD_EBCDIC_DF03_"
+ "IRV\0csOSDEBCDICDF03IRV\0OSD_EBCDIC_DF04_1\0csOSDEBCDICDF041\0ISO-11548-1\0ISO_11548-1\0ISO_TR_11548-"
+ "1\0csISO115481\0KZ-1048\0STRK1048-2002\0RK1048\0csKZ1048\0ISO-10646-UCS-2\0csUnicode\0ISO-10646-UCS-"
+ "4\0csUCS4\0ISO-10646-UCS-Basic\0csUnicodeASCII\0ISO-10646-Unicode-Latin1\0csUnicodeLatin1\0ISO-10646\0ISO-10646-"
+ "J-1\0csUnicodeJapanese\0ISO-Unicode-IBM-1261\0csUnicodeIBM1261\0ISO-Unicode-IBM-1268\0csUnicodeIBM1268\0ISO-"
+ "Unicode-IBM-1276\0csUnicodeIBM1276\0ISO-Unicode-IBM-1264\0csUnicodeIBM1264\0ISO-Unicode-IBM-"
+ "1265\0csUnicodeIBM1265\0UNICODE-1-1\0csUnicode11\0SCSU\0csSCSU\0UTF-7\0csUTF7\0UTF-16BE\0csUTF16BE\0UTF-"
+ "16LE\0csUTF16LE\0UTF-16\0csUTF16\0CESU-8\0csCESU8\0csCESU-8\0UTF-32\0csUTF32\0UTF-32BE\0csUTF32BE\0UTF-"
+ "32LE\0csUTF32LE\0BOCU-1\0csBOCU1\0csBOCU-1\0UTF-7-IMAP\0csUTF7IMAP\0ISO-8859-1-Windows-3.0-Latin-"
+ "1\0csWindows30Latin1\0ISO-8859-1-Windows-3.1-Latin-1\0csWindows31Latin1\0ISO-8859-2-Windows-Latin-"
+ "2\0csWindows31Latin2\0ISO-8859-9-Windows-Latin-5\0csWindows31Latin5\0hp-roman8\0roman8\0r8\0csHPRoman8\0Adobe-"
+ "Standard-Encoding\0csAdobeStandardEncoding\0Ventura-US\0csVenturaUS\0Ventura-"
+ "International\0csVenturaInternational\0DEC-"
+ "MCS\0dec\0csDECMCS\0IBM850\0cp850\0850\0csPC850Multilingual\0IBM852\0cp852\0852\0csPCp852\0IBM437\0cp437\0"
+ "437\0csPC8CodePage437\0PC8-Danish-Norwegian\0csPC8DanishNorwegian\0IBM862\0cp862\0862\0csPC862LatinHebrew\0PC8-"
+ "Turkish\0csPC8Turkish\0IBM-Symbols\0csIBMSymbols\0IBM-Thai\0csIBMThai\0HP-Legal\0csHPLegal\0HP-Pi-"
+ "font\0csHPPiFont\0HP-Math8\0csHPMath8\0Adobe-Symbol-Encoding\0csHPPSMath\0HP-DeskTop\0csHPDesktop\0Ventura-"
+ "Math\0csVenturaMath\0Microsoft-Publishing\0csMicrosoftPublishing\0Windows-"
+ "31J\0csWindows31J\0GB2312\0csGB2312\0Big5\0csBig5\0macintosh\0mac\0csMacintosh\0IBM037\0cp037\0ebcdic-cp-"
+ "us\0ebcdic-cp-ca\0ebcdic-cp-wt\0ebcdic-cp-nl\0csIBM037\0IBM038\0EBCDIC-"
+ "INT\0cp038\0csIBM038\0IBM273\0CP273\0csIBM273\0IBM274\0EBCDIC-BE\0CP274\0csIBM274\0IBM275\0EBCDIC-"
+ "BR\0cp275\0csIBM275\0IBM277\0EBCDIC-CP-DK\0EBCDIC-CP-NO\0csIBM277\0IBM278\0CP278\0ebcdic-cp-fi\0ebcdic-cp-"
+ "se\0csIBM278\0IBM280\0CP280\0ebcdic-cp-it\0csIBM280\0IBM281\0EBCDIC-JP-"
+ "E\0cp281\0csIBM281\0IBM284\0CP284\0ebcdic-cp-es\0csIBM284\0IBM285\0CP285\0ebcdic-cp-"
+ "gb\0csIBM285\0IBM290\0cp290\0EBCDIC-JP-kana\0csIBM290\0IBM297\0cp297\0ebcdic-cp-"
+ "fr\0csIBM297\0IBM420\0cp420\0ebcdic-cp-ar1\0csIBM420\0IBM423\0cp423\0ebcdic-cp-"
+ "gr\0csIBM423\0IBM424\0cp424\0ebcdic-cp-he\0csIBM424\0IBM500\0CP500\0ebcdic-cp-be\0ebcdic-cp-"
+ "ch\0csIBM500\0IBM851\0cp851\0851\0csIBM851\0IBM855\0cp855\0855\0csIBM855\0IBM857\0cp857\0857\0csIBM857\0IBM860\0"
+ "cp860\0860\0csIBM860\0IBM861\0cp861\0861\0cp-"
+ "is\0csIBM861\0IBM863\0cp863\0863\0csIBM863\0IBM864\0cp864\0csIBM864\0IBM865\0cp865\0865\0csIBM865\0IBM868\0CP868"
+ "\0cp-ar\0csIBM868\0IBM869\0cp869\0869\0cp-gr\0csIBM869\0IBM870\0CP870\0ebcdic-cp-roece\0ebcdic-cp-"
+ "yu\0csIBM870\0IBM871\0CP871\0ebcdic-cp-is\0csIBM871\0IBM880\0cp880\0EBCDIC-"
+ "Cyrillic\0csIBM880\0IBM891\0cp891\0csIBM891\0IBM903\0cp903\0csIBM903\0IBM904\0cp904\0904\0csIBBM904\0IBM905\0CP9"
+ "05\0ebcdic-cp-tr\0csIBM905\0IBM918\0CP918\0ebcdic-cp-ar2\0csIBM918\0IBM1026\0CP1026\0csIBM1026\0EBCDIC-AT-"
+ "DE\0csIBMEBCDICATDE\0EBCDIC-AT-DE-A\0csEBCDICATDEA\0EBCDIC-CA-FR\0csEBCDICCAFR\0EBCDIC-DK-"
+ "NO\0csEBCDICDKNO\0EBCDIC-DK-NO-A\0csEBCDICDKNOA\0EBCDIC-FI-SE\0csEBCDICFISE\0EBCDIC-FI-SE-"
+ "A\0csEBCDICFISEA\0EBCDIC-FR\0csEBCDICFR\0EBCDIC-IT\0csEBCDICIT\0EBCDIC-PT\0csEBCDICPT\0EBCDIC-"
+ "ES\0csEBCDICES\0EBCDIC-ES-A\0csEBCDICESA\0EBCDIC-ES-S\0csEBCDICESS\0EBCDIC-UK\0csEBCDICUK\0EBCDIC-"
+ "US\0csEBCDICUS\0UNKNOWN-"
+ "8BIT\0csUnknown8BiT\0MNEMONIC\0csMnemonic\0MNEM\0csMnem\0VISCII\0csVISCII\0VIQR\0csVIQR\0KOI8-R\0csKOI8R\0HZ-GB-"
+ "2312\0IBM866\0cp866\0866\0csIBM866\0IBM775\0cp775\0csPC775Baltic\0KOI8-"
+ "U\0csKOI8U\0IBM00858\0CCSID00858\0CP00858\0PC-Multilingual-850+"
+ "euro\0csIBM00858\0IBM00924\0CCSID00924\0CP00924\0ebcdic-Latin9--"
+ "euro\0csIBM00924\0IBM01140\0CCSID01140\0CP01140\0ebcdic-us-37+"
+ "euro\0csIBM01140\0IBM01141\0CCSID01141\0CP01141\0ebcdic-de-273+"
+ "euro\0csIBM01141\0IBM01142\0CCSID01142\0CP01142\0ebcdic-dk-277+euro\0ebcdic-no-277+"
+ "euro\0csIBM01142\0IBM01143\0CCSID01143\0CP01143\0ebcdic-fi-278+euro\0ebcdic-se-278+"
+ "euro\0csIBM01143\0IBM01144\0CCSID01144\0CP01144\0ebcdic-it-280+"
+ "euro\0csIBM01144\0IBM01145\0CCSID01145\0CP01145\0ebcdic-es-284+"
+ "euro\0csIBM01145\0IBM01146\0CCSID01146\0CP01146\0ebcdic-gb-285+"
+ "euro\0csIBM01146\0IBM01147\0CCSID01147\0CP01147\0ebcdic-fr-297+"
+ "euro\0csIBM01147\0IBM01148\0CCSID01148\0CP01148\0ebcdic-international-500+"
+ "euro\0csIBM01148\0IBM01149\0CCSID01149\0CP01149\0ebcdic-is-871+euro\0csIBM01149\0Big5-"
+ "HKSCS\0csBig5HKSCS\0IBM1047\0IBM-1047\0csIBM1047\0PTCP154\0csPTCP154\0PT154\0CP154\0Cyrillic-Asian\0Amiga-"
+ "1251\0Ami1251\0Amiga1251\0Ami-1251\0csAmiga1251\0KOI7-"
+ "switched\0csKOI7switched\0BRF\0csBRF\0TSCII\0csTSCII\0CP51932\0csCP51932\0windows-874\0cswindows874\0windows-"
+ "1250\0cswindows1250\0windows-1251\0cswindows1251\0windows-1252\0cswindows1252\0windows-"
+ "1253\0cswindows1253\0windows-1254\0cswindows1254\0windows-1255\0cswindows1255\0windows-"
+ "1256\0cswindows1256\0windows-1257\0cswindows1257\0windows-1258\0cswindows1258\0TIS-620\0csTIS620\0ISO-8859-"
+ "11\0CP50220\0csCP50220\0";
+
+ struct __offset_table {
+ constexpr static unsigned long long __num_aliases =
+ std::count(__aliases_string, __aliases_string + sizeof(__aliases_string), '\0') + 1;
+ unsigned short __table[__num_aliases];
+ };
+
+ static constexpr __offset_table __alias_offsets = [] {
+ __offset_table __aliases{};
+ __aliases.__table[0] = sizeof(__aliases_string) - 1;
+ __aliases.__table[1] = sizeof(__aliases_string) - 1;
+ __aliases.__table[2] = 0;
+
+ unsigned long long __idx = 3;
+
+ for (unsigned short __pos = 0; __pos < sizeof(__aliases_string) - 1 && __idx < __offset_table::__num_aliases;
+ __pos++) {
+ if (__aliases_string[__pos] == '\0') {
+ __aliases.__table[__idx++] = __pos + 1;
+ }
+ }
+
+ return __aliases;
+ }();
+};
+
+template <>
+struct hash<text_encoding> {
+ [[nodiscard]] static size_t operator()(const text_encoding& __enc) noexcept {
+ return std::hash<std::text_encoding::id>()(__enc.mib());
+ }
+};
+
+template <>
+inline constexpr bool ranges::enable_borrowed_range<text_encoding::aliases_view> = true;
+
+_LIBCPP_END_NAMESPACE_STD
+
+# endif // _LIBCPP_STD_VER >= 26
+
+#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
+
+#endif // _LIBCPP_TEXT_ENCODING
diff --git a/libcxx/include/version b/libcxx/include/version
index 53e879959ec17..0b4438d90190d 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -633,7 +633,7 @@ __cpp_lib_void_t 201411L <type_traits>
# undef __cpp_lib_string_view
# define __cpp_lib_string_view 202403L
// # define __cpp_lib_submdspan 202306L
-// # define __cpp_lib_text_encoding 202306L
+# define __cpp_lib_text_encoding 202306L
# undef __cpp_lib_to_chars
// # define __cpp_lib_to_chars 202306L
// # define __cpp_lib_to_string 202306L
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 74283373d1b65..2a419e8c8af05 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1562,6 +1562,7 @@
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKvx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__throw_system_errorEiPKc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__121__get_locale_encodingEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__121__throw_runtime_errorEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutex4lockEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutex6unlockEv', 'type': 'FUNC'}
@@ -2655,4 +2656,4 @@
{'is_defined': True, 'name': '___cxa_vec_new2', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_vec_new3', 'type': 'I'}
{'is_defined': True, 'name': '___dynamic_cast', 'type': 'I'}
-{'is_defined': True, 'name': '___gxx_personality_v0', 'type': 'I'}
+{'is_defined': True, 'name': '___gxx_personality_v0', 'type': 'I'}
\ No newline at end of file
diff --git a/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
index 291149608c9c7..414a239757e1c 100644
--- a/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1199,6 +1199,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__throw_system_errorEiPKc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk121__get_locale_encodingEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121__throw_runtime_errorEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutex4lockEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutex6unlockEv', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index da6d608af462c..590c0de8ce20f 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -555,6 +555,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__120__throw_system_errorEiPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121__get_locale_encodingEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex6unlockEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 6ee31613d5320..f4f4ab99ad866 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -555,6 +555,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEEl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__120__throw_system_errorEiPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121__get_locale_encodingEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex6unlockEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
index 7b09d3dd3f75c..e1b1e110318fa 100644
--- a/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1199,6 +1199,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__throw_system_errorEiPKc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk121__get_locale_encodingEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121__throw_runtime_errorEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutex4lockEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutex6unlockEv', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index 725ed669fb561..11cc8f180e824 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1212,6 +1212,7 @@
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEEl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__throw_system_errorEiPKc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__121__get_locale_encodingEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex6unlockEv', 'type': 'FUNC'}
@@ -2031,4 +2032,4 @@
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD0Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
\ No newline at end of file
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 717d4c9bee726..a28229a9d6e97 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
@@ -1210,6 +1210,7 @@
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__throw_system_errorEiPKc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__121__get_locale_encodingEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex6unlockEv', 'type': 'FUNC'}
@@ -2030,4 +2031,4 @@
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD0Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
\ No newline at end of file
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 45db143b4cf4a..2b69d6dc89138 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -1181,6 +1181,7 @@
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__throw_system_errorEiPKc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__121__get_locale_encodingEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutex6unlockEv', 'type': 'FUNC'}
diff --git a/libcxx/modules/std.compat.cppm.in b/libcxx/modules/std.compat.cppm.in
index dd7385bf33a42..ab08125c4c4e4 100644
--- a/libcxx/modules/std.compat.cppm.in
+++ b/libcxx/modules/std.compat.cppm.in
@@ -75,9 +75,6 @@ module;
# if __has_include(<stdfloat>)
# error "please update the header information for <stdfloat> in headers_not_available in utils/libcxx/header_information.py"
# endif // __has_include(<stdfloat>)
-# if __has_include(<text_encoding>)
-# error "please update the header information for <text_encoding> in headers_not_available in utils/libcxx/header_information.py"
-# endif // __has_include(<text_encoding>)
#endif // _WIN32
export module std.compat;
diff --git a/libcxx/modules/std.cppm.in b/libcxx/modules/std.cppm.in
index 6de6369c3387f..b9a491653659a 100644
--- a/libcxx/modules/std.cppm.in
+++ b/libcxx/modules/std.cppm.in
@@ -108,6 +108,7 @@ module;
#include <strstream>
#include <syncstream>
#include <system_error>
+#include <text_encoding>
#include <thread>
#include <tuple>
#include <type_traits>
@@ -157,9 +158,6 @@ module;
# if __has_include(<stdfloat>)
# error "please update the header information for <stdfloat> in headers_not_available in utils/libcxx/header_information.py"
# endif // __has_include(<stdfloat>)
-# if __has_include(<text_encoding>)
-# error "please update the header information for <text_encoding> in headers_not_available in utils/libcxx/header_information.py"
-# endif // __has_include(<text_encoding>)
#endif // _WIN32
export module std;
diff --git a/libcxx/modules/std/text_encoding.inc b/libcxx/modules/std/text_encoding.inc
index 6d5e3f1d68c60..8ad1e7bfced43 100644
--- a/libcxx/modules/std/text_encoding.inc
+++ b/libcxx/modules/std/text_encoding.inc
@@ -8,12 +8,11 @@
//===----------------------------------------------------------------------===//
export namespace std {
-#if 0
-# if _LIBCPP_STD_VER >= 23
- using std::text_encoding;
-
- // hash support
+#if _LIBCPP_STD_VER >= 26
using std::hash;
-# endif // _LIBCPP_STD_VER >= 23
+ namespace ranges {
+ using std::ranges::enable_borrowed_range;
+ }
+ using std::text_encoding;
#endif
} // namespace std
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index de7817ad69f26..0c883e9ecd30d 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -91,6 +91,7 @@ if (LIBCXX_ENABLE_LOCALIZATION)
ostream.cpp
regex.cpp
strstream.cpp
+ text_encoding.cpp
)
endif()
diff --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp
index e7c7a114e9ce6..c5117564438a5 100644
--- a/libcxx/src/support/win32/locale_win32.cpp
+++ b/libcxx/src/support/win32/locale_win32.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include <__locale_dir/support/windows.h>
+#include <cctype>
+#include <charconv>
#include <clocale> // std::localeconv() & friends
#include <cstdarg> // va_start & friends
#include <cstddef>
@@ -14,6 +16,8 @@
#include <cstdlib> // std::strtof & friends
#include <ctime> // std::strftime
#include <cwchar> // wide char manipulation
+#include <string_view>
+#include <windows.h>
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
@@ -35,6 +39,262 @@ __lconv_t* __localeconv(__locale_t& loc) {
return loc.__store_lconv(lc);
}
+namespace {
+const char* __codepage_name(unsigned int __codepage) {
+ switch (__codepage) {
+ case 0:
+ // If no ANSI code page is available, only Unicode can be used for the locale.
+ // In this case, the value is CP_ACP (0).
+ // Such a locale cannot be set as the system locale.
+ // Applications that do not support Unicode do not work correctly with locales
+ // marked as "Unicode only".
+ return nullptr;
+ case 037:
+ return "IBM037";
+ case 437:
+ return "IBM437";
+ case 500:
+ return "IBM500";
+ case 708:
+ return "ASMO-708";
+ case 709:
+ return "ASMO_449";
+ case 775:
+ return "IBM775";
+ case 850:
+ return "IBM850";
+ case 852:
+ return "IBM852";
+ case 855:
+ return "IBM855";
+ case 857:
+ return "IBM857";
+ case 858:
+ return "IBM00858";
+ case 860:
+ return "IBM860";
+ case 861:
+ return "IBM861";
+ case 862:
+ return "IBM862";
+ case 863:
+ return "IBM863";
+ case 864:
+ return "IBM864";
+ case 865:
+ return "IBM865";
+ case 866:
+ return "IBM866";
+ case 869:
+ return "IBM869";
+ case 870:
+ return "IBM870";
+ case 874:
+ return "windows-874";
+ case 932:
+ return "Shift_JIS";
+ case 936:
+ return "GB2312";
+ case 949:
+ return "KS_C_5601-1989";
+ case 950:
+ return "Big5";
+ case 1026:
+ return "IBM1026";
+ case 1047:
+ return "IBM1047";
+ case 1140:
+ return "IBM01140";
+ case 1141:
+ return "IBM01141";
+ case 1142:
+ return "IBM01142";
+ case 1143:
+ return "IBM01143";
+ case 1144:
+ return "IBM01144";
+ case 1145:
+ return "IBM01145";
+ case 1146:
+ return "IBM01146";
+ case 1147:
+ return "IBM01147";
+ case 1148:
+ return "IBM01148";
+ case 1149:
+ return "IBM01149";
+ case 1200:
+ return "UTF-16LE";
+ case 1201:
+ return "UTF-16BE";
+ case 1250:
+ return "windows-1250";
+ case 1251:
+ return "windows-1251";
+ case 1252:
+ return "windows-1252";
+ case 1253:
+ return "windows-1253";
+ case 1254:
+ return "windows-1254";
+ case 1255:
+ return "windows-1255";
+ case 1256:
+ return "windows-1256";
+ case 1257:
+ return "windows-1257";
+ case 1258:
+ return "windows-1258";
+ case 10000:
+ return "macintosh";
+ case 12000:
+ return "UTF-32LE";
+ case 12001:
+ return "UTF-32BE";
+ case 20127:
+ return "US-ASCII";
+ case 20273:
+ return "IBM273";
+ case 20277:
+ return "IBM277";
+ case 20278:
+ return "IBM278";
+ case 20280:
+ return "IBM280";
+ case 20284:
+ return "IBM284";
+ case 20285:
+ return "IBM285";
+ case 20290:
+ return "IBM290";
+ case 20297:
+ return "IBM297";
+ case 20420:
+ return "IBM420";
+ case 20423:
+ return "IBM423";
+ case 20424:
+ return "IBM424";
+ case 20838:
+ return "IBM-Thai";
+ case 20866:
+ return "KOI8-R";
+ case 20871:
+ return "IBM871";
+ case 20880:
+ return "IBM880";
+ case 20905:
+ return "IBM905";
+ case 20924:
+ return "IBM00924";
+ case 20932:
+ return "EUC-JP";
+ case 21866:
+ return "KOI8-U";
+ case 28591:
+ return "ISO-8859-1";
+ case 28592:
+ return "ISO-8859-2";
+ case 28593:
+ return "ISO-8859-3";
+ case 28594:
+ return "ISO-8859-4";
+ case 28595:
+ return "ISO-8859-9";
+ case 28596:
+ return "ISO-8859-10";
+ case 28597:
+ return "ISO-8859-7";
+ case 28598:
+ return "ISO-8859-8";
+ case 28599:
+ return "ISO-8859-9-Windows-Latin-5";
+ case 28603:
+ return "ISO-8859-13";
+ case 28605:
+ return "ISO-8859-15";
+ case 38598:
+ return "ISO-8859-8-I";
+ case 50220:
+ case 50221:
+ case 50222:
+ return "ISO-2022-JP";
+ case 51932:
+ return "EUC-JP";
+ case 51936:
+ return "GB2312";
+ case 51949:
+ return "EUC-KR";
+ case 52936:
+ return "HZ-GB-2312";
+ case 54936:
+ return "GB18030";
+ case 65000:
+ return "UTF-7";
+ case 65001:
+ return "UTF-8";
+ default:
+ return nullptr;
+ }
+}
+} // namespace
+
+const char* __get_locale_encoding(__locale_t loc) {
+ const char* locale_name = loc.__get_locale();
+ if (locale_name == nullptr) {
+ return __codepage_name(::GetACP());
+ }
+
+ std::string_view __sv(locale_name);
+
+ // locale :: "locale-name"
+ // | "language"[_country-region[.code-page]]
+ // | ".code-page"
+ // GetLocaleInfoEx doesn't accept anything other than BCP-47 locale names, e.g. "en_US",
+ // so do a best-attempt to derive the text encoding from the name.
+ if (__sv == "C" || __sv == "") {
+ // "A locale argument value of C specifies the minimal ANSI conforming environment for C translation."
+ // TODO: Figure out what to do for an empty string:
+ // "If locale points to an empty string, the locale is the implementation-defined native environment."
+ return __codepage_name(::GetACP());
+ } else if (auto dot = __sv.find('.'); dot != std::string_view::npos) {
+ std::string_view __code_page(locale_name + dot + 1);
+
+ // Windows allows the codepage number as part of the name,
+ // e.g. "en_US.1252" for English US, Windows-1252.
+ if (std::isdigit(__code_page[0])) {
+ unsigned int __cpage{};
+ auto __res = std::from_chars(__code_page.data(), __code_page.data() + __code_page.size(), __cpage);
+ if (__res) {
+ return __codepage_name(__cpage);
+ }
+ } else { // POSIX-style name
+ return locale_name + dot + 1;
+ }
+ }
+
+ wchar_t locale_wbuffer[LOCALE_NAME_MAX_LENGTH + 1]{};
+ wchar_t number_buffer[11]{};
+
+ bool is_ansi = ::AreFileApisANSI();
+ auto codepage = is_ansi ? CP_ACP : CP_OEMCP;
+ int ret = ::MultiByteToWideChar(
+ codepage, MB_ERR_INVALID_CHARS, locale_name, __sv.size(), locale_wbuffer, LOCALE_NAME_MAX_LENGTH);
+
+ if (ret <= 0)
+ return nullptr;
+
+ // The below function fills the string with the number in text.
+ auto lctype = is_ansi ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE;
+ int result = ::GetLocaleInfoEx(locale_wbuffer, lctype, number_buffer, 10);
+
+ if (result <= 0)
+ return nullptr;
+
+ unsigned int acp = std::wcstoul(number_buffer, nullptr, 10);
+ return __codepage_name(acp);
+}
+
//
// Strtonum functions
//
diff --git a/libcxx/src/text_encoding.cpp b/libcxx/src/text_encoding.cpp
new file mode 100644
index 0000000000000..871cf9b8b818b
--- /dev/null
+++ b/libcxx/src/text_encoding.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <__locale_dir/locale_base_api.h>
+#include <__utility/scope_guard.h>
+#include <text_encoding>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
+
+#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; }
+#else
+static text_encoding __make_text_encoding(const char* __name) {
+ if (__name == nullptr)
+ return text_encoding{};
+
+ string_view __name_view(__name);
+ if (__name_view.size() > text_encoding::max_name_length)
+ return text_encoding{};
+
+ return text_encoding(__name_view);
+}
+
+std::text_encoding __get_locale_encoding(const char* __name) {
+ if (__name == nullptr)
+ return __make_text_encoding(__locale::__get_locale_encoding(static_cast<__locale::__locale_t>(nullptr)));
+
+ __locale::__locale_t __l = __locale::__newlocale(_LIBCPP_CTYPE_MASK, __name, static_cast<__locale::__locale_t>(0));
+
+ __scope_guard __locale_guard([&__l] {
+ if (__l) {
+ __locale::__freelocale(__l);
+ }
+ });
+
+ if (!__l) {
+ return text_encoding{};
+ }
+
+ return __make_text_encoding(__locale::__get_locale_encoding(__l));
+}
+
+#endif // __ANDROID__
+
+_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
+_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/libcxx/localization/nodiscard.verify.cpp b/libcxx/test/libcxx/localization/nodiscard.verify.cpp
index dd14091b90182..7267b4c9c7b9c 100644
--- a/libcxx/test/libcxx/localization/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/localization/nodiscard.verify.cpp
@@ -32,8 +32,9 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
l.combine<std::messages<char> >(l);
l.name(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-#if TEST_STD_VER >= 26
- // l.encoding(); // TODO: Verify this once P1885R12 (https://llvm.org/PR105373) is implemented.
+#if TEST_STD_VER >= 26 && _LIBCPP_AVAILABILITY_HAS_TEXT_ENCODING_ENVIRONMENT
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ l.encoding();
#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
l(std::string(), std::string());
diff --git a/libcxx/test/libcxx/text/text_encoding/environment.android.pass.cpp b/libcxx/test/libcxx/text/text_encoding/environment.android.pass.cpp
new file mode 100644
index 0000000000000..6a80e8224d528
--- /dev/null
+++ b/libcxx/test/libcxx/text/text_encoding/environment.android.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <text_encoding>
+
+// REQUIRES: std-at-least-c++26
+// REQUIRES: locale.fr_CA.ISO8859-1
+
+// UNSUPPORTED: no-localization
+// UNSUPPORTED: availability-te-environment-missing
+// REQUIRES: android
+
+// std::text_encoding::environment()
+
+#include <cassert>
+#include <cstdlib>
+#include <text_encoding>
+
+#include "platform_support.h" // locale name macros
+
+int main(int, char**) {
+ // On Android, UTF-8 is unconditionally returned.
+ ::setenv("LANG", LOCALE_fr_CA_ISO8859_1, 1);
+
+ auto te = std::text_encoding::environment();
+ assert(std::text_encoding::environment_is<std::text_encoding::id::UTF8>());
+ assert(te == std::text_encoding::environment());
+ assert(te.mib() == std::text_encoding::id::UTF8);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/text/text_encoding/environment.pass.cpp b/libcxx/test/libcxx/text/text_encoding/environment.pass.cpp
new file mode 100644
index 0000000000000..b5c88c6e6d568
--- /dev/null
+++ b/libcxx/test/libcxx/text/text_encoding/environment.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <text_encoding>
+
+// REQUIRES: std-at-least-c++26
+// REQUIRES: locale.fr_CA.ISO8859-1
+
+// UNSUPPORTED: no-localization
+// UNSUPPORTED: windows, android
+// UNSUPPORTED: availability-te-environment-missing
+
+// std::text_encoding::environment()
+
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <text_encoding>
+
+#include "platform_support.h" // locale name macros
+
+int main(int, char**) {
+ // The default text_encoding::environment() which relies on nl_langinfo is
+ // affected by changes to the "LANG" environment variable on POSIX systems.
+ setenv("LANG", LOCALE_fr_CA_ISO8859_1, 1);
+
+ auto te = std::text_encoding::environment();
+
+ assert(std::text_encoding::environment_is<std::text_encoding::id::ISOLatin1>());
+ assert(te == std::text_encoding::environment());
+ assert(te.mib() == std::text_encoding::id::ISOLatin1);
+ assert(std::ranges::contains(te.aliases(), std::string_view("ISO_8859-1")));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/text/text_encoding/environment.windows.pass.cpp b/libcxx/test/libcxx/text/text_encoding/environment.windows.pass.cpp
new file mode 100644
index 0000000000000..465a62078adc1
--- /dev/null
+++ b/libcxx/test/libcxx/text/text_encoding/environment.windows.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <text_encoding>
+
+// REQUIRES: std-at-least-c++26
+// REQUIRES: locale.fr_CA.ISO8859-1
+
+// UNSUPPORTED: no-localization
+// UNSUPPORTED: availability-te-environment-missing
+// REQUIRES: windows
+
+// std::text_encoding::environment()
+
+#include <cassert>
+#include <cstdlib>
+#include <text_encoding>
+#include <windows.h>
+
+#include "platform_support.h" // locale name macros
+
+int main(int, char**) {
+ // On Windows, changes to the "LANG" environment variable don't affect the result
+ // of std::text_encoding::environment() and environment_is()
+ auto te = std::text_encoding::environment();
+
+ ::SetEnvironmentVariableA("LANG", LOCALE_fr_CA_ISO8859_1);
+
+ assert(std::text_encoding::environment_is<std::text_encoding::id::windows1252>());
+ assert(te == std::text_encoding::environment());
+ assert(te.mib() == std::text_encoding::id::windows1252);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/text/text_encoding/nodiscard.verify.cpp b/libcxx/test/libcxx/text/text_encoding/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..8bd3b0780c26b
--- /dev/null
+++ b/libcxx/test/libcxx/text/text_encoding/nodiscard.verify.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+#include <text_encoding>
+
+#include "test_macros.h"
+
+void test() {
+ std::text_encoding te{};
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ te.mib();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ te.name();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ te.aliases();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ te.aliases();
+
+ auto alias = te.aliases();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ alias.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ alias.end();
+
+ auto it = alias.begin();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ *it;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it[0];
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it + 1;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it - 1;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ it - it;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::hash<std::text_encoding>()(std::text_encoding::ASCII);
+
+#if !defined(TEST_HAS_NO_LOCALIZATION) && _LIBCPP_AVAILABILITY_HAS_TEXT_ENCODING_ENVIRONMENT
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ te.environment();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ te.environment_is<std::text_encoding::UTF8>();
+#endif
+}
+
+consteval void literal() {
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::text_encoding::literal();
+}
diff --git a/libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.id.pass.cpp b/libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.id.pass.cpp
new file mode 100644
index 0000000000000..f23629d5020ab
--- /dev/null
+++ b/libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.id.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// REQUIRES: std-at-least-c++26
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+
+// <text_encoding>
+
+// text_encoding text_encoding(std::text_encoding::id) noexcept
+
+#include <climits>
+#include <text_encoding>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // Make sure that text_encoding(id) asserts when the input id is not in the range of allowed values
+
+ TEST_LIBCPP_ASSERT_FAILURE(std::text_encoding(std::text_encoding::id(33)), "Mib for NATS-DANO used");
+ TEST_LIBCPP_ASSERT_FAILURE(std::text_encoding(std::text_encoding::id(34)), "Mib for NATS-DANO-ADD used");
+ TEST_LIBCPP_ASSERT_FAILURE(std::text_encoding(std::text_encoding::id(-1)), "invalid text_encoding::id passed");
+ TEST_LIBCPP_ASSERT_FAILURE(std::text_encoding(std::text_encoding::id(INT_MAX)), "invalid text_encoding::id passed");
+ TEST_LIBCPP_ASSERT_FAILURE(std::text_encoding(std::text_encoding::id(int(std::text_encoding::id::CP50220) + 1)),
+ "invalid text_encoding::id passed");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.string_view.pass.cpp b/libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.string_view.pass.cpp
new file mode 100644
index 0000000000000..ddeef710c62f4
--- /dev/null
+++ b/libcxx/test/libcxx/text/text_encoding/text_encoding.ctor/assert.string_view.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// REQUIRES: std-at-least-c++26
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+
+// <text_encoding>
+
+// text_encoding text_encoding(string_view)
+
+#include <string>
+#include <string_view>
+#include <text_encoding>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::string str(std::text_encoding::max_name_length + 1, 'X');
+
+ // text_encoding(string_view) asserts if its input size() > max_name_length
+ TEST_LIBCPP_ASSERT_FAILURE(std::text_encoding(std::string_view(str)), "input string_view must have size <= 63");
+
+ // text_encoding(string_view) asserts if its input contains a null terminator
+ std::string str2(std::text_encoding::max_name_length, 'X');
+ str2[3] = '\0';
+
+ TEST_LIBCPP_ASSERT_FAILURE(std::text_encoding(std::string_view(str2)), "input string_view must not contain '\\0'");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/text/text_encoding/text_encoding.members/environment.delete.verify.cpp b/libcxx/test/libcxx/text/text_encoding/text_encoding.members/environment.delete.verify.cpp
new file mode 100644
index 0000000000000..23fe29bd798bd
--- /dev/null
+++ b/libcxx/test/libcxx/text/text_encoding/text_encoding.members/environment.delete.verify.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// REQUIRES: no-localization
+
+// <text_encoding>
+
+// text_encoding text_encoding::environment()
+// template<std::text_encoding::id> text_encoding text_encoding::environment_is()
+
+// environment() and environment_is() are deleted if libc++ is built without localization.
+
+#include <text_encoding>
+
+void test() {
+ // expected-error at +1 {{attempt to use a deleted function}}
+ std::text_encoding::environment();
+ // expected-error at +1 {{call to deleted function 'environment_is'}}
+ std::text_encoding::environment_is<std::text_encoding::UTF8>();
+}
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index c0031543e47bc..b0b58724e64ab 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -69,6 +69,7 @@ any streambuf
any string
any string_view
any system_error
+any text_encoding
any tuple
any type_traits
any typeinfo
@@ -122,15 +123,19 @@ atomic ratio
atomic type_traits
atomic version
barrier atomic
+barrier cctype
barrier climits
barrier cmath
barrier compare
barrier concepts
barrier cstddef
barrier cstdint
+barrier cstdio
barrier cstdlib
barrier cstring
barrier ctime
+barrier cwchar
+barrier cwctype
barrier exception
barrier initializer_list
barrier iosfwd
@@ -234,6 +239,7 @@ ccomplex streambuf
ccomplex string
ccomplex string_view
ccomplex system_error
+ccomplex text_encoding
ccomplex tuple
ccomplex type_traits
ccomplex typeinfo
@@ -292,6 +298,7 @@ chrono streambuf
chrono string
chrono string_view
chrono system_error
+chrono text_encoding
chrono tuple
chrono type_traits
chrono typeinfo
@@ -337,6 +344,7 @@ codecvt stdexcept
codecvt string
codecvt string_view
codecvt system_error
+codecvt text_encoding
codecvt tuple
codecvt type_traits
codecvt typeinfo
@@ -396,6 +404,7 @@ complex streambuf
complex string
complex string_view
complex system_error
+complex text_encoding
complex tuple
complex type_traits
complex typeinfo
@@ -501,6 +510,7 @@ ctgmath streambuf
ctgmath string
ctgmath string_view
ctgmath system_error
+ctgmath text_encoding
ctgmath tuple
ctgmath type_traits
ctgmath typeinfo
@@ -552,6 +562,7 @@ deque streambuf
deque string
deque string_view
deque system_error
+deque text_encoding
deque tuple
deque type_traits
deque typeinfo
@@ -607,6 +618,7 @@ experimental/iterator streambuf
experimental/iterator string
experimental/iterator string_view
experimental/iterator system_error
+experimental/iterator text_encoding
experimental/iterator tuple
experimental/iterator type_traits
experimental/iterator typeinfo
@@ -732,6 +744,7 @@ format streambuf
format string
format string_view
format system_error
+format text_encoding
format tuple
format type_traits
format typeinfo
@@ -778,6 +791,7 @@ forward_list streambuf
forward_list string
forward_list string_view
forward_list system_error
+forward_list text_encoding
forward_list tuple
forward_list type_traits
forward_list typeinfo
@@ -834,6 +848,7 @@ fstream streambuf
fstream string
fstream string_view
fstream system_error
+fstream text_encoding
fstream tuple
fstream type_traits
fstream typeinfo
@@ -879,6 +894,7 @@ functional streambuf
functional string
functional string_view
functional system_error
+functional text_encoding
functional tuple
functional type_traits
functional typeinfo
@@ -936,6 +952,7 @@ future streambuf
future string
future string_view
future system_error
+future text_encoding
future thread
future tuple
future type_traits
@@ -993,6 +1010,7 @@ iomanip streambuf
iomanip string
iomanip string_view
iomanip system_error
+iomanip text_encoding
iomanip tuple
iomanip type_traits
iomanip typeinfo
@@ -1033,6 +1051,7 @@ ios stdexcept
ios string
ios string_view
ios system_error
+ios text_encoding
ios tuple
ios type_traits
ios typeinfo
@@ -1086,6 +1105,7 @@ iostream streambuf
iostream string
iostream string_view
iostream system_error
+iostream text_encoding
iostream tuple
iostream type_traits
iostream typeinfo
@@ -1139,6 +1159,7 @@ istream streambuf
istream string
istream string_view
istream system_error
+istream text_encoding
istream tuple
istream type_traits
istream typeinfo
@@ -1223,6 +1244,7 @@ list streambuf
list string
list string_view
list system_error
+list text_encoding
list tuple
list type_traits
list typeinfo
@@ -1266,6 +1288,7 @@ locale streambuf
locale string
locale string_view
locale system_error
+locale text_encoding
locale tuple
locale type_traits
locale typeinfo
@@ -1310,6 +1333,7 @@ map streambuf
map string
map string_view
map system_error
+map text_encoding
map tuple
map type_traits
map typeinfo
@@ -1442,6 +1466,7 @@ numeric streambuf
numeric string
numeric string_view
numeric system_error
+numeric text_encoding
numeric tuple
numeric type_traits
numeric typeinfo
@@ -1523,6 +1548,7 @@ ostream streambuf
ostream string
ostream string_view
ostream system_error
+ostream text_encoding
ostream tuple
ostream type_traits
ostream typeinfo
@@ -1573,6 +1599,7 @@ print streambuf
print string
print string_view
print system_error
+print text_encoding
print tuple
print type_traits
print typeinfo
@@ -1620,6 +1647,7 @@ queue streambuf
queue string
queue string_view
queue system_error
+queue text_encoding
queue tuple
queue type_traits
queue typeinfo
@@ -1668,6 +1696,7 @@ random streambuf
random string
random string_view
random system_error
+random text_encoding
random tuple
random type_traits
random typeinfo
@@ -1742,6 +1771,7 @@ regex streambuf
regex string
regex string_view
regex system_error
+regex text_encoding
regex tuple
regex type_traits
regex typeinfo
@@ -1830,6 +1860,7 @@ set streambuf
set string
set string_view
set system_error
+set text_encoding
set tuple
set type_traits
set typeinfo
@@ -1914,6 +1945,7 @@ span streambuf
span string
span string_view
span system_error
+span text_encoding
span tuple
span type_traits
span typeinfo
@@ -1968,6 +2000,7 @@ sstream streambuf
sstream string
sstream string_view
sstream system_error
+sstream text_encoding
sstream tuple
sstream type_traits
sstream typeinfo
@@ -2015,6 +2048,7 @@ stack streambuf
stack string
stack string_view
stack system_error
+stack text_encoding
stack tuple
stack type_traits
stack typeinfo
@@ -2032,6 +2066,7 @@ stdexcept new
stdexcept type_traits
stdexcept typeinfo
stdexcept version
+stop_token cstddef
stop_token iosfwd
stop_token version
streambuf algorithm
@@ -2067,6 +2102,7 @@ streambuf stdexcept
streambuf string
streambuf string_view
streambuf system_error
+streambuf text_encoding
streambuf tuple
streambuf type_traits
streambuf typeinfo
@@ -2184,6 +2220,7 @@ strstream streambuf
strstream string
strstream string_view
strstream system_error
+strstream text_encoding
strstream tuple
strstream type_traits
strstream typeinfo
@@ -2239,6 +2276,7 @@ syncstream streambuf
syncstream string
syncstream string_view
syncstream system_error
+syncstream text_encoding
syncstream tuple
syncstream type_traits
syncstream typeinfo
@@ -2331,6 +2369,7 @@ thread streambuf
thread string
thread string_view
thread system_error
+thread text_encoding
thread tuple
thread type_traits
thread typeinfo
@@ -2443,6 +2482,7 @@ unordered_set streambuf
unordered_set string
unordered_set string_view
unordered_set system_error
+unordered_set text_encoding
unordered_set tuple
unordered_set type_traits
unordered_set typeinfo
@@ -2499,6 +2539,7 @@ valarray streambuf
valarray string
valarray string_view
valarray system_error
+valarray text_encoding
valarray tuple
valarray type_traits
valarray typeinfo
@@ -2560,6 +2601,7 @@ vector streambuf
vector string
vector string_view
vector system_error
+vector text_encoding
vector tuple
vector type_traits
vector typeinfo
diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index c0031543e47bc..b0b58724e64ab 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -69,6 +69,7 @@ any streambuf
any string
any string_view
any system_error
+any text_encoding
any tuple
any type_traits
any typeinfo
@@ -122,15 +123,19 @@ atomic ratio
atomic type_traits
atomic version
barrier atomic
+barrier cctype
barrier climits
barrier cmath
barrier compare
barrier concepts
barrier cstddef
barrier cstdint
+barrier cstdio
barrier cstdlib
barrier cstring
barrier ctime
+barrier cwchar
+barrier cwctype
barrier exception
barrier initializer_list
barrier iosfwd
@@ -234,6 +239,7 @@ ccomplex streambuf
ccomplex string
ccomplex string_view
ccomplex system_error
+ccomplex text_encoding
ccomplex tuple
ccomplex type_traits
ccomplex typeinfo
@@ -292,6 +298,7 @@ chrono streambuf
chrono string
chrono string_view
chrono system_error
+chrono text_encoding
chrono tuple
chrono type_traits
chrono typeinfo
@@ -337,6 +344,7 @@ codecvt stdexcept
codecvt string
codecvt string_view
codecvt system_error
+codecvt text_encoding
codecvt tuple
codecvt type_traits
codecvt typeinfo
@@ -396,6 +404,7 @@ complex streambuf
complex string
complex string_view
complex system_error
+complex text_encoding
complex tuple
complex type_traits
complex typeinfo
@@ -501,6 +510,7 @@ ctgmath streambuf
ctgmath string
ctgmath string_view
ctgmath system_error
+ctgmath text_encoding
ctgmath tuple
ctgmath type_traits
ctgmath typeinfo
@@ -552,6 +562,7 @@ deque streambuf
deque string
deque string_view
deque system_error
+deque text_encoding
deque tuple
deque type_traits
deque typeinfo
@@ -607,6 +618,7 @@ experimental/iterator streambuf
experimental/iterator string
experimental/iterator string_view
experimental/iterator system_error
+experimental/iterator text_encoding
experimental/iterator tuple
experimental/iterator type_traits
experimental/iterator typeinfo
@@ -732,6 +744,7 @@ format streambuf
format string
format string_view
format system_error
+format text_encoding
format tuple
format type_traits
format typeinfo
@@ -778,6 +791,7 @@ forward_list streambuf
forward_list string
forward_list string_view
forward_list system_error
+forward_list text_encoding
forward_list tuple
forward_list type_traits
forward_list typeinfo
@@ -834,6 +848,7 @@ fstream streambuf
fstream string
fstream string_view
fstream system_error
+fstream text_encoding
fstream tuple
fstream type_traits
fstream typeinfo
@@ -879,6 +894,7 @@ functional streambuf
functional string
functional string_view
functional system_error
+functional text_encoding
functional tuple
functional type_traits
functional typeinfo
@@ -936,6 +952,7 @@ future streambuf
future string
future string_view
future system_error
+future text_encoding
future thread
future tuple
future type_traits
@@ -993,6 +1010,7 @@ iomanip streambuf
iomanip string
iomanip string_view
iomanip system_error
+iomanip text_encoding
iomanip tuple
iomanip type_traits
iomanip typeinfo
@@ -1033,6 +1051,7 @@ ios stdexcept
ios string
ios string_view
ios system_error
+ios text_encoding
ios tuple
ios type_traits
ios typeinfo
@@ -1086,6 +1105,7 @@ iostream streambuf
iostream string
iostream string_view
iostream system_error
+iostream text_encoding
iostream tuple
iostream type_traits
iostream typeinfo
@@ -1139,6 +1159,7 @@ istream streambuf
istream string
istream string_view
istream system_error
+istream text_encoding
istream tuple
istream type_traits
istream typeinfo
@@ -1223,6 +1244,7 @@ list streambuf
list string
list string_view
list system_error
+list text_encoding
list tuple
list type_traits
list typeinfo
@@ -1266,6 +1288,7 @@ locale streambuf
locale string
locale string_view
locale system_error
+locale text_encoding
locale tuple
locale type_traits
locale typeinfo
@@ -1310,6 +1333,7 @@ map streambuf
map string
map string_view
map system_error
+map text_encoding
map tuple
map type_traits
map typeinfo
@@ -1442,6 +1466,7 @@ numeric streambuf
numeric string
numeric string_view
numeric system_error
+numeric text_encoding
numeric tuple
numeric type_traits
numeric typeinfo
@@ -1523,6 +1548,7 @@ ostream streambuf
ostream string
ostream string_view
ostream system_error
+ostream text_encoding
ostream tuple
ostream type_traits
ostream typeinfo
@@ -1573,6 +1599,7 @@ print streambuf
print string
print string_view
print system_error
+print text_encoding
print tuple
print type_traits
print typeinfo
@@ -1620,6 +1647,7 @@ queue streambuf
queue string
queue string_view
queue system_error
+queue text_encoding
queue tuple
queue type_traits
queue typeinfo
@@ -1668,6 +1696,7 @@ random streambuf
random string
random string_view
random system_error
+random text_encoding
random tuple
random type_traits
random typeinfo
@@ -1742,6 +1771,7 @@ regex streambuf
regex string
regex string_view
regex system_error
+regex text_encoding
regex tuple
regex type_traits
regex typeinfo
@@ -1830,6 +1860,7 @@ set streambuf
set string
set string_view
set system_error
+set text_encoding
set tuple
set type_traits
set typeinfo
@@ -1914,6 +1945,7 @@ span streambuf
span string
span string_view
span system_error
+span text_encoding
span tuple
span type_traits
span typeinfo
@@ -1968,6 +2000,7 @@ sstream streambuf
sstream string
sstream string_view
sstream system_error
+sstream text_encoding
sstream tuple
sstream type_traits
sstream typeinfo
@@ -2015,6 +2048,7 @@ stack streambuf
stack string
stack string_view
stack system_error
+stack text_encoding
stack tuple
stack type_traits
stack typeinfo
@@ -2032,6 +2066,7 @@ stdexcept new
stdexcept type_traits
stdexcept typeinfo
stdexcept version
+stop_token cstddef
stop_token iosfwd
stop_token version
streambuf algorithm
@@ -2067,6 +2102,7 @@ streambuf stdexcept
streambuf string
streambuf string_view
streambuf system_error
+streambuf text_encoding
streambuf tuple
streambuf type_traits
streambuf typeinfo
@@ -2184,6 +2220,7 @@ strstream streambuf
strstream string
strstream string_view
strstream system_error
+strstream text_encoding
strstream tuple
strstream type_traits
strstream typeinfo
@@ -2239,6 +2276,7 @@ syncstream streambuf
syncstream string
syncstream string_view
syncstream system_error
+syncstream text_encoding
syncstream tuple
syncstream type_traits
syncstream typeinfo
@@ -2331,6 +2369,7 @@ thread streambuf
thread string
thread string_view
thread system_error
+thread text_encoding
thread tuple
thread type_traits
thread typeinfo
@@ -2443,6 +2482,7 @@ unordered_set streambuf
unordered_set string
unordered_set string_view
unordered_set system_error
+unordered_set text_encoding
unordered_set tuple
unordered_set type_traits
unordered_set typeinfo
@@ -2499,6 +2539,7 @@ valarray streambuf
valarray string
valarray string_view
valarray system_error
+valarray text_encoding
valarray tuple
valarray type_traits
valarray typeinfo
@@ -2560,6 +2601,7 @@ vector streambuf
vector string
vector string_view
vector system_error
+vector text_encoding
vector tuple
vector type_traits
vector typeinfo
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index c2eb5b44e8d7a..b438907b35195 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -71,6 +71,7 @@ any streambuf
any string
any string_view
any system_error
+any text_encoding
any tuple
any type_traits
any typeinfo
@@ -125,15 +126,19 @@ atomic ratio
atomic type_traits
atomic version
barrier atomic
+barrier cctype
barrier climits
barrier cmath
barrier compare
barrier concepts
barrier cstddef
barrier cstdint
+barrier cstdio
barrier cstdlib
barrier cstring
barrier ctime
+barrier cwchar
+barrier cwctype
barrier exception
barrier initializer_list
barrier iosfwd
@@ -239,6 +244,7 @@ ccomplex streambuf
ccomplex string
ccomplex string_view
ccomplex system_error
+ccomplex text_encoding
ccomplex tuple
ccomplex type_traits
ccomplex typeinfo
@@ -298,6 +304,7 @@ chrono streambuf
chrono string
chrono string_view
chrono system_error
+chrono text_encoding
chrono tuple
chrono type_traits
chrono typeinfo
@@ -344,6 +351,7 @@ codecvt stdexcept
codecvt string
codecvt string_view
codecvt system_error
+codecvt text_encoding
codecvt tuple
codecvt type_traits
codecvt typeinfo
@@ -404,6 +412,7 @@ complex streambuf
complex string
complex string_view
complex system_error
+complex text_encoding
complex tuple
complex type_traits
complex typeinfo
@@ -511,6 +520,7 @@ ctgmath streambuf
ctgmath string
ctgmath string_view
ctgmath system_error
+ctgmath text_encoding
ctgmath tuple
ctgmath type_traits
ctgmath typeinfo
@@ -563,6 +573,7 @@ deque streambuf
deque string
deque string_view
deque system_error
+deque text_encoding
deque tuple
deque type_traits
deque typeinfo
@@ -619,6 +630,7 @@ experimental/iterator streambuf
experimental/iterator string
experimental/iterator string_view
experimental/iterator system_error
+experimental/iterator text_encoding
experimental/iterator tuple
experimental/iterator type_traits
experimental/iterator typeinfo
@@ -751,6 +763,7 @@ format streambuf
format string
format string_view
format system_error
+format text_encoding
format tuple
format type_traits
format typeinfo
@@ -798,6 +811,7 @@ forward_list streambuf
forward_list string
forward_list string_view
forward_list system_error
+forward_list text_encoding
forward_list tuple
forward_list type_traits
forward_list typeinfo
@@ -855,6 +869,7 @@ fstream streambuf
fstream string
fstream string_view
fstream system_error
+fstream text_encoding
fstream tuple
fstream type_traits
fstream typeinfo
@@ -901,6 +916,7 @@ functional streambuf
functional string
functional string_view
functional system_error
+functional text_encoding
functional tuple
functional type_traits
functional typeinfo
@@ -959,6 +975,7 @@ future streambuf
future string
future string_view
future system_error
+future text_encoding
future thread
future tuple
future type_traits
@@ -1017,6 +1034,7 @@ iomanip streambuf
iomanip string
iomanip string_view
iomanip system_error
+iomanip text_encoding
iomanip tuple
iomanip type_traits
iomanip typeinfo
@@ -1058,6 +1076,7 @@ ios stdexcept
ios string
ios string_view
ios system_error
+ios text_encoding
ios tuple
ios type_traits
ios typeinfo
@@ -1112,6 +1131,7 @@ iostream streambuf
iostream string
iostream string_view
iostream system_error
+iostream text_encoding
iostream tuple
iostream type_traits
iostream typeinfo
@@ -1166,6 +1186,7 @@ istream streambuf
istream string
istream string_view
istream system_error
+istream text_encoding
istream tuple
istream type_traits
istream typeinfo
@@ -1251,6 +1272,7 @@ list streambuf
list string
list string_view
list system_error
+list text_encoding
list tuple
list type_traits
list typeinfo
@@ -1295,6 +1317,7 @@ locale streambuf
locale string
locale string_view
locale system_error
+locale text_encoding
locale tuple
locale type_traits
locale typeinfo
@@ -1340,6 +1363,7 @@ map streambuf
map string
map string_view
map system_error
+map text_encoding
map tuple
map type_traits
map typeinfo
@@ -1473,6 +1497,7 @@ numeric streambuf
numeric string
numeric string_view
numeric system_error
+numeric text_encoding
numeric tuple
numeric type_traits
numeric typeinfo
@@ -1555,6 +1580,7 @@ ostream streambuf
ostream string
ostream string_view
ostream system_error
+ostream text_encoding
ostream tuple
ostream type_traits
ostream typeinfo
@@ -1606,6 +1632,7 @@ print streambuf
print string
print string_view
print system_error
+print text_encoding
print tuple
print type_traits
print typeinfo
@@ -1654,6 +1681,7 @@ queue streambuf
queue string
queue string_view
queue system_error
+queue text_encoding
queue tuple
queue type_traits
queue typeinfo
@@ -1702,6 +1730,7 @@ random streambuf
random string
random string_view
random system_error
+random text_encoding
random tuple
random type_traits
random typeinfo
@@ -1777,6 +1806,7 @@ regex streambuf
regex string
regex string_view
regex system_error
+regex text_encoding
regex tuple
regex type_traits
regex typeinfo
@@ -1866,6 +1896,7 @@ set streambuf
set string
set string_view
set system_error
+set text_encoding
set tuple
set type_traits
set typeinfo
@@ -1952,6 +1983,7 @@ span streambuf
span string
span string_view
span system_error
+span text_encoding
span tuple
span type_traits
span typeinfo
@@ -2007,6 +2039,7 @@ sstream streambuf
sstream string
sstream string_view
sstream system_error
+sstream text_encoding
sstream tuple
sstream type_traits
sstream typeinfo
@@ -2055,6 +2088,7 @@ stack streambuf
stack string
stack string_view
stack system_error
+stack text_encoding
stack tuple
stack type_traits
stack typeinfo
@@ -2072,6 +2106,7 @@ stdexcept new
stdexcept type_traits
stdexcept typeinfo
stdexcept version
+stop_token cstddef
stop_token iosfwd
stop_token version
streambuf algorithm
@@ -2108,6 +2143,7 @@ streambuf stdexcept
streambuf string
streambuf string_view
streambuf system_error
+streambuf text_encoding
streambuf tuple
streambuf type_traits
streambuf typeinfo
@@ -2228,6 +2264,7 @@ strstream streambuf
strstream string
strstream string_view
strstream system_error
+strstream text_encoding
strstream tuple
strstream type_traits
strstream typeinfo
@@ -2284,6 +2321,7 @@ syncstream streambuf
syncstream string
syncstream string_view
syncstream system_error
+syncstream text_encoding
syncstream tuple
syncstream type_traits
syncstream typeinfo
@@ -2378,6 +2416,7 @@ thread streambuf
thread string
thread string_view
thread system_error
+thread text_encoding
thread tuple
thread type_traits
thread typeinfo
@@ -2492,6 +2531,7 @@ unordered_set streambuf
unordered_set string
unordered_set string_view
unordered_set system_error
+unordered_set text_encoding
unordered_set tuple
unordered_set type_traits
unordered_set typeinfo
@@ -2549,6 +2589,7 @@ valarray streambuf
valarray string
valarray string_view
valarray system_error
+valarray text_encoding
valarray tuple
valarray type_traits
valarray typeinfo
@@ -2611,6 +2652,7 @@ vector streambuf
vector string
vector string_view
vector system_error
+vector text_encoding
vector tuple
vector type_traits
vector typeinfo
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index 332cb62f35b5f..a93fb1e26196b 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -69,6 +69,7 @@ any streambuf
any string
any string_view
any system_error
+any text_encoding
any tuple
any type_traits
any typeinfo
@@ -122,15 +123,19 @@ atomic ratio
atomic type_traits
atomic version
barrier atomic
+barrier cctype
barrier climits
barrier cmath
barrier compare
barrier concepts
barrier cstddef
barrier cstdint
+barrier cstdio
barrier cstdlib
barrier cstring
barrier ctime
+barrier cwchar
+barrier cwctype
barrier exception
barrier initializer_list
barrier iosfwd
@@ -234,6 +239,7 @@ ccomplex streambuf
ccomplex string
ccomplex string_view
ccomplex system_error
+ccomplex text_encoding
ccomplex tuple
ccomplex type_traits
ccomplex typeinfo
@@ -294,6 +300,7 @@ chrono streambuf
chrono string
chrono string_view
chrono system_error
+chrono text_encoding
chrono tuple
chrono type_traits
chrono typeinfo
@@ -339,6 +346,7 @@ codecvt stdexcept
codecvt string
codecvt string_view
codecvt system_error
+codecvt text_encoding
codecvt tuple
codecvt type_traits
codecvt typeinfo
@@ -398,6 +406,7 @@ complex streambuf
complex string
complex string_view
complex system_error
+complex text_encoding
complex tuple
complex type_traits
complex typeinfo
@@ -503,6 +512,7 @@ ctgmath streambuf
ctgmath string
ctgmath string_view
ctgmath system_error
+ctgmath text_encoding
ctgmath tuple
ctgmath type_traits
ctgmath typeinfo
@@ -554,6 +564,7 @@ deque streambuf
deque string
deque string_view
deque system_error
+deque text_encoding
deque tuple
deque type_traits
deque typeinfo
@@ -609,6 +620,7 @@ experimental/iterator streambuf
experimental/iterator string
experimental/iterator string_view
experimental/iterator system_error
+experimental/iterator text_encoding
experimental/iterator tuple
experimental/iterator type_traits
experimental/iterator typeinfo
@@ -693,6 +705,7 @@ filesystem streambuf
filesystem string
filesystem string_view
filesystem system_error
+filesystem text_encoding
filesystem tuple
filesystem type_traits
filesystem typeinfo
@@ -758,6 +771,7 @@ format streambuf
format string
format string_view
format system_error
+format text_encoding
format tuple
format type_traits
format typeinfo
@@ -804,6 +818,7 @@ forward_list streambuf
forward_list string
forward_list string_view
forward_list system_error
+forward_list text_encoding
forward_list tuple
forward_list type_traits
forward_list typeinfo
@@ -860,6 +875,7 @@ fstream streambuf
fstream string
fstream string_view
fstream system_error
+fstream text_encoding
fstream tuple
fstream type_traits
fstream typeinfo
@@ -905,6 +921,7 @@ functional streambuf
functional string
functional string_view
functional system_error
+functional text_encoding
functional tuple
functional type_traits
functional typeinfo
@@ -962,6 +979,7 @@ future streambuf
future string
future string_view
future system_error
+future text_encoding
future thread
future tuple
future type_traits
@@ -1019,6 +1037,7 @@ iomanip streambuf
iomanip string
iomanip string_view
iomanip system_error
+iomanip text_encoding
iomanip tuple
iomanip type_traits
iomanip typeinfo
@@ -1059,6 +1078,7 @@ ios stdexcept
ios string
ios string_view
ios system_error
+ios text_encoding
ios tuple
ios type_traits
ios typeinfo
@@ -1112,6 +1132,7 @@ iostream streambuf
iostream string
iostream string_view
iostream system_error
+iostream text_encoding
iostream tuple
iostream type_traits
iostream typeinfo
@@ -1165,6 +1186,7 @@ istream streambuf
istream string
istream string_view
istream system_error
+istream text_encoding
istream tuple
istream type_traits
istream typeinfo
@@ -1249,6 +1271,7 @@ list streambuf
list string
list string_view
list system_error
+list text_encoding
list tuple
list type_traits
list typeinfo
@@ -1292,6 +1315,7 @@ locale streambuf
locale string
locale string_view
locale system_error
+locale text_encoding
locale tuple
locale type_traits
locale typeinfo
@@ -1336,6 +1360,7 @@ map streambuf
map string
map string_view
map system_error
+map text_encoding
map tuple
map type_traits
map typeinfo
@@ -1495,6 +1520,7 @@ numeric streambuf
numeric string
numeric string_view
numeric system_error
+numeric text_encoding
numeric tuple
numeric type_traits
numeric typeinfo
@@ -1576,6 +1602,7 @@ ostream streambuf
ostream string
ostream string_view
ostream system_error
+ostream text_encoding
ostream tuple
ostream type_traits
ostream typeinfo
@@ -1626,6 +1653,7 @@ print streambuf
print string
print string_view
print system_error
+print text_encoding
print tuple
print type_traits
print typeinfo
@@ -1673,6 +1701,7 @@ queue streambuf
queue string
queue string_view
queue system_error
+queue text_encoding
queue tuple
queue type_traits
queue typeinfo
@@ -1721,6 +1750,7 @@ random streambuf
random string
random string_view
random system_error
+random text_encoding
random tuple
random type_traits
random typeinfo
@@ -1795,6 +1825,7 @@ regex streambuf
regex string
regex string_view
regex system_error
+regex text_encoding
regex tuple
regex type_traits
regex typeinfo
@@ -1883,6 +1914,7 @@ set streambuf
set string
set string_view
set system_error
+set text_encoding
set tuple
set type_traits
set typeinfo
@@ -1967,6 +1999,7 @@ span streambuf
span string
span string_view
span system_error
+span text_encoding
span tuple
span type_traits
span typeinfo
@@ -2021,6 +2054,7 @@ sstream streambuf
sstream string
sstream string_view
sstream system_error
+sstream text_encoding
sstream tuple
sstream type_traits
sstream typeinfo
@@ -2068,6 +2102,7 @@ stack streambuf
stack string
stack string_view
stack system_error
+stack text_encoding
stack tuple
stack type_traits
stack typeinfo
@@ -2085,6 +2120,7 @@ stdexcept new
stdexcept type_traits
stdexcept typeinfo
stdexcept version
+stop_token cstddef
stop_token iosfwd
stop_token version
streambuf algorithm
@@ -2120,6 +2156,7 @@ streambuf stdexcept
streambuf string
streambuf string_view
streambuf system_error
+streambuf text_encoding
streambuf tuple
streambuf type_traits
streambuf typeinfo
@@ -2237,6 +2274,7 @@ strstream streambuf
strstream string
strstream string_view
strstream system_error
+strstream text_encoding
strstream tuple
strstream type_traits
strstream typeinfo
@@ -2292,6 +2330,7 @@ syncstream streambuf
syncstream string
syncstream string_view
syncstream system_error
+syncstream text_encoding
syncstream tuple
syncstream type_traits
syncstream typeinfo
@@ -2384,6 +2423,7 @@ thread streambuf
thread string
thread string_view
thread system_error
+thread text_encoding
thread tuple
thread type_traits
thread typeinfo
@@ -2496,6 +2536,7 @@ unordered_set streambuf
unordered_set string
unordered_set string_view
unordered_set system_error
+unordered_set text_encoding
unordered_set tuple
unordered_set type_traits
unordered_set typeinfo
@@ -2552,6 +2593,7 @@ valarray streambuf
valarray string
valarray string_view
valarray system_error
+valarray text_encoding
valarray tuple
valarray type_traits
valarray typeinfo
@@ -2613,6 +2655,7 @@ vector streambuf
vector string
vector string_view
vector system_error
+vector text_encoding
vector tuple
vector type_traits
vector typeinfo
diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index 55c79acff5a8f..ded0dd1a51c16 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -219,6 +219,7 @@ ccomplex streambuf
ccomplex string
ccomplex string_view
ccomplex system_error
+ccomplex text_encoding
ccomplex tuple
ccomplex type_traits
ccomplex typeinfo
@@ -289,6 +290,7 @@ chrono streambuf
chrono string
chrono string_view
chrono system_error
+chrono text_encoding
chrono tuple
chrono type_traits
chrono typeinfo
@@ -334,6 +336,7 @@ codecvt stdexcept
codecvt string
codecvt string_view
codecvt system_error
+codecvt text_encoding
codecvt tuple
codecvt type_traits
codecvt typeinfo
@@ -393,6 +396,7 @@ complex streambuf
complex string
complex string_view
complex system_error
+complex text_encoding
complex tuple
complex type_traits
complex typeinfo
@@ -499,6 +503,7 @@ ctgmath streambuf
ctgmath string
ctgmath string_view
ctgmath system_error
+ctgmath text_encoding
ctgmath tuple
ctgmath type_traits
ctgmath typeinfo
@@ -550,6 +555,7 @@ deque streambuf
deque string
deque string_view
deque system_error
+deque text_encoding
deque tuple
deque type_traits
deque typeinfo
@@ -605,6 +611,7 @@ experimental/iterator streambuf
experimental/iterator string
experimental/iterator string_view
experimental/iterator system_error
+experimental/iterator text_encoding
experimental/iterator tuple
experimental/iterator type_traits
experimental/iterator typeinfo
@@ -689,6 +696,7 @@ filesystem streambuf
filesystem string
filesystem string_view
filesystem system_error
+filesystem text_encoding
filesystem tuple
filesystem type_traits
filesystem typeinfo
@@ -754,6 +762,7 @@ format streambuf
format string
format string_view
format system_error
+format text_encoding
format tuple
format type_traits
format typeinfo
@@ -800,6 +809,7 @@ forward_list streambuf
forward_list string
forward_list string_view
forward_list system_error
+forward_list text_encoding
forward_list tuple
forward_list type_traits
forward_list typeinfo
@@ -856,6 +866,7 @@ fstream streambuf
fstream string
fstream string_view
fstream system_error
+fstream text_encoding
fstream tuple
fstream type_traits
fstream typeinfo
@@ -901,6 +912,7 @@ functional streambuf
functional string
functional string_view
functional system_error
+functional text_encoding
functional tuple
functional type_traits
functional typeinfo
@@ -956,6 +968,7 @@ future streambuf
future string
future string_view
future system_error
+future text_encoding
future thread
future tuple
future type_traits
@@ -1013,6 +1026,7 @@ iomanip streambuf
iomanip string
iomanip string_view
iomanip system_error
+iomanip text_encoding
iomanip tuple
iomanip type_traits
iomanip typeinfo
@@ -1053,6 +1067,7 @@ ios stdexcept
ios string
ios string_view
ios system_error
+ios text_encoding
ios tuple
ios type_traits
ios typeinfo
@@ -1106,6 +1121,7 @@ iostream streambuf
iostream string
iostream string_view
iostream system_error
+iostream text_encoding
iostream tuple
iostream type_traits
iostream typeinfo
@@ -1159,6 +1175,7 @@ istream streambuf
istream string
istream string_view
istream system_error
+istream text_encoding
istream tuple
istream type_traits
istream typeinfo
@@ -1243,6 +1260,7 @@ list streambuf
list string
list string_view
list system_error
+list text_encoding
list tuple
list type_traits
list typeinfo
@@ -1286,6 +1304,7 @@ locale streambuf
locale string
locale string_view
locale system_error
+locale text_encoding
locale tuple
locale type_traits
locale typeinfo
@@ -1330,6 +1349,7 @@ map streambuf
map string
map string_view
map system_error
+map text_encoding
map tuple
map type_traits
map typeinfo
@@ -1489,6 +1509,7 @@ numeric streambuf
numeric string
numeric string_view
numeric system_error
+numeric text_encoding
numeric tuple
numeric type_traits
numeric typeinfo
@@ -1570,6 +1591,7 @@ ostream streambuf
ostream string
ostream string_view
ostream system_error
+ostream text_encoding
ostream tuple
ostream type_traits
ostream typeinfo
@@ -1620,6 +1642,7 @@ print streambuf
print string
print string_view
print system_error
+print text_encoding
print tuple
print type_traits
print typeinfo
@@ -1667,6 +1690,7 @@ queue streambuf
queue string
queue string_view
queue system_error
+queue text_encoding
queue tuple
queue type_traits
queue typeinfo
@@ -1715,6 +1739,7 @@ random streambuf
random string
random string_view
random system_error
+random text_encoding
random tuple
random type_traits
random typeinfo
@@ -1762,6 +1787,7 @@ ranges streambuf
ranges string
ranges string_view
ranges system_error
+ranges text_encoding
ranges tuple
ranges type_traits
ranges typeinfo
@@ -1813,6 +1839,7 @@ regex streambuf
regex string
regex string_view
regex system_error
+regex text_encoding
regex tuple
regex type_traits
regex typeinfo
@@ -1901,6 +1928,7 @@ set streambuf
set string
set string_view
set system_error
+set text_encoding
set tuple
set type_traits
set typeinfo
@@ -1985,6 +2013,7 @@ span streambuf
span string
span string_view
span system_error
+span text_encoding
span tuple
span type_traits
span typeinfo
@@ -2039,6 +2068,7 @@ sstream streambuf
sstream string
sstream string_view
sstream system_error
+sstream text_encoding
sstream tuple
sstream type_traits
sstream typeinfo
@@ -2086,6 +2116,7 @@ stack streambuf
stack string
stack string_view
stack system_error
+stack text_encoding
stack tuple
stack type_traits
stack typeinfo
@@ -2150,6 +2181,7 @@ streambuf stdexcept
streambuf string
streambuf string_view
streambuf system_error
+streambuf text_encoding
streambuf tuple
streambuf type_traits
streambuf typeinfo
@@ -2267,6 +2299,7 @@ strstream streambuf
strstream string
strstream string_view
strstream system_error
+strstream text_encoding
strstream tuple
strstream type_traits
strstream typeinfo
@@ -2322,6 +2355,7 @@ syncstream streambuf
syncstream string
syncstream string_view
syncstream system_error
+syncstream text_encoding
syncstream tuple
syncstream type_traits
syncstream typeinfo
@@ -2412,6 +2446,7 @@ thread streambuf
thread string
thread string_view
thread system_error
+thread text_encoding
thread tuple
thread type_traits
thread typeinfo
@@ -2524,6 +2559,7 @@ unordered_set streambuf
unordered_set string
unordered_set string_view
unordered_set system_error
+unordered_set text_encoding
unordered_set tuple
unordered_set type_traits
unordered_set typeinfo
@@ -2580,6 +2616,7 @@ valarray streambuf
valarray string
valarray string_view
valarray system_error
+valarray text_encoding
valarray tuple
valarray type_traits
valarray typeinfo
@@ -2641,6 +2678,7 @@ vector streambuf
vector string
vector string_view
vector system_error
+vector text_encoding
vector tuple
vector type_traits
vector typeinfo
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index 073f698786117..8385b37c07822 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -90,6 +90,7 @@ ccomplex stdexcept
ccomplex streambuf
ccomplex string
ccomplex string_view
+ccomplex text_encoding
ccomplex tuple
ccomplex typeinfo
ccomplex version
@@ -129,6 +130,7 @@ chrono stdexcept
chrono streambuf
chrono string
chrono string_view
+chrono text_encoding
chrono tuple
chrono typeinfo
chrono version
@@ -152,6 +154,7 @@ codecvt limits
codecvt stdexcept
codecvt string
codecvt string_view
+codecvt text_encoding
codecvt tuple
codecvt typeinfo
codecvt version
@@ -185,6 +188,7 @@ complex stdexcept
complex streambuf
complex string
complex string_view
+complex text_encoding
complex tuple
complex typeinfo
complex version
@@ -234,6 +238,7 @@ ctgmath stdexcept
ctgmath streambuf
ctgmath string
ctgmath string_view
+ctgmath text_encoding
ctgmath tuple
ctgmath typeinfo
ctgmath version
@@ -285,6 +290,7 @@ experimental/iterator stdexcept
experimental/iterator streambuf
experimental/iterator string
experimental/iterator string_view
+experimental/iterator text_encoding
experimental/iterator tuple
experimental/iterator typeinfo
experimental/iterator variant
@@ -330,6 +336,7 @@ filesystem stdexcept
filesystem streambuf
filesystem string
filesystem string_view
+filesystem text_encoding
filesystem tuple
filesystem typeinfo
filesystem version
@@ -380,6 +387,7 @@ format optional
format stdexcept
format string
format string_view
+format text_encoding
format tuple
format typeinfo
format version
@@ -419,6 +427,7 @@ fstream stdexcept
fstream streambuf
fstream string
fstream string_view
+fstream text_encoding
fstream tuple
fstream typeinfo
fstream version
@@ -463,6 +472,7 @@ future stdexcept
future streambuf
future string
future string_view
+future text_encoding
future tuple
future typeinfo
future version
@@ -490,6 +500,7 @@ iomanip stdexcept
iomanip streambuf
iomanip string
iomanip string_view
+iomanip text_encoding
iomanip tuple
iomanip typeinfo
iomanip version
@@ -513,6 +524,7 @@ ios ratio
ios stdexcept
ios string
ios string_view
+ios text_encoding
ios tuple
ios typeinfo
ios version
@@ -548,6 +560,7 @@ iostream stdexcept
iostream streambuf
iostream string
iostream string_view
+iostream text_encoding
iostream tuple
iostream typeinfo
iostream version
@@ -575,6 +588,7 @@ istream stdexcept
istream streambuf
istream string
istream string_view
+istream text_encoding
istream tuple
istream typeinfo
istream version
@@ -631,6 +645,7 @@ locale stdexcept
locale streambuf
locale string
locale string_view
+locale text_encoding
locale tuple
locale typeinfo
locale version
@@ -735,6 +750,7 @@ ostream stdexcept
ostream streambuf
ostream string
ostream string_view
+ostream text_encoding
ostream tuple
ostream typeinfo
ostream version
@@ -760,6 +776,7 @@ print optional
print stdexcept
print string
print string_view
+print text_encoding
print tuple
print typeinfo
print version
@@ -850,6 +867,7 @@ regex limits
regex stdexcept
regex string
regex string_view
+regex text_encoding
regex tuple
regex typeinfo
regex vector
@@ -916,6 +934,7 @@ sstream stdexcept
sstream streambuf
sstream string
sstream string_view
+sstream text_encoding
sstream tuple
sstream typeinfo
sstream version
@@ -960,6 +979,7 @@ streambuf ratio
streambuf stdexcept
streambuf string
streambuf string_view
+streambuf text_encoding
streambuf tuple
streambuf typeinfo
streambuf version
@@ -1015,6 +1035,7 @@ strstream stdexcept
strstream streambuf
strstream string
strstream string_view
+strstream text_encoding
strstream tuple
strstream typeinfo
strstream version
@@ -1050,6 +1071,7 @@ syncstream stdexcept
syncstream streambuf
syncstream string
syncstream string_view
+syncstream text_encoding
syncstream tuple
syncstream typeinfo
syncstream version
@@ -1098,6 +1120,7 @@ thread stdexcept
thread streambuf
thread string
thread string_view
+thread text_encoding
thread tuple
thread typeinfo
thread version
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index 1450a13e125ef..cf1154a251f23 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -85,6 +85,7 @@ ccomplex stdexcept
ccomplex streambuf
ccomplex string
ccomplex string_view
+ccomplex text_encoding
ccomplex tuple
ccomplex typeinfo
ccomplex version
@@ -123,6 +124,7 @@ chrono stdexcept
chrono streambuf
chrono string
chrono string_view
+chrono text_encoding
chrono tuple
chrono typeinfo
chrono version
@@ -146,6 +148,7 @@ codecvt limits
codecvt stdexcept
codecvt string
codecvt string_view
+codecvt text_encoding
codecvt tuple
codecvt typeinfo
codecvt version
@@ -176,6 +179,7 @@ complex stdexcept
complex streambuf
complex string
complex string_view
+complex text_encoding
complex tuple
complex typeinfo
complex version
@@ -221,6 +225,7 @@ ctgmath stdexcept
ctgmath streambuf
ctgmath string
ctgmath string_view
+ctgmath text_encoding
ctgmath tuple
ctgmath typeinfo
ctgmath version
@@ -268,6 +273,7 @@ experimental/iterator stdexcept
experimental/iterator streambuf
experimental/iterator string
experimental/iterator string_view
+experimental/iterator text_encoding
experimental/iterator tuple
experimental/iterator typeinfo
experimental/iterator variant
@@ -312,6 +318,7 @@ filesystem ratio
filesystem stdexcept
filesystem string
filesystem string_view
+filesystem text_encoding
filesystem tuple
filesystem typeinfo
filesystem version
@@ -361,6 +368,7 @@ format optional
format stdexcept
format string
format string_view
+format text_encoding
format tuple
format typeinfo
format version
@@ -396,6 +404,7 @@ fstream stdexcept
fstream streambuf
fstream string
fstream string_view
+fstream text_encoding
fstream tuple
fstream typeinfo
fstream version
@@ -439,6 +448,7 @@ future stdexcept
future streambuf
future string
future string_view
+future text_encoding
future tuple
future typeinfo
future version
@@ -462,6 +472,7 @@ iomanip limits
iomanip stdexcept
iomanip string
iomanip string_view
+iomanip text_encoding
iomanip tuple
iomanip typeinfo
iomanip version
@@ -483,6 +494,7 @@ ios limits
ios stdexcept
ios string
ios string_view
+ios text_encoding
ios tuple
ios typeinfo
ios version
@@ -514,6 +526,7 @@ iostream stdexcept
iostream streambuf
iostream string
iostream string_view
+iostream text_encoding
iostream tuple
iostream typeinfo
iostream version
@@ -538,6 +551,7 @@ istream stdexcept
istream streambuf
istream string
istream string_view
+istream text_encoding
istream tuple
istream typeinfo
istream version
@@ -592,6 +606,7 @@ locale stdexcept
locale streambuf
locale string
locale string_view
+locale text_encoding
locale tuple
locale typeinfo
locale version
@@ -691,6 +706,7 @@ ostream stdexcept
ostream streambuf
ostream string
ostream string_view
+ostream text_encoding
ostream tuple
ostream typeinfo
ostream version
@@ -715,6 +731,7 @@ print optional
print stdexcept
print string
print string_view
+print text_encoding
print tuple
print typeinfo
print version
@@ -797,6 +814,7 @@ regex limits
regex stdexcept
regex string
regex string_view
+regex text_encoding
regex tuple
regex typeinfo
regex vector
@@ -860,6 +878,7 @@ sstream stdexcept
sstream streambuf
sstream string
sstream string_view
+sstream text_encoding
sstream tuple
sstream typeinfo
sstream version
@@ -901,6 +920,7 @@ streambuf limits
streambuf stdexcept
streambuf string
streambuf string_view
+streambuf text_encoding
streambuf tuple
streambuf typeinfo
streambuf version
@@ -953,6 +973,7 @@ strstream stdexcept
strstream streambuf
strstream string
strstream string_view
+strstream text_encoding
strstream tuple
strstream typeinfo
strstream version
@@ -986,6 +1007,7 @@ syncstream stdexcept
syncstream streambuf
syncstream string
syncstream string_view
+syncstream text_encoding
syncstream tuple
syncstream typeinfo
syncstream version
@@ -1006,6 +1028,20 @@ system_error string
system_error string_view
system_error tuple
system_error version
+text_encoding cctype
+text_encoding climits
+text_encoding compare
+text_encoding cstdint
+text_encoding cstdio
+text_encoding cstring
+text_encoding cwchar
+text_encoding cwctype
+text_encoding initializer_list
+text_encoding iosfwd
+text_encoding limits
+text_encoding stdexcept
+text_encoding string_view
+text_encoding version
thread array
thread bitset
thread cctype
@@ -1032,6 +1068,7 @@ thread stdexcept
thread streambuf
thread string
thread string_view
+thread text_encoding
thread tuple
thread typeinfo
thread version
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/text_encoding.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/text_encoding.version.compile.pass.cpp
new file mode 100644
index 0000000000000..1678e8840af8d
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/text_encoding.version.compile.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <text_encoding>
+
+// Test the feature test macros defined by <text_encoding>
+
+// clang-format off
+
+#include <text_encoding>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_text_encoding
+# error "__cpp_lib_text_encoding should not be defined before c++26"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_text_encoding
+# error "__cpp_lib_text_encoding should not be defined before c++26"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_text_encoding
+# error "__cpp_lib_text_encoding should not be defined before c++26"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifdef __cpp_lib_text_encoding
+# error "__cpp_lib_text_encoding should not be defined before c++26"
+# endif
+
+#elif TEST_STD_VER == 23
+
+# ifdef __cpp_lib_text_encoding
+# error "__cpp_lib_text_encoding should not be defined before c++26"
+# endif
+
+#elif TEST_STD_VER > 23
+
+# ifndef __cpp_lib_text_encoding
+# error "__cpp_lib_text_encoding should be defined in c++26"
+# endif
+# if __cpp_lib_text_encoding != 202306L
+# error "__cpp_lib_text_encoding should have the value 202306L in c++26"
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index d4808fde45444..83131c5402321 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -8146,17 +8146,11 @@
# endif
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_text_encoding
-# error "__cpp_lib_text_encoding should be defined in c++26"
-# endif
-# if __cpp_lib_text_encoding != 202306L
-# error "__cpp_lib_text_encoding should have the value 202306L in c++26"
-# endif
-# else
-# ifdef __cpp_lib_text_encoding
-# error "__cpp_lib_text_encoding should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_text_encoding
+# error "__cpp_lib_text_encoding should be defined in c++26"
+# endif
+# if __cpp_lib_text_encoding != 202306L
+# error "__cpp_lib_text_encoding should have the value 202306L in c++26"
# endif
# ifndef __cpp_lib_three_way_comparison
diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
index c9ed59f3cb9aa..efaac8f8d4507 100644
--- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
@@ -30,6 +30,11 @@
#include "platform_support.h" // locale name macros
#include "test_macros.h"
+// glibc <langinfo.h> has a THOUSANDS_SEP macro already defined
+#ifdef THOUSANDS_SEP
+# undef THOUSANDS_SEP
+#endif
+
#ifdef _AIX
// the AIX libc expects U202F as LC_MONETARY thousands_sep
# define THOUSANDS_SEP L"\u202F"
diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
index f9d7998b07ff4..7d03b7053150f 100644
--- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
@@ -30,6 +30,11 @@
#include "platform_support.h" // locale name macros
#include "test_macros.h"
+// glibc <langinfo.h> has a THOUSANDS_SEP macro already defined
+#ifdef THOUSANDS_SEP
+# undef THOUSANDS_SEP
+#endif
+
#ifdef _AIX
// the AIX libc expects U202F as LC_MONETARY thousands_sep
# define THOUSANDS_SEP L"\u202F"
diff --git a/libcxx/test/std/localization/locales/locale/locale.members/encoding.pass.cpp b/libcxx/test/std/localization/locales/locale/locale.members/encoding.pass.cpp
new file mode 100644
index 0000000000000..74ba547cf6619
--- /dev/null
+++ b/libcxx/test/std/localization/locales/locale/locale.members/encoding.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <text_encoding>
+
+// REQUIRES: std-at-least-c++26
+// REQUIRES: locale.en_US.UTF-8
+// UNSUPPORTED: no-localization
+// UNSUPPORTED: availability-te-environment-missing
+
+// class locale
+
+// text_encoding locale::encoding() const
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <iostream>
+#include <locale>
+#include <text_encoding>
+
+#include "platform_support.h"
+
+int main(int, char**) {
+ {
+ // 1. Locale built with en_US.UTF-8 returns text_encoding representing "UTF-8"
+ const std::locale utf8_locale(LOCALE_en_US_UTF_8);
+ std::same_as<std::text_encoding> decltype(auto) te = utf8_locale.encoding();
+ auto utf8_te = std::text_encoding{std::text_encoding::UTF8};
+
+ if (te != std::text_encoding::UTF8) {
+ std::cerr << std::format("Expected UTF-8, received {{ {}, \"{}\" }}", int(te.mib()), te.name());
+ assert(false);
+ }
+ assert(te == utf8_te);
+ }
+#if defined(_WIN32)
+ {
+ // BCP-47 locale name
+ const std::locale loc("en-US");
+ std::same_as<std::text_encoding> decltype(auto) te = loc.encoding();
+ auto w1252 = std::text_encoding{std::text_encoding::windows1252};
+ assert(te == std::text_encoding::windows1252);
+ assert(te == w1252);
+ }
+#endif
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/test_text_encoding.h b/libcxx/test/std/text/text_encoding/test_text_encoding.h
new file mode 100644
index 0000000000000..e18bc3aaeea15
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/test_text_encoding.h
@@ -0,0 +1,1171 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 _LIBCPP_TEST_TEXT_ENCODING_H
+#define _LIBCPP_TEST_TEXT_ENCODING_H
+
+#include <string_view>
+
+struct encoding_data {
+ std::string_view name;
+ int mib;
+ int size;
+};
+
+constexpr encoding_data unique_encoding_data[]{
+ {"US-ASCII", 3, 8},
+ {"ISO_8859-1:1987", 4, 15},
+ {"ISO_8859-2:1987", 5, 15},
+ {"ISO_8859-3:1988", 6, 15},
+ {"ISO_8859-4:1988", 7, 15},
+ {"ISO_8859-5:1988", 8, 15},
+ {"ISO_8859-6:1987", 9, 15},
+ {"ISO_8859-7:1987", 10, 15},
+ {"ISO_8859-8:1988", 11, 15},
+ {"ISO_8859-9:1989", 12, 15},
+ {"ISO-8859-10", 13, 11},
+ {"ISO_6937-2-add", 14, 14},
+ {"JIS_X0201", 15, 9},
+ {"JIS_Encoding", 16, 12},
+ {"Shift_JIS", 17, 9},
+ {"Extended_UNIX_Code_Packed_Format_for_Japanese", 18, 45},
+ {"Extended_UNIX_Code_Fixed_Width_for_Japanese", 19, 43},
+ {"BS_4730", 20, 7},
+ {"SEN_850200_C", 21, 12},
+ {"IT", 22, 2},
+ {"ES", 23, 2},
+ {"DIN_66003", 24, 9},
+ {"NS_4551-1", 25, 9},
+ {"NF_Z_62-010", 26, 11},
+ {"ISO-10646-UTF-1", 27, 15},
+ {"ISO_646.basic:1983", 28, 18},
+ {"INVARIANT", 29, 9},
+ {"ISO_646.irv:1983", 30, 16},
+ {"NATS-SEFI", 31, 9},
+ {"NATS-SEFI-ADD", 32, 13},
+ {"SEN_850200_B", 35, 12},
+ {"KS_C_5601-1987", 36, 14},
+ {"ISO-2022-KR", 37, 11},
+ {"EUC-KR", 38, 6},
+ {"ISO-2022-JP", 39, 11},
+ {"ISO-2022-JP-2", 40, 13},
+ {"JIS_C6220-1969-jp", 41, 17},
+ {"JIS_C6220-1969-ro", 42, 17},
+ {"PT", 43, 2},
+ {"greek7-old", 44, 10},
+ {"latin-greek", 45, 11},
+ {"NF_Z_62-010_(1973)", 46, 18},
+ {"Latin-greek-1", 47, 13},
+ {"ISO_5427", 48, 8},
+ {"JIS_C6226-1978", 49, 14},
+ {"BS_viewdata", 50, 11},
+ {"INIS", 51, 4},
+ {"INIS-8", 52, 6},
+ {"INIS-cyrillic", 53, 13},
+ {"ISO_5427:1981", 54, 13},
+ {"ISO_5428:1980", 55, 13},
+ {"GB_1988-80", 56, 10},
+ {"GB_2312-80", 57, 10},
+ {"NS_4551-2", 58, 9},
+ {"videotex-suppl", 59, 14},
+ {"PT2", 60, 3},
+ {"ES2", 61, 3},
+ {"MSZ_7795.3", 62, 10},
+ {"JIS_C6226-1983", 63, 14},
+ {"greek7", 64, 6},
+ {"ASMO_449", 65, 8},
+ {"iso-ir-90", 66, 9},
+ {"JIS_C6229-1984-a", 67, 16},
+ {"JIS_C6229-1984-b", 68, 16},
+ {"JIS_C6229-1984-b-add", 69, 20},
+ {"JIS_C6229-1984-hand", 70, 19},
+ {"JIS_C6229-1984-hand-add", 71, 23},
+ {"JIS_C6229-1984-kana", 72, 19},
+ {"ISO_2033-1983", 73, 13},
+ {"ANSI_X3.110-1983", 74, 16},
+ {"T.61-7bit", 75, 9},
+ {"T.61-8bit", 76, 9},
+ {"ECMA-cyrillic", 77, 13},
+ {"CSA_Z243.4-1985-1", 78, 17},
+ {"CSA_Z243.4-1985-2", 79, 17},
+ {"CSA_Z243.4-1985-gr", 80, 18},
+ {"ISO_8859-6-E", 81, 12},
+ {"ISO_8859-6-I", 82, 12},
+ {"T.101-G2", 83, 8},
+ {"ISO_8859-8-E", 84, 12},
+ {"ISO_8859-8-I", 85, 12},
+ {"CSN_369103", 86, 10},
+ {"JUS_I.B1.002", 87, 12},
+ {"IEC_P27-1", 88, 9},
+ {"JUS_I.B1.003-serb", 89, 17},
+ {"JUS_I.B1.003-mac", 90, 16},
+ {"greek-ccitt", 91, 11},
+ {"NC_NC00-10:81", 92, 13},
+ {"ISO_6937-2-25", 93, 13},
+ {"GOST_19768-74", 94, 13},
+ {"ISO_8859-supp", 95, 13},
+ {"ISO_10367-box", 96, 13},
+ {"latin-lap", 97, 9},
+ {"JIS_X0212-1990", 98, 14},
+ {"DS_2089", 99, 7},
+ {"us-dk", 100, 5},
+ {"dk-us", 101, 5},
+ {"KSC5636", 102, 7},
+ {"UNICODE-1-1-UTF-7", 103, 17},
+ {"ISO-2022-CN", 104, 11},
+ {"ISO-2022-CN-EXT", 105, 15},
+ {"UTF-8", 106, 5},
+ {"ISO-8859-13", 109, 11},
+ {"ISO-8859-14", 110, 11},
+ {"ISO-8859-15", 111, 11},
+ {"ISO-8859-16", 112, 11},
+ {"GBK", 113, 3},
+ {"GB18030", 114, 7},
+ {"OSD_EBCDIC_DF04_15", 115, 18},
+ {"OSD_EBCDIC_DF03_IRV", 116, 19},
+ {"OSD_EBCDIC_DF04_1", 117, 17},
+ {"ISO-11548-1", 118, 11},
+ {"KZ-1048", 119, 7},
+ {"ISO-10646-UCS-2", 1000, 15},
+ {"ISO-10646-UCS-4", 1001, 15},
+ {"ISO-10646-UCS-Basic", 1002, 19},
+ {"ISO-10646-Unicode-Latin1", 1003, 24},
+ {"ISO-10646-J-1", 1004, 13},
+ {"ISO-Unicode-IBM-1261", 1005, 20},
+ {"ISO-Unicode-IBM-1268", 1006, 20},
+ {"ISO-Unicode-IBM-1276", 1007, 20},
+ {"ISO-Unicode-IBM-1264", 1008, 20},
+ {"ISO-Unicode-IBM-1265", 1009, 20},
+ {"UNICODE-1-1", 1010, 11},
+ {"SCSU", 1011, 4},
+ {"UTF-7", 1012, 5},
+ {"UTF-16BE", 1013, 8},
+ {"UTF-16LE", 1014, 8},
+ {"UTF-16", 1015, 6},
+ {"CESU-8", 1016, 6},
+ {"UTF-32", 1017, 6},
+ {"UTF-32BE", 1018, 8},
+ {"UTF-32LE", 1019, 8},
+ {"BOCU-1", 1020, 6},
+ {"UTF-7-IMAP", 1021, 10},
+ {"ISO-8859-1-Windows-3.0-Latin-1", 2000, 30},
+ {"ISO-8859-1-Windows-3.1-Latin-1", 2001, 30},
+ {"ISO-8859-2-Windows-Latin-2", 2002, 26},
+ {"ISO-8859-9-Windows-Latin-5", 2003, 26},
+ {"hp-roman8", 2004, 9},
+ {"Adobe-Standard-Encoding", 2005, 23},
+ {"Ventura-US", 2006, 10},
+ {"Ventura-International", 2007, 21},
+ {"DEC-MCS", 2008, 7},
+ {"IBM850", 2009, 6},
+ {"IBM852", 2010, 6},
+ {"IBM437", 2011, 6},
+ {"PC8-Danish-Norwegian", 2012, 20},
+ {"IBM862", 2013, 6},
+ {"PC8-Turkish", 2014, 11},
+ {"IBM-Symbols", 2015, 11},
+ {"IBM-Thai", 2016, 8},
+ {"HP-Legal", 2017, 8},
+ {"HP-Pi-font", 2018, 10},
+ {"HP-Math8", 2019, 8},
+ {"Adobe-Symbol-Encoding", 2020, 21},
+ {"HP-DeskTop", 2021, 10},
+ {"Ventura-Math", 2022, 12},
+ {"Microsoft-Publishing", 2023, 20},
+ {"Windows-31J", 2024, 11},
+ {"GB2312", 2025, 6},
+ {"Big5", 2026, 4},
+ {"macintosh", 2027, 9},
+ {"IBM037", 2028, 6},
+ {"IBM038", 2029, 6},
+ {"IBM273", 2030, 6},
+ {"IBM274", 2031, 6},
+ {"IBM275", 2032, 6},
+ {"IBM277", 2033, 6},
+ {"IBM278", 2034, 6},
+ {"IBM280", 2035, 6},
+ {"IBM281", 2036, 6},
+ {"IBM284", 2037, 6},
+ {"IBM285", 2038, 6},
+ {"IBM290", 2039, 6},
+ {"IBM297", 2040, 6},
+ {"IBM420", 2041, 6},
+ {"IBM423", 2042, 6},
+ {"IBM424", 2043, 6},
+ {"IBM500", 2044, 6},
+ {"IBM851", 2045, 6},
+ {"IBM855", 2046, 6},
+ {"IBM857", 2047, 6},
+ {"IBM860", 2048, 6},
+ {"IBM861", 2049, 6},
+ {"IBM863", 2050, 6},
+ {"IBM864", 2051, 6},
+ {"IBM865", 2052, 6},
+ {"IBM868", 2053, 6},
+ {"IBM869", 2054, 6},
+ {"IBM870", 2055, 6},
+ {"IBM871", 2056, 6},
+ {"IBM880", 2057, 6},
+ {"IBM891", 2058, 6},
+ {"IBM903", 2059, 6},
+ {"IBM904", 2060, 6},
+ {"IBM905", 2061, 6},
+ {"IBM918", 2062, 6},
+ {"IBM1026", 2063, 7},
+ {"EBCDIC-AT-DE", 2064, 12},
+ {"EBCDIC-AT-DE-A", 2065, 14},
+ {"EBCDIC-CA-FR", 2066, 12},
+ {"EBCDIC-DK-NO", 2067, 12},
+ {"EBCDIC-DK-NO-A", 2068, 14},
+ {"EBCDIC-FI-SE", 2069, 12},
+ {"EBCDIC-FI-SE-A", 2070, 14},
+ {"EBCDIC-FR", 2071, 9},
+ {"EBCDIC-IT", 2072, 9},
+ {"EBCDIC-PT", 2073, 9},
+ {"EBCDIC-ES", 2074, 9},
+ {"EBCDIC-ES-A", 2075, 11},
+ {"EBCDIC-ES-S", 2076, 11},
+ {"EBCDIC-UK", 2077, 9},
+ {"EBCDIC-US", 2078, 9},
+ {"UNKNOWN-8BIT", 2079, 12},
+ {"MNEMONIC", 2080, 8},
+ {"MNEM", 2081, 4},
+ {"VISCII", 2082, 6},
+ {"VIQR", 2083, 4},
+ {"KOI8-R", 2084, 6},
+ {"HZ-GB-2312", 2085, 10},
+ {"IBM866", 2086, 6},
+ {"IBM775", 2087, 6},
+ {"KOI8-U", 2088, 6},
+ {"IBM00858", 2089, 8},
+ {"IBM00924", 2090, 8},
+ {"IBM01140", 2091, 8},
+ {"IBM01141", 2092, 8},
+ {"IBM01142", 2093, 8},
+ {"IBM01143", 2094, 8},
+ {"IBM01144", 2095, 8},
+ {"IBM01145", 2096, 8},
+ {"IBM01146", 2097, 8},
+ {"IBM01147", 2098, 8},
+ {"IBM01148", 2099, 8},
+ {"IBM01149", 2100, 8},
+ {"Big5-HKSCS", 2101, 10},
+ {"IBM1047", 2102, 7},
+ {"PTCP154", 2103, 7},
+ {"Amiga-1251", 2104, 10},
+ {"KOI7-switched", 2105, 13},
+ {"BRF", 2106, 3},
+ {"TSCII", 2107, 5},
+ {"CP51932", 2108, 7},
+ {"windows-874", 2109, 11},
+ {"windows-1250", 2250, 12},
+ {"windows-1251", 2251, 12},
+ {"windows-1252", 2252, 12},
+ {"windows-1253", 2253, 12},
+ {"windows-1254", 2254, 12},
+ {"windows-1255", 2255, 12},
+ {"windows-1256", 2256, 12},
+ {"windows-1257", 2257, 12},
+ {"windows-1258", 2258, 12},
+ {"TIS-620", 2259, 7},
+ {"CP50220", 2260, 7},
+};
+
+constexpr std::string_view other_names[]{
+ "graah", "oops", "libcxx", "foobar", "barbaz", "1234567", "llvm-project", "utf-81", "utf-9", "CA-ASCII"};
+
+struct enc_data {
+ int mib;
+ std::string_view name;
+};
+
+constexpr inline enc_data all_encoding_data[] = {
+ {3, "US-ASCII"},
+ {3, "ANSI_X3.4-1968"},
+ {3, "ANSI_X3.4-1986"},
+ {3, "IBM367"},
+ {3, "ISO646-US"},
+ {3, "ISO_646.irv:1991"},
+ {3, "cp367"},
+ {3, "csASCII"},
+ {3, "iso-ir-6"},
+ {3, "us"},
+ {4, "ISO-8859-1"},
+ {4, "ISO_8859-1:1987"},
+ {4, "CP819"},
+ {4, "IBM819"},
+ {4, "ISO_8859-1"},
+ {4, "csISOLatin1"},
+ {4, "iso-ir-100"},
+ {4, "l1"},
+ {4, "latin1"},
+ {5, "ISO-8859-2"},
+ {5, "ISO_8859-2:1987"},
+ {5, "ISO_8859-2"},
+ {5, "csISOLatin2"},
+ {5, "iso-ir-101"},
+ {5, "l2"},
+ {5, "latin2"},
+ {6, "ISO-8859-3"},
+ {6, "ISO_8859-3:1988"},
+ {6, "ISO_8859-3"},
+ {6, "csISOLatin3"},
+ {6, "iso-ir-109"},
+ {6, "l3"},
+ {6, "latin3"},
+ {7, "ISO-8859-4"},
+ {7, "ISO_8859-4:1988"},
+ {7, "ISO_8859-4"},
+ {7, "csISOLatin4"},
+ {7, "iso-ir-110"},
+ {7, "l4"},
+ {7, "latin4"},
+ {8, "ISO-8859-5"},
+ {8, "ISO_8859-5:1988"},
+ {8, "ISO_8859-5"},
+ {8, "csISOLatinCyrillic"},
+ {8, "cyrillic"},
+ {8, "iso-ir-144"},
+ {9, "ISO-8859-6"},
+ {9, "ISO_8859-6:1987"},
+ {9, "ASMO-708"},
+ {9, "ECMA-114"},
+ {9, "ISO_8859-6"},
+ {9, "arabic"},
+ {9, "csISOLatinArabic"},
+ {9, "iso-ir-127"},
+ {10, "ISO-8859-7"},
+ {10, "ISO_8859-7:1987"},
+ {10, "ECMA-118"},
+ {10, "ELOT_928"},
+ {10, "ISO_8859-7"},
+ {10, "csISOLatinGreek"},
+ {10, "greek"},
+ {10, "greek8"},
+ {10, "iso-ir-126"},
+ {11, "ISO-8859-8"},
+ {11, "ISO_8859-8:1988"},
+ {11, "ISO_8859-8"},
+ {11, "csISOLatinHebrew"},
+ {11, "hebrew"},
+ {11, "iso-ir-138"},
+ {12, "ISO-8859-9"},
+ {12, "ISO_8859-9:1989"},
+ {12, "ISO_8859-9"},
+ {12, "csISOLatin5"},
+ {12, "iso-ir-148"},
+ {12, "l5"},
+ {12, "latin5"},
+ {13, "ISO-8859-10"},
+ {13, "ISO_8859-10:1992"},
+ {13, "csISOLatin6"},
+ {13, "iso-ir-157"},
+ {13, "l6"},
+ {13, "latin6"},
+ {14, "ISO_6937-2-add"},
+ {14, "csISOTextComm"},
+ {14, "iso-ir-142"},
+ {15, "JIS_X0201"},
+ {15, "X0201"},
+ {15, "csHalfWidthKatakana"},
+ {16, "JIS_Encoding"},
+ {16, "csJISEncoding"},
+ {17, "Shift_JIS"},
+ {17, "MS_Kanji"},
+ {17, "csShiftJIS"},
+ {18, "EUC-JP"},
+ {18, "Extended_UNIX_Code_Packed_Format_for_Japanese"},
+ {18, "csEUCPkdFmtJapanese"},
+ {19, "Extended_UNIX_Code_Fixed_Width_for_Japanese"},
+ {19, "csEUCFixWidJapanese"},
+ {20, "BS_4730"},
+ {20, "ISO646-GB"},
+ {20, "csISO4UnitedKingdom"},
+ {20, "gb"},
+ {20, "iso-ir-4"},
+ {20, "uk"},
+ {21, "SEN_850200_C"},
+ {21, "ISO646-SE2"},
+ {21, "csISO11SwedishForNames"},
+ {21, "iso-ir-11"},
+ {21, "se2"},
+ {22, "IT"},
+ {22, "ISO646-IT"},
+ {22, "csISO15Italian"},
+ {22, "iso-ir-15"},
+ {23, "ES"},
+ {23, "ISO646-ES"},
+ {23, "csISO17Spanish"},
+ {23, "iso-ir-17"},
+ {24, "DIN_66003"},
+ {24, "ISO646-DE"},
+ {24, "csISO21German"},
+ {24, "de"},
+ {24, "iso-ir-21"},
+ {25, "NS_4551-1"},
+ {25, "ISO646-NO"},
+ {25, "csISO60DanishNorwegian"},
+ {25, "csISO60Norwegian1"},
+ {25, "iso-ir-60"},
+ {25, "no"},
+ {26, "NF_Z_62-010"},
+ {26, "ISO646-FR"},
+ {26, "csISO69French"},
+ {26, "fr"},
+ {26, "iso-ir-69"},
+ {27, "ISO-10646-UTF-1"},
+ {27, "csISO10646UTF1"},
+ {28, "ISO_646.basic:1983"},
+ {28, "csISO646basic1983"},
+ {28, "ref"},
+ {29, "INVARIANT"},
+ {29, "csINVARIANT"},
+ {30, "ISO_646.irv:1983"},
+ {30, "csISO2IntlRefVersion"},
+ {30, "irv"},
+ {30, "iso-ir-2"},
+ {31, "NATS-SEFI"},
+ {31, "csNATSSEFI"},
+ {31, "iso-ir-8-1"},
+ {32, "NATS-SEFI-ADD"},
+ {32, "csNATSSEFIADD"},
+ {32, "iso-ir-8-2"},
+ // 33 NATS-DANO, 34 NATS-DANO-ADD omitted
+ {35, "SEN_850200_B"},
+ {35, "FI"},
+ {35, "ISO646-FI"},
+ {35, "ISO646-SE"},
+ {35, "csISO10Swedish"},
+ {35, "iso-ir-10"},
+ {35, "se"},
+ {36, "KS_C_5601-1987"},
+ {36, "KSC_5601"},
+ {36, "KS_C_5601-1989"},
+ {36, "csKSC56011987"},
+ {36, "iso-ir-149"},
+ {36, "korean"},
+ {37, "ISO-2022-KR"},
+ {37, "csISO2022KR"},
+ {38, "EUC-KR"},
+ {38, "csEUCKR"},
+ {39, "ISO-2022-JP"},
+ {39, "csISO2022JP"},
+ {40, "ISO-2022-JP-2"},
+ {40, "csISO2022JP2"},
+ {41, "JIS_C6220-1969-jp"},
+ {41, "JIS_C6220-1969"},
+ {41, "csISO13JISC6220jp"},
+ {41, "iso-ir-13"},
+ {41, "katakana"},
+ {41, "x0201-7"},
+ {42, "JIS_C6220-1969-ro"},
+ {42, "ISO646-JP"},
+ {42, "csISO14JISC6220ro"},
+ {42, "iso-ir-14"},
+ {42, "jp"},
+ {43, "PT"},
+ {43, "ISO646-PT"},
+ {43, "csISO16Portuguese"},
+ {43, "iso-ir-16"},
+ {44, "greek7-old"},
+ {44, "csISO18Greek7Old"},
+ {44, "iso-ir-18"},
+ {45, "latin-greek"},
+ {45, "csISO19LatinGreek"},
+ {45, "iso-ir-19"},
+ {46, "NF_Z_62-010_(1973)"},
+ {46, "ISO646-FR1"},
+ {46, "csISO25French"},
+ {46, "iso-ir-25"},
+ {47, "Latin-greek-1"},
+ {47, "csISO27LatinGreek1"},
+ {47, "iso-ir-27"},
+ {48, "ISO_5427"},
+ {48, "csISO5427Cyrillic"},
+ {48, "iso-ir-37"},
+ {49, "JIS_C6226-1978"},
+ {49, "csISO42JISC62261978"},
+ {49, "iso-ir-42"},
+ {50, "BS_viewdata"},
+ {50, "csISO47BSViewdata"},
+ {50, "iso-ir-47"},
+ {51, "INIS"},
+ {51, "csISO49INIS"},
+ {51, "iso-ir-49"},
+ {52, "INIS-8"},
+ {52, "csISO50INIS8"},
+ {52, "iso-ir-50"},
+ {53, "INIS-cyrillic"},
+ {53, "csISO51INISCyrillic"},
+ {53, "iso-ir-51"},
+ {54, "ISO_5427:1981"},
+ {54, "ISO5427Cyrillic1981"},
+ {54, "csISO54271981"},
+ {54, "iso-ir-54"},
+ {55, "ISO_5428:1980"},
+ {55, "csISO5428Greek"},
+ {55, "iso-ir-55"},
+ {56, "GB_1988-80"},
+ {56, "ISO646-CN"},
+ {56, "cn"},
+ {56, "csISO57GB1988"},
+ {56, "iso-ir-57"},
+ {57, "GB_2312-80"},
+ {57, "chinese"},
+ {57, "csISO58GB231280"},
+ {57, "iso-ir-58"},
+ {58, "NS_4551-2"},
+ {58, "ISO646-NO2"},
+ {58, "csISO61Norwegian2"},
+ {58, "iso-ir-61"},
+ {58, "no2"},
+ {59, "videotex-suppl"},
+ {59, "csISO70VideotexSupp1"},
+ {59, "iso-ir-70"},
+ {60, "PT2"},
+ {60, "ISO646-PT2"},
+ {60, "csISO84Portuguese2"},
+ {60, "iso-ir-84"},
+ {61, "ES2"},
+ {61, "ISO646-ES2"},
+ {61, "csISO85Spanish2"},
+ {61, "iso-ir-85"},
+ {62, "MSZ_7795.3"},
+ {62, "ISO646-HU"},
+ {62, "csISO86Hungarian"},
+ {62, "hu"},
+ {62, "iso-ir-86"},
+ {63, "JIS_C6226-1983"},
+ {63, "JIS_X0208-1983"},
+ {63, "csISO87JISX0208"},
+ {63, "iso-ir-87"},
+ {63, "x0208"},
+ {64, "greek7"},
+ {64, "csISO88Greek7"},
+ {64, "iso-ir-88"},
+ {65, "ASMO_449"},
+ {65, "ISO_9036"},
+ {65, "arabic7"},
+ {65, "csISO89ASMO449"},
+ {65, "iso-ir-89"},
+ {66, "iso-ir-90"},
+ {66, "csISO90"},
+ {67, "JIS_C6229-1984-a"},
+ {67, "csISO91JISC62291984a"},
+ {67, "iso-ir-91"},
+ {67, "jp-ocr-a"},
+ {68, "JIS_C6229-1984-b"},
+ {68, "ISO646-JP-OCR-B"},
+ {68, "csISO92JISC62991984b"},
+ {68, "iso-ir-92"},
+ {68, "jp-ocr-b"},
+ {69, "JIS_C6229-1984-b-add"},
+ {69, "csISO93JIS62291984badd"},
+ {69, "iso-ir-93"},
+ {69, "jp-ocr-b-add"},
+ {70, "JIS_C6229-1984-hand"},
+ {70, "csISO94JIS62291984hand"},
+ {70, "iso-ir-94"},
+ {70, "jp-ocr-hand"},
+ {71, "JIS_C6229-1984-hand-add"},
+ {71, "csISO95JIS62291984handadd"},
+ {71, "iso-ir-95"},
+ {71, "jp-ocr-hand-add"},
+ {72, "JIS_C6229-1984-kana"},
+ {72, "csISO96JISC62291984kana"},
+ {72, "iso-ir-96"},
+ {73, "ISO_2033-1983"},
+ {73, "csISO2033"},
+ {73, "e13b"},
+ {73, "iso-ir-98"},
+ {74, "ANSI_X3.110-1983"},
+ {74, "CSA_T500-1983"},
+ {74, "NAPLPS"},
+ {74, "csISO99NAPLPS"},
+ {74, "iso-ir-99"},
+ {75, "T.61-7bit"},
+ {75, "csISO102T617bit"},
+ {75, "iso-ir-102"},
+ {76, "T.61-8bit"},
+ {76, "T.61"},
+ {76, "csISO103T618bit"},
+ {76, "iso-ir-103"},
+ {77, "ECMA-cyrillic"},
+ {77, "KOI8-E"},
+ {77, "csISO111ECMACyrillic"},
+ {77, "iso-ir-111"},
+ {78, "CSA_Z243.4-1985-1"},
+ {78, "ISO646-CA"},
+ {78, "ca"},
+ {78, "csISO121Canadian1"},
+ {78, "csa7-1"},
+ {78, "csa71"},
+ {78, "iso-ir-121"},
+ {79, "CSA_Z243.4-1985-2"},
+ {79, "ISO646-CA2"},
+ {79, "csISO122Canadian2"},
+ {79, "csa7-2"},
+ {79, "csa72"},
+ {79, "iso-ir-122"},
+ {80, "CSA_Z243.4-1985-gr"},
+ {80, "csISO123CSAZ24341985gr"},
+ {80, "iso-ir-123"},
+ {81, "ISO-8859-6-E"},
+ {81, "ISO_8859-6-E"},
+ {81, "csISO88596E"},
+ {82, "ISO-8859-6-I"},
+ {82, "ISO_8859-6-I"},
+ {82, "csISO88596I"},
+ {83, "T.101-G2"},
+ {83, "csISO128T101G2"},
+ {83, "iso-ir-128"},
+ {84, "ISO-8859-8-E"},
+ {84, "ISO_8859-8-E"},
+ {84, "csISO88598E"},
+ {85, "ISO-8859-8-I"},
+ {85, "ISO_8859-8-I"},
+ {85, "csISO88598I"},
+ {86, "CSN_369103"},
+ {86, "csISO139CSN369103"},
+ {86, "iso-ir-139"},
+ {87, "JUS_I.B1.002"},
+ {87, "ISO646-YU"},
+ {87, "csISO141JUSIB1002"},
+ {87, "iso-ir-141"},
+ {87, "js"},
+ {87, "yu"},
+ {88, "IEC_P27-1"},
+ {88, "csISO143IECP271"},
+ {88, "iso-ir-143"},
+ {89, "JUS_I.B1.003-serb"},
+ {89, "csISO146Serbian"},
+ {89, "iso-ir-146"},
+ {89, "serbian"},
+ {90, "JUS_I.B1.003-mac"},
+ {90, "csISO147Macedonian"},
+ {90, "iso-ir-147"},
+ {90, "macedonian"},
+ {91, "greek-ccitt"},
+ {91, "csISO150"},
+ {91, "csISO150GreekCCITT"},
+ {91, "iso-ir-150"},
+ {92, "NC_NC00-10:81"},
+ {92, "ISO646-CU"},
+ {92, "csISO151Cuba"},
+ {92, "cuba"},
+ {92, "iso-ir-151"},
+ {93, "ISO_6937-2-25"},
+ {93, "csISO6937Add"},
+ {93, "iso-ir-152"},
+ {94, "GOST_19768-74"},
+ {94, "ST_SEV_358-88"},
+ {94, "csISO153GOST1976874"},
+ {94, "iso-ir-153"},
+ {95, "ISO_8859-supp"},
+ {95, "csISO8859Supp"},
+ {95, "iso-ir-154"},
+ {95, "latin1-2-5"},
+ {96, "ISO_10367-box"},
+ {96, "csISO10367Box"},
+ {96, "iso-ir-155"},
+ {97, "latin-lap"},
+ {97, "csISO158Lap"},
+ {97, "iso-ir-158"},
+ {97, "lap"},
+ {98, "JIS_X0212-1990"},
+ {98, "csISO159JISX02121990"},
+ {98, "iso-ir-159"},
+ {98, "x0212"},
+ {99, "DS_2089"},
+ {99, "DS2089"},
+ {99, "ISO646-DK"},
+ {99, "csISO646Danish"},
+ {99, "dk"},
+ {100, "us-dk"},
+ {100, "csUSDK"},
+ {101, "dk-us"},
+ {101, "csDKUS"},
+ {102, "KSC5636"},
+ {102, "ISO646-KR"},
+ {102, "csKSC5636"},
+ {103, "UNICODE-1-1-UTF-7"},
+ {103, "csUnicode11UTF7"},
+ {104, "ISO-2022-CN"},
+ {104, "csISO2022CN"},
+ {105, "ISO-2022-CN-EXT"},
+ {105, "csISO2022CNEXT"},
+ {106, "UTF-8"},
+ {106, "csUTF8"},
+ {109, "ISO-8859-13"},
+ {109, "csISO885913"},
+ {110, "ISO-8859-14"},
+ {110, "ISO_8859-14"},
+ {110, "ISO_8859-14:1998"},
+ {110, "csISO885914"},
+ {110, "iso-celtic"},
+ {110, "iso-ir-199"},
+ {110, "l8"},
+ {110, "latin8"},
+ {111, "ISO-8859-15"},
+ {111, "ISO_8859-15"},
+ {111, "Latin-9"},
+ {111, "csISO885915"},
+ {112, "ISO-8859-16"},
+ {112, "ISO_8859-16"},
+ {112, "ISO_8859-16:2001"},
+ {112, "csISO885916"},
+ {112, "iso-ir-226"},
+ {112, "l10"},
+ {112, "latin10"},
+ {113, "GBK"},
+ {113, "CP936"},
+ {113, "MS936"},
+ {113, "csGBK"},
+ {113, "windows-936"},
+ {114, "GB18030"},
+ {114, "csGB18030"},
+ {115, "OSD_EBCDIC_DF04_15"},
+ {115, "csOSDEBCDICDF0415"},
+ {116, "OSD_EBCDIC_DF03_IRV"},
+ {116, "csOSDEBCDICDF03IRV"},
+ {117, "OSD_EBCDIC_DF04_1"},
+ {117, "csOSDEBCDICDF041"},
+ {118, "ISO-11548-1"},
+ {118, "ISO_11548-1"},
+ {118, "ISO_TR_11548-1"},
+ {118, "csISO115481"},
+ {119, "KZ-1048"},
+ {119, "RK1048"},
+ {119, "STRK1048-2002"},
+ {119, "csKZ1048"},
+ {1000, "ISO-10646-UCS-2"},
+ {1000, "csUnicode"},
+ {1001, "ISO-10646-UCS-4"},
+ {1001, "csUCS4"},
+ {1002, "ISO-10646-UCS-Basic"},
+ {1002, "csUnicodeASCII"},
+ {1003, "ISO-10646-Unicode-Latin1"},
+ {1003, "ISO-10646"},
+ {1003, "csUnicodeLatin1"},
+ {1004, "ISO-10646-J-1"},
+ {1004, "csUnicodeJapanese"},
+ {1005, "ISO-Unicode-IBM-1261"},
+ {1005, "csUnicodeIBM1261"},
+ {1006, "ISO-Unicode-IBM-1268"},
+ {1006, "csUnicodeIBM1268"},
+ {1007, "ISO-Unicode-IBM-1276"},
+ {1007, "csUnicodeIBM1276"},
+ {1008, "ISO-Unicode-IBM-1264"},
+ {1008, "csUnicodeIBM1264"},
+ {1009, "ISO-Unicode-IBM-1265"},
+ {1009, "csUnicodeIBM1265"},
+ {1010, "UNICODE-1-1"},
+ {1010, "csUnicode11"},
+ {1011, "SCSU"},
+ {1011, "csSCSU"},
+ {1012, "UTF-7"},
+ {1012, "csUTF7"},
+ {1013, "UTF-16BE"},
+ {1013, "csUTF16BE"},
+ {1014, "UTF-16LE"},
+ {1014, "csUTF16LE"},
+ {1015, "UTF-16"},
+ {1015, "csUTF16"},
+ {1016, "CESU-8"},
+ {1016, "csCESU-8"},
+ {1016, "csCESU8"},
+ {1017, "UTF-32"},
+ {1017, "csUTF32"},
+ {1018, "UTF-32BE"},
+ {1018, "csUTF32BE"},
+ {1019, "UTF-32LE"},
+ {1019, "csUTF32LE"},
+ {1020, "BOCU-1"},
+ {1020, "csBOCU-1"},
+ {1020, "csBOCU1"},
+ {1021, "UTF-7-IMAP"},
+ {1021, "csUTF7IMAP"},
+ {2000, "ISO-8859-1-Windows-3.0-Latin-1"},
+ {2000, "csWindows30Latin1"},
+ {2001, "ISO-8859-1-Windows-3.1-Latin-1"},
+ {2001, "csWindows31Latin1"},
+ {2002, "ISO-8859-2-Windows-Latin-2"},
+ {2002, "csWindows31Latin2"},
+ {2003, "ISO-8859-9-Windows-Latin-5"},
+ {2003, "csWindows31Latin5"},
+ {2004, "hp-roman8"},
+ {2004, "csHPRoman8"},
+ {2004, "r8"},
+ {2004, "roman8"},
+ {2005, "Adobe-Standard-Encoding"},
+ {2005, "csAdobeStandardEncoding"},
+ {2006, "Ventura-US"},
+ {2006, "csVenturaUS"},
+ {2007, "Ventura-International"},
+ {2007, "csVenturaInternational"},
+ {2008, "DEC-MCS"},
+ {2008, "csDECMCS"},
+ {2008, "dec"},
+ {2009, "IBM850"},
+ {2009, "850"},
+ {2009, "cp850"},
+ {2009, "csPC850Multilingual"},
+ {2012, "PC8-Danish-Norwegian"},
+ {2012, "csPC8DanishNorwegian"},
+ {2013, "IBM862"},
+ {2013, "862"},
+ {2013, "cp862"},
+ {2013, "csPC862LatinHebrew"},
+ {2014, "PC8-Turkish"},
+ {2014, "csPC8Turkish"},
+ {2015, "IBM-Symbols"},
+ {2015, "csIBMSymbols"},
+ {2016, "IBM-Thai"},
+ {2016, "csIBMThai"},
+ {2017, "HP-Legal"},
+ {2017, "csHPLegal"},
+ {2018, "HP-Pi-font"},
+ {2018, "csHPPiFont"},
+ {2019, "HP-Math8"},
+ {2019, "csHPMath8"},
+ {2020, "Adobe-Symbol-Encoding"},
+ {2020, "csHPPSMath"},
+ {2021, "HP-DeskTop"},
+ {2021, "csHPDesktop"},
+ {2022, "Ventura-Math"},
+ {2022, "csVenturaMath"},
+ {2023, "Microsoft-Publishing"},
+ {2023, "csMicrosoftPublishing"},
+ {2024, "Windows-31J"},
+ {2024, "csWindows31J"},
+ {2025, "GB2312"},
+ {2025, "csGB2312"},
+ {2026, "Big5"},
+ {2026, "csBig5"},
+ {2027, "macintosh"},
+ {2027, "csMacintosh"},
+ {2027, "mac"},
+ {2028, "IBM037"},
+ {2028, "cp037"},
+ {2028, "csIBM037"},
+ {2028, "ebcdic-cp-ca"},
+ {2028, "ebcdic-cp-nl"},
+ {2028, "ebcdic-cp-us"},
+ {2028, "ebcdic-cp-wt"},
+ {2029, "IBM038"},
+ {2029, "EBCDIC-INT"},
+ {2029, "cp038"},
+ {2029, "csIBM038"},
+ {2030, "IBM273"},
+ {2030, "CP273"},
+ {2030, "csIBM273"},
+ {2031, "IBM274"},
+ {2031, "CP274"},
+ {2031, "EBCDIC-BE"},
+ {2031, "csIBM274"},
+ {2032, "IBM275"},
+ {2032, "EBCDIC-BR"},
+ {2032, "cp275"},
+ {2032, "csIBM275"},
+ {2033, "IBM277"},
+ {2033, "EBCDIC-CP-DK"},
+ {2033, "EBCDIC-CP-NO"},
+ {2033, "csIBM277"},
+ {2034, "IBM278"},
+ {2034, "CP278"},
+ {2034, "csIBM278"},
+ {2034, "ebcdic-cp-fi"},
+ {2034, "ebcdic-cp-se"},
+ {2035, "IBM280"},
+ {2035, "CP280"},
+ {2035, "csIBM280"},
+ {2035, "ebcdic-cp-it"},
+ {2036, "IBM281"},
+ {2036, "EBCDIC-JP-E"},
+ {2036, "cp281"},
+ {2036, "csIBM281"},
+ {2037, "IBM284"},
+ {2037, "CP284"},
+ {2037, "csIBM284"},
+ {2037, "ebcdic-cp-es"},
+ {2038, "IBM285"},
+ {2038, "CP285"},
+ {2038, "csIBM285"},
+ {2038, "ebcdic-cp-gb"},
+ {2039, "IBM290"},
+ {2039, "EBCDIC-JP-kana"},
+ {2039, "cp290"},
+ {2039, "csIBM290"},
+ {2040, "IBM297"},
+ {2040, "cp297"},
+ {2040, "csIBM297"},
+ {2040, "ebcdic-cp-fr"},
+ {2041, "IBM420"},
+ {2041, "cp420"},
+ {2041, "csIBM420"},
+ {2041, "ebcdic-cp-ar1"},
+ {2042, "IBM423"},
+ {2042, "cp423"},
+ {2042, "csIBM423"},
+ {2042, "ebcdic-cp-gr"},
+ {2043, "IBM424"},
+ {2043, "cp424"},
+ {2043, "csIBM424"},
+ {2043, "ebcdic-cp-he"},
+ {2011, "IBM437"},
+ {2011, "437"},
+ {2011, "cp437"},
+ {2011, "csPC8CodePage437"},
+ {2044, "IBM500"},
+ {2044, "CP500"},
+ {2044, "csIBM500"},
+ {2044, "ebcdic-cp-be"},
+ {2044, "ebcdic-cp-ch"},
+ {2045, "IBM851"},
+ {2045, "851"},
+ {2045, "cp851"},
+ {2045, "csIBM851"},
+ {2010, "IBM852"},
+ {2010, "852"},
+ {2010, "cp852"},
+ {2010, "csPCp852"},
+ {2046, "IBM855"},
+ {2046, "855"},
+ {2046, "cp855"},
+ {2046, "csIBM855"},
+ {2047, "IBM857"},
+ {2047, "857"},
+ {2047, "cp857"},
+ {2047, "csIBM857"},
+ {2048, "IBM860"},
+ {2048, "860"},
+ {2048, "cp860"},
+ {2048, "csIBM860"},
+ {2049, "IBM861"},
+ {2049, "861"},
+ {2049, "cp-is"},
+ {2049, "cp861"},
+ {2049, "csIBM861"},
+ {2050, "IBM863"},
+ {2050, "863"},
+ {2050, "cp863"},
+ {2050, "csIBM863"},
+ {2051, "IBM864"},
+ {2051, "cp864"},
+ {2051, "csIBM864"},
+ {2052, "IBM865"},
+ {2052, "865"},
+ {2052, "cp865"},
+ {2052, "csIBM865"},
+ {2053, "IBM868"},
+ {2053, "CP868"},
+ {2053, "cp-ar"},
+ {2053, "csIBM868"},
+ {2054, "IBM869"},
+ {2054, "869"},
+ {2054, "cp-gr"},
+ {2054, "cp869"},
+ {2054, "csIBM869"},
+ {2055, "IBM870"},
+ {2055, "CP870"},
+ {2055, "csIBM870"},
+ {2055, "ebcdic-cp-roece"},
+ {2055, "ebcdic-cp-yu"},
+ {2056, "IBM871"},
+ {2056, "CP871"},
+ {2056, "csIBM871"},
+ {2056, "ebcdic-cp-is"},
+ {2057, "IBM880"},
+ {2057, "EBCDIC-Cyrillic"},
+ {2057, "cp880"},
+ {2057, "csIBM880"},
+ {2058, "IBM891"},
+ {2058, "cp891"},
+ {2058, "csIBM891"},
+ {2059, "IBM903"},
+ {2059, "cp903"},
+ {2059, "csIBM903"},
+ {2060, "IBM904"},
+ {2060, "904"},
+ {2060, "cp904"},
+ {2060, "csIBBM904"},
+ {2061, "IBM905"},
+ {2061, "CP905"},
+ {2061, "csIBM905"},
+ {2061, "ebcdic-cp-tr"},
+ {2062, "IBM918"},
+ {2062, "CP918"},
+ {2062, "csIBM918"},
+ {2062, "ebcdic-cp-ar2"},
+ {2063, "IBM1026"},
+ {2063, "CP1026"},
+ {2063, "csIBM1026"},
+ {2064, "EBCDIC-AT-DE"},
+ {2064, "csIBMEBCDICATDE"},
+ {2065, "EBCDIC-AT-DE-A"},
+ {2065, "csEBCDICATDEA"},
+ {2066, "EBCDIC-CA-FR"},
+ {2066, "csEBCDICCAFR"},
+ {2067, "EBCDIC-DK-NO"},
+ {2067, "csEBCDICDKNO"},
+ {2068, "EBCDIC-DK-NO-A"},
+ {2068, "csEBCDICDKNOA"},
+ {2069, "EBCDIC-FI-SE"},
+ {2069, "csEBCDICFISE"},
+ {2070, "EBCDIC-FI-SE-A"},
+ {2070, "csEBCDICFISEA"},
+ {2071, "EBCDIC-FR"},
+ {2071, "csEBCDICFR"},
+ {2072, "EBCDIC-IT"},
+ {2072, "csEBCDICIT"},
+ {2073, "EBCDIC-PT"},
+ {2073, "csEBCDICPT"},
+ {2074, "EBCDIC-ES"},
+ {2074, "csEBCDICES"},
+ {2075, "EBCDIC-ES-A"},
+ {2075, "csEBCDICESA"},
+ {2076, "EBCDIC-ES-S"},
+ {2076, "csEBCDICESS"},
+ {2077, "EBCDIC-UK"},
+ {2077, "csEBCDICUK"},
+ {2078, "EBCDIC-US"},
+ {2078, "csEBCDICUS"},
+ {2079, "UNKNOWN-8BIT"},
+ {2079, "csUnknown8BiT"},
+ {2080, "MNEMONIC"},
+ {2080, "csMnemonic"},
+ {2081, "MNEM"},
+ {2081, "csMnem"},
+ {2082, "VISCII"},
+ {2082, "csVISCII"},
+ {2083, "VIQR"},
+ {2083, "csVIQR"},
+ {2084, "KOI8-R"},
+ {2084, "csKOI8R"},
+ {2085, "HZ-GB-2312"},
+ {2086, "IBM866"},
+ {2086, "866"},
+ {2086, "cp866"},
+ {2086, "csIBM866"},
+ {2087, "IBM775"},
+ {2087, "cp775"},
+ {2087, "csPC775Baltic"},
+ {2088, "KOI8-U"},
+ {2088, "csKOI8U"},
+ {2089, "IBM00858"},
+ {2089, "CCSID00858"},
+ {2089, "CP00858"},
+ {2089, "PC-Multilingual-850+euro"},
+ {2089, "csIBM00858"},
+ {2090, "IBM00924"},
+ {2090, "CCSID00924"},
+ {2090, "CP00924"},
+ {2090, "csIBM00924"},
+ {2090, "ebcdic-Latin9--euro"},
+ {2091, "IBM01140"},
+ {2091, "CCSID01140"},
+ {2091, "CP01140"},
+ {2091, "csIBM01140"},
+ {2091, "ebcdic-us-37+euro"},
+ {2092, "IBM01141"},
+ {2092, "CCSID01141"},
+ {2092, "CP01141"},
+ {2092, "csIBM01141"},
+ {2092, "ebcdic-de-273+euro"},
+ {2093, "IBM01142"},
+ {2093, "CCSID01142"},
+ {2093, "CP01142"},
+ {2093, "csIBM01142"},
+ {2093, "ebcdic-dk-277+euro"},
+ {2093, "ebcdic-no-277+euro"},
+ {2094, "IBM01143"},
+ {2094, "CCSID01143"},
+ {2094, "CP01143"},
+ {2094, "csIBM01143"},
+ {2094, "ebcdic-fi-278+euro"},
+ {2094, "ebcdic-se-278+euro"},
+ {2095, "IBM01144"},
+ {2095, "CCSID01144"},
+ {2095, "CP01144"},
+ {2095, "csIBM01144"},
+ {2095, "ebcdic-it-280+euro"},
+ {2096, "IBM01145"},
+ {2096, "CCSID01145"},
+ {2096, "CP01145"},
+ {2096, "csIBM01145"},
+ {2096, "ebcdic-es-284+euro"},
+ {2097, "IBM01146"},
+ {2097, "CCSID01146"},
+ {2097, "CP01146"},
+ {2097, "csIBM01146"},
+ {2097, "ebcdic-gb-285+euro"},
+ {2098, "IBM01147"},
+ {2098, "CCSID01147"},
+ {2098, "CP01147"},
+ {2098, "csIBM01147"},
+ {2098, "ebcdic-fr-297+euro"},
+ {2099, "IBM01148"},
+ {2099, "CCSID01148"},
+ {2099, "CP01148"},
+ {2099, "csIBM01148"},
+ {2099, "ebcdic-international-500+euro"},
+ {2100, "IBM01149"},
+ {2100, "CCSID01149"},
+ {2100, "CP01149"},
+ {2100, "csIBM01149"},
+ {2100, "ebcdic-is-871+euro"},
+ {2101, "Big5-HKSCS"},
+ {2101, "csBig5HKSCS"},
+ {2102, "IBM1047"},
+ {2102, "IBM-1047"},
+ {2102, "csIBM1047"},
+ {2103, "PTCP154"},
+ {2103, "CP154"},
+ {2103, "Cyrillic-Asian"},
+ {2103, "PT154"},
+ {2103, "csPTCP154"},
+ {2104, "Amiga-1251"},
+ {2104, "Ami-1251"},
+ {2104, "Ami1251"},
+ {2104, "Amiga1251"},
+ {2104, "csAmiga1251"},
+ {2105, "KOI7-switched"},
+ {2105, "csKOI7switched"},
+ {2106, "BRF"},
+ {2106, "csBRF"},
+ {2107, "TSCII"},
+ {2107, "csTSCII"},
+ {2108, "CP51932"},
+ {2108, "csCP51932"},
+ {2109, "windows-874"},
+ {2109, "cswindows874"},
+ {2250, "windows-1250"},
+ {2250, "cswindows1250"},
+ {2251, "windows-1251"},
+ {2251, "cswindows1251"},
+ {2252, "windows-1252"},
+ {2252, "cswindows1252"},
+ {2253, "windows-1253"},
+ {2253, "cswindows1253"},
+ {2254, "windows-1254"},
+ {2254, "cswindows1254"},
+ {2255, "windows-1255"},
+ {2255, "cswindows1255"},
+ {2256, "windows-1256"},
+ {2256, "cswindows1256"},
+ {2257, "windows-1257"},
+ {2257, "cswindows1257"},
+ {2258, "windows-1258"},
+ {2258, "cswindows1258"},
+ {2259, "TIS-620"},
+ {2259, "ISO-8859-11"},
+ {2259, "csTIS620"},
+ {2260, "CP50220"},
+ {2260, "csCP50220"}};
+
+#endif // _LIBCPP_TEST_TEXT_ENCODING_H
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.ctor/default.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.ctor/default.pass.cpp
new file mode 100644
index 0000000000000..23757d82d8811
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.ctor/default.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding::text_encoding() noexcept
+
+#include <cassert>
+#include <concepts>
+#include <text_encoding>
+#include <type_traits>
+
+constexpr bool test() {
+ std::text_encoding te{};
+ assert(te.mib() == std::text_encoding::unknown);
+ assert(std::string_view("") == te.name());
+
+ return true;
+}
+
+int main(int, char**) {
+ // 1. Default constructor must be nothrow
+ static_assert(std::is_nothrow_default_constructible_v<std::text_encoding>, "Must be nothrow default constructible");
+
+ // 2. Default constructing a text_encoding object makes it so that mib() == id::unknown, and its name is empty
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.ctor/id.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.ctor/id.pass.cpp
new file mode 100644
index 0000000000000..bc3d729e770e3
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.ctor/id.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding::text_encoding(std::text_encoding::id) noexcept
+
+#include <algorithm>
+#include <cassert>
+#include <concepts>
+#include <ranges>
+#include <text_encoding>
+#include <type_traits>
+
+#include "../test_text_encoding.h"
+
+using id = std::text_encoding::id;
+
+constexpr bool test() {
+ {
+ // 2. Constructing an object with a valid id must set mib() and the name to the corresponding value.
+ for (auto pair : unique_encoding_data) {
+ std::text_encoding te{id(pair.mib)};
+
+ assert(te.mib() == id(pair.mib));
+ assert(pair.name == te.name());
+ assert(std::ranges::contains(te.aliases(), pair.name));
+ }
+ }
+
+ {
+ // 3. Constructing an object using id::unknown or id::other must set mib() to id::unknown or id::other, respectively, and the name to an empty string.
+ {
+ std::text_encoding te{id::other};
+
+ assert(te.mib() == id::other);
+ assert(std::string_view("") == te.name());
+ assert(std::ranges::empty(te.aliases()));
+ }
+
+ {
+ std::text_encoding te{id::unknown};
+
+ assert(te.mib() == id::unknown);
+ assert(std::string_view("") == te.name());
+ assert(std::ranges::empty(te.aliases()));
+ }
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ // 1. text_encoding(id) must be nothrow
+ static_assert(std::is_nothrow_constructible_v<std::text_encoding, std::text_encoding::id>,
+ "Must be nothrow constructible with id");
+
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.ctor/string_view.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.ctor/string_view.pass.cpp
new file mode 100644
index 0000000000000..c3202f78642f2
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.ctor/string_view.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=40000000
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=1000000000
+
+// <text_encoding>
+
+// text_encoding::text_encoding(string_view) noexcept
+
+#include <cassert>
+#include <string_view>
+#include <text_encoding>
+#include <type_traits>
+
+#include "../test_text_encoding.h"
+
+using id = std::text_encoding::id;
+
+constexpr void test_ctor(std::string_view str, id expect_id) {
+ std::text_encoding te{str};
+
+ assert(te.mib() == expect_id);
+ assert(te.name() == str);
+}
+
+constexpr bool test() {
+ // The first encoding name for each mib in the data table.
+ for (auto& data : unique_encoding_data) {
+ std::text_encoding te{data.name};
+
+ assert(te.mib() == id(data.mib));
+ assert(te.name() == data.name);
+ }
+
+ // Names that should all result in an "other" text encoding
+ for (auto& name : other_names) {
+ std::text_encoding te{name};
+
+ assert(te.mib() == std::text_encoding::other);
+ assert(te.name() == name);
+ }
+
+ test_ctor("U_T_F-8", id::UTF8);
+ test_ctor("utf8", id::UTF8);
+ test_ctor("u.t.f-008", id::UTF8);
+ test_ctor("utf-80", id::other);
+ test_ctor("iso885931988", id::ISOLatin3);
+ test_ctor("iso00885931988", id::ISOLatin3);
+
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(std::is_nothrow_constructible_v<std::text_encoding, std::string_view>,
+ "Must be nothrow constructible with string_view");
+
+ test();
+ static_assert(test());
+
+ // Check every possible alias, intentionally runtime only as it would take unreasonably long to test in constexpr.
+ for (auto& enc : all_encoding_data) {
+ test_ctor(enc.name, id(enc.mib));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.eq/equal.id.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.eq/equal.id.pass.cpp
new file mode 100644
index 0000000000000..79de614299fa0
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.eq/equal.id.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// bool text_encoding::operator==(const text_encoding&, id) noexcept
+
+#include <cassert>
+#include <text_encoding>
+
+#include "test_macros.h"
+#include "../test_text_encoding.h"
+
+using id = std::text_encoding::id;
+
+constexpr void test_primary_encodings() {
+ for (auto& data : unique_encoding_data) {
+ std::text_encoding te{id(data.mib)};
+ assert(te == id(data.mib));
+ }
+}
+
+constexpr bool test() {
+ // operator==(const text_encoding&, id) must be noexcept and returns bool
+ {
+ std::text_encoding te{};
+ ASSERT_SAME_TYPE(decltype(te == id::UTF8), bool);
+ ASSERT_NOEXCEPT(te == id::UTF8);
+ }
+
+ // operator==(const text_encoding&, id) returns true if mib() is equal to the id
+ {
+ test_primary_encodings();
+
+ // unknown, other cases
+ assert(std::text_encoding() == id::unknown);
+ assert(std::text_encoding(id::unknown) == id::unknown);
+ assert(std::text_encoding(id::other) == id::other);
+ }
+
+ // operator==(const text_encoding&, id) returns false if mib() is not equal to the id
+ {
+ assert(!(std::text_encoding(id::UTF8) == id::UTF16));
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.eq/equal.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.eq/equal.pass.cpp
new file mode 100644
index 0000000000000..5041801fcb3e8
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.eq/equal.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// bool text_encoding::operator==(const text_encoding&, const text_encoding&) noexcept
+
+#include <cassert>
+#include <text_encoding>
+
+#include "test_macros.h"
+
+using id = std::text_encoding::id;
+
+constexpr bool test() {
+ // 1. operator==(const text_encoding&, const text_encoding&) must be noexcept and returns bool
+ {
+ ASSERT_NOEXCEPT(std::text_encoding() == std::text_encoding());
+ ASSERT_SAME_TYPE(bool, decltype(std::text_encoding() == std::text_encoding()));
+ }
+
+ // 2. operator==(const text_encoding&, const text_encoding&) returns true if both text_encoding ids are equal
+ {
+ std::text_encoding te1{id::UTF8};
+ std::text_encoding te2{id::UTF8};
+ assert(te1 == te2);
+ assert((te1 == te2) == !(te1 != te2));
+
+ const std::text_encoding& te11 = te1;
+ const std::text_encoding& te22 = te2;
+ assert(te11 == te22);
+ assert((te11 == te22) == !(te11 != te22));
+ }
+
+ // 3. operator==(const text_encoding&, const text_encoding&) for text_encodings with ids of "other" return true if the names are equal
+ {
+ std::text_encoding other_te1{"foo"};
+ std::text_encoding other_te2{"foo"};
+ assert(other_te1 == other_te2);
+ }
+
+ // 4. operator==(const text_encoding&, const text_encoding&) returns false when comparing text_encodings with
diff erent ids
+ {
+ std::text_encoding te1{id::UTF8};
+ std::text_encoding te2{id::UTF16};
+ assert(!(te1 == te2));
+ }
+
+ // 5. operator==(const text_encoding&, const text_encoding&) for text_encodings with ids of "other" returns false if the names are not equal
+ {
+ std::text_encoding other_te1("foo");
+ std::text_encoding other_te2("bar");
+ assert(!(other_te1 == other_te2));
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.hash/enabled_hash.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.hash/enabled_hash.pass.cpp
new file mode 100644
index 0000000000000..642b67fa3c08c
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.hash/enabled_hash.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// template <> struct hash<text_encoding>
+
+#include <text_encoding>
+
+#include "poisoned_hash_helper.h"
+
+int main(int, char**) {
+ test_library_hash_specializations_available();
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.hash/hash.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.hash/hash.pass.cpp
new file mode 100644
index 0000000000000..82ca786174ad7
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.hash/hash.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// template <> struct hash<text_encoding>
+
+#include "poisoned_hash_helper.h"
+#include <cassert>
+#include <cstdint>
+#include <text_encoding>
+#include <type_traits>
+
+void test_te_hash() {
+ using T = std::text_encoding;
+ using H = std::hash<T>;
+
+ {
+ const T te(T::ASCII);
+ const H h{};
+ assert(h(te) == h(te));
+ static_assert(std::is_same_v<decltype(h(te)), std::size_t>);
+ }
+
+ {
+ const T te1(T::ASCII);
+ const T te2(T::UTF8);
+ const H h{};
+
+ assert(h(te1) != h(te2));
+ }
+
+ {
+ const T te1(T::unknown);
+ const T te2(T::unknown);
+ const H h{};
+ assert(h(te1) == h(te2));
+ }
+
+ {
+ const T te1(T::other);
+ const T te2(T::other);
+ const H h{};
+ assert(h(te1) == h(te2));
+ }
+}
+
+int main(int, char**) {
+ test_te_hash();
+ test_hash_enabled<std::text_encoding>();
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/aliases.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/aliases.pass.cpp
new file mode 100644
index 0000000000000..bf616788fe449
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/aliases.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// constexpr text_encoding::aliases()
+
+#include <cassert>
+#include <string_view>
+#include <text_encoding>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+ static_assert(noexcept(std::text_encoding().aliases()));
+ ASSERT_SAME_TYPE(decltype(std::text_encoding().aliases()), std::text_encoding::aliases_view);
+
+ // 2 aliases
+ std::text_encoding utf8{std::text_encoding::UTF8};
+
+ auto aliases = utf8.aliases();
+
+ assert(aliases.size() == 2);
+ assert(std::string_view(aliases[0]) == "UTF-8");
+ assert(std::string_view(aliases[1]) == "csUTF8");
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/aliases_view.compile.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/aliases_view.compile.pass.cpp
new file mode 100644
index 0000000000000..711ad99476e77
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/aliases_view.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding::aliases_view;
+
+#include <concepts>
+#include <text_encoding>
+
+static_assert(std::copyable<std::text_encoding::aliases_view>);
+static_assert(std::ranges::view<std::text_encoding::aliases_view>);
+static_assert(std::ranges::random_access_range<std::text_encoding::aliases_view>);
+static_assert(std::ranges::borrowed_range<std::text_encoding::aliases_view>);
+static_assert(std::same_as<std::ranges::range_value_t<std::text_encoding::aliases_view>, const char*>);
+static_assert(std::same_as<std::ranges::range_reference_t<std::text_encoding::aliases_view>, const char*>);
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/environment.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/environment.pass.cpp
new file mode 100644
index 0000000000000..113b151765c81
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/environment.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// REQUIRES: locale.en_US.UTF-8
+
+// UNSUPPORTED: no-localization
+// UNSUPPORTED: availability-te-environment-missing
+
+// <text_encoding>
+
+// text_encoding text_encoding::environment();
+
+#include <cassert>
+#include <clocale>
+#include <format>
+#include <iostream>
+#include <text_encoding>
+
+#include "platform_support.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+ auto check_env = []() {
+#if defined(__ANDROID__)
+ constexpr std::text_encoding::id expected_id = std::text_encoding::UTF8;
+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
+ constexpr std::text_encoding::id expected_id = std::text_encoding::ASCII;
+#elif defined(_WIN32)
+ constexpr std::text_encoding::id expected_id = std::text_encoding::windows1252;
+#elif defined(_AIX)
+ constexpr std::text_encoding::id expected_id = std::text_encoding::ISOLatin1;
+#else
+ constexpr std::text_encoding::id expected_id = std::text_encoding::unknown;
+#endif
+
+ std::same_as<std::text_encoding> decltype(auto) te = std::text_encoding::environment();
+
+ bool fail = false;
+ if (te != expected_id) {
+ std::cerr << std::format(
+ "Environment mismatch: Expected ID {}, received: {{{},{}}}\n", int(expected_id), int(te.mib()), te.name());
+ fail = true;
+ }
+ std::same_as<bool> decltype(auto) env_is_expected = std::text_encoding::environment_is<expected_id>();
+ if (!env_is_expected) {
+ fail = true;
+ }
+
+ return !fail;
+ };
+
+ {
+ // 1. Depending on the platform's default, verify that environment() returns the corresponding text encoding.
+ assert(check_env());
+ }
+
+ auto te = std::text_encoding::environment();
+ // 2. text_encoding::environment()'s return value isn't altered by changes to locale.
+ {
+ std::setlocale(LC_ALL, LOCALE_en_US_UTF_8);
+
+ auto te2 = std::text_encoding::environment();
+ assert(te == te2);
+ }
+
+ {
+ std::setlocale(LC_CTYPE, LOCALE_en_US_UTF_8);
+
+ auto te2 = std::text_encoding::environment();
+ assert(te == te2);
+ }
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/id.compile.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/id.compile.pass.cpp
new file mode 100644
index 0000000000000..65a7bddea3afa
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/id.compile.pass.cpp
@@ -0,0 +1,281 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// std::text_encoding::id;
+// Test that every member of the id enumeration has the correct value.
+
+#include <cstdint>
+#include <text_encoding>
+#include <type_traits>
+
+using std::int_least32_t;
+
+static_assert(std::is_scoped_enum_v<std::text_encoding::id>);
+static_assert(std::is_same_v<std::underlying_type_t<std::text_encoding::id>, std::int_least32_t>);
+static_assert(int_least32_t(std::text_encoding::id::other) == 1);
+static_assert(int_least32_t(std::text_encoding::id::unknown) == 2);
+static_assert(int_least32_t(std::text_encoding::id::ASCII) == 3);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatin1) == 4);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatin2) == 5);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatin3) == 6);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatin4) == 7);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatinCyrillic) == 8);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatinArabic) == 9);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatinGreek) == 10);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatinHebrew) == 11);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatin5) == 12);
+static_assert(int_least32_t(std::text_encoding::id::ISOLatin6) == 13);
+static_assert(int_least32_t(std::text_encoding::id::ISOTextComm) == 14);
+static_assert(int_least32_t(std::text_encoding::id::HalfWidthKatakana) == 15);
+static_assert(int_least32_t(std::text_encoding::id::JISEncoding) == 16);
+static_assert(int_least32_t(std::text_encoding::id::ShiftJIS) == 17);
+static_assert(int_least32_t(std::text_encoding::id::EUCPkdFmtJapanese) == 18);
+static_assert(int_least32_t(std::text_encoding::id::EUCFixWidJapanese) == 19);
+static_assert(int_least32_t(std::text_encoding::id::ISO4UnitedKingdom) == 20);
+static_assert(int_least32_t(std::text_encoding::id::ISO11SwedishForNames) == 21);
+static_assert(int_least32_t(std::text_encoding::id::ISO15Italian) == 22);
+static_assert(int_least32_t(std::text_encoding::id::ISO17Spanish) == 23);
+static_assert(int_least32_t(std::text_encoding::id::ISO21German) == 24);
+static_assert(int_least32_t(std::text_encoding::id::ISO60DanishNorwegian) == 25);
+static_assert(int_least32_t(std::text_encoding::id::ISO69French) == 26);
+static_assert(int_least32_t(std::text_encoding::id::ISO10646UTF1) == 27);
+static_assert(int_least32_t(std::text_encoding::id::ISO646basic1983) == 28);
+static_assert(int_least32_t(std::text_encoding::id::INVARIANT) == 29);
+static_assert(int_least32_t(std::text_encoding::id::ISO2IntlRefVersion) == 30);
+static_assert(int_least32_t(std::text_encoding::id::NATSSEFI) == 31);
+static_assert(int_least32_t(std::text_encoding::id::NATSSEFIADD) == 32);
+static_assert(int_least32_t(std::text_encoding::id::ISO10Swedish) == 35);
+static_assert(int_least32_t(std::text_encoding::id::KSC56011987) == 36);
+static_assert(int_least32_t(std::text_encoding::id::ISO2022KR) == 37);
+static_assert(int_least32_t(std::text_encoding::id::EUCKR) == 38);
+static_assert(int_least32_t(std::text_encoding::id::ISO2022JP) == 39);
+static_assert(int_least32_t(std::text_encoding::id::ISO2022JP2) == 40);
+static_assert(int_least32_t(std::text_encoding::id::ISO13JISC6220jp) == 41);
+static_assert(int_least32_t(std::text_encoding::id::ISO14JISC6220ro) == 42);
+static_assert(int_least32_t(std::text_encoding::id::ISO16Portuguese) == 43);
+static_assert(int_least32_t(std::text_encoding::id::ISO18Greek7Old) == 44);
+static_assert(int_least32_t(std::text_encoding::id::ISO19LatinGreek) == 45);
+static_assert(int_least32_t(std::text_encoding::id::ISO25French) == 46);
+static_assert(int_least32_t(std::text_encoding::id::ISO27LatinGreek1) == 47);
+static_assert(int_least32_t(std::text_encoding::id::ISO5427Cyrillic) == 48);
+static_assert(int_least32_t(std::text_encoding::id::ISO42JISC62261978) == 49);
+static_assert(int_least32_t(std::text_encoding::id::ISO47BSViewdata) == 50);
+static_assert(int_least32_t(std::text_encoding::id::ISO49INIS) == 51);
+static_assert(int_least32_t(std::text_encoding::id::ISO50INIS8) == 52);
+static_assert(int_least32_t(std::text_encoding::id::ISO51INISCyrillic) == 53);
+static_assert(int_least32_t(std::text_encoding::id::ISO54271981) == 54);
+static_assert(int_least32_t(std::text_encoding::id::ISO5428Greek) == 55);
+static_assert(int_least32_t(std::text_encoding::id::ISO57GB1988) == 56);
+static_assert(int_least32_t(std::text_encoding::id::ISO58GB231280) == 57);
+static_assert(int_least32_t(std::text_encoding::id::ISO61Norwegian2) == 58);
+static_assert(int_least32_t(std::text_encoding::id::ISO70VideotexSupp1) == 59);
+static_assert(int_least32_t(std::text_encoding::id::ISO84Portuguese2) == 60);
+static_assert(int_least32_t(std::text_encoding::id::ISO85Spanish2) == 61);
+static_assert(int_least32_t(std::text_encoding::id::ISO86Hungarian) == 62);
+static_assert(int_least32_t(std::text_encoding::id::ISO87JISX0208) == 63);
+static_assert(int_least32_t(std::text_encoding::id::ISO88Greek7) == 64);
+static_assert(int_least32_t(std::text_encoding::id::ISO89ASMO449) == 65);
+static_assert(int_least32_t(std::text_encoding::id::ISO90) == 66);
+static_assert(int_least32_t(std::text_encoding::id::ISO91JISC62291984a) == 67);
+static_assert(int_least32_t(std::text_encoding::id::ISO92JISC62991984b) == 68);
+static_assert(int_least32_t(std::text_encoding::id::ISO93JIS62291984badd) == 69);
+static_assert(int_least32_t(std::text_encoding::id::ISO94JIS62291984hand) == 70);
+static_assert(int_least32_t(std::text_encoding::id::ISO95JIS62291984handadd) == 71);
+static_assert(int_least32_t(std::text_encoding::id::ISO96JISC62291984kana) == 72);
+static_assert(int_least32_t(std::text_encoding::id::ISO2033) == 73);
+static_assert(int_least32_t(std::text_encoding::id::ISO99NAPLPS) == 74);
+static_assert(int_least32_t(std::text_encoding::id::ISO102T617bit) == 75);
+static_assert(int_least32_t(std::text_encoding::id::ISO103T618bit) == 76);
+static_assert(int_least32_t(std::text_encoding::id::ISO111ECMACyrillic) == 77);
+static_assert(int_least32_t(std::text_encoding::id::ISO121Canadian1) == 78);
+static_assert(int_least32_t(std::text_encoding::id::ISO122Canadian2) == 79);
+static_assert(int_least32_t(std::text_encoding::id::ISO123CSAZ24341985gr) == 80);
+static_assert(int_least32_t(std::text_encoding::id::ISO88596E) == 81);
+static_assert(int_least32_t(std::text_encoding::id::ISO88596I) == 82);
+static_assert(int_least32_t(std::text_encoding::id::ISO128T101G2) == 83);
+static_assert(int_least32_t(std::text_encoding::id::ISO88598E) == 84);
+static_assert(int_least32_t(std::text_encoding::id::ISO88598I) == 85);
+static_assert(int_least32_t(std::text_encoding::id::ISO139CSN369103) == 86);
+static_assert(int_least32_t(std::text_encoding::id::ISO141JUSIB1002) == 87);
+static_assert(int_least32_t(std::text_encoding::id::ISO143IECP271) == 88);
+static_assert(int_least32_t(std::text_encoding::id::ISO146Serbian) == 89);
+static_assert(int_least32_t(std::text_encoding::id::ISO147Macedonian) == 90);
+static_assert(int_least32_t(std::text_encoding::id::ISO150) == 91);
+static_assert(int_least32_t(std::text_encoding::id::ISO151Cuba) == 92);
+static_assert(int_least32_t(std::text_encoding::id::ISO6937Add) == 93);
+static_assert(int_least32_t(std::text_encoding::id::ISO153GOST1976874) == 94);
+static_assert(int_least32_t(std::text_encoding::id::ISO8859Supp) == 95);
+static_assert(int_least32_t(std::text_encoding::id::ISO10367Box) == 96);
+static_assert(int_least32_t(std::text_encoding::id::ISO158Lap) == 97);
+static_assert(int_least32_t(std::text_encoding::id::ISO159JISX02121990) == 98);
+static_assert(int_least32_t(std::text_encoding::id::ISO646Danish) == 99);
+static_assert(int_least32_t(std::text_encoding::id::USDK) == 100);
+static_assert(int_least32_t(std::text_encoding::id::DKUS) == 101);
+static_assert(int_least32_t(std::text_encoding::id::KSC5636) == 102);
+static_assert(int_least32_t(std::text_encoding::id::Unicode11UTF7) == 103);
+static_assert(int_least32_t(std::text_encoding::id::ISO2022CN) == 104);
+static_assert(int_least32_t(std::text_encoding::id::ISO2022CNEXT) == 105);
+static_assert(int_least32_t(std::text_encoding::id::UTF8) == 106);
+static_assert(int_least32_t(std::text_encoding::id::ISO885913) == 109);
+static_assert(int_least32_t(std::text_encoding::id::ISO885914) == 110);
+static_assert(int_least32_t(std::text_encoding::id::ISO885915) == 111);
+static_assert(int_least32_t(std::text_encoding::id::ISO885916) == 112);
+static_assert(int_least32_t(std::text_encoding::id::GBK) == 113);
+static_assert(int_least32_t(std::text_encoding::id::GB18030) == 114);
+static_assert(int_least32_t(std::text_encoding::id::OSDEBCDICDF0415) == 115);
+static_assert(int_least32_t(std::text_encoding::id::OSDEBCDICDF03IRV) == 116);
+static_assert(int_least32_t(std::text_encoding::id::OSDEBCDICDF041) == 117);
+static_assert(int_least32_t(std::text_encoding::id::ISO115481) == 118);
+static_assert(int_least32_t(std::text_encoding::id::KZ1048) == 119);
+static_assert(int_least32_t(std::text_encoding::id::UCS2) == 1000);
+static_assert(int_least32_t(std::text_encoding::id::UCS4) == 1001);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeASCII) == 1002);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeLatin1) == 1003);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeJapanese) == 1004);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeIBM1261) == 1005);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeIBM1268) == 1006);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeIBM1276) == 1007);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeIBM1264) == 1008);
+static_assert(int_least32_t(std::text_encoding::id::UnicodeIBM1265) == 1009);
+static_assert(int_least32_t(std::text_encoding::id::Unicode11) == 1010);
+static_assert(int_least32_t(std::text_encoding::id::SCSU) == 1011);
+static_assert(int_least32_t(std::text_encoding::id::UTF7) == 1012);
+static_assert(int_least32_t(std::text_encoding::id::UTF16BE) == 1013);
+static_assert(int_least32_t(std::text_encoding::id::UTF16LE) == 1014);
+static_assert(int_least32_t(std::text_encoding::id::UTF16) == 1015);
+static_assert(int_least32_t(std::text_encoding::id::CESU8) == 1016);
+static_assert(int_least32_t(std::text_encoding::id::UTF32) == 1017);
+static_assert(int_least32_t(std::text_encoding::id::UTF32BE) == 1018);
+static_assert(int_least32_t(std::text_encoding::id::UTF32LE) == 1019);
+static_assert(int_least32_t(std::text_encoding::id::BOCU1) == 1020);
+static_assert(int_least32_t(std::text_encoding::id::UTF7IMAP) == 1021);
+static_assert(int_least32_t(std::text_encoding::id::Windows30Latin1) == 2000);
+static_assert(int_least32_t(std::text_encoding::id::Windows31Latin1) == 2001);
+static_assert(int_least32_t(std::text_encoding::id::Windows31Latin2) == 2002);
+static_assert(int_least32_t(std::text_encoding::id::Windows31Latin5) == 2003);
+static_assert(int_least32_t(std::text_encoding::id::HPRoman8) == 2004);
+static_assert(int_least32_t(std::text_encoding::id::AdobeStandardEncoding) == 2005);
+static_assert(int_least32_t(std::text_encoding::id::VenturaUS) == 2006);
+static_assert(int_least32_t(std::text_encoding::id::VenturaInternational) == 2007);
+static_assert(int_least32_t(std::text_encoding::id::DECMCS) == 2008);
+static_assert(int_least32_t(std::text_encoding::id::PC850Multilingual) == 2009);
+static_assert(int_least32_t(std::text_encoding::id::PC8DanishNorwegian) == 2012);
+static_assert(int_least32_t(std::text_encoding::id::PC862LatinHebrew) == 2013);
+static_assert(int_least32_t(std::text_encoding::id::PC8Turkish) == 2014);
+static_assert(int_least32_t(std::text_encoding::id::IBMSymbols) == 2015);
+static_assert(int_least32_t(std::text_encoding::id::IBMThai) == 2016);
+static_assert(int_least32_t(std::text_encoding::id::HPLegal) == 2017);
+static_assert(int_least32_t(std::text_encoding::id::HPPiFont) == 2018);
+static_assert(int_least32_t(std::text_encoding::id::HPMath8) == 2019);
+static_assert(int_least32_t(std::text_encoding::id::HPPSMath) == 2020);
+static_assert(int_least32_t(std::text_encoding::id::HPDesktop) == 2021);
+static_assert(int_least32_t(std::text_encoding::id::VenturaMath) == 2022);
+static_assert(int_least32_t(std::text_encoding::id::MicrosoftPublishing) == 2023);
+static_assert(int_least32_t(std::text_encoding::id::Windows31J) == 2024);
+static_assert(int_least32_t(std::text_encoding::id::GB2312) == 2025);
+static_assert(int_least32_t(std::text_encoding::id::Big5) == 2026);
+static_assert(int_least32_t(std::text_encoding::id::Macintosh) == 2027);
+static_assert(int_least32_t(std::text_encoding::id::IBM037) == 2028);
+static_assert(int_least32_t(std::text_encoding::id::IBM038) == 2029);
+static_assert(int_least32_t(std::text_encoding::id::IBM273) == 2030);
+static_assert(int_least32_t(std::text_encoding::id::IBM274) == 2031);
+static_assert(int_least32_t(std::text_encoding::id::IBM275) == 2032);
+static_assert(int_least32_t(std::text_encoding::id::IBM277) == 2033);
+static_assert(int_least32_t(std::text_encoding::id::IBM278) == 2034);
+static_assert(int_least32_t(std::text_encoding::id::IBM280) == 2035);
+static_assert(int_least32_t(std::text_encoding::id::IBM281) == 2036);
+static_assert(int_least32_t(std::text_encoding::id::IBM284) == 2037);
+static_assert(int_least32_t(std::text_encoding::id::IBM285) == 2038);
+static_assert(int_least32_t(std::text_encoding::id::IBM290) == 2039);
+static_assert(int_least32_t(std::text_encoding::id::IBM297) == 2040);
+static_assert(int_least32_t(std::text_encoding::id::IBM420) == 2041);
+static_assert(int_least32_t(std::text_encoding::id::IBM423) == 2042);
+static_assert(int_least32_t(std::text_encoding::id::IBM424) == 2043);
+static_assert(int_least32_t(std::text_encoding::id::PC8CodePage437) == 2011);
+static_assert(int_least32_t(std::text_encoding::id::IBM500) == 2044);
+static_assert(int_least32_t(std::text_encoding::id::IBM851) == 2045);
+static_assert(int_least32_t(std::text_encoding::id::PCp852) == 2010);
+static_assert(int_least32_t(std::text_encoding::id::IBM855) == 2046);
+static_assert(int_least32_t(std::text_encoding::id::IBM857) == 2047);
+static_assert(int_least32_t(std::text_encoding::id::IBM860) == 2048);
+static_assert(int_least32_t(std::text_encoding::id::IBM861) == 2049);
+static_assert(int_least32_t(std::text_encoding::id::IBM863) == 2050);
+static_assert(int_least32_t(std::text_encoding::id::IBM864) == 2051);
+static_assert(int_least32_t(std::text_encoding::id::IBM865) == 2052);
+static_assert(int_least32_t(std::text_encoding::id::IBM868) == 2053);
+static_assert(int_least32_t(std::text_encoding::id::IBM869) == 2054);
+static_assert(int_least32_t(std::text_encoding::id::IBM870) == 2055);
+static_assert(int_least32_t(std::text_encoding::id::IBM871) == 2056);
+static_assert(int_least32_t(std::text_encoding::id::IBM880) == 2057);
+static_assert(int_least32_t(std::text_encoding::id::IBM891) == 2058);
+static_assert(int_least32_t(std::text_encoding::id::IBM903) == 2059);
+static_assert(int_least32_t(std::text_encoding::id::IBM904) == 2060);
+static_assert(int_least32_t(std::text_encoding::id::IBM905) == 2061);
+static_assert(int_least32_t(std::text_encoding::id::IBM918) == 2062);
+static_assert(int_least32_t(std::text_encoding::id::IBM1026) == 2063);
+static_assert(int_least32_t(std::text_encoding::id::IBMEBCDICATDE) == 2064);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICATDEA) == 2065);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICCAFR) == 2066);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICDKNO) == 2067);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICDKNOA) == 2068);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICFISE) == 2069);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICFISEA) == 2070);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICFR) == 2071);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICIT) == 2072);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICPT) == 2073);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICES) == 2074);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICESA) == 2075);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICESS) == 2076);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICUK) == 2077);
+static_assert(int_least32_t(std::text_encoding::id::EBCDICUS) == 2078);
+static_assert(int_least32_t(std::text_encoding::id::Unknown8BiT) == 2079);
+static_assert(int_least32_t(std::text_encoding::id::Mnemonic) == 2080);
+static_assert(int_least32_t(std::text_encoding::id::Mnem) == 2081);
+static_assert(int_least32_t(std::text_encoding::id::VISCII) == 2082);
+static_assert(int_least32_t(std::text_encoding::id::VIQR) == 2083);
+static_assert(int_least32_t(std::text_encoding::id::KOI8R) == 2084);
+static_assert(int_least32_t(std::text_encoding::id::HZGB2312) == 2085);
+static_assert(int_least32_t(std::text_encoding::id::IBM866) == 2086);
+static_assert(int_least32_t(std::text_encoding::id::PC775Baltic) == 2087);
+static_assert(int_least32_t(std::text_encoding::id::KOI8U) == 2088);
+static_assert(int_least32_t(std::text_encoding::id::IBM00858) == 2089);
+static_assert(int_least32_t(std::text_encoding::id::IBM00924) == 2090);
+static_assert(int_least32_t(std::text_encoding::id::IBM01140) == 2091);
+static_assert(int_least32_t(std::text_encoding::id::IBM01141) == 2092);
+static_assert(int_least32_t(std::text_encoding::id::IBM01142) == 2093);
+static_assert(int_least32_t(std::text_encoding::id::IBM01143) == 2094);
+static_assert(int_least32_t(std::text_encoding::id::IBM01144) == 2095);
+static_assert(int_least32_t(std::text_encoding::id::IBM01145) == 2096);
+static_assert(int_least32_t(std::text_encoding::id::IBM01146) == 2097);
+static_assert(int_least32_t(std::text_encoding::id::IBM01147) == 2098);
+static_assert(int_least32_t(std::text_encoding::id::IBM01148) == 2099);
+static_assert(int_least32_t(std::text_encoding::id::IBM01149) == 2100);
+static_assert(int_least32_t(std::text_encoding::id::Big5HKSCS) == 2101);
+static_assert(int_least32_t(std::text_encoding::id::IBM1047) == 2102);
+static_assert(int_least32_t(std::text_encoding::id::PTCP154) == 2103);
+static_assert(int_least32_t(std::text_encoding::id::Amiga1251) == 2104);
+static_assert(int_least32_t(std::text_encoding::id::KOI7switched) == 2105);
+static_assert(int_least32_t(std::text_encoding::id::BRF) == 2106);
+static_assert(int_least32_t(std::text_encoding::id::TSCII) == 2107);
+static_assert(int_least32_t(std::text_encoding::id::CP51932) == 2108);
+static_assert(int_least32_t(std::text_encoding::id::windows874) == 2109);
+static_assert(int_least32_t(std::text_encoding::id::windows1250) == 2250);
+static_assert(int_least32_t(std::text_encoding::id::windows1251) == 2251);
+static_assert(int_least32_t(std::text_encoding::id::windows1252) == 2252);
+static_assert(int_least32_t(std::text_encoding::id::windows1253) == 2253);
+static_assert(int_least32_t(std::text_encoding::id::windows1254) == 2254);
+static_assert(int_least32_t(std::text_encoding::id::windows1255) == 2255);
+static_assert(int_least32_t(std::text_encoding::id::windows1256) == 2256);
+static_assert(int_least32_t(std::text_encoding::id::windows1257) == 2257);
+static_assert(int_least32_t(std::text_encoding::id::windows1258) == 2258);
+static_assert(int_least32_t(std::text_encoding::id::TIS620) == 2259);
+static_assert(int_least32_t(std::text_encoding::id::CP50220) == 2260);
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/literal.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/literal.pass.cpp
new file mode 100644
index 0000000000000..949d286ad10fb
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/literal.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding text_encoding::literal() noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <text_encoding>
+
+constexpr bool test() {
+ std::same_as<std::text_encoding> decltype(auto) te = std::text_encoding::literal();
+#ifdef __GNUC_EXECUTION_CHARSET_NAME
+ assert(std::string_view(te.name()) == std::string_view(__GNUC_EXECUTION_CHARSET_NAME));
+#elif defined(__clang_literal_encoding__)
+ assert(std::string_view(te.name()) == std::string_view(__clang_literal_encoding__));
+#else
+ assert(te.mib() = std::text_encoding::id::unknown);
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/begin.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/begin.pass.cpp
new file mode 100644
index 0000000000000..8465196338b41
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/begin.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// constexpr implementation-defined text_encoding::aliases_view::begin() const;
+
+#include <cassert>
+#include <ranges>
+#include <text_encoding>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+ // 1. begin() of an aliases_view from a single text_encoding object are the same.
+ {
+ std::text_encoding te{std::text_encoding::UTF8};
+
+ std::same_as<std::text_encoding::aliases_view> decltype(auto) view1 = te.aliases();
+
+ auto view2 = te.aliases();
+ ASSERT_NOEXCEPT(view1.begin());
+
+ assert(std::ranges::begin(view1) == std::ranges::begin(view2));
+ assert(view1.begin() == view2.begin());
+ }
+
+ // 2. begin() of aliases_views of two text_encoding objects that represent the same ID but hold
diff erent names are the same.
+ {
+ std::text_encoding te1{"ANSI_X3.4-1968"};
+ std::text_encoding te2{"ANSI_X3.4-1986"};
+
+ auto view1 = te1.aliases();
+ auto view2 = te2.aliases();
+
+ assert(view1.begin() == view2.begin());
+ assert(std::ranges::begin(view1) == std::ranges::begin(view2));
+ }
+
+ // 3. begin() of aliases_views of two text_encoding objects that represent
diff erent IDs are
diff erent.
+ {
+ std::text_encoding te1{std::text_encoding::UTF8};
+ std::text_encoding te2{std::text_encoding::ASCII};
+
+ auto view1 = te1.aliases();
+ auto view2 = te2.aliases();
+
+ assert(!(view1.begin() == view2.begin()));
+ assert(!(std::ranges::begin(view1) == std::ranges::begin(view2)));
+ }
+
+ {
+ // 2 aliases
+ std::text_encoding te{std::text_encoding::UTF8};
+
+ auto view = te.aliases();
+
+ assert(view.begin() + 2 == view.end());
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/empty.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/empty.pass.cpp
new file mode 100644
index 0000000000000..367f9216ef5ff
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/empty.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// view_interface<text_encoding::aliases_view>::empty()
+
+#include <cassert>
+#include <ranges>
+#include <text_encoding>
+
+#include "../../test_text_encoding.h"
+
+using id = std::text_encoding::id;
+
+constexpr bool test() {
+ // 1. An alias_view of a text_encoding object for "other" and "unknown" are empty
+ {
+ std::text_encoding te_other{id::other};
+
+ auto other_range = te_other.aliases();
+ assert(other_range.empty());
+ }
+
+ {
+ std::text_encoding te_unknown{id::unknown};
+
+ auto unknown_range = te_unknown.aliases();
+ assert(unknown_range.empty());
+ }
+
+ // 2. An alias_view of a text_encoding object for a known encoding e.g. "UTF-8" is not empty
+ for (auto& data : unique_encoding_data) {
+ std::text_encoding te{id(data.mib)};
+ std::text_encoding::aliases_view range = te.aliases();
+ assert(!range.empty());
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/end.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/end.pass.cpp
new file mode 100644
index 0000000000000..b99517fcf2400
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/end.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding::aliases_view::end()
+
+#include <cassert>
+#include <text_encoding>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+ {
+ std::text_encoding a_other{"foobar"};
+
+ std::text_encoding::aliases_view other_aliases = a_other.aliases();
+
+ // 1. begin() of an aliases_view of "other" is equal to end()
+ ASSERT_NOEXCEPT(other_aliases.end());
+ assert(other_aliases.begin() == other_aliases.end());
+ }
+
+ {
+ std::text_encoding utf8{std::text_encoding::UTF8};
+
+ std::text_encoding::aliases_view aliases = utf8.aliases();
+
+ assert(aliases.begin() != aliases.end());
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/front.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/front.pass.cpp
new file mode 100644
index 0000000000000..86b10aaa2d478
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/front.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding::aliases_view::front()
+
+#include <cassert>
+#include <ranges>
+#include <string_view>
+#include <text_encoding>
+
+using id = std::text_encoding::id;
+
+constexpr bool test() {
+ // 1. An aliases_view from a single text_encoding object returns the same front()
+ {
+ std::text_encoding te{id::UTF8};
+
+ auto view1 = te.aliases();
+ auto view2 = te.aliases();
+
+ assert(std::string_view(view1.front()) == std::string_view(view2.front()));
+ }
+
+ // 2. An aliases_views of two text_encoding objects that represent the same ID but hold
diff erent names return the same front()
+ {
+ std::text_encoding te1{"US-ASCII"};
+ std::text_encoding te2{"ANSI_X3.4-1986"};
+
+ auto view1 = te1.aliases();
+ auto view2 = te2.aliases();
+
+ assert(std::string_view(view1.front()) == std::string_view(view2.front()));
+ }
+
+ // 3. An aliases_views of two text_encoding objects that represent
diff erent IDs return
diff erent front()
+ {
+ std::text_encoding te1{id::UTF8};
+ std::text_encoding te2{id::ASCII};
+
+ auto view1 = te1.aliases();
+ auto view2 = te2.aliases();
+
+ assert(!(std::string_view(view1.front()) == std::string_view(view2.front())));
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/index.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/index.pass.cpp
new file mode 100644
index 0000000000000..d6376dbfa958f
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/index.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding::aliases_view::operator[]
+
+#include <cassert>
+#include <string_view>
+#include <text_encoding>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+ std::text_encoding te(std::text_encoding::id::UTF8);
+ std::text_encoding::aliases_view aliases = te.aliases();
+ auto iter = aliases.begin();
+
+ ASSERT_SAME_TYPE(decltype(aliases[0]), const char*);
+ assert(aliases.size() >= 2 && "assumed below");
+ assert(std::string_view(aliases[0]) == *iter);
+ assert(std::string_view(aliases[1]) == std::string_view(*(iter + 1)));
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/iterator.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/iterator.pass.cpp
new file mode 100644
index 0000000000000..ae9397983e9ef
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/iterator.pass.cpp
@@ -0,0 +1,156 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// text_encoding::aliases_view::iterator (implementation-defined)
+//
+// Implementation is almost trivial, so everything is tested here.
+
+#include <cassert>
+#include <compare>
+#include <concepts>
+#include <string_view>
+#include <text_encoding>
+#include <type_traits>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+ // Test iterator operators.
+ std::text_encoding te{std::text_encoding::ASCII}; // 11 aliases
+
+ auto i = te.aliases().begin();
+ auto j = te.aliases().begin();
+ auto k = te.aliases().end();
+
+ static_assert(std::three_way_comparable<decltype(i)>);
+
+ { // iterator operator return types
+ ASSERT_SAME_TYPE(const char*, decltype(*i));
+ ASSERT_SAME_TYPE(const char*, decltype(i[0]));
+ ASSERT_SAME_TYPE(decltype(i), decltype(i + 1));
+ ASSERT_SAME_TYPE(decltype(i), decltype(1 + i));
+ ASSERT_SAME_TYPE(decltype(i), decltype(i - 1));
+ ASSERT_SAME_TYPE(std::add_lvalue_reference_t<decltype(i)>, decltype(++i));
+ ASSERT_SAME_TYPE(decltype(i), decltype(i++));
+ ASSERT_SAME_TYPE(std::add_lvalue_reference_t<decltype(i)>, decltype(--i));
+ ASSERT_SAME_TYPE(decltype(i), decltype(i--));
+ ASSERT_SAME_TYPE(std::add_lvalue_reference_t<decltype(i)>, decltype(i += 1));
+ ASSERT_SAME_TYPE(std::add_lvalue_reference_t<decltype(i)>, decltype(i -= 1));
+ ASSERT_SAME_TYPE(bool, decltype(i == j));
+ ASSERT_SAME_TYPE(bool, decltype(i != j));
+ ASSERT_SAME_TYPE(bool, decltype(i > j));
+ ASSERT_SAME_TYPE(bool, decltype(i < j));
+ ASSERT_SAME_TYPE(bool, decltype(i >= j));
+ ASSERT_SAME_TYPE(bool, decltype(i <= j));
+ ASSERT_SAME_TYPE(std::strong_ordering, decltype(i <=> j));
+ }
+ {
+ ASSERT_NOEXCEPT(i == j);
+ ASSERT_NOEXCEPT(i != k);
+ ASSERT_NOEXCEPT(i <=> j);
+ ASSERT_NOEXCEPT(i > j);
+ ASSERT_NOEXCEPT(i < j);
+ ASSERT_NOEXCEPT(i >= j);
+ ASSERT_NOEXCEPT(i <= j);
+ assert(i == j);
+ assert(i != k);
+ assert(i <= j);
+ assert(i >= j);
+ assert(i <=> j == std::strong_ordering::equal);
+ assert(std::string_view(*i) == std::string_view(*j));
+ }
+ {
+ ASSERT_NOEXCEPT(*i);
+ ASSERT_NOEXCEPT(i[0]);
+ assert(std::string_view(i[0]) == std::string_view(j[0]));
+ assert(std::string_view(i[1]) != std::string_view(j[3]));
+ }
+ {
+ i++;
+ assert(i > j);
+ assert(i >= j);
+ assert(!(i <= j));
+ assert(i <=> j == std::strong_ordering::greater);
+ assert(i - j == 1);
+ assert(std::string_view(*i) != std::string_view(*j));
+ }
+ {
+ i--;
+ assert(i == te.aliases().begin());
+ assert(i == j);
+ assert(i != k);
+ std::same_as<const char*> decltype(auto) str1 = *i;
+ std::same_as<const char*> decltype(auto) str2 = *j;
+ assert(std::string_view(str1) == std::string_view(str2));
+ }
+ {
+ i++;
+ j++;
+ assert(i != te.aliases().begin());
+ assert(i == j);
+ assert(i != k);
+ assert(std::string_view(*i) == std::string_view(*j));
+ }
+ {
+ ASSERT_NOEXCEPT(i + 1);
+ ASSERT_NOEXCEPT(1 + i);
+ ASSERT_NOEXCEPT(i - 1);
+ std::same_as<decltype(j)> decltype(auto) temp = i + 2;
+ assert(i != temp);
+ assert(std::string_view(*temp) != std::string_view(*j));
+ std::same_as<decltype(j)> decltype(auto) temp2 = temp - 2;
+ assert(std::string_view(*temp2) == std::string_view(*j));
+ }
+ {
+ ASSERT_NOEXCEPT(i - j);
+ assert(i - j == 0);
+ assert(k - i > 0);
+ }
+ {
+ ASSERT_NOEXCEPT(i++);
+ ASSERT_NOEXCEPT(++i);
+ ASSERT_NOEXCEPT(i--);
+ ASSERT_NOEXCEPT(--i);
+ std::same_as<std::add_lvalue_reference_t<decltype(i)>> decltype(auto) temp = ++i;
+ assert(temp == i);
+ assert(&temp == &i);
+
+ std::same_as<decltype(j)> decltype(auto) temp2 = j++;
+ assert(temp2 == j - 1);
+ assert(i == j);
+ }
+ {
+ ASSERT_NOEXCEPT(i += 2);
+ ASSERT_NOEXCEPT(i -= 2);
+ i += 2;
+ j += 3;
+
+ auto tempi = i;
+ auto tempj = j;
+ assert(i != j);
+ assert((i <=> j) == std::strong_ordering::less);
+ i -= 2;
+ j -= 3;
+ assert(i == j);
+ assert(i != tempi && (tempi - i) == 2);
+ assert(j != tempj && (tempj - j) == 3);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/operator-bool.pass.cpp b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/operator-bool.pass.cpp
new file mode 100644
index 0000000000000..9d63ff4cdfccd
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/text_encoding.members/text_encoding.aliases_view/operator-bool.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+
+// view_interface<text_encoding::aliases_view>::operator bool()
+
+#include <cassert>
+#include <ranges>
+#include <text_encoding>
+
+#include "../../test_text_encoding.h"
+
+using id = std::text_encoding::id;
+
+constexpr bool test() {
+ // 1. An alias_view of a text_encoding object for "other" and "unknown" are empty
+ {
+ {
+ std::text_encoding te_other{id::other};
+ auto other_range = te_other.aliases();
+ assert(!bool(other_range));
+ }
+
+ {
+ std::text_encoding te_unknown{id::unknown};
+ auto unknown_range = te_unknown.aliases();
+ assert(!bool(unknown_range));
+ }
+ }
+
+ // 2. An alias_view of a text_encoding object for a known encoding e.g. "UTF-8" is not empty
+ {
+ for (auto& data : unique_encoding_data) {
+ std::text_encoding te{id(data.mib)};
+ auto range = te.aliases();
+ assert(bool(range));
+ }
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/text/text_encoding/trivially_copyable.compile.pass.cpp b/libcxx/test/std/text/text_encoding/trivially_copyable.compile.pass.cpp
new file mode 100644
index 0000000000000..7f555a289641a
--- /dev/null
+++ b/libcxx/test/std/text/text_encoding/trivially_copyable.compile.pass.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <text_encoding>
+// Class text_encoding is a trivially copyable type ([basic.types.general]).
+
+#include <text_encoding>
+#include <type_traits>
+
+static_assert(std::is_trivially_copyable_v<std::text_encoding>);
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 56b5d620d73a4..83d97605213ad 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1417,7 +1417,6 @@ def add_version_header(tc):
"c++26": 202306 # P1885R12 Naming Text Encodings to Demystify Them
},
"headers": ["text_encoding"],
- "unimplemented": True,
},
{
"name": "__cpp_lib_three_way_comparison",
diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py
index 5e4c98675e41b..dbb1d9e040a33 100644
--- a/libcxx/utils/libcxx/header_information.py
+++ b/libcxx/utils/libcxx/header_information.py
@@ -172,7 +172,6 @@ def __hash__(self) -> int:
"spanstream",
"stacktrace",
"stdfloat",
- "text_encoding",
]))
# Undeprecate headers that are deprecated in C++17 and removed in C++20.
diff --git a/libcxx/utils/libcxx/test/features/availability.py b/libcxx/utils/libcxx/test/features/availability.py
index bae7b33d2130b..c0f2a3d4cdc88 100644
--- a/libcxx/utils/libcxx/test/features/availability.py
+++ b/libcxx/utils/libcxx/test/features/availability.py
@@ -203,4 +203,12 @@
cfg.available_features,
),
),
+ # Tests that require std::text_encoding::environment() in the built library
+ Feature(
+ name="availability-te-environment-missing",
+ when=lambda cfg: BooleanExpression.evaluate(
+ "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-23)",
+ cfg.available_features,
+ ),
+ ),
]
More information about the libcxx-commits
mailing list