[libcxx-commits] [libcxx] [libcxx][format] Partial P3391R2: `constexpr` `std::to_string` and `std::to_wstring` (PR #228535)

Lucas Mellone via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 7 07:52:59 PDT 2026


https://github.com/lknknm updated https://github.com/llvm/llvm-project/pull/228535

>From fb9d5ee3a740c5622f7095a060c8183e50119f66 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 2 Oct 2026 19:19:44 +0200
Subject: [PATCH 01/17] initial additions

---
 libcxx/include/__format/format_functions.h |  6 +++---
 libcxx/include/string                      | 24 +++++++++++-----------
 libcxx/src/string.cpp                      | 24 +++++++++++-----------
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index 8f214a493a49e..727fbb1c6ff83 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -351,15 +351,15 @@ struct __dynamic_format_string {
   friend struct basic_format_string;
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __dynamic_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __dynamic_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {}
 
   __dynamic_format_string(const __dynamic_format_string&)            = delete;
   __dynamic_format_string& operator=(const __dynamic_format_string&) = delete;
 };
 
-_LIBCPP_HIDE_FROM_ABI inline __dynamic_format_string<char> dynamic_format(string_view __fmt) noexcept { return __fmt; }
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 inline __dynamic_format_string<char> dynamic_format(string_view __fmt) noexcept { return __fmt; }
 #    if _LIBCPP_HAS_WIDE_CHARACTERS
-_LIBCPP_HIDE_FROM_ABI inline __dynamic_format_string<wchar_t> dynamic_format(wstring_view __fmt) noexcept {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 inline __dynamic_format_string<wchar_t> dynamic_format(wstring_view __fmt) noexcept {
   return __fmt;
 }
 #    endif
diff --git a/libcxx/include/string b/libcxx/include/string
index a27f9344916d1..ff6ea409bd53f 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -3825,12 +3825,12 @@ stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
 
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(int __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
@@ -3849,12 +3849,12 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
 
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(int __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
diff --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp
index b55f9ff5c9a43..79675db7d5065 100644
--- a/libcxx/src/string.cpp
+++ b/libcxx/src/string.cpp
@@ -342,20 +342,20 @@ S i_to_string(V v) {
 
 } // unnamed namespace
 
-string to_string(int val) { return i_to_string< string>(val); }
-string to_string(long val) { return i_to_string< string>(val); }
-string to_string(long long val) { return i_to_string< string>(val); }
-string to_string(unsigned val) { return i_to_string< string>(val); }
-string to_string(unsigned long val) { return i_to_string< string>(val); }
-string to_string(unsigned long long val) { return i_to_string< string>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(int val) { return i_to_string< string>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long val) { return i_to_string< string>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long long val) { return i_to_string< string>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned val) { return i_to_string< string>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long val) { return i_to_string< string>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long long val) { return i_to_string< string>(val); }
 
 #if _LIBCPP_HAS_WIDE_CHARACTERS
-wstring to_wstring(int val) { return i_to_string<wstring>(val); }
-wstring to_wstring(long val) { return i_to_string<wstring>(val); }
-wstring to_wstring(long long val) { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(int val) { return i_to_string<wstring>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long val) { return i_to_string<wstring>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long long val) { return i_to_string<wstring>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
+_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
 #endif
 
 string to_string(float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }

>From ea3b44a9465e8b03f17a50e62d827d2ded41a92d Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 2 Oct 2026 19:27:08 +0200
Subject: [PATCH 02/17] add: mark P3391R2 as Complete

---
 libcxx/docs/Status/Cxx26Papers.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index f3cdf8c53bab4..ef9e5d5c38f82 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -175,7 +175,7 @@
 "`P3887R1 <https://wg21.link/P3887R1>`__","Make ``when_all`` a Ronseal Algorithm","2025-11 (Kona)","","","`#171289 <https://github.com/llvm/llvm-project/issues/171289>`__",""
 "`P3923R0 <https://wg21.link/P3923R0>`__","Additional NB comment resolutions for Kona 2025","2025-11 (Kona)","","","`#171290 <https://github.com/llvm/llvm-project/issues/171290>`__",""
 "`P3371R5 <https://wg21.link/P3371R5>`__","Fix C++26 by making the rank-1, rank-2, rank-k, and rank-2k updates consistent with the BLAS","2025-11 (Kona)","","","`#171291 <https://github.com/llvm/llvm-project/issues/171291>`__",""
-"`P3391R2 <https://wg21.link/P3391R2>`__","``constexpr`` ``std::format``","2025-11 (Kona)","","","`#171292 <https://github.com/llvm/llvm-project/issues/171292>`__",""
+"`P3391R2 <https://wg21.link/P3391R2>`__","``constexpr`` ``std::format``","2025-11 (Kona)","|Complete|","24","`#171292 <https://github.com/llvm/llvm-project/issues/171292>`__",""
 "`P3913R1 <https://wg21.link/P3913R1>`__","Optimize ``for std::optional`` in range adaptors","2025-11 (Kona)","","","`#171294 <https://github.com/llvm/llvm-project/issues/171294>`__",""
 "","","","","","",""
 "`P3726R2 <https://wg21.link/P3726R2>`__","Adjustments to Union Lifetime Rules","2026-03 (Croydon)","","","`#189560 <https://github.com/llvm/llvm-project/issues/189560>`__",""

>From 8842de8059d6b1665a6a5b879206526c0dd71672 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 2 Oct 2026 19:35:18 +0200
Subject: [PATCH 03/17] add: constexpr to vformat_to

---
 libcxx/include/__format/format_functions.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index 727fbb1c6ff83..3019fdbb167a0 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -425,13 +425,14 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(_OutIt __out_it,
 // https://reviews.llvm.org/D110499#inline-1180704
 // TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
 template <output_iterator<const char&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt 
+vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
   return std::__vformat_to(std::move(__out_it), __fmt, __args);
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
   return std::__vformat_to(std::move(__out_it), __fmt, __args);
 }

>From 9a8811fd09b1600724f59c8455477e638475cbb1 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 2 Oct 2026 20:01:23 +0200
Subject: [PATCH 04/17] fewer other updates

---
 libcxx/include/__format/format_functions.h | 21 +++++++++++----------
 libcxx/include/format                      |  4 ++--
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index 3019fdbb167a0..2cdcf79b05bf2 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -439,14 +439,14 @@ vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
 #  endif
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_format_args(__args...));
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_wformat_args(__args...));
 }
@@ -493,7 +493,8 @@ template <class _CharT>
 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
 // fires too eagerly, see http://llvm.org/PR61563.
 template <class = void>
-[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(string_view __fmt, format_args __args) {
+[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string 
+vformat(string_view __fmt, format_args __args) {
   auto __result = __format::__try_constant_folding(__fmt, __args);
   if (__result.has_value())
     return *std::move(__result);
@@ -506,7 +507,7 @@ template <class = void>
 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
 // fires too eagerly, see http://llvm.org/PR61563.
 template <class = void>
-[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
+[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
 vformat(wstring_view __fmt, wformat_args __args) {
   auto __result = __format::__try_constant_folding(__fmt, __args);
   if (__result.has_value())
@@ -518,14 +519,14 @@ vformat(wstring_view __fmt, wformat_args __args) {
 #  endif
 
 template <class... _Args>
-[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
+[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
 format(format_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat(__fmt.get(), std::make_format_args(__args...));
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <class... _Args>
-[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
+[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
 format(wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat(__fmt.get(), std::make_wformat_args(__args...));
 }
@@ -544,14 +545,14 @@ __vformat_to_n(_OutIt __out_it,
 }
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformat_to_n<format_context>(std::move(__out_it), __n, __fmt.get(), std::make_format_args(__args...));
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformat_to_n<wformat_context>(std::move(__out_it), __n, __fmt.get(), std::make_wformat_args(__args...));
 }
@@ -566,14 +567,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt,
 }
 
 template <class... _Args>
-[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
+[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_format_args(__args...)});
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <class... _Args>
-[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
+[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_wformat_args(__args...)});
 }
diff --git a/libcxx/include/format b/libcxx/include/format
index d89c8d8b0ae89..fa7136b6c44a8 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -179,10 +179,10 @@ namespace std {
   template<class Context, class... Args> struct format-arg-store;    // exposition only
 
   template<class Context = format_context, class... Args>
-    format-arg-store<Context, Args...>
+    constexpr format-arg-store<Context, Args...>
       make_format_args(Args&... args);
   template<class... Args>
-    format-arg-store<wformat_context, Args...>
+    constexpr format-arg-store<wformat_context, Args...>
       make_wformat_args(Args&... args);
 
   // [format.error], class format_error

>From f0881ce8ef75f34201b6cdcd37fe4792162898af Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Fri, 2 Oct 2026 20:07:37 +0200
Subject: [PATCH 05/17] add: constexpr since C++26 comments

---
 libcxx/include/format | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/libcxx/include/format b/libcxx/include/format
index fa7136b6c44a8..5f83ef33e5642 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -47,7 +47,7 @@ namespace std {
     basic_string_view<charT> str;                               // exposition-only
 
   public:
-    dynamic-format-string(basic_string_view<charT> s) noexcept : str(s) {}
+    dynamic-format-string(basic_string_view<charT> s) noexcept : str(s) {} // constexpr since C++26
 
     dynamic-format-string(const dynamic-format-string&) = delete;
     dynamic-format-string& operator=(const dynamic-format-string&) = delete;
@@ -62,32 +62,32 @@ namespace std {
 
   // [format.functions], formatting functions
   template<class... Args>
-    string format(format-string<Args...> fmt, Args&&... args);
+    string format(format-string<Args...> fmt, Args&&... args);   // constexpr since C++26
   template<class... Args>
-    wstring format(wformat-string<Args...> fmt, Args&&... args);
+    wstring format(wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
   template<class... Args>
     string format(const locale& loc, format-string<Args...> fmt, Args&&... args);
   template<class... Args>
     wstring format(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
 
-  string vformat(string_view fmt, format_args args);
-  wstring vformat(wstring_view fmt, wformat_args args);
+  string vformat(string_view fmt, format_args args);    // constexpr since C++26
+  wstring vformat(wstring_view fmt, wformat_args args); // constexpr since C++26
   string vformat(const locale& loc, string_view fmt, format_args args);
   wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
 
   template<class Out, class... Args>
-    Out format_to(Out out, format-string<Args...> fmt, Args&&... args);
+    Out format_to(Out out, format-string<Args...> fmt, Args&&... args);  // constexpr since C++26
   template<class Out, class... Args>
-    Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args);
+    Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
   template<class Out, class... Args>
     Out format_to(Out out, const locale& loc, format-string<Args...> fmt, Args&&... args);
   template<class Out, class... Args>
     Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, Args&&... args);
 
   template<class Out>
-    Out vformat_to(Out out, string_view fmt, format_args args);
+    Out vformat_to(Out out, string_view fmt, format_args args);   // constexpr since C++26
   template<class Out>
-    Out vformat_to(Out out, wstring_view fmt, wformat_args args);
+    Out vformat_to(Out out, wstring_view fmt, wformat_args args); // constexpr since C++26
   template<class Out>
     Out vformat_to(Out out, const locale& loc, string_view fmt,
                    format_args char> args);
@@ -101,10 +101,10 @@ namespace std {
   };
   template<class Out, class... Args>
     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
-                                        format-string<Args...> fmt, Args&&... args);
+                                        format-string<Args...> fmt, Args&&... args);  // constexpr since C++26
   template<class Out, class... Args>
     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
-                                        wformat-string<Args...> fmt, Args&&... args);
+                                        wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
   template<class Out, class... Args>
     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
                                         const locale& loc, format-string<Args...> fmt,
@@ -115,9 +115,9 @@ namespace std {
                                         Args&&... args);
 
   template<class... Args>
-    size_t formatted_size(format-string<Args...> fmt, Args&&... args);
+    size_t formatted_size(format-string<Args...> fmt, Args&&... args);  // constexpr since C++26
   template<class... Args>
-    size_t formatted_size(wformat-string<Args...> fmt, Args&&... args);
+    size_t formatted_size(wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
   template<class... Args>
     size_t formatted_size(const locale& loc, format-string<Args...> fmt, Args&&... args);
   template<class... Args>

>From eb506961302e60dcb0f86252aae9730ccb3a93c9 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 14:01:35 +0200
Subject: [PATCH 06/17] split: remove constexpr from format functions for now

---
 libcxx/docs/Status/Cxx26Papers.csv         |  2 +-
 libcxx/include/__format/format_functions.h | 32 ++++++++++------------
 libcxx/include/format                      | 30 ++++++++++----------
 3 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index ef9e5d5c38f82..2aa7969b3cd10 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -175,7 +175,7 @@
 "`P3887R1 <https://wg21.link/P3887R1>`__","Make ``when_all`` a Ronseal Algorithm","2025-11 (Kona)","","","`#171289 <https://github.com/llvm/llvm-project/issues/171289>`__",""
 "`P3923R0 <https://wg21.link/P3923R0>`__","Additional NB comment resolutions for Kona 2025","2025-11 (Kona)","","","`#171290 <https://github.com/llvm/llvm-project/issues/171290>`__",""
 "`P3371R5 <https://wg21.link/P3371R5>`__","Fix C++26 by making the rank-1, rank-2, rank-k, and rank-2k updates consistent with the BLAS","2025-11 (Kona)","","","`#171291 <https://github.com/llvm/llvm-project/issues/171291>`__",""
-"`P3391R2 <https://wg21.link/P3391R2>`__","``constexpr`` ``std::format``","2025-11 (Kona)","|Complete|","24","`#171292 <https://github.com/llvm/llvm-project/issues/171292>`__",""
+"`P3391R2 <https://wg21.link/P3391R2>`__","``constexpr`` ``std::format``","2025-11 (Kona)","|Partial|","24","`#171292 <https://github.com/llvm/llvm-project/issues/171292>`__",""
 "`P3913R1 <https://wg21.link/P3913R1>`__","Optimize ``for std::optional`` in range adaptors","2025-11 (Kona)","","","`#171294 <https://github.com/llvm/llvm-project/issues/171294>`__",""
 "","","","","","",""
 "`P3726R2 <https://wg21.link/P3726R2>`__","Adjustments to Union Lifetime Rules","2026-03 (Croydon)","","","`#189560 <https://github.com/llvm/llvm-project/issues/189560>`__",""
diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index 2cdcf79b05bf2..8f214a493a49e 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -351,15 +351,15 @@ struct __dynamic_format_string {
   friend struct basic_format_string;
 
 public:
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __dynamic_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {}
+  _LIBCPP_HIDE_FROM_ABI __dynamic_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {}
 
   __dynamic_format_string(const __dynamic_format_string&)            = delete;
   __dynamic_format_string& operator=(const __dynamic_format_string&) = delete;
 };
 
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 inline __dynamic_format_string<char> dynamic_format(string_view __fmt) noexcept { return __fmt; }
+_LIBCPP_HIDE_FROM_ABI inline __dynamic_format_string<char> dynamic_format(string_view __fmt) noexcept { return __fmt; }
 #    if _LIBCPP_HAS_WIDE_CHARACTERS
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 inline __dynamic_format_string<wchar_t> dynamic_format(wstring_view __fmt) noexcept {
+_LIBCPP_HIDE_FROM_ABI inline __dynamic_format_string<wchar_t> dynamic_format(wstring_view __fmt) noexcept {
   return __fmt;
 }
 #    endif
@@ -425,28 +425,27 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(_OutIt __out_it,
 // https://reviews.llvm.org/D110499#inline-1180704
 // TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
 template <output_iterator<const char&> _OutIt>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt 
-vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
   return std::__vformat_to(std::move(__out_it), __fmt, __args);
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
   return std::__vformat_to(std::move(__out_it), __fmt, __args);
 }
 #  endif
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_format_args(__args...));
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
 format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_wformat_args(__args...));
 }
@@ -493,8 +492,7 @@ template <class _CharT>
 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
 // fires too eagerly, see http://llvm.org/PR61563.
 template <class = void>
-[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string 
-vformat(string_view __fmt, format_args __args) {
+[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(string_view __fmt, format_args __args) {
   auto __result = __format::__try_constant_folding(__fmt, __args);
   if (__result.has_value())
     return *std::move(__result);
@@ -507,7 +505,7 @@ vformat(string_view __fmt, format_args __args) {
 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
 // fires too eagerly, see http://llvm.org/PR61563.
 template <class = void>
-[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
+[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
 vformat(wstring_view __fmt, wformat_args __args) {
   auto __result = __format::__try_constant_folding(__fmt, __args);
   if (__result.has_value())
@@ -519,14 +517,14 @@ vformat(wstring_view __fmt, wformat_args __args) {
 #  endif
 
 template <class... _Args>
-[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
+[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
 format(format_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat(__fmt.get(), std::make_format_args(__args...));
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <class... _Args>
-[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
+[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
 format(wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::vformat(__fmt.get(), std::make_wformat_args(__args...));
 }
@@ -545,14 +543,14 @@ __vformat_to_n(_OutIt __out_it,
 }
 
 template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformat_to_n<format_context>(std::move(__out_it), __n, __fmt.get(), std::make_format_args(__args...));
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
+_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformat_to_n<wformat_context>(std::move(__out_it), __n, __fmt.get(), std::make_wformat_args(__args...));
 }
@@ -567,14 +565,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt,
 }
 
 template <class... _Args>
-[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
+[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_format_args(__args...)});
 }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
 template <class... _Args>
-[[nodiscard]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
+[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
 formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
   return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_wformat_args(__args...)});
 }
diff --git a/libcxx/include/format b/libcxx/include/format
index 5f83ef33e5642..d89c8d8b0ae89 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -47,7 +47,7 @@ namespace std {
     basic_string_view<charT> str;                               // exposition-only
 
   public:
-    dynamic-format-string(basic_string_view<charT> s) noexcept : str(s) {} // constexpr since C++26
+    dynamic-format-string(basic_string_view<charT> s) noexcept : str(s) {}
 
     dynamic-format-string(const dynamic-format-string&) = delete;
     dynamic-format-string& operator=(const dynamic-format-string&) = delete;
@@ -62,32 +62,32 @@ namespace std {
 
   // [format.functions], formatting functions
   template<class... Args>
-    string format(format-string<Args...> fmt, Args&&... args);   // constexpr since C++26
+    string format(format-string<Args...> fmt, Args&&... args);
   template<class... Args>
-    wstring format(wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
+    wstring format(wformat-string<Args...> fmt, Args&&... args);
   template<class... Args>
     string format(const locale& loc, format-string<Args...> fmt, Args&&... args);
   template<class... Args>
     wstring format(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
 
-  string vformat(string_view fmt, format_args args);    // constexpr since C++26
-  wstring vformat(wstring_view fmt, wformat_args args); // constexpr since C++26
+  string vformat(string_view fmt, format_args args);
+  wstring vformat(wstring_view fmt, wformat_args args);
   string vformat(const locale& loc, string_view fmt, format_args args);
   wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
 
   template<class Out, class... Args>
-    Out format_to(Out out, format-string<Args...> fmt, Args&&... args);  // constexpr since C++26
+    Out format_to(Out out, format-string<Args...> fmt, Args&&... args);
   template<class Out, class... Args>
-    Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
+    Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args);
   template<class Out, class... Args>
     Out format_to(Out out, const locale& loc, format-string<Args...> fmt, Args&&... args);
   template<class Out, class... Args>
     Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, Args&&... args);
 
   template<class Out>
-    Out vformat_to(Out out, string_view fmt, format_args args);   // constexpr since C++26
+    Out vformat_to(Out out, string_view fmt, format_args args);
   template<class Out>
-    Out vformat_to(Out out, wstring_view fmt, wformat_args args); // constexpr since C++26
+    Out vformat_to(Out out, wstring_view fmt, wformat_args args);
   template<class Out>
     Out vformat_to(Out out, const locale& loc, string_view fmt,
                    format_args char> args);
@@ -101,10 +101,10 @@ namespace std {
   };
   template<class Out, class... Args>
     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
-                                        format-string<Args...> fmt, Args&&... args);  // constexpr since C++26
+                                        format-string<Args...> fmt, Args&&... args);
   template<class Out, class... Args>
     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
-                                        wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
+                                        wformat-string<Args...> fmt, Args&&... args);
   template<class Out, class... Args>
     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
                                         const locale& loc, format-string<Args...> fmt,
@@ -115,9 +115,9 @@ namespace std {
                                         Args&&... args);
 
   template<class... Args>
-    size_t formatted_size(format-string<Args...> fmt, Args&&... args);  // constexpr since C++26
+    size_t formatted_size(format-string<Args...> fmt, Args&&... args);
   template<class... Args>
-    size_t formatted_size(wformat-string<Args...> fmt, Args&&... args); // constexpr since C++26
+    size_t formatted_size(wformat-string<Args...> fmt, Args&&... args);
   template<class... Args>
     size_t formatted_size(const locale& loc, format-string<Args...> fmt, Args&&... args);
   template<class... Args>
@@ -179,10 +179,10 @@ namespace std {
   template<class Context, class... Args> struct format-arg-store;    // exposition only
 
   template<class Context = format_context, class... Args>
-    constexpr format-arg-store<Context, Args...>
+    format-arg-store<Context, Args...>
       make_format_args(Args&... args);
   template<class... Args>
-    constexpr format-arg-store<wformat_context, Args...>
+    format-arg-store<wformat_context, Args...>
       make_wformat_args(Args&... args);
 
   // [format.error], class format_error

>From 5a147d053e6bbb06f9e047e24f958efdb7977355 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 14:57:51 +0200
Subject: [PATCH 07/17] copy: strategy from sstream into to_string method for
 constexpr usage

---
 libcxx/include/string | 58 ++++++++++++++++++++++++++++++++++---------
 libcxx/src/string.cpp | 24 +++++++++---------
 2 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index ff6ea409bd53f..a6364fc329e96 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -597,6 +597,7 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
 #  include <__algorithm/min.h>
 #  include <__algorithm/remove.h>
 #  include <__algorithm/remove_if.h>
+#  include <__charconv/to_chars_integral.h>
 #  include <__assert>
 #  include <__config>
 #  include <__cstddef/size_t.h>
@@ -3825,12 +3826,45 @@ stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
 
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(int __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long long __val);
+# if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
+# else
+template <class _StringT, class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _StringT __to_string_integral(_Tp __val) {
+  //  numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
+  //  For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
+  //  so we need +1 here.
+  char __buf[numeric_limits<_Tp>::digits10 + 2]; // +1 for minus, +1 for digits10
+  auto __res = std::to_chars(__buf, __buf + sizeof(__buf), __val);
+  _LIBCPP_ASSERT_INTERNAL(__res.ec == errc(), "__buf must be large enough to accomodate the value");
+  return _StringT(__buf, __res.ptr);
+}
+
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI constexpr string to_string(int __val) {
+    return std::__to_string_integral<string>(__val);
+}
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val) {
+    return std::__to_string_integral<string>(__val);
+}
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val) {
+    return std::__to_string_integral<string>(__val);
+}
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val) {
+    return std::__to_string_integral<string>(__val);
+}
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val) {
+    return std::__to_string_integral<string>(__val);
+}
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val) {
+    return std::__to_string_integral<string>(__val);
+}
+# endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
@@ -3849,12 +3883,12 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
 
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(int __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long long __val);
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
diff --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp
index 79675db7d5065..b55f9ff5c9a43 100644
--- a/libcxx/src/string.cpp
+++ b/libcxx/src/string.cpp
@@ -342,20 +342,20 @@ S i_to_string(V v) {
 
 } // unnamed namespace
 
-_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(int val) { return i_to_string< string>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long val) { return i_to_string< string>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(long long val) { return i_to_string< string>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned val) { return i_to_string< string>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long val) { return i_to_string< string>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 string to_string(unsigned long long val) { return i_to_string< string>(val); }
+string to_string(int val) { return i_to_string< string>(val); }
+string to_string(long val) { return i_to_string< string>(val); }
+string to_string(long long val) { return i_to_string< string>(val); }
+string to_string(unsigned val) { return i_to_string< string>(val); }
+string to_string(unsigned long val) { return i_to_string< string>(val); }
+string to_string(unsigned long long val) { return i_to_string< string>(val); }
 
 #if _LIBCPP_HAS_WIDE_CHARACTERS
-_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(int val) { return i_to_string<wstring>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long val) { return i_to_string<wstring>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(long long val) { return i_to_string<wstring>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
-_LIBCPP_CONSTEXPR_SINCE_CXX26 wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
+wstring to_wstring(int val) { return i_to_string<wstring>(val); }
+wstring to_wstring(long val) { return i_to_string<wstring>(val); }
+wstring to_wstring(long long val) { return i_to_string<wstring>(val); }
+wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); }
+wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); }
+wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
 #endif
 
 string to_string(float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); }

>From 9b9254be25d96e101eecf0cb225c72186753109e Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 15:10:10 +0200
Subject: [PATCH 08/17] propagate changes to to_wstring

---
 libcxx/include/string | 46 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index a6364fc329e96..4ac4577e852a9 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -3845,23 +3845,23 @@ _LIBCPP_HIDE_FROM_ABI constexpr _StringT __to_string_integral(_Tp __val) {
   return _StringT(__buf, __res.ptr);
 }
 
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI constexpr string to_string(int __val) {
-    return std::__to_string_integral<string>(__val);
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr string to_string(int __val) {
+  return std::__to_string_integral<string>(__val);
 }
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val) {
-    return std::__to_string_integral<string>(__val);
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr string to_string(unsigned __val) {
+  return std::__to_string_integral<string>(__val);
 }
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val) {
-    return std::__to_string_integral<string>(__val);
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr string to_string(long __val) {
+  return std::__to_string_integral<string>(__val);
 }
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val) {
-    return std::__to_string_integral<string>(__val);
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr string to_string(unsigned long __val) {
+  return std::__to_string_integral<string>(__val);
 }
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val) {
-    return std::__to_string_integral<string>(__val);
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr string to_string(long long __val) {
+  return std::__to_string_integral<string>(__val);
 }
-[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val) {
-    return std::__to_string_integral<string>(__val);
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr string to_string(unsigned long long __val) {
+  return std::__to_string_integral<string>(__val);
 }
 # endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 
@@ -3883,15 +3883,37 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
 
+# if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
+# else 
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(int __val) {
+  return std::__to_string_integral<wstring>(__val);
+}
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(unsigned __val) {
+  return std::__to_string_integral<wstring>(__val);
+}
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(long __val) {
+  return std::__to_string_integral<wstring>(__val);
+}
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(unsigned long __val) {
+  return std::__to_string_integral<wstring>(__val);
+}
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(long long __val) {
+  return std::__to_string_integral<wstring>(__val);
+}
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(unsigned long long __val) {
+  return std::__to_string_integral<wstring>(__val);
+}
+# endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
+
 #  endif // _LIBCPP_HAS_WIDE_CHARACTERS
 
 template <class _CharT, class _Traits, class _Allocator>

>From 741a6c03beb0860611a1078a5f507b71aeceb244 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 15:13:08 +0200
Subject: [PATCH 09/17] add: constexpr since C++26 comment

---
 libcxx/include/string | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index 4ac4577e852a9..3b3f296611e51 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -542,12 +542,12 @@ float       stof (const string& str, size_t* idx = nullptr);
 double      stod (const string& str, size_t* idx = nullptr);
 long double stold(const string& str, size_t* idx = nullptr);
 
-string to_string(int val);
-string to_string(unsigned val);
-string to_string(long val);
-string to_string(unsigned long val);
-string to_string(long long val);
-string to_string(unsigned long long val);
+string to_string(int val);                // constexpr since C++26
+string to_string(unsigned val);           // constexpr since C++26
+string to_string(long val);               // constexpr since C++26
+string to_string(unsigned long val);      // constexpr since C++26
+string to_string(long long val);          // constexpr since C++26
+string to_string(unsigned long long val); // constexpr since C++26
 string to_string(float val);
 string to_string(double val);
 string to_string(long double val);
@@ -562,12 +562,12 @@ float       stof (const wstring& str, size_t* idx = nullptr);
 double      stod (const wstring& str, size_t* idx = nullptr);
 long double stold(const wstring& str, size_t* idx = nullptr);
 
-wstring to_wstring(int val);
-wstring to_wstring(unsigned val);
-wstring to_wstring(long val);
-wstring to_wstring(unsigned long val);
-wstring to_wstring(long long val);
-wstring to_wstring(unsigned long long val);
+wstring to_wstring(int val);                // constexpr since C++26
+wstring to_wstring(unsigned val);           // constexpr since C++26
+wstring to_wstring(long val);               // constexpr since C++26
+wstring to_wstring(unsigned long val);      // constexpr since C++26
+wstring to_wstring(long long val);          // constexpr since C++26
+wstring to_wstring(unsigned long long val); // constexpr since C++26
 wstring to_wstring(float val);
 wstring to_wstring(double val);
 wstring to_wstring(long double val);

>From b6e811cddfc659addf6794dd4d19b0d0006092a7 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 15:16:08 +0200
Subject: [PATCH 10/17] tentative: fix clang-format

---
 libcxx/include/string | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index 3b3f296611e51..322b6b55a7809 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -597,8 +597,8 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
 #  include <__algorithm/min.h>
 #  include <__algorithm/remove.h>
 #  include <__algorithm/remove_if.h>
-#  include <__charconv/to_chars_integral.h>
 #  include <__assert>
+#  include <__charconv/to_chars_integral.h>
 #  include <__config>
 #  include <__cstddef/size_t.h>
 #  include <__debug_utils/sanitizers.h>
@@ -3826,14 +3826,14 @@ stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
 
-# if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+#  if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
-# else
+#  else
 template <class _StringT, class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr _StringT __to_string_integral(_Tp __val) {
   //  numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
@@ -3863,7 +3863,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _StringT __to_string_integral(_Tp __val) {
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr string to_string(unsigned long long __val) {
   return std::__to_string_integral<string>(__val);
 }
-# endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+#  endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
@@ -3883,14 +3883,14 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
 
-# if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+#  if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
-# else 
+#  else 
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(int __val) {
   return std::__to_string_integral<wstring>(__val);
 }
@@ -3909,7 +3909,7 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(unsigned long long __val) {
   return std::__to_string_integral<wstring>(__val);
 }
-# endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+#  endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);

>From 23cba05bee5e9b7ac0fe87d1e80d14eacf79d820 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 15:22:06 +0200
Subject: [PATCH 11/17] update: to_string test

---
 .../string.conversions/to_string.pass.cpp     | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/libcxx/test/std/strings/string.conversions/to_string.pass.cpp b/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
index 4731a072e8910..f8fee6d889f36 100644
--- a/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
+++ b/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
@@ -102,6 +102,21 @@ void test_float() {
   }
 }
 
+# if TEST_STD_VER >= 26
+constexpr bool test_constexpr() {
+  assert(std::to_string(0) == "0");
+  assert(std::to_string(-12345) == "-12345");
+  assert(std::to_string(12345u) == "12345");
+  assert(std::to_string(-12345l) == "-12345");
+  assert(std::to_string(12345ul) == "12345");
+  assert(std::to_string(-12345ll) == "-12345");
+  assert(std::to_string(12345ull) == "12345");
+  assert(std::to_string(std::numeric_limits<long long>::min()) == "-9223372036854775808");
+  assert(std::to_string(std::numeric_limits<unsigned long long>::max()) == "18446744073709551615");
+  return true;
+}
+# endif
+
 int main(int, char**) {
   test_signed<int>();
   test_signed<long>();
@@ -113,5 +128,10 @@ int main(int, char**) {
   test_float<double>();
   test_float<long double>();
 
+#if TEST_STD_VER >= 26
+  test_constexpr();
+  static_assert(test_constexpr());
+#endif
+
   return 0;
 }

>From bdd5f5872302bf0986aa42eb905d619d3fe96558 Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 15:23:17 +0200
Subject: [PATCH 12/17] remove: trailing line

---
 libcxx/include/string | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index 322b6b55a7809..caf3e0ab9bd53 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -3913,7 +3913,6 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
-
 #  endif // _LIBCPP_HAS_WIDE_CHARACTERS
 
 template <class _CharT, class _Traits, class _Allocator>

>From 581efc4c77345a895fa2e7372c086a4d5ed608db Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 15:28:10 +0200
Subject: [PATCH 13/17] fix: clang-format

---
 libcxx/include/string | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index caf3e0ab9bd53..c0ee6876d336f 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -3883,14 +3883,14 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
 
-#  if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+#    if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
-#  else 
+#    else
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(int __val) {
   return std::__to_string_integral<wstring>(__val);
 }
@@ -3909,7 +3909,7 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr wstring to_wstring(unsigned long long __val) {
   return std::__to_string_integral<wstring>(__val);
 }
-#  endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
+#    endif // _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_BUILDING_LIBRARY)
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);

>From 0ec18658318e6ea1888903266e2136e376721d1c Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 16:10:56 +0200
Subject: [PATCH 14/17] fix: clang-format

---
 libcxx/include/string                                         | 4 ++--
 libcxx/test/std/strings/string.conversions/to_string.pass.cpp | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index c0ee6876d336f..855525e69920a 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -936,7 +936,7 @@ private:
     return std::__make_bounded_iter(__p, __get_pointer(), __get_pointer() + size());
 #  else
     return const_iterator(__p);
-#  endif                    // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
+#  endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
   }
 
 public:
@@ -3913,7 +3913,7 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
-#  endif // _LIBCPP_HAS_WIDE_CHARACTERS
+#  endif   // _LIBCPP_HAS_WIDE_CHARACTERS
 
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type
diff --git a/libcxx/test/std/strings/string.conversions/to_string.pass.cpp b/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
index f8fee6d889f36..9c1daff4ed192 100644
--- a/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
+++ b/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
@@ -102,7 +102,7 @@ void test_float() {
   }
 }
 
-# if TEST_STD_VER >= 26
+#if TEST_STD_VER >= 26
 constexpr bool test_constexpr() {
   assert(std::to_string(0) == "0");
   assert(std::to_string(-12345) == "-12345");
@@ -115,7 +115,7 @@ constexpr bool test_constexpr() {
   assert(std::to_string(std::numeric_limits<unsigned long long>::max()) == "18446744073709551615");
   return true;
 }
-# endif
+#endif
 
 int main(int, char**) {
   test_signed<int>();

>From 5052ff2f242930a2728bda57696c66bd47ac554c Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 16:18:13 +0200
Subject: [PATCH 15/17] add: constexpr since C++26 on comments for test file

---
 .../strings/string.conversions/to_string.pass.cpp    | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libcxx/test/std/strings/string.conversions/to_string.pass.cpp b/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
index 9c1daff4ed192..a865c95b5793b 100644
--- a/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
+++ b/libcxx/test/std/strings/string.conversions/to_string.pass.cpp
@@ -8,12 +8,12 @@
 
 // <string>
 
-// string to_string(int val);
-// string to_string(unsigned val);
-// string to_string(long val);
-// string to_string(unsigned long val);
-// string to_string(long long val);
-// string to_string(unsigned long long val);
+// string to_string(int val);                // constexpr since C++26
+// string to_string(unsigned val);           // constexpr since C++26
+// string to_string(long val);               // constexpr since C++26
+// string to_string(unsigned long val);      // constexpr since C++26
+// string to_string(long long val);          // constexpr since C++26
+// string to_string(unsigned long long val); // constexpr since C++26
 // string to_string(float val);
 // string to_string(double val);
 // string to_string(long double val);

>From 47131667b9eb6c3b902d8c31c2ca3ceb95b87d2b Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 16:45:21 +0200
Subject: [PATCH 16/17] update: to_wstring.pass.cpp

---
 .../string.conversions/to_wstring.pass.cpp    | 32 +++++++++++++++----
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/libcxx/test/std/strings/string.conversions/to_wstring.pass.cpp b/libcxx/test/std/strings/string.conversions/to_wstring.pass.cpp
index bd4bd47671a81..f5f58c82f0e6c 100644
--- a/libcxx/test/std/strings/string.conversions/to_wstring.pass.cpp
+++ b/libcxx/test/std/strings/string.conversions/to_wstring.pass.cpp
@@ -10,12 +10,12 @@
 
 // <string>
 
-// wstring to_wstring(int val);
-// wstring to_wstring(unsigned val);
-// wstring to_wstring(long val);
-// wstring to_wstring(unsigned long val);
-// wstring to_wstring(long long val);
-// wstring to_wstring(unsigned long long val);
+// wstring to_wstring(int val);                // constexpr since C++26
+// wstring to_wstring(unsigned val);           // constexpr since C++26
+// wstring to_wstring(long val);               // constexpr since C++26
+// wstring to_wstring(unsigned long val);      // constexpr since C++26
+// wstring to_wstring(long long val);          // constexpr since C++26
+// wstring to_wstring(unsigned long long val); // constexpr since C++26
 // wstring to_wstring(float val);
 // wstring to_wstring(double val);
 // wstring to_wstring(long double val);
@@ -107,6 +107,21 @@ void test_float() {
   }
 }
 
+#if TEST_STD_VER >= 26
+constexpr bool test_constexpr() {
+  assert(std::to_wstring(0) == L"0");
+  assert(std::to_wstring(-12345) == L"-12345");
+  assert(std::to_wstring(12345u) == L"12345");
+  assert(std::to_wstring(-12345l) == L"-12345");
+  assert(std::to_wstring(12345ul) == L"12345");
+  assert(std::to_wstring(-12345ll) == L"-12345");
+  assert(std::to_wstring(12345ull) == L"12345");
+  assert(std::to_wstring(std::numeric_limits<long long>::min()) == L"-9223372036854775808");
+  assert(std::to_wstring(std::numeric_limits<unsigned long long>::max()) == L"18446744073709551615");
+  return true;
+}
+#endif
+
 int main(int, char**) {
   test_signed<int>();
   test_signed<long>();
@@ -118,5 +133,10 @@ int main(int, char**) {
   test_float<double>();
   test_float<long double>();
 
+#if TEST_STD_VER >= 26
+  test_constexpr();
+  static_assert(test_constexpr());
+#endif
+
   return 0;
 }

>From 4d98836d14d759994753af05ebd1d6a826da804f Mon Sep 17 00:00:00 2001
From: Lucas Mellone <github.snugness349 at passinbox.com>
Date: Wed, 7 Oct 2026 16:49:55 +0200
Subject: [PATCH 17/17] update: Cxx26Papers.csv

---
 libcxx/docs/Status/Cxx26Papers.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index 2aa7969b3cd10..e8387ef389b40 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -175,7 +175,7 @@
 "`P3887R1 <https://wg21.link/P3887R1>`__","Make ``when_all`` a Ronseal Algorithm","2025-11 (Kona)","","","`#171289 <https://github.com/llvm/llvm-project/issues/171289>`__",""
 "`P3923R0 <https://wg21.link/P3923R0>`__","Additional NB comment resolutions for Kona 2025","2025-11 (Kona)","","","`#171290 <https://github.com/llvm/llvm-project/issues/171290>`__",""
 "`P3371R5 <https://wg21.link/P3371R5>`__","Fix C++26 by making the rank-1, rank-2, rank-k, and rank-2k updates consistent with the BLAS","2025-11 (Kona)","","","`#171291 <https://github.com/llvm/llvm-project/issues/171291>`__",""
-"`P3391R2 <https://wg21.link/P3391R2>`__","``constexpr`` ``std::format``","2025-11 (Kona)","|Partial|","24","`#171292 <https://github.com/llvm/llvm-project/issues/171292>`__",""
+"`P3391R2 <https://wg21.link/P3391R2>`__","``constexpr`` ``std::format``","2025-11 (Kona)","|Partial|","24","`#171292 <https://github.com/llvm/llvm-project/issues/171292>`__","``to_string`` and ``to_wstring`` are ``constexpr``. ``std::format`` is not yet"
 "`P3913R1 <https://wg21.link/P3913R1>`__","Optimize ``for std::optional`` in range adaptors","2025-11 (Kona)","","","`#171294 <https://github.com/llvm/llvm-project/issues/171294>`__",""
 "","","","","","",""
 "`P3726R2 <https://wg21.link/P3726R2>`__","Adjustments to Union Lifetime Rules","2026-03 (Croydon)","","","`#189560 <https://github.com/llvm/llvm-project/issues/189560>`__",""



More information about the libcxx-commits mailing list