public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-6990] libstdc++: Implement P2909R4 ("Dude, where's my char?") for C++20
@ 2024-01-08  1:15 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2024-01-08  1:15 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:74a0dab18292bef54f316eb086112332befbc6a7

commit r14-6990-g74a0dab18292bef54f316eb086112332befbc6a7
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jan 3 15:35:50 2024 +0000

    libstdc++: Implement P2909R4 ("Dude, where's my char?") for C++20
    
    This change ensures that char and wchar_t arguments are formatted
    consistently when using integer presentation types. This avoids
    non-portable std::format output that depends on whether char and wchar_t
    happen to be signed or unsigned on the target. Formatting '\xff' as an
    integer will now always format 255 and not sometimes -1. This was
    approved in Kona 2023 as a DR for C++20 so the change is implemented
    unconditionally.
    
    Also make character formatters check for _Pres_c explicitly and call
    _M_format_character directly. This avoid the overhead of calling format
    and _S_to_character and then calling _M_format_character anyway.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/version.def (format_uchar): Define.
            * include/bits/version.h: Regenerate.
            * include/std/format (formatter<C, C>::format): Check for
            _Pres_c and call _M_format_character directly. Cast C to its
            unsigned equivalent for formatting as an integer.
            (formatter<char, wchar_t>::format): Likewise.
            (basic_format_arg(T&)): Store char arguments as unsigned char
            for formatting to a wide string.
            * testsuite/std/format/functions/format.cc: Adjust test. Check
            formatting of

Diff:
---
 libstdc++-v3/include/bits/version.def              |   9 ++
 libstdc++-v3/include/bits/version.h                | 141 +++++++++++----------
 libstdc++-v3/include/std/format                    |  14 +-
 .../testsuite/std/format/functions/format.cc       |  27 +++-
 4 files changed, 118 insertions(+), 73 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index fa304146c65..7c7ba066161 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1166,6 +1166,15 @@ ftms = {
   };
 };
 
+ftms = {
+  name = format_uchar;
+  values = {
+    v = 202311;
+    cxxmin = 20;
+    hosted = yes;
+  };
+};
+
 // FIXME: #define __glibcxx_execution 201902L
 
 ftms = {
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 1e1da11e085..65d5164347e 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1422,7 +1422,18 @@
 #endif /* !defined(__cpp_lib_format) && defined(__glibcxx_want_format) */
 #undef __glibcxx_want_format
 
-// from version.def line 1172
+// from version.def line 1170
+#if !defined(__cpp_lib_format_uchar)
+# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
+#  define __glibcxx_format_uchar 202311L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_format_uchar)
+#   define __cpp_lib_format_uchar 202311L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_format_uchar) && defined(__glibcxx_want_format_uchar) */
+#undef __glibcxx_want_format_uchar
+
+// from version.def line 1181
 #if !defined(__cpp_lib_constexpr_complex)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_constexpr_complex 201711L
@@ -1433,7 +1444,7 @@
 #endif /* !defined(__cpp_lib_constexpr_complex) && defined(__glibcxx_want_constexpr_complex) */
 #undef __glibcxx_want_constexpr_complex
 
-// from version.def line 1181
+// from version.def line 1190
 #if !defined(__cpp_lib_constexpr_dynamic_alloc)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_constexpr_dynamic_alloc 201907L
@@ -1444,7 +1455,7 @@
 #endif /* !defined(__cpp_lib_constexpr_dynamic_alloc) && defined(__glibcxx_want_constexpr_dynamic_alloc) */
 #undef __glibcxx_want_constexpr_dynamic_alloc
 
-// from version.def line 1190
+// from version.def line 1199
 #if !defined(__cpp_lib_constexpr_string)
 # if (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED && (defined(__glibcxx_is_constant_evaluated))
 #  define __glibcxx_constexpr_string 201907L
@@ -1465,7 +1476,7 @@
 #endif /* !defined(__cpp_lib_constexpr_string) && defined(__glibcxx_want_constexpr_string) */
 #undef __glibcxx_want_constexpr_string
 
-// from version.def line 1214
+// from version.def line 1223
 #if !defined(__cpp_lib_constexpr_vector)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_constexpr_vector 201907L
@@ -1476,7 +1487,7 @@
 #endif /* !defined(__cpp_lib_constexpr_vector) && defined(__glibcxx_want_constexpr_vector) */
 #undef __glibcxx_want_constexpr_vector
 
-// from version.def line 1223
+// from version.def line 1232
 #if !defined(__cpp_lib_erase_if)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_erase_if 202002L
@@ -1487,7 +1498,7 @@
 #endif /* !defined(__cpp_lib_erase_if) && defined(__glibcxx_want_erase_if) */
 #undef __glibcxx_want_erase_if
 
-// from version.def line 1232
+// from version.def line 1241
 #if !defined(__cpp_lib_generic_unordered_lookup)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_generic_unordered_lookup 201811L
@@ -1498,7 +1509,7 @@
 #endif /* !defined(__cpp_lib_generic_unordered_lookup) && defined(__glibcxx_want_generic_unordered_lookup) */
 #undef __glibcxx_want_generic_unordered_lookup
 
-// from version.def line 1241
+// from version.def line 1250
 #if !defined(__cpp_lib_jthread)
 # if (__cplusplus >= 202002L) && defined(_GLIBCXX_HAS_GTHREADS) && _GLIBCXX_HOSTED
 #  define __glibcxx_jthread 201911L
@@ -1509,7 +1520,7 @@
 #endif /* !defined(__cpp_lib_jthread) && defined(__glibcxx_want_jthread) */
 #undef __glibcxx_want_jthread
 
-// from version.def line 1251
+// from version.def line 1260
 #if !defined(__cpp_lib_latch)
 # if (__cplusplus >= 202002L) && (__glibcxx_atomic_wait)
 #  define __glibcxx_latch 201907L
@@ -1520,7 +1531,7 @@
 #endif /* !defined(__cpp_lib_latch) && defined(__glibcxx_want_latch) */
 #undef __glibcxx_want_latch
 
-// from version.def line 1260
+// from version.def line 1269
 #if !defined(__cpp_lib_list_remove_return_type)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_list_remove_return_type 201806L
@@ -1531,7 +1542,7 @@
 #endif /* !defined(__cpp_lib_list_remove_return_type) && defined(__glibcxx_want_list_remove_return_type) */
 #undef __glibcxx_want_list_remove_return_type
 
-// from version.def line 1269
+// from version.def line 1278
 #if !defined(__cpp_lib_polymorphic_allocator)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_polymorphic_allocator 201902L
@@ -1542,7 +1553,7 @@
 #endif /* !defined(__cpp_lib_polymorphic_allocator) && defined(__glibcxx_want_polymorphic_allocator) */
 #undef __glibcxx_want_polymorphic_allocator
 
-// from version.def line 1278
+// from version.def line 1287
 #if !defined(__cpp_lib_move_iterator_concept)
 # if (__cplusplus >= 202002L) && (__glibcxx_concepts)
 #  define __glibcxx_move_iterator_concept 202207L
@@ -1553,7 +1564,7 @@
 #endif /* !defined(__cpp_lib_move_iterator_concept) && defined(__glibcxx_want_move_iterator_concept) */
 #undef __glibcxx_want_move_iterator_concept
 
-// from version.def line 1288
+// from version.def line 1297
 #if !defined(__cpp_lib_semaphore)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED && (__glibcxx_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE)
 #  define __glibcxx_semaphore 201907L
@@ -1564,7 +1575,7 @@
 #endif /* !defined(__cpp_lib_semaphore) && defined(__glibcxx_want_semaphore) */
 #undef __glibcxx_want_semaphore
 
-// from version.def line 1298
+// from version.def line 1307
 #if !defined(__cpp_lib_smart_ptr_for_overwrite)
 # if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
 #  define __glibcxx_smart_ptr_for_overwrite 202002L
@@ -1575,7 +1586,7 @@
 #endif /* !defined(__cpp_lib_smart_ptr_for_overwrite) && defined(__glibcxx_want_smart_ptr_for_overwrite) */
 #undef __glibcxx_want_smart_ptr_for_overwrite
 
-// from version.def line 1307
+// from version.def line 1316
 #if !defined(__cpp_lib_syncbuf)
 # if (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED
 #  define __glibcxx_syncbuf 201803L
@@ -1586,7 +1597,7 @@
 #endif /* !defined(__cpp_lib_syncbuf) && defined(__glibcxx_want_syncbuf) */
 #undef __glibcxx_want_syncbuf
 
-// from version.def line 1317
+// from version.def line 1326
 #if !defined(__cpp_lib_byteswap)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_byteswap 202110L
@@ -1597,7 +1608,7 @@
 #endif /* !defined(__cpp_lib_byteswap) && defined(__glibcxx_want_byteswap) */
 #undef __glibcxx_want_byteswap
 
-// from version.def line 1325
+// from version.def line 1334
 #if !defined(__cpp_lib_constexpr_charconv)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_constexpr_charconv 202207L
@@ -1608,7 +1619,7 @@
 #endif /* !defined(__cpp_lib_constexpr_charconv) && defined(__glibcxx_want_constexpr_charconv) */
 #undef __glibcxx_want_constexpr_charconv
 
-// from version.def line 1333
+// from version.def line 1342
 #if !defined(__cpp_lib_constexpr_typeinfo)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_constexpr_typeinfo 202106L
@@ -1619,7 +1630,7 @@
 #endif /* !defined(__cpp_lib_constexpr_typeinfo) && defined(__glibcxx_want_constexpr_typeinfo) */
 #undef __glibcxx_want_constexpr_typeinfo
 
-// from version.def line 1341
+// from version.def line 1350
 #if !defined(__cpp_lib_expected)
 # if (__cplusplus >= 202100L) && (__cpp_concepts >= 202002L)
 #  define __glibcxx_expected 202211L
@@ -1630,7 +1641,7 @@
 #endif /* !defined(__cpp_lib_expected) && defined(__glibcxx_want_expected) */
 #undef __glibcxx_want_expected
 
-// from version.def line 1350
+// from version.def line 1359
 #if !defined(__cpp_lib_freestanding_algorithm)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_freestanding_algorithm 202311L
@@ -1641,7 +1652,7 @@
 #endif /* !defined(__cpp_lib_freestanding_algorithm) && defined(__glibcxx_want_freestanding_algorithm) */
 #undef __glibcxx_want_freestanding_algorithm
 
-// from version.def line 1359
+// from version.def line 1368
 #if !defined(__cpp_lib_freestanding_array)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_freestanding_array 202311L
@@ -1652,7 +1663,7 @@
 #endif /* !defined(__cpp_lib_freestanding_array) && defined(__glibcxx_want_freestanding_array) */
 #undef __glibcxx_want_freestanding_array
 
-// from version.def line 1368
+// from version.def line 1377
 #if !defined(__cpp_lib_freestanding_cstring)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_freestanding_cstring 202311L
@@ -1663,7 +1674,7 @@
 #endif /* !defined(__cpp_lib_freestanding_cstring) && defined(__glibcxx_want_freestanding_cstring) */
 #undef __glibcxx_want_freestanding_cstring
 
-// from version.def line 1377
+// from version.def line 1386
 #if !defined(__cpp_lib_freestanding_expected)
 # if (__cplusplus >= 202100L) && (__cpp_lib_expected)
 #  define __glibcxx_freestanding_expected 202311L
@@ -1674,7 +1685,7 @@
 #endif /* !defined(__cpp_lib_freestanding_expected) && defined(__glibcxx_want_freestanding_expected) */
 #undef __glibcxx_want_freestanding_expected
 
-// from version.def line 1387
+// from version.def line 1396
 #if !defined(__cpp_lib_freestanding_optional)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_freestanding_optional 202311L
@@ -1685,7 +1696,7 @@
 #endif /* !defined(__cpp_lib_freestanding_optional) && defined(__glibcxx_want_freestanding_optional) */
 #undef __glibcxx_want_freestanding_optional
 
-// from version.def line 1396
+// from version.def line 1405
 #if !defined(__cpp_lib_freestanding_string_view)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_freestanding_string_view 202311L
@@ -1696,7 +1707,7 @@
 #endif /* !defined(__cpp_lib_freestanding_string_view) && defined(__glibcxx_want_freestanding_string_view) */
 #undef __glibcxx_want_freestanding_string_view
 
-// from version.def line 1405
+// from version.def line 1414
 #if !defined(__cpp_lib_freestanding_variant)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_freestanding_variant 202311L
@@ -1707,7 +1718,7 @@
 #endif /* !defined(__cpp_lib_freestanding_variant) && defined(__glibcxx_want_freestanding_variant) */
 #undef __glibcxx_want_freestanding_variant
 
-// from version.def line 1414
+// from version.def line 1423
 #if !defined(__cpp_lib_invoke_r)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_invoke_r 202106L
@@ -1718,7 +1729,7 @@
 #endif /* !defined(__cpp_lib_invoke_r) && defined(__glibcxx_want_invoke_r) */
 #undef __glibcxx_want_invoke_r
 
-// from version.def line 1422
+// from version.def line 1431
 #if !defined(__cpp_lib_is_scoped_enum)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_is_scoped_enum 202011L
@@ -1729,7 +1740,7 @@
 #endif /* !defined(__cpp_lib_is_scoped_enum) && defined(__glibcxx_want_is_scoped_enum) */
 #undef __glibcxx_want_is_scoped_enum
 
-// from version.def line 1430
+// from version.def line 1439
 #if !defined(__cpp_lib_reference_from_temporary)
 # if (__cplusplus >= 202100L) && (__has_builtin(__reference_constructs_from_temporary) && __has_builtin(__reference_converts_from_temporary))
 #  define __glibcxx_reference_from_temporary 202202L
@@ -1740,7 +1751,7 @@
 #endif /* !defined(__cpp_lib_reference_from_temporary) && defined(__glibcxx_want_reference_from_temporary) */
 #undef __glibcxx_want_reference_from_temporary
 
-// from version.def line 1450
+// from version.def line 1459
 #if !defined(__cpp_lib_ranges_to_container)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_ranges_to_container 202202L
@@ -1751,7 +1762,7 @@
 #endif /* !defined(__cpp_lib_ranges_to_container) && defined(__glibcxx_want_ranges_to_container) */
 #undef __glibcxx_want_ranges_to_container
 
-// from version.def line 1459
+// from version.def line 1468
 #if !defined(__cpp_lib_ranges_zip)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_zip 202110L
@@ -1762,7 +1773,7 @@
 #endif /* !defined(__cpp_lib_ranges_zip) && defined(__glibcxx_want_ranges_zip) */
 #undef __glibcxx_want_ranges_zip
 
-// from version.def line 1467
+// from version.def line 1476
 #if !defined(__cpp_lib_ranges_chunk)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_chunk 202202L
@@ -1773,7 +1784,7 @@
 #endif /* !defined(__cpp_lib_ranges_chunk) && defined(__glibcxx_want_ranges_chunk) */
 #undef __glibcxx_want_ranges_chunk
 
-// from version.def line 1475
+// from version.def line 1484
 #if !defined(__cpp_lib_ranges_slide)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_slide 202202L
@@ -1784,7 +1795,7 @@
 #endif /* !defined(__cpp_lib_ranges_slide) && defined(__glibcxx_want_ranges_slide) */
 #undef __glibcxx_want_ranges_slide
 
-// from version.def line 1483
+// from version.def line 1492
 #if !defined(__cpp_lib_ranges_chunk_by)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_chunk_by 202202L
@@ -1795,7 +1806,7 @@
 #endif /* !defined(__cpp_lib_ranges_chunk_by) && defined(__glibcxx_want_ranges_chunk_by) */
 #undef __glibcxx_want_ranges_chunk_by
 
-// from version.def line 1491
+// from version.def line 1500
 #if !defined(__cpp_lib_ranges_join_with)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_join_with 202202L
@@ -1806,7 +1817,7 @@
 #endif /* !defined(__cpp_lib_ranges_join_with) && defined(__glibcxx_want_ranges_join_with) */
 #undef __glibcxx_want_ranges_join_with
 
-// from version.def line 1499
+// from version.def line 1508
 #if !defined(__cpp_lib_ranges_repeat)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_repeat 202207L
@@ -1817,7 +1828,7 @@
 #endif /* !defined(__cpp_lib_ranges_repeat) && defined(__glibcxx_want_ranges_repeat) */
 #undef __glibcxx_want_ranges_repeat
 
-// from version.def line 1507
+// from version.def line 1516
 #if !defined(__cpp_lib_ranges_stride)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_stride 202207L
@@ -1828,7 +1839,7 @@
 #endif /* !defined(__cpp_lib_ranges_stride) && defined(__glibcxx_want_ranges_stride) */
 #undef __glibcxx_want_ranges_stride
 
-// from version.def line 1515
+// from version.def line 1524
 #if !defined(__cpp_lib_ranges_cartesian_product)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_cartesian_product 202207L
@@ -1839,7 +1850,7 @@
 #endif /* !defined(__cpp_lib_ranges_cartesian_product) && defined(__glibcxx_want_ranges_cartesian_product) */
 #undef __glibcxx_want_ranges_cartesian_product
 
-// from version.def line 1523
+// from version.def line 1532
 #if !defined(__cpp_lib_ranges_as_rvalue)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_as_rvalue 202207L
@@ -1850,7 +1861,7 @@
 #endif /* !defined(__cpp_lib_ranges_as_rvalue) && defined(__glibcxx_want_ranges_as_rvalue) */
 #undef __glibcxx_want_ranges_as_rvalue
 
-// from version.def line 1531
+// from version.def line 1540
 #if !defined(__cpp_lib_ranges_as_const)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_as_const 202207L
@@ -1861,7 +1872,7 @@
 #endif /* !defined(__cpp_lib_ranges_as_const) && defined(__glibcxx_want_ranges_as_const) */
 #undef __glibcxx_want_ranges_as_const
 
-// from version.def line 1539
+// from version.def line 1548
 #if !defined(__cpp_lib_ranges_enumerate)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_enumerate 202302L
@@ -1872,7 +1883,7 @@
 #endif /* !defined(__cpp_lib_ranges_enumerate) && defined(__glibcxx_want_ranges_enumerate) */
 #undef __glibcxx_want_ranges_enumerate
 
-// from version.def line 1547
+// from version.def line 1556
 #if !defined(__cpp_lib_ranges_fold)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_fold 202207L
@@ -1883,7 +1894,7 @@
 #endif /* !defined(__cpp_lib_ranges_fold) && defined(__glibcxx_want_ranges_fold) */
 #undef __glibcxx_want_ranges_fold
 
-// from version.def line 1555
+// from version.def line 1564
 #if !defined(__cpp_lib_ranges_contains)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_contains 202207L
@@ -1894,7 +1905,7 @@
 #endif /* !defined(__cpp_lib_ranges_contains) && defined(__glibcxx_want_ranges_contains) */
 #undef __glibcxx_want_ranges_contains
 
-// from version.def line 1563
+// from version.def line 1572
 #if !defined(__cpp_lib_ranges_iota)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_iota 202202L
@@ -1905,7 +1916,7 @@
 #endif /* !defined(__cpp_lib_ranges_iota) && defined(__glibcxx_want_ranges_iota) */
 #undef __glibcxx_want_ranges_iota
 
-// from version.def line 1571
+// from version.def line 1580
 #if !defined(__cpp_lib_ranges_find_last)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_find_last 202207L
@@ -1916,7 +1927,7 @@
 #endif /* !defined(__cpp_lib_ranges_find_last) && defined(__glibcxx_want_ranges_find_last) */
 #undef __glibcxx_want_ranges_find_last
 
-// from version.def line 1579
+// from version.def line 1588
 #if !defined(__cpp_lib_constexpr_bitset)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (__cpp_constexpr_dynamic_alloc)
 #  define __glibcxx_constexpr_bitset 202202L
@@ -1927,7 +1938,7 @@
 #endif /* !defined(__cpp_lib_constexpr_bitset) && defined(__glibcxx_want_constexpr_bitset) */
 #undef __glibcxx_want_constexpr_bitset
 
-// from version.def line 1589
+// from version.def line 1598
 #if !defined(__cpp_lib_stdatomic_h)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_stdatomic_h 202011L
@@ -1938,7 +1949,7 @@
 #endif /* !defined(__cpp_lib_stdatomic_h) && defined(__glibcxx_want_stdatomic_h) */
 #undef __glibcxx_want_stdatomic_h
 
-// from version.def line 1597
+// from version.def line 1606
 #if !defined(__cpp_lib_adaptor_iterator_pair_constructor)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_adaptor_iterator_pair_constructor 202106L
@@ -1949,7 +1960,7 @@
 #endif /* !defined(__cpp_lib_adaptor_iterator_pair_constructor) && defined(__glibcxx_want_adaptor_iterator_pair_constructor) */
 #undef __glibcxx_want_adaptor_iterator_pair_constructor
 
-// from version.def line 1606
+// from version.def line 1615
 #if !defined(__cpp_lib_formatters)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_formatters 202302L
@@ -1960,7 +1971,7 @@
 #endif /* !defined(__cpp_lib_formatters) && defined(__glibcxx_want_formatters) */
 #undef __glibcxx_want_formatters
 
-// from version.def line 1615
+// from version.def line 1624
 #if !defined(__cpp_lib_forward_like)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_forward_like 202207L
@@ -1971,7 +1982,7 @@
 #endif /* !defined(__cpp_lib_forward_like) && defined(__glibcxx_want_forward_like) */
 #undef __glibcxx_want_forward_like
 
-// from version.def line 1623
+// from version.def line 1632
 #if !defined(__cpp_lib_ios_noreplace)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_ios_noreplace 202207L
@@ -1982,7 +1993,7 @@
 #endif /* !defined(__cpp_lib_ios_noreplace) && defined(__glibcxx_want_ios_noreplace) */
 #undef __glibcxx_want_ios_noreplace
 
-// from version.def line 1632
+// from version.def line 1641
 #if !defined(__cpp_lib_move_only_function)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_move_only_function 202110L
@@ -1993,7 +2004,7 @@
 #endif /* !defined(__cpp_lib_move_only_function) && defined(__glibcxx_want_move_only_function) */
 #undef __glibcxx_want_move_only_function
 
-// from version.def line 1641
+// from version.def line 1650
 #if !defined(__cpp_lib_out_ptr)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_out_ptr 202311L
@@ -2004,7 +2015,7 @@
 #endif /* !defined(__cpp_lib_out_ptr) && defined(__glibcxx_want_out_ptr) */
 #undef __glibcxx_want_out_ptr
 
-// from version.def line 1649
+// from version.def line 1658
 #if !defined(__cpp_lib_print)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_print 202211L
@@ -2015,7 +2026,7 @@
 #endif /* !defined(__cpp_lib_print) && defined(__glibcxx_want_print) */
 #undef __glibcxx_want_print
 
-// from version.def line 1658
+// from version.def line 1667
 #if !defined(__cpp_lib_spanstream)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (__glibcxx_span)
 #  define __glibcxx_spanstream 202106L
@@ -2026,7 +2037,7 @@
 #endif /* !defined(__cpp_lib_spanstream) && defined(__glibcxx_want_spanstream) */
 #undef __glibcxx_want_spanstream
 
-// from version.def line 1668
+// from version.def line 1677
 #if !defined(__cpp_lib_stacktrace)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && (_GLIBCXX_HAVE_STACKTRACE)
 #  define __glibcxx_stacktrace 202011L
@@ -2037,7 +2048,7 @@
 #endif /* !defined(__cpp_lib_stacktrace) && defined(__glibcxx_want_stacktrace) */
 #undef __glibcxx_want_stacktrace
 
-// from version.def line 1678
+// from version.def line 1687
 #if !defined(__cpp_lib_string_contains)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_string_contains 202011L
@@ -2048,7 +2059,7 @@
 #endif /* !defined(__cpp_lib_string_contains) && defined(__glibcxx_want_string_contains) */
 #undef __glibcxx_want_string_contains
 
-// from version.def line 1687
+// from version.def line 1696
 #if !defined(__cpp_lib_string_resize_and_overwrite)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_string_resize_and_overwrite 202110L
@@ -2059,7 +2070,7 @@
 #endif /* !defined(__cpp_lib_string_resize_and_overwrite) && defined(__glibcxx_want_string_resize_and_overwrite) */
 #undef __glibcxx_want_string_resize_and_overwrite
 
-// from version.def line 1696
+// from version.def line 1705
 #if !defined(__cpp_lib_to_underlying)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_to_underlying 202102L
@@ -2070,7 +2081,7 @@
 #endif /* !defined(__cpp_lib_to_underlying) && defined(__glibcxx_want_to_underlying) */
 #undef __glibcxx_want_to_underlying
 
-// from version.def line 1704
+// from version.def line 1713
 #if !defined(__cpp_lib_unreachable)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_unreachable 202202L
@@ -2081,7 +2092,7 @@
 #endif /* !defined(__cpp_lib_unreachable) && defined(__glibcxx_want_unreachable) */
 #undef __glibcxx_want_unreachable
 
-// from version.def line 1712
+// from version.def line 1721
 #if !defined(__cpp_lib_fstream_native_handle)
 # if (__cplusplus >  202302L) && _GLIBCXX_HOSTED
 #  define __glibcxx_fstream_native_handle 202306L
@@ -2092,7 +2103,7 @@
 #endif /* !defined(__cpp_lib_fstream_native_handle) && defined(__glibcxx_want_fstream_native_handle) */
 #undef __glibcxx_want_fstream_native_handle
 
-// from version.def line 1721
+// from version.def line 1730
 #if !defined(__cpp_lib_ratio)
 # if (__cplusplus >  202302L)
 #  define __glibcxx_ratio 202306L
@@ -2103,7 +2114,7 @@
 #endif /* !defined(__cpp_lib_ratio) && defined(__glibcxx_want_ratio) */
 #undef __glibcxx_want_ratio
 
-// from version.def line 1729
+// from version.def line 1738
 #if !defined(__cpp_lib_saturation_arithmetic)
 # if (__cplusplus >  202302L)
 #  define __glibcxx_saturation_arithmetic 202311L
@@ -2114,7 +2125,7 @@
 #endif /* !defined(__cpp_lib_saturation_arithmetic) && defined(__glibcxx_want_saturation_arithmetic) */
 #undef __glibcxx_want_saturation_arithmetic
 
-// from version.def line 1737
+// from version.def line 1746
 #if !defined(__cpp_lib_to_string)
 # if (__cplusplus >  202302L) && _GLIBCXX_HOSTED && (__glibcxx_to_chars)
 #  define __glibcxx_to_string 202306L
@@ -2125,9 +2136,9 @@
 #endif /* !defined(__cpp_lib_to_string) && defined(__glibcxx_want_to_string) */
 #undef __glibcxx_want_to_string
 
-// from version.def line 1637
+// from version.def line 1756
 #if !defined(__cpp_lib_generator)
-# if (__cplusplus >= 202302L) && (__glibcxx_coroutine)
+# if (__cplusplus >= 202100L) && (__glibcxx_coroutine)
 #  define __glibcxx_generator 202207L
 #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_generator)
 #   define __cpp_lib_generator 202207L
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 1110ba4ab16..886c7c64c14 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -35,6 +35,7 @@
 
 #define __glibcxx_want_format
 #define __glibcxx_want_format_ranges
+#define __glibcxx_want_format_uchar
 #include <bits/version.h>
 
 #ifdef __cpp_lib_format // C++ >= 20 && HOSTED
@@ -1804,7 +1805,8 @@ namespace __format
 	typename basic_format_context<_Out, _CharT>::iterator
 	format(_CharT __u, basic_format_context<_Out, _CharT>& __fc) const
 	{
-	  if (_M_f._M_spec._M_type == __format::_Pres_none)
+	  if (_M_f._M_spec._M_type == __format::_Pres_none
+	      || _M_f._M_spec._M_type == __format::_Pres_c)
 	    return _M_f._M_format_character(__u, __fc);
 	  else if (_M_f._M_spec._M_type == __format::_Pres_esc)
 	    {
@@ -1812,7 +1814,7 @@ namespace __format
 	      return __fc.out();
 	    }
 	  else
-	    return _M_f.format(__u, __fc);
+	    return _M_f.format(static_cast<make_unsigned_t<_CharT>>(__u), __fc);
 	}
 
 #if __cpp_lib_format_ranges
@@ -1842,7 +1844,8 @@ namespace __format
 	typename basic_format_context<_Out, wchar_t>::iterator
 	format(char __u, basic_format_context<_Out, wchar_t>& __fc) const
 	{
-	  if (_M_f._M_spec._M_type == __format::_Pres_none)
+	  if (_M_f._M_spec._M_type == __format::_Pres_none
+	      || _M_f._M_spec._M_type == __format::_Pres_c)
 	    return _M_f._M_format_character(__u, __fc);
 	  else if (_M_f._M_spec._M_type == __format::_Pres_esc)
 	    {
@@ -1850,7 +1853,7 @@ namespace __format
 	      return __fc.out();
 	    }
 	  else
-	    return _M_f.format(__u, __fc);
+	    return _M_f.format(static_cast<unsigned char>(__u), __fc);
 	}
 
 #if __cpp_lib_format_ranges
@@ -3399,6 +3402,9 @@ namespace __format
 	  using _Td = _Normalize<_Tp>;
 	  if constexpr (is_same_v<_Td, basic_string_view<_CharT>>)
 	    _M_set(_Td{__v.data(), __v.size()});
+	  else if constexpr (is_same_v<remove_const_t<_Tp>, char>
+			       && is_same_v<_CharT, wchar_t>)
+	    _M_set(static_cast<_Td>(static_cast<unsigned char>(__v)));
 	  else
 	    _M_set(static_cast<_Td>(__v));
 	}
diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc
index b3b4f0647bc..6bf7a126ed1 100644
--- a/libstdc++-v3/testsuite/std/format/functions/format.cc
+++ b/libstdc++-v3/testsuite/std/format/functions/format.cc
@@ -9,6 +9,12 @@
 # error "Feature test macro for std::format has wrong value in <format>"
 #endif
 
+#ifndef __cpp_lib_format_uchar
+# error "Feature test macro for formatting chars as integers is missing in <format>"
+#elif __cpp_lib_format_uchar < 202311L
+# error "Feature test macro for formatting chars as integers has wrong value in <format>"
+#endif
+
 #undef __cpp_lib_format
 #include <version>
 #ifndef __cpp_lib_format
@@ -17,6 +23,12 @@
 # error "Feature test macro for std::format has wrong value in <version>"
 #endif
 
+#ifndef __cpp_lib_format_uchar
+# error "Feature test macro for formatting chars as integers is missing in <version>"
+#elif __cpp_lib_format_uchar < 202311L
+# error "Feature test macro for formatting chars as integers has wrong value in <version>"
+#endif
+
 #include <string>
 #include <limits>
 #include <cstdint>
@@ -274,13 +286,16 @@ test_char()
   VERIFY( s == "0023 0077" );
 
   s = std::format("{:b} {:B} {:#b} {:#B}", '\xff', '\xa0', '\x17', '\x3f');
-  if constexpr (std::is_unsigned_v<char>)
-    VERIFY( s == "11111111 10100000 0b10111 0B111111" );
-  else
-    VERIFY( s == "-1 -1100000 0b10111 0B111111" );
+  VERIFY( s == "11111111 10100000 0b10111 0B111111" );
 
   s = std::format("{:x} {:#x} {:#X}", '\x12', '\x34', '\x45');
   VERIFY( s == "12 0x34 0X45" );
+
+  // P2909R4 Fix formatting of code units as integers (Dude, where’s my char?)
+  // char and wchar_t should be converted to unsigned when formatting them
+  // with an integer presentation type.
+  s = std::format("{0:b} {0:B} {0:d} {0:o} {0:x} {0:X}", '\xf0');
+  VERIFY( s == "11110000 11110000 240 360 f0 F0" );
 }
 
 void
@@ -313,6 +328,10 @@ test_wchar()
 
   s = std::format(L"{0:#b} {0:#B} {0:#x} {0:#X}", 99);
   VERIFY( s == L"0b1100011 0B1100011 0x63 0X63" );
+
+  // P2909R4 Fix formatting of code units as integers (Dude, where’s my char?)
+  s = std::format(L"{:d} {:d}", wchar_t(-1), char(-1));
+  VERIFY( s.find('-') == std::wstring::npos );
 }
 
 void

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-01-08  1:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-08  1:15 [gcc r14-6990] libstdc++: Implement P2909R4 ("Dude, where's my char?") for C++20 Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).