public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r13-6085] libstdc++: Enable CTAD for std::basic_format_args (LWG 3810) Date: Thu, 16 Feb 2023 14:38:55 +0000 (GMT) [thread overview] Message-ID: <20230216143855.07DA1385B513@sourceware.org> (raw) https://gcc.gnu.org/g:4024f39941f30570afc32324a8a567519a30e0cd commit r13-6085-g4024f39941f30570afc32324a8a567519a30e0cd Author: Jonathan Wakely <jwakely@redhat.com> Date: Mon Feb 13 12:22:00 2023 +0000 libstdc++: Enable CTAD for std::basic_format_args (LWG 3810) 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. Diff: --- libstdc++-v3/include/std/format | 101 ++++++++++++--------- .../testsuite/std/format/arguments/lwg3810.cc | 25 +++++ 2 files changed, 82 insertions(+), 44 deletions(-) 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<typename _Context, typename... _Args> + class _Arg_store; + } // namespace __format /// @endcond @@ -2833,6 +2837,9 @@ namespace __format template<typename _Ctx> friend class basic_format_args; + template<typename _Ctx, typename... _Args> + 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<typename... _Args> - class _Store; + using _Store = __format::_Arg_store<_Context, _Args...>; + + template<typename _Ctx, typename... _Args> + 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<typename _Context, typename... _Args> + basic_format_args(__format::_Arg_store<_Context, _Args...>) + -> basic_format_args<_Context>; + + template<typename _Context, typename... _Args> + auto + make_format_args(_Args&&... __fmt_args) noexcept; + // An array of type-erased formatting arguments. - template<typename _Context> - template<typename... _Args> - class basic_format_args<_Context>::_Store - { - friend class basic_format_args; + template<typename _Context, typename... _Args> + class __format::_Arg_store + { + friend std::basic_format_args<_Context>; - template<typename _Ctx, typename... _Argz> - friend auto - make_format_args(_Argz&&...) noexcept; + template<typename _Ctx, typename... _Argz> + 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<typename _Tp> - 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<typename _Tp> + 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<typename... _Tp> - requires (sizeof...(_Tp) == sizeof...(_Args)) - [[__gnu__::__always_inline__]] - _Store(_Tp&... __a) noexcept - : _M_args{_S_make_elt(__a)...} - { } - }; + template<typename... _Tp> + requires (sizeof...(_Tp) == sizeof...(_Args)) + [[__gnu__::__always_inline__]] + _Arg_store(_Tp&... __a) noexcept + : _M_args{_S_make_elt(__a)...} + { } + }; template<typename _Context> - template<typename... _Args> requires (sizeof...(_Args) == 0) - class basic_format_args<_Context>::_Store<_Args...> - { }; + class __format::_Arg_store<_Context> + { }; template<typename _Context> template<typename... _Args> @@ -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<typename _Fmt_arg::template + using _Store = __format::_Arg_store<_Context, typename _Fmt_arg::template _Normalize<remove_reference_t<_Args>>...>; 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 <format> + +auto args_store = std::make_format_args(1,2,3); +std::basic_format_args args = args_store; +static_assert(std::is_same_v<decltype(args), std::format_args>); + + +template<typename Context> +void foo(std::basic_format_args<Context>); + +void +test_ctad() +{ + using std::basic_format_args; + using std::make_format_args; + using SomeContext = std::wformat_context; + + // foo(make_format_args<SomeContext>(…)); // won't work + foo(basic_format_args(make_format_args<SomeContext>(1, 2, 3))); // should work +}
reply other threads:[~2023-02-16 14:38 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230216143855.07DA1385B513@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).