[PATCH] libstdc++: implement constexpr std::format
This patch implements constexpr formatting from P3391R2,
and introduces the constexpr_format feature-test macro.
Since pre-cxx11 cow_string is not constexpr-enabled,
only exposing the feature-test macro under cxx11 ABI.
Add `__format::__toupper_numeric` function that work in constexpr.
It is not fully general, but `` doesn't need all uppercasing.
Avoid using `_Ptr_sink` in constexpr in `__do_vformat_to`,
since it is a bit non-trivial to get it to work, and it is just an optimization.
Mark `basic_format_string` consteval constructor noexcept,
since exceptions are now constexpr, and the standard mandates
failure to parse to be non-catchable ill-formed.
https://eel.is/c++draft/format#fmt.string-3
> Remarks: A call to this function is not a core constant expression
> ([expr.const]) unless there exist args of types Args such that
> str is a format string for args.
Update some formatting tests to test constexpr as well,
and introduce a dedicated smoke test for constexpr formatting.
libstdc++-v3/include/ChangeLog:
* bits/version.def: Add constexpr_format.
* bits/version.h: Regenerate.
* std/format:
Expose constexpr_format feature-test macro,
constexpr-ify most functions, replace memcpy with ranges::copy.
(__format::__toupper_numeric): Define.
(__format::__do_vformat_to): Avoid using _Ptr_sink in constexpr.
libstdc++-v3/testsuite/ChangeLog:
* std/format/arguments/args_neg.cc: Diagnostics change.
* std/format/constexpr.cc: New test.
* std/format/debug.cc: Constexpr testing.
* std/format/functions/format.cc: Constexpr testing.
* std/format/functions/format_to.cc: Constexpr testing.
* std/format/functions/size.cc: Constexpr testing.
* std/format/ranges/format_kind.cc: Constexpr testing.
* std/format/ranges/formatter.cc: Constexpr testing.
* std/format/ranges/sequence.cc: Constexpr testing.
* std/format/runtime_format.cc: Constexpr testing.
* std/format/string.cc: Constexpr testing.
* std/format/tuple.cc: Constexpr testing.
* std/time/format/data_not_present_neg.cc: Diagnostics change.
Signed-off-by: Ivan Lazaric
---
Rebased, no unmerged patches anymore
Restricted to CXX11 ABI
Guarding tests and constexpr-ification with __glibcxx_constexpr_format
libstdc++-v3/include/bits/version.def | 12 +
libstdc++-v3/include/bits/version.h | 9 +
libstdc++-v3/include/std/format | 393 +++---
.../std/format/arguments/args_neg.cc | 4 +-
.../testsuite/std/format/constexpr.cc | 166
libstdc++-v3/testsuite/std/format/debug.cc| 82 ++--
.../testsuite/std/format/functions/format.cc | 281 +++--
.../std/format/functions/format_to.cc | 58 ++-
.../testsuite/std/format/functions/size.cc| 23 +-
.../std/format/ranges/format_kind.cc | 15 +-
.../testsuite/std/format/ranges/formatter.cc | 37 +-
.../testsuite/std/format/ranges/sequence.cc | 64 ++-
.../testsuite/std/format/runtime_format.cc| 25 +-
libstdc++-v3/testsuite/std/format/string.cc | 59 ++-
libstdc++-v3/testsuite/std/format/tuple.cc| 70 +++-
.../std/time/format/data_not_present_neg.cc | 3 +-
16 files changed, 914 insertions(+), 387 deletions(-)
create mode 100644 libstdc++-v3/testsuite/std/format/constexpr.cc
diff --git a/libstdc++-v3/include/bits/version.def
b/libstdc++-v3/include/bits/version.def
index dbe95b8b79f..6a1ee0b0579 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1330,6 +1330,18 @@ ftms = {
};
};
+ftms = {
+ name = constexpr_format;
+ // 202511 P3391R2 constexpr std::format
+ no_stdname = true; // in progress
+ values = {
+v = 202511;
+cxxmin = 26;
+hosted = yes;
+cxx11abi = yes;
+ };
+};
+
ftms = {
name = format_uchar;
values = {
diff --git a/libstdc++-v3/include/bits/version.h
b/libstdc++-v3/include/bits/version.h
index eee99847490..f690c46c739 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1476,6 +1476,15 @@
#endif /* !defined(__cpp_lib_format) */
#undef __glibcxx_want_format
+#if !defined(__cpp_lib_constexpr_format)
+# if (__cplusplus > 202302L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED
+# define __glibcxx_constexpr_format 202511L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_constexpr_format)
+# endif
+# endif
+#endif /* !defined(__cpp_lib_constexpr_format) */
+#undef __glibcxx_want_constexpr_format
+
#if !defined(__cpp_lib_format_uchar)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_format_uchar 202311L
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 4297bcc1007..bcbb5211227 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -39,6 +39,7 @@
#define __glibcxx_want_format_ranges
#define __glibcxx_want_forma
[PATCH] libstdc++: implement constexpr std::format
This patch implements constexpr formatting from P3391R2,
and introduces the constexpr_format feature-test macro.
This patch mostly adds `_GLIBCXX26_CONSTEXPR` to functions.
Add `__format::__toupper_numeric` function that work in constexpr.
It is not fully general, but `` doesn't need all uppercasing.
Avoid using `_Ptr_sink` in constexpr in `__do_vformat_to`,
since it is a bit non-trivial to get it to work, and it is just an optimization.
Mark `basic_format_string` consteval constructor noexcept,
since exceptions are now constexpr, and the standard mandates
failure to parse to be non-catchable ill-formed.
https://eel.is/c++draft/format#fmt.string-3
> Remarks: A call to this function is not a core constant expression
> ([expr.const]) unless there exist args of types Args such that
> str is a format string for args.
Mark integer to_{,w}string functions constexpr.
Introduce constexpr tests for them.
Update some formatting tests to test constexpr as well,
and introduce a dedicated smoke test for constexpr formatting.
libstdc++-v3/include/ChangeLog:
* bits/basic_string.h:
Add _GLIBCXX26_CONSTEXPR to std::to_{,w}string.
* bits/version.def: Add constexpr_format.
* bits/version.h: Regenerate.
* std/format:
Expose constexpr_format feature-test macro,
pepper in _GLIBCXX26_CONSTEXPR, replace memcpy with ranges::copy.
(__format::__toupper_numeric): Define.
(__format::__do_vformat_to): Avoid using _Ptr_sink in constexpr.
libstdc++-v3/testsuite/ChangeLog:
* std/format/arguments/args_neg.cc: Diagnostics change.
* std/format/constexpr.cc: New test.
* std/format/debug.cc: Constexpr testing.
* std/format/functions/format.cc: Constexpr testing.
* std/format/functions/format_to.cc: Constexpr testing.
* std/format/functions/size.cc: Constexpr testing.
* std/format/ranges/format_kind.cc: Constexpr testing.
* std/format/ranges/formatter.cc: Constexpr testing.
* std/format/ranges/sequence.cc: Constexpr testing.
* std/format/runtime_format.cc: Constexpr testing.
* std/format/string.cc: Constexpr testing.
* std/format/tuple.cc: Constexpr testing.
* std/time/format/data_not_present_neg.cc: Diagnostics change.
*
21_strings/basic_string/numeric_conversions/char/to_string_constexpr.cc:
New test.
*
21_strings/basic_string/numeric_conversions/wchar_t/to_wstring_constexpr.cc:
New test.
Signed-off-by: Ivan Lazaric
---
Rebased, only non-merged prerequisites are:
* libstdc++: Introduce __format::_Ptr_sink for contingous iterators.
* libstdc+: Eliminate usage of alloca for non-localized formatting
Added constexpr to std::to_{,w}string, added tests for them.
The couple existing tests I looked at don't allow for easy constexpr testing,
for example to_string_int.cc test depends on snprintf.
In current shape it's rather complete, might make sense to drop no_stdname
from the feature-test macro.
libstdc++-v3/include/bits/basic_string.h | 24 +-
libstdc++-v3/include/bits/version.def | 11 +
libstdc++-v3/include/bits/version.h | 9 +
libstdc++-v3/include/std/format | 387 +++---
.../char/to_string_constexpr.cc | 63 +++
.../wchar_t/to_wstring_constexpr.cc | 63 +++
.../std/format/arguments/args_neg.cc | 4 +-
.../testsuite/std/format/constexpr.cc | 156 +++
libstdc++-v3/testsuite/std/format/debug.cc| 82 ++--
.../testsuite/std/format/functions/format.cc | 281 +++--
.../std/format/functions/format_to.cc | 58 ++-
.../testsuite/std/format/functions/size.cc| 23 +-
.../std/format/ranges/format_kind.cc | 15 +-
.../testsuite/std/format/ranges/formatter.cc | 37 +-
.../testsuite/std/format/ranges/sequence.cc | 64 ++-
.../testsuite/std/format/runtime_format.cc| 17 +-
libstdc++-v3/testsuite/std/format/string.cc | 59 ++-
libstdc++-v3/testsuite/std/format/tuple.cc| 70 +++-
.../std/time/format/data_not_present_neg.cc | 3 +-
19 files changed, 1026 insertions(+), 400 deletions(-)
create mode 100644
libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/to_string_constexpr.cc
create mode 100644
libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/to_wstring_constexpr.cc
create mode 100644 libstdc++-v3/testsuite/std/format/constexpr.cc
diff --git a/libstdc++-v3/include/bits/basic_string.h
b/libstdc++-v3/include/bits/basic_string.h
index 9bbe16507d0..1317b292335 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -4582,7 +4582,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// DR 1261. Insufficent overloads for to_string / to_wstring
_GLIBCXX_NODISCARD
- inline string
+ inline _GLIBCXX26_CONSTEXPR string
to_string(int __val)
#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_I
[PATCH] libstdc++: implement constexpr std::format
This patch partially implements constexpr formatting from P3391R2,
and introduces the constexpr_format feature-test macro.
This patch mostly adds `_GLIBCXX26_CONSTEXPR` to functions.
Add `__format::__toupper_numeric` function that work in constexpr.
It is not fully general, but `` doesn't need all uppercasing.
Avoid using `_Ptr_sink` in constexpr in `__do_vformat_to`,
since it is a bit non-trivial to get it to work, and it is just an optimization.
Mark `basic_format_string` consteval constructor noexcept,
since exceptions are now constexpr, and the standard mandates
failure to parse to be non-catchable ill-formed.
https://eel.is/c++draft/format#fmt.string-3
> Remarks: A call to this function is not a core constant expression
> ([expr.const]) unless there exist args of types Args such that
> str is a format string for args.
Some wide formatting relies on `__builtin_alloca` which doesn't work
in constexpr, changed it to go through regular allocation
and cleanup in constexpr.
Update some formatting tests to test constexpr as well,
and introduce a dedicated smoke test for constexpr formatting.
This patch is missing:
* constexpr to_{,w}string
* more constexpr tests
libstdc++-v3/ChangeLog:
* include/bits/version.def: Add constexpr_format.
* include/bits/version.h: Regenerate.
* include/std/format:
Pepper in _GLIBCXX26_CONSTEXPR, replace memcpy with ranges::copy,
avoid __builtin_alloca in constexpr wide formatting.
(__format::__toupper_numeric): Define.
(__format::__do_vformat_to):
Avoid using _Ptr_sink in constexpr.
* testsuite/std/format/arguments/args_neg.cc: Diagnostics change.
* testsuite/std/format/constexpr.cc: New test.
* testsuite/std/format/debug.cc: Constexpr testing.
* testsuite/std/format/functions/format.cc: Constexpr testing.
* testsuite/std/format/functions/format_to.cc: Constexpr testing.
* testsuite/std/format/functions/size.cc: Constexpr testing.
* testsuite/std/format/ranges/format_kind.cc: Constexpr testing.
* testsuite/std/format/ranges/formatter.cc: Constexpr testing.
* testsuite/std/format/ranges/sequence.cc: Constexpr testing.
* testsuite/std/format/runtime_format.cc: Constexpr testing.
* testsuite/std/format/string.cc: Constexpr testing.
* testsuite/std/format/tuple.cc: Constexpr testing.
* testsuite/std/time/format/data_not_present_neg.cc: Diagnostics change.
Signed-off-by: Ivan Lazaric
---
Notable changes:
std/format/arguments/args_neg.cc & std/time/format/data_not_present_neg.cc:
touched up the diagnostics they expect.
Fixed up constexpr wide formatting, avoiding the __builtin_alloca
with regular allocation, and a unique_ptr-esque _Cleanup deallocation
on scope exit. Last remaining __builtin_alloca is in locale related path.
Testing constexpr wide formatting in both existing tests and
newly introduced constexpr.cc.
Rebased on top of untested fix mentioned in:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124145
This allows for constexpr tests related to exceptions,
enabled them in the existing tests I touched.
Marked basic_format_string constructor as noexcept,
so the exception blows up compilation and is not catchable.
Patches this is based on top of that aren't merged yet:
* libstdc++: Store basic_format_arg::handle in __format::_Arg_value
* libstdc++: Introduce __format::_Ptr_sink for contingous iterators.
* libstdc++: Remove UB in _Arg_value union alteranatives assigment
* PR c++/124145 mentioned fix
In case the base for this patch is becoming confusing, it can be found at:
https://github.com/ilazaric/gcc/tree/ilazaric/constexpr-formatting-base
One test I took a look at and didn't constexpr-ify:
std/format/parse_ctx.cc
I'm unsure it makes sense to constexpr-ify it,
as it runs into: https://eel.is/c++draft/format#parse.ctx-note-1
> Note: Any call to next_arg_id, check_arg_id, or check_dynamic_spec
> on an instance of basic_format_parse_context initialized using
> this constructor is not a core constant expression.
I am also noting not yet resolved LWG issue as relevant:
https://cplusplus.github.io/LWG/issue4531
libstdc++-v3/include/bits/version.def | 11 +
libstdc++-v3/include/bits/version.h | 9 +
libstdc++-v3/include/std/format | 429 +++---
.../std/format/arguments/args_neg.cc | 4 +-
.../testsuite/std/format/constexpr.cc | 156 +++
libstdc++-v3/testsuite/std/format/debug.cc| 82 ++--
.../testsuite/std/format/functions/format.cc | 281 +++-
.../std/format/functions/format_to.cc | 58 ++-
.../testsuite/std/format/functions/size.cc| 23 +-
.../std/format/ranges/format_kind.cc | 15 +-
.../testsuite/std/format/ranges/formatter.cc | 37 +-
.../testsuite/std/format/ranges/sequence.cc | 64 ++-
.../testsuite/std/format/runtime_format.cc| 17 +-
libstdc++-v3/testsuite/std/format/strin
[PATCH] libstdc++: implement constexpr std::format
libstdc++: partially implement constexpr std::format
This patch partially implements constexpr formatting from P3391R2,
as such it does not define the __cpp_lib_constexpr_format feature-test macro.
This patch mostly adds `_GLIBCXX26_CONSTEXPR` to functions.
Add `__format::__toupper` function that work in constexpr.
It is not fully general, but `` doesn't need all uppercasing.
Avoid using `_Ptr_sink` in constexpr in `__do_vformat_to`,
since it is a bit non-trivial to get it to work, and it is just an optimization.
Update some formatting tests to test constexpr as well,
and introduce a dedicated smoke test for constexpr formatting.
This patch is missing:
* wide constexpr formatting
* constexpr to_{,w}string
* more constexpr tests
libstdc++-v3/ChangeLog:
* include/std/format:
Pepper in _GLIBCXX26_CONSTEXPR, replace memcpy with ranges::copy.
(__format::__toupper): Define.
(__format::__do_vformat_to):
Avoid using _Ptr_sink in constexpr.
* testsuite/std/format/constexpr.cc: New test.
* testsuite/std/format/debug.cc: Constexpr testing.
* testsuite/std/format/functions/format.cc: Constexpr testing.
* testsuite/std/format/functions/format_to.cc: Constexpr testing.
* testsuite/std/format/functions/size.cc: Constexpr testing.
* testsuite/std/format/ranges/format_kind.cc: Constexpr testing.
* testsuite/std/format/ranges/formatter.cc: Constexpr testing.
* testsuite/std/format/ranges/sequence.cc: Constexpr testing.
* testsuite/std/format/runtime_format.cc: Constexpr testing.
* testsuite/std/format/string.cc: Constexpr testing.
* testsuite/std/format/tuple.cc: Constexpr testing.
Signed-off-by: Ivan Lazaric
---
Updates to patch:
Replaced __memcpy with ranges::copy
Simplified __toupper as a switch
if (not) consteval replaced with std::is_constant_evaluated()
Rebased on top of your _M_access patch
Removed the version.{def,h} since this doesn't implement full paper
Cleaned up tests as suggested
Added a constexpr.cc test with c++26 target
Killed Counting_constexpr_sink, just going through _Ptr_sink
Regarding formatting of nullptr:
basic_format_arg(nullptr) will store a `const void*` ,
so `format(nullptr)` will actually go through `formatter`.
I've been testing with GLIBCXX_TESTSUITE_STDS=20,23,26,
two tests are failing in 26 now, both are testing compilation errors:
std/format/arguments/args_neg.cc
std/time/format/data_not_present_neg.cc
Haven't yet investigated.
libstdc++-v3/include/std/format | 388 +++---
.../testsuite/std/format/constexpr.cc | 126 ++
libstdc++-v3/testsuite/std/format/debug.cc| 105 +++--
.../testsuite/std/format/functions/format.cc | 265 +++-
.../std/format/functions/format_to.cc | 63 ++-
.../testsuite/std/format/functions/size.cc| 24 +-
.../std/format/ranges/format_kind.cc | 15 +-
.../testsuite/std/format/ranges/formatter.cc | 45 +-
.../testsuite/std/format/ranges/sequence.cc | 73 +++-
.../testsuite/std/format/runtime_format.cc| 18 +-
libstdc++-v3/testsuite/std/format/string.cc | 230 +++
libstdc++-v3/testsuite/std/format/tuple.cc| 78 +++-
12 files changed, 967 insertions(+), 463 deletions(-)
create mode 100644 libstdc++-v3/testsuite/std/format/constexpr.cc
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 4f0b0f377c6..b5670d0ec32 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -128,6 +128,7 @@ namespace __format
struct _Runtime_format_string
{
[[__gnu__::__always_inline__]]
+ _GLIBCXX26_CONSTEXPR
_Runtime_format_string(basic_string_view<_CharT> __s) noexcept
: _M_str(__s) { }
@@ -173,6 +174,7 @@ namespace __format
basic_format_string(const _Tp& __s);
[[__gnu__::__always_inline__]]
+ _GLIBCXX26_CONSTEXPR
basic_format_string(__format::_Runtime_format_string<_CharT> __s)
noexcept
: _M_str(__s._M_str)
{ }
@@ -197,13 +199,13 @@ namespace __format
#if __cpp_lib_format >= 202311L // >= C++26
[[__gnu__::__always_inline__]]
- inline __format::_Runtime_format_string
+ inline _GLIBCXX26_CONSTEXPR __format::_Runtime_format_string
runtime_format(string_view __fmt) noexcept
{ return __fmt; }
#ifdef _GLIBCXX_USE_WCHAR_T
[[__gnu__::__always_inline__]]
- inline __format::_Runtime_format_string
+ inline _GLIBCXX26_CONSTEXPR __format::_Runtime_format_string
runtime_format(wstring_view __fmt) noexcept
{ return __fmt; }
#endif
@@ -238,7 +240,7 @@ namespace __format
/// @cond undocumented
[[noreturn]]
- inline void
+ inline _GLIBCXX26_CONSTEXPR void
__throw_format_error(const char* __what)
{ _GLIBCXX_THROW_OR_ABORT(format_error(__what)); }
@@ -249,27 +251,27 @@ namespace __format
// XXX use named functions for each constexpr error?
[[noreturn]]
- inline void
+ inline
[PATCH] libstdc++: implement constexpr std::format
This patch partially implements constexpr formatting from P3391R2,
and defines the feature test macro__cpp_lib_constexpr_format to 202511L,
provided only in .
This patch mostly adds `_GLIBCXX26_CONSTEXPR` to functions.
Add `__format::__{toupper,memcpy}` functions that work in constexpr.
Due to constexpr limitations, previous implementation of
`_Arg_value::_M_set` via `_S_get` wouldn't work.
Instead of adding a `_S_set` function duplicating most of the
`_S_get` logic, generalize `_S_get` to `_S_get_set` by
folding over assignment, update `_M_set` to go through it.
Avoid using `_Ptr_sink` in constexpr, in `__do_vformat_to`
and `formatted_size`.
Update some formatting tests to test constexpr as well.
This patch is missing:
* wide constexpr formatting
* more constexpr tests
libstdc++-v3/ChangeLog:
* include/bits/version.def (constexpr_format): Define.
* include/bits/version.h: Regenerate.
* include/std/format:
(__format::__toupper, __format::memcpy): Define.
(_Arg_value::_S_get): Generalize to _S_get_set.
(__format::_Counting_constexpr_sink): Define.
(__format::__do_vformat_to, formatted_size):
Avoid using _Ptr_sink in constexpr.
* testsuite/std/format/functions/format.cc: Constexpr testing.
* testsuite/std/format/functions/format_to.cc: Constexpr testing.
* testsuite/std/format/ranges/format_kind.cc: Constexpr testing.
* testsuite/std/format/ranges/formatter.cc: Constexpr testing.
* testsuite/std/format/ranges/sequence.cc: Constexpr testing.
* testsuite/std/format/string.cc: Constexpr testing.
* testsuite/std/format/tuple.cc: Constexpr testing.
Signed-off-by: Ivan Lazaric
---
This patch is based on top of the 2 following not-yet-merged patches:
libstdc++: Store basic_format_arg::handle in __format::_Arg_value
libstdc++: Introduce __format::_Ptr_sink for contingous iterators
libstdc++-v3/include/bits/version.def | 10 +
libstdc++-v3/include/bits/version.h | 10 +
libstdc++-v3/include/std/format | 367 ++
.../testsuite/std/format/functions/format.cc | 191 +
.../std/format/functions/format_to.cc | 58 ++-
.../std/format/ranges/format_kind.cc | 11 +-
.../testsuite/std/format/ranges/formatter.cc | 40 +-
.../testsuite/std/format/ranges/sequence.cc | 73 +++-
libstdc++-v3/testsuite/std/format/string.cc | 222 ++-
libstdc++-v3/testsuite/std/format/tuple.cc| 72 +++-
10 files changed, 742 insertions(+), 312 deletions(-)
diff --git a/libstdc++-v3/include/bits/version.def
b/libstdc++-v3/include/bits/version.def
index c7709ba3a07..827498732c6 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1330,6 +1330,16 @@ ftms = {
};
};
+ftms = {
+ name = constexpr_format;
+ // 202511 P3391R2 constexpr std::format
+ values = {
+v = 202511;
+cxxmin = 26;
+hosted = yes;
+ };
+};
+
ftms = {
name = format_uchar;
values = {
diff --git a/libstdc++-v3/include/bits/version.h
b/libstdc++-v3/include/bits/version.h
index c72cda506f1..4911b741bb1 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1476,6 +1476,16 @@
#endif /* !defined(__cpp_lib_format) */
#undef __glibcxx_want_format
+#if !defined(__cpp_lib_constexpr_format)
+# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED
+# define __glibcxx_constexpr_format 202511L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_constexpr_format)
+# define __cpp_lib_constexpr_format 202511L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_constexpr_format) */
+#undef __glibcxx_want_constexpr_format
+
#if !defined(__cpp_lib_format_uchar)
# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_format_uchar 202311L
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 245ea964675..1ecfabb2590 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -39,6 +39,7 @@
#define __glibcxx_want_format_ranges
#define __glibcxx_want_format_uchar
#define __glibcxx_want_constexpr_exceptions
+#define __glibcxx_want_constexpr_format
#include
#ifdef __cpp_lib_format // C++ >= 20 && HOSTED
@@ -98,6 +99,34 @@ namespace __format
#define _GLIBCXX_WIDEN_(C, S) ::std::__format::_Widen(S, L##S)
#define _GLIBCXX_WIDEN(S) _GLIBCXX_WIDEN_(_CharT, S)
+ [[__gnu__::__always_inline__]]
+ constexpr char
+ __toupper(char __c)
+ {
+if consteval {
+ if (__c < 'a' || __c > 'z') return __c;
+ return __c - 'a' + 'A';
+} else {
+#if __has_builtin(__builtin_toupper)
+ return __builtin_toupper(__c);
+#else
+ return std::toupper(__c);
+#endif
+}
+ }
+
+ [[__gnu__::__always_inline__]]
+ constexpr void
+ __memcpy(char* __dest, const char* __src, size_t __n)
+ {
+if consteval {
+ for (size_t __i = 0; __i < __n; ++__i)
+ __dest[__i] = __src[_
