public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: Patrick Palka <ppalka@redhat.com>
Cc: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org
Subject: Re: [PATCH] libstdc++: Reduce integer std::to/from_chars symbol sizes
Date: Fri, 15 Sep 2023 21:48:52 +0100	[thread overview]
Message-ID: <CACb0b4=cbowtDBQ=nNc-jcspmdCj7rch_HMkbn=CqHHd-TCr4w@mail.gmail.com> (raw)
In-Reply-To: <20230913225206.4188935-1-ppalka@redhat.com>

On Wed, 13 Sept 2023 at 23:52, Patrick Palka via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

OK, thanks.

>
> -- >8 --
>
> For std::to_chars:
>
> The constrained alias __integer_to_chars_result_type seems unnecessary
> ever since r10-3080-g28f0075742ed58 got rid of the only public overload
> which used it.  Now only non-public overloads are constrained by it
> (through their return type) and these non-public overloads aren't used
> in a SFINAE context, so the constraints have no observable effect.  So
> this patch gets rid of this alias, which greatly reduces the symbol
> sizes of the affected functions (since the expanded alias is quite
> large).
>
> For std::from_chars:
>
> We can't get rid of the corresponding alias because it's constrains
> the public integer std::from_chars overload.  But we can avoid having
> the constraint bloat the mangled name by instead encoding it as a
> defaulted template parameter.  We use the non-type parameter form
>
>   enable_if_t<..., int> = 0
>
> instead of the type parameter form
>
>   typename = enable_if_t<...>
>
> because the type form can be circumvented by providing an explicit template
> argument to type parameter, e.g. 'std::from_chars<int, void>(...)', so the
> non-type form seems like the more robust choice.
>
> In passing, use __is_standard_integer in the constraint.
>
> libstdc++-v3/ChangeLog:
>
>         * include/std/charconv (__detail::__integer_to_chars_result_type):
>         Remove.
>         (__detail::__to_chars_16): Use to_chars_result as return type.
>         (__detail::__to_chars_10): Likewise.
>         (__detail::__to_chars_8): Likewise.
>         (__detail::__to_chars_2): Likewise.
>         (__detail::__to_chars_i): Likewise.
>         (__detail::__integer_from_chars_result_type): Pull out enable_if_t
>         condition into and replace with ...
>         (__detail::__integer_from_chars_enabled): ... this.  Use
>         __is_standard_integer instead of __is_signed_integer and
>         __is_unsigned_integer.
>         (from_chars): Encode constraint as a defaulted non-type template
>         parameter instead of within the return type.
> ---
>  libstdc++-v3/include/std/charconv | 33 ++++++++++---------------------
>  1 file changed, 10 insertions(+), 23 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv
> index 01711d38576..ec25ae139ba 100644
> --- a/libstdc++-v3/include/std/charconv
> +++ b/libstdc++-v3/include/std/charconv
> @@ -79,17 +79,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>  namespace __detail
>  {
> -  template<typename _Tp>
> -    using __integer_to_chars_result_type
> -      = enable_if_t<__or_<__is_signed_integer<_Tp>,
> -                         __is_unsigned_integer<_Tp>,
> -#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__
> -                         is_same<_Tp, signed __int128>,
> -                         is_same<_Tp, unsigned __int128>,
> -#endif
> -                         is_same<char, remove_cv_t<_Tp>>>::value,
> -                   to_chars_result>;
> -
>    // Pick an unsigned type of suitable size. This is used to reduce the
>    // number of specializations of __to_chars_len, __to_chars etc. that
>    // get instantiated. For example, to_chars<char> and to_chars<short>
> @@ -162,7 +151,7 @@ namespace __detail
>      }
>
>    template<typename _Tp>
> -    constexpr __integer_to_chars_result_type<_Tp>
> +    constexpr to_chars_result
>      __to_chars_16(char* __first, char* __last, _Tp __val) noexcept
>      {
>        static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
> @@ -208,7 +197,7 @@ namespace __detail
>      }
>
>    template<typename _Tp>
> -    constexpr __integer_to_chars_result_type<_Tp>
> +    constexpr to_chars_result
>      __to_chars_10(char* __first, char* __last, _Tp __val) noexcept
>      {
>        static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
> @@ -231,7 +220,7 @@ namespace __detail
>      }
>
>    template<typename _Tp>
> -    constexpr __integer_to_chars_result_type<_Tp>
> +    constexpr to_chars_result
>      __to_chars_8(char* __first, char* __last, _Tp __val) noexcept
>      {
>        static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
> @@ -284,7 +273,7 @@ namespace __detail
>      }
>
>    template<typename _Tp>
> -    constexpr __integer_to_chars_result_type<_Tp>
> +    constexpr to_chars_result
>      __to_chars_2(char* __first, char* __last, _Tp __val) noexcept
>      {
>        static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
> @@ -320,7 +309,7 @@ namespace __detail
>  } // namespace __detail
>
>    template<typename _Tp>
> -    constexpr __detail::__integer_to_chars_result_type<_Tp>
> +    constexpr to_chars_result
>      __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10)
>      {
>        __glibcxx_assert(2 <= __base && __base <= 36);
> @@ -548,17 +537,15 @@ namespace __detail
>      }
>
>    template<typename _Tp>
> -    using __integer_from_chars_result_type
> -      = enable_if_t<__or_<__is_signed_integer<_Tp>,
> -                         __is_unsigned_integer<_Tp>,
> -                         is_same<char, remove_cv_t<_Tp>>>::value,
> -                   from_chars_result>;
> +    constexpr bool __integer_from_chars_enabled
> +      = __or_<__is_standard_integer<_Tp>, is_same<char, remove_cv_t<_Tp>>>::value;
>
>  } // namespace __detail
>
>    /// std::from_chars for integral types.
> -  template<typename _Tp>
> -    _GLIBCXX23_CONSTEXPR __detail::__integer_from_chars_result_type<_Tp>
> +  template<typename _Tp,
> +          enable_if_t<__detail::__integer_from_chars_enabled<_Tp>, int> = 0>
> +    _GLIBCXX23_CONSTEXPR from_chars_result
>      from_chars(const char* __first, const char* __last, _Tp& __value,
>                int __base = 10)
>      {
> --
> 2.42.0.158.g94e83dcf5b
>


      reply	other threads:[~2023-09-15 20:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-13 22:52 Patrick Palka
2023-09-15 20:48 ` Jonathan Wakely [this message]

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='CACb0b4=cbowtDBQ=nNc-jcspmdCj7rch_HMkbn=CqHHd-TCr4w@mail.gmail.com' \
    --to=jwakely@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    --cc=ppalka@redhat.com \
    /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: link
Be 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).