From patchwork Mon Jan 8 01:15:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1883449 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=eP1AZjeb; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T7bkj3gzgz1yP7 for ; Mon, 8 Jan 2024 12:17:01 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 56999386187C for ; Mon, 8 Jan 2024 01:16:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id BFEFB385803B for ; Mon, 8 Jan 2024 01:16:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BFEFB385803B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BFEFB385803B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704676593; cv=none; b=gYLanytK6O5VUIbuCVM+y2HBHouqKER4VEgE5SMR060LSg+ArJRJyPNsutK1mu4S0HYoEtkxrn9J9AHuBv7oSMfbp3ww2RCzsyG3g6p7JRHYOXc5KHzBayFY62jwe2DxONx0Q23cmf0rMeRKlloI4q4FcF7JMlwU7kvdtdT9bPU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704676593; c=relaxed/simple; bh=agzyAp4MeEFfGxi+1yxYGkcBBSQRnbt+VWG8C90iDRM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=c4QrkZhluEyBk/oD0qhZfStqmPBluVYILiK1kFjTUJoidjN18nDzcImAQ6XLspM9i4fNaBgeb3+n9S0JZm4cbveWISo46vc95rrVzLwDQbz7rsbzPUR24AgWnabpOnlcfav7baAThP0vAPUBB4voENn1Fxhx7Rjut75vmVaPLNc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1704676589; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=RaHCa1VgFE4bFD56hDdpCR+y7vGk/DU+6g9CmEi6bmk=; b=eP1AZjeb+i7EU1K2/2ViYl1ipnAdvUcDxJN5vl7KttRmoAUQuMRDVZdDtfik7PJQjI+LNY RbtD7bZr6STUbOmFv2jDGo7TivwijqCQBn3KGk8jXzDeuUHeF7Sm25wx68G0zE7J9RSX1j C/f7WkJRCGTIecufY/q8rfZhbB2eACo= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-112-flRFR-06N2S4BvYzv0EkKQ-1; Sun, 07 Jan 2024 20:16:23 -0500 X-MC-Unique: flRFR-06N2S4BvYzv0EkKQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C2EB5862DE1; Mon, 8 Jan 2024 01:16:22 +0000 (UTC) Received: from localhost (unknown [10.42.28.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id 42AF95190; Mon, 8 Jan 2024 01:16:22 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Implement P2909R4 ("Dude, where's my char?") for C++20 Date: Mon, 8 Jan 2024 01:15:50 +0000 Message-ID: <20240108011621.3670359-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, PP_MIME_FAKE_ASCII_TEXT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Tested x86_64-linux and aarch64-linux. Pushed to trunk. -- >8 -- 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::format): Check for _Pres_c and call _M_format_character directly. Cast C to its unsigned equivalent for formatting as an integer. (formatter::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 --- 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 #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>(__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(__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, char> + && is_same_v<_CharT, wchar_t>) + _M_set(static_cast<_Td>(static_cast(__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 " #endif +#ifndef __cpp_lib_format_uchar +# error "Feature test macro for formatting chars as integers is missing in " +#elif __cpp_lib_format_uchar < 202311L +# error "Feature test macro for formatting chars as integers has wrong value in " +#endif + #undef __cpp_lib_format #include #ifndef __cpp_lib_format @@ -17,6 +23,12 @@ # error "Feature test macro for std::format has wrong value in " #endif +#ifndef __cpp_lib_format_uchar +# error "Feature test macro for formatting chars as integers is missing in " +#elif __cpp_lib_format_uchar < 202311L +# error "Feature test macro for formatting chars as integers has wrong value in " +#endif + #include #include #include @@ -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) - 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