From patchwork Tue Jul 16 11:56:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1961062 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=RqUG7hJJ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; 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 [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4WNd9p2MVHz1xrQ for ; Tue, 16 Jul 2024 22:07:42 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 946B2384A058 for ; Tue, 16 Jul 2024 12:07:40 +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.129.124]) by sourceware.org (Postfix) with ESMTPS id 7D517384A05A for ; Tue, 16 Jul 2024 12:04:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7D517384A05A 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 7D517384A05A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721131499; cv=none; b=u2KpJJ5EbkqqiuhpiBBN5PFUz0Shd9/j3mQCoeH+inm5Is3KVuOePrFnIp5EYZuo6gOnQyX0mKsuoS905EOQwrUXKzIlF1LML7Dbc80iCmuyzjnAN/1QW5o6PCp/GGGVB/TAsqnD09va2ClFqEuTZyX9dgzGaKPGV9pD2g776XE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721131499; c=relaxed/simple; bh=R99lnCMpFJu4LSNhBPaXystF7bmw0gH1vTQsbroj4ks=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=LDiybmZNrmWeSC1mJRDz7GNea/pZrUsyJAlA3cVDGVtG3z1QRfim57b7wgIPYbnb0WQMTCWcYwm7W7WccoGW1M6Uc5VzyC2JYhgfygKYDdyvPxcE71qA29xxTTvmhSAY99dUu93JZdIuhrCgKsjDv3qjpNuq7cJdDV73Zo0Ewdw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721131493; 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: in-reply-to:in-reply-to:references:references; bh=69UR+FpFmtepx4MFg61pD+j57zMdG7/Nc6xSL0yDpac=; b=RqUG7hJJO1+CEPz8p2kxQwqGLWuvgiwfg1lMdGFwZR826I8hp50tFbwIANLpEg1nc1+LW3 FT6LgqBRaxApc+A24g1BgIX6Uo88RBboyz5BqFEFiye1exck3Nz57C5eDEaYlP+who1mgz oJFm37q5LJkj8bIHG3gvMuflvT+tEHg= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-267-OTjxh20VPPy4XbNlkBfAcA-1; Tue, 16 Jul 2024 08:04:49 -0400 X-MC-Unique: OTjxh20VPPy4XbNlkBfAcA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5CE861955F3D; Tue, 16 Jul 2024 12:04:48 +0000 (UTC) Received: from localhost (unknown [10.42.28.14]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CFDAA1955F40; Tue, 16 Jul 2024 12:04:47 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH 5/6] libstdc++: Define C++26 member visit for std::basic_format_arg [PR110356] Date: Tue, 16 Jul 2024 12:56:01 +0100 Message-ID: <20240716120436.2135312-5-jwakely@redhat.com> In-Reply-To: <20240716120436.2135312-1-jwakely@redhat.com> References: <20240716120436.2135312-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham 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. -- >8 -- Implement the std::format changes from P2637R3. This adds visit member functions to std::basic_format_arg and deprecates the non-member function std::visit_format_arg. libstdc++-v3/ChangeLog: PR libstdc++/110356 * include/bits/c++config (_GLIBCXX26_DEPRECATED): Define. (_GLIBCXX26_DEPRECATED_SUGGEST): Define. * include/bits/version.def (format): Update for C++26. * include/bits/version.h: Regenerate. * include/std/format (basic_format_arg::visit): New member functions. (visit_format_arg): Add deprecated attribute. * testsuite/std/format/arguments/args.cc: Expect deprecated warnings. Check member visit. * testsuite/std/format/functions/format.cc: Update expected value for __cpp_lib_format macro. * testsuite/std/format/parse_ctx.cc: Add dg-warning for deprecation. --- libstdc++-v3/include/bits/c++config | 10 +++++ libstdc++-v3/include/bits/version.def | 2 +- libstdc++-v3/include/bits/version.h | 4 +- libstdc++-v3/include/std/format | 16 +++++++ .../testsuite/std/format/arguments/args.cc | 43 +++++++++++++++++++ .../testsuite/std/format/functions/format.cc | 4 +- .../testsuite/std/format/parse_ctx.cc | 2 +- 7 files changed, 75 insertions(+), 6 deletions(-) diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 6dca2d9467a..0f0cc7cd659 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -90,6 +90,8 @@ // _GLIBCXX20_DEPRECATED_SUGGEST( string-literal ) // _GLIBCXX23_DEPRECATED // _GLIBCXX23_DEPRECATED_SUGGEST( string-literal ) +// _GLIBCXX26_DEPRECATED +// _GLIBCXX26_DEPRECATED_SUGGEST( string-literal ) #ifndef _GLIBCXX_USE_DEPRECATED # define _GLIBCXX_USE_DEPRECATED 1 #endif @@ -143,6 +145,14 @@ # define _GLIBCXX23_DEPRECATED_SUGGEST(ALT) #endif +#if defined(__DEPRECATED) && (__cplusplus >= 202400L) +# define _GLIBCXX26_DEPRECATED [[__deprecated__]] +# define _GLIBCXX26_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT) +#else +# define _GLIBCXX26_DEPRECATED +# define _GLIBCXX26_DEPRECATED_SUGGEST(ALT) +#endif + // Macros for ABI tag attributes. #ifndef _GLIBCXX_ABI_TAG_CXX11 # define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 806f1e9549b..ec330911d66 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -1171,7 +1171,7 @@ ftms = { // 202306 P2637R3 Member visit // 202311 P2918R2 Runtime format strings II values = { - v = 202305; + v = 202306; cxxmin = 26; hosted = yes; }; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index e8ca0faf5dc..148ee87e087 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -1310,9 +1310,9 @@ #if !defined(__cpp_lib_format) # if (__cplusplus > 202302L) && _GLIBCXX_HOSTED -# define __glibcxx_format 202305L +# define __glibcxx_format 202306L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_format) -# define __cpp_lib_format 202305L +# define __cpp_lib_format 202306L # endif # elif (__cplusplus >= 202002L) && _GLIBCXX_HOSTED # define __glibcxx_format 202304L diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 0e61bc5e6bc..f1a1f736a80 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -3346,6 +3346,18 @@ namespace __format explicit operator bool() const noexcept { return _M_type != __format::_Arg_none; } +#if __cpp_lib_format >= 202306L // >= C++26 + template + decltype(auto) + visit(this basic_format_arg __arg, _Visitor&& __vis) + { return __arg._M_visit(std::forward<_Visitor>(__vis), __arg._M_type); } + + template + _Res + visit(this basic_format_arg __arg, _Visitor&& __vis) + { return __arg._M_visit(std::forward<_Visitor>(__vis), __arg._M_type); } +#endif + private: template friend class basic_format_args; @@ -3631,6 +3643,7 @@ namespace __format }; template + _GLIBCXX26_DEPRECATED_SUGGEST("std::basic_format_arg::visit") inline decltype(auto) visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { @@ -3666,6 +3679,8 @@ namespace __format } }; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" template inline size_t __int_from_arg(const basic_format_arg<_Context>& __arg) @@ -4299,6 +4314,7 @@ namespace __format else return std::move(__sink)._M_finish().out; } +#pragma GCC diagnostic pop } // namespace __format /// @endcond diff --git a/libstdc++-v3/testsuite/std/format/arguments/args.cc b/libstdc++-v3/testsuite/std/format/arguments/args.cc index eba129ff894..4e0eb69262b 100644 --- a/libstdc++-v3/testsuite/std/format/arguments/args.cc +++ b/libstdc++-v3/testsuite/std/format/arguments/args.cc @@ -3,6 +3,8 @@ #include #include +// { dg-warning "deprecated" "" { target c++26 } 0 } + template bool equals(std::basic_format_arg fmt_arg, T expected) { return std::visit_format_arg([=](auto arg_val) { @@ -51,6 +53,9 @@ test_args() char c = '2'; double d = 3.4; + // We need an lvalue of type format-arg-store for the + // lvalue args to point to, otherwise it will have a dangling pointer. + // This is not how you're supposed to use format args, just for testing. auto store = std::make_format_args(b, i, c, d); std::format_args args = store; VERIFY(equals(args.get(0), false)); @@ -102,8 +107,46 @@ test_args() VERIFY(std::visit_format_arg(is_handle, args.get(1))); } +void +test_member_visit() +{ +#if __cpp_lib_format >= 202306L // C++26 adds std::basic_format_arg::visit + int one = 1; + float two = 2.0; + std::string_view three = "three"; + auto store = std::make_format_args(one, two, three); // See comment above. + std::format_args args = store; + auto a1 = args.get(0).visit([=](auto a) { + if constexpr (std::is_same_v) + return a == one; + return false; + }); + VERIFY( a1 ); + auto a2 = args.get(1).visit([=](auto a) { + if constexpr (std::is_same_v) + return a == two; + return false; + }); + VERIFY( a2 ); + auto a3 = args.get(2).visit([=](auto a) { + if constexpr (std::is_same_v) + return a == three; + return false; + }); + VERIFY( a3 ); + + auto a4 = args.get(0).visit([](auto) { return "str"; }); + static_assert( std::is_same_v ); + VERIFY( a4 == "str" ); + args.get(0).visit([](auto){}); + using V = decltype(args.get(0).visit([](auto){})); + static_assert( std::is_same_v ); +#endif +} + int main() { test_empty(); test_args(); + test_member_visit(); } diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc index 3c441d711b3..0549d171e5a 100644 --- a/libstdc++-v3/testsuite/std/format/functions/format.cc +++ b/libstdc++-v3/testsuite/std/format/functions/format.cc @@ -8,7 +8,7 @@ # error "Feature test macro for std::format is missing in " #elif __cpp_lib_format < 202110L # error "Feature test macro for std::format has wrong value in " -#elif __cplusplus > 202302L && __cpp_lib_format < 202305L +#elif __cplusplus > 202302L && __cpp_lib_format < 202306L # error "Feature test macro for std::format has wrong value in " #endif @@ -24,7 +24,7 @@ # error "Feature test macro for std::format is missing in " #elif __cpp_lib_format < 202110L # error "Feature test macro for std::format has wrong value in " -#elif __cplusplus > 202302L && __cpp_lib_format < 202305L +#elif __cplusplus > 202302L && __cpp_lib_format < 202306L # error "Feature test macro for std::format has wrong value in " #endif diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx.cc b/libstdc++-v3/testsuite/std/format/parse_ctx.cc index b0cef2da41b..88ffd77debe 100644 --- a/libstdc++-v3/testsuite/std/format/parse_ctx.cc +++ b/libstdc++-v3/testsuite/std/format/parse_ctx.cc @@ -473,7 +473,7 @@ struct std::formatter std::format_context::iterator format(X, std::format_context& c) const { - std::visit_format_arg([this](T) { + std::visit_format_arg([this](T) { // { dg-warning "deprecated" "" { target c++26 } } if (is_integral_v != this->integer) throw std::format_error("invalid argument type"); }, c.arg(1));