public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libstdc++: Reduce integer std::to/from_chars symbol sizes
@ 2023-09-13 22:52 Patrick Palka
  2023-09-15 20:48 ` Jonathan Wakely
  0 siblings, 1 reply; 2+ messages in thread
From: Patrick Palka @ 2023-09-13 22:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Patrick Palka

Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

-- >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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] libstdc++: Reduce integer std::to/from_chars symbol sizes
  2023-09-13 22:52 [PATCH] libstdc++: Reduce integer std::to/from_chars symbol sizes Patrick Palka
@ 2023-09-15 20:48 ` Jonathan Wakely
  0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2023-09-15 20:48 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches, libstdc++

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
>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-09-15 20:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-13 22:52 [PATCH] libstdc++: Reduce integer std::to/from_chars symbol sizes Patrick Palka
2023-09-15 20:48 ` Jonathan Wakely

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).