[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