From patchwork Thu Feb 16 14:39:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 58111 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2388:b0:96:219d:e725 with SMTP id i8csp566843dyf; Thu, 16 Feb 2023 06:41:15 -0800 (PST) X-Google-Smtp-Source: AK7set9r9NAM7pOEvGVTxibObhX6Jg53WHxbBKS9iyJXsOygdtLnoVhDoRxI7M+aWydyUkRhnigB X-Received: by 2002:a17:906:e253:b0:8a9:e031:c4ae with SMTP id gq19-20020a170906e25300b008a9e031c4aemr6414437ejb.2.1676558475297; Thu, 16 Feb 2023 06:41:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676558475; cv=none; d=google.com; s=arc-20160816; b=Lj5u/3BWfQW1uEk0WNlsxg/Orw4ljGNwjx70u5lbaYDiE0P37f31S56gw/DWD17RXT NuU2LlKo/oVeB4iFUCLY/W4PLPu6kYkWSi5tCQCTa2TvwmRqO7cL1jnWcbQO68CzvZcT uU4zf5O4sEUWCsWTKxJuijlIiZSQzFoMy9/64wcc0z2FbBA6iiRLMn1iDI//G6LhtbtB pFMXmO7Vldb+nDO4T7ZqIb0ltzdC/AJwR5wFsrbpC70M7YzWk4VpZIn984LlAkTJ+yB4 3UKo5UrF1MjCyHmmS69PbHq3/deAAyzsD0vVZPSCGpAVy9S0tx3r+MZmU2pxtb+iYmwu Pzyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=Wrkkr49gDYvnF3A840ySIqtfZpcwRzm2Jx8qdTpAe78=; b=u8AW1HJJJEQ/AjXsOX5vA8oGQQbJjsZ8O979rgzZXgNuV44ZqjXrWON3g4dgvNHuVz NB/yu7iYUqAZIF0VfGcTe+9L6Npsu8jC8MRld3ypI99B7uILBgHcanU0mMGHLDnOAhT/ 0OR2C8RuWi8MdSTtxRNV9TheqqvPt0zAPTUmpD/Vgh18G6tvoqgRNKwFL74c0dqpEbDX 7oCBnE20+bcKEGl8ypWmtrqZsqifYWbuNi9dyBtUn+Q8fusBvca526ZFqkpn52XSKez1 sGm5JSJj4cTlqOSjVqAEAufUyqdz0QqlgFr3IBMg2QOr460FTQMxOhVHlfBNdd6v/qXZ C3sg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kQagB2po; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id up18-20020a170907cc9200b0088fa3b44d5csi1817388ejc.468.2023.02.16.06.41.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Feb 2023 06:41:15 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kQagB2po; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1F3F63888C7F for ; Thu, 16 Feb 2023 14:40:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1F3F63888C7F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676558415; bh=Wrkkr49gDYvnF3A840ySIqtfZpcwRzm2Jx8qdTpAe78=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=kQagB2po9J53pepeaocuLl8Hh9JL3ON7N4J8rZ/CaaavgSh/mvqtykls3vDNQR3fX V2v2pbITfOxaJSY3E46C4fgTTGe10sOvgDLQFDla6Xx/bYmJwCqOt1RGY13WLHJ7cx ZwSL/QCu2WcDA7hUy791FXJdVqAjXmE3zrrSsWrc= 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 890993858291 for ; Thu, 16 Feb 2023 14:39:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 890993858291 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-180-E8soAlKqPWiwEknwf2xsGw-1; Thu, 16 Feb 2023 09:39:27 -0500 X-MC-Unique: E8soAlKqPWiwEknwf2xsGw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id CBA7A80280C; Thu, 16 Feb 2023 14:39:26 +0000 (UTC) Received: from localhost (unknown [10.33.37.21]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9221E4024BDC; Thu, 16 Feb 2023 14:39:26 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Enable CTAD for std::basic_format_args (LWG 3810) Date: Thu, 16 Feb 2023 14:39:26 +0000 Message-Id: <20230216143926.138064-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, PP_MIME_FAKE_ASCII_TEXT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757998980160765093?= X-GMAIL-MSGID: =?utf-8?q?1757998980160765093?= Tested powerpc64le-linux. Pushed to trunk. -- >8 -- This was just approved in Issaquah. libstdc++-v3/ChangeLog: * include/std/format (__format::_Arg_store): New class template. (basic_format_args): Remove nested type _Store and add deduction guide from _Arg_store. (basic_format_arg, make_format_args): Adjust. * testsuite/std/format/arguments/lwg3810.cc: New test. --- libstdc++-v3/include/std/format | 101 ++++++++++-------- .../testsuite/std/format/arguments/lwg3810.cc | 25 +++++ 2 files changed, 82 insertions(+), 44 deletions(-) create mode 100644 libstdc++-v3/testsuite/std/format/arguments/lwg3810.cc diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 1cce4ebd45c..b1e627048de 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -2757,6 +2757,10 @@ namespace __format } }; + // [format.arg.store], class template format-arg-store + template + class _Arg_store; + } // namespace __format /// @endcond @@ -2833,6 +2837,9 @@ namespace __format template friend class basic_format_args; + template + friend class __format::_Arg_store; + static_assert(is_trivially_copyable_v<__format::_Arg_value<_Context>>); __format::_Arg_value<_Context> _M_val; @@ -3150,11 +3157,11 @@ namespace __format static_assert( __format::_Arg_max_ <= (1 << _S_packed_type_bits) ); - // [format.arg.store], class template format-arg-store - // XXX: Should this be defined outside the class, so basic_format_args - // can use CTAD with a _Store argument? template - class _Store; + using _Store = __format::_Arg_store<_Context, _Args...>; + + template + friend class __format::_Arg_store; using uint64_t = __UINT64_TYPE__; using _Format_arg = basic_format_arg<_Context>; @@ -3215,52 +3222,60 @@ namespace __format } }; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3810. CTAD for std::basic_format_args + template + basic_format_args(__format::_Arg_store<_Context, _Args...>) + -> basic_format_args<_Context>; + + template + auto + make_format_args(_Args&&... __fmt_args) noexcept; + // An array of type-erased formatting arguments. - template - template - class basic_format_args<_Context>::_Store - { - friend class basic_format_args; + template + class __format::_Arg_store + { + friend std::basic_format_args<_Context>; - template - friend auto - make_format_args(_Argz&&...) noexcept; + template + friend auto + std::make_format_args(_Argz&&...) noexcept; - // For a sufficiently small number of arguments we only store values. - // basic_format_args can get the types from the _Args pack. - static constexpr bool _S_values_only - = sizeof...(_Args) <= _S_max_packed_args; + // For a sufficiently small number of arguments we only store values. + // basic_format_args can get the types from the _Args pack. + static constexpr bool _S_values_only + = sizeof...(_Args) <= basic_format_args<_Context>::_S_max_packed_args; - using _Element_t - = __conditional_t<_S_values_only, - __format::_Arg_value<_Context>, - basic_format_arg<_Context>>; + using _Element_t + = __conditional_t<_S_values_only, + __format::_Arg_value<_Context>, + basic_format_arg<_Context>>; - _Element_t _M_args[sizeof...(_Args)]; + _Element_t _M_args[sizeof...(_Args)]; - template - static _Element_t - _S_make_elt(_Tp& __v) - { - basic_format_arg<_Context> __arg(__v); - if constexpr (_S_values_only) - return __arg._M_val; - else - return __arg; - } + template + static _Element_t + _S_make_elt(_Tp& __v) + { + basic_format_arg<_Context> __arg(__v); + if constexpr (_S_values_only) + return __arg._M_val; + else + return __arg; + } - template - requires (sizeof...(_Tp) == sizeof...(_Args)) - [[__gnu__::__always_inline__]] - _Store(_Tp&... __a) noexcept - : _M_args{_S_make_elt(__a)...} - { } - }; + template + requires (sizeof...(_Tp) == sizeof...(_Args)) + [[__gnu__::__always_inline__]] + _Arg_store(_Tp&... __a) noexcept + : _M_args{_S_make_elt(__a)...} + { } + }; template - template requires (sizeof...(_Args) == 0) - class basic_format_args<_Context>::_Store<_Args...> - { }; + class __format::_Arg_store<_Context> + { }; template template @@ -3300,10 +3315,8 @@ namespace __format inline auto make_format_args(_Args&&... __fmt_args) noexcept { - using _Fmt_args = basic_format_args<_Context>; using _Fmt_arg = basic_format_arg<_Context>; - using _Store = typename _Fmt_args::template - _Store>...>; return _Store(__fmt_args...); } diff --git a/libstdc++-v3/testsuite/std/format/arguments/lwg3810.cc b/libstdc++-v3/testsuite/std/format/arguments/lwg3810.cc new file mode 100644 index 00000000000..c1be229040f --- /dev/null +++ b/libstdc++-v3/testsuite/std/format/arguments/lwg3810.cc @@ -0,0 +1,25 @@ +// { dg-do compile { target c++20 } } +// { dg-options "-std=gnu++20" } + +// LWG 3810. CTAD for std::basic_format_args + +#include + +auto args_store = std::make_format_args(1,2,3); +std::basic_format_args args = args_store; +static_assert(std::is_same_v); + + +template +void foo(std::basic_format_args); + +void +test_ctad() +{ + using std::basic_format_args; + using std::make_format_args; + using SomeContext = std::wformat_context; + + // foo(make_format_args(…)); // won't work + foo(basic_format_args(make_format_args(1, 2, 3))); // should work +}