From 6e672b1801f9443916a8b5033d9e3bf88baa3f5d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 2 Sep 2019 12:31:25 +0100 Subject: [PATCH] Minor simplifications for std::to_chars implementation * include/std/charconv (__detail::__to_chars_2_len): Use std::log2p1. (__detail::__to_chars_8_len): Remove. (__detail::__to_chars_8): Inline length calculation here. (__detail::__from_chars_binary): Use numeric_limits instead of CHAR_BIT. From-SVN: r275313 --- libstdc++-v3/ChangeLog | 8 +++++ libstdc++-v3/include/std/charconv | 58 +++++++++---------------------- 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 20cec73afb9..876e7ff49f6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2019-09-02 Jonathan Wakely + + * include/std/charconv (__detail::__to_chars_2_len): Use std::log2p1. + (__detail::__to_chars_8_len): Remove. + (__detail::__to_chars_8): Inline length calculation here. + (__detail::__from_chars_binary): Use numeric_limits instead of + CHAR_BIT. + 2019-09-02 Rainer Orth * config/abi/post/i386-solaris/baseline_symbols.txt: Regenerate. diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv index 4e94c39656d..ceefa3b6778 100644 --- a/libstdc++-v3/include/std/charconv +++ b/libstdc++-v3/include/std/charconv @@ -35,8 +35,9 @@ #include #include -#include -#include // for __to_chars_len, __to_chars_10_impl +#include // for __log2p1 +#include // for isdigit +#include // for __to_chars_len, __to_chars_10_impl #include // for std::errc // Define when floating point is supported: #define __cpp_lib_to_chars 201611L @@ -96,43 +97,7 @@ namespace __detail template constexpr unsigned __to_chars_len_2(_Tp __value) noexcept - { - static_assert(is_integral<_Tp>::value, "implementation bug"); - static_assert(is_unsigned<_Tp>::value, "implementation bug"); - - constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp); - - // N.B. __builtin_clzll is undefined if __value == 0, but std::to_chars - // handles zero values directly. - - // For sizeof(_Tp) > 1 this is an order of magnitude faster than - // the generic __to_chars_len. - return __nbits - - (__builtin_clzll(__value) - - ((__CHAR_BIT__ * sizeof(long long)) - __nbits)); - } - - template - constexpr unsigned - __to_chars_len_8(_Tp __value) noexcept - { - static_assert(is_integral<_Tp>::value, "implementation bug"); - static_assert(is_unsigned<_Tp>::value, "implementation bug"); - - constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp); - - if _GLIBCXX17_CONSTEXPR (__nbits <= 16) - { - return __value > 077777u ? 6u - : __value > 07777u ? 5u - : __value > 0777u ? 4u - : __value > 077u ? 3u - : __value > 07u ? 2u - : 1u; - } - else - return (__to_chars_len_2(__value) + 2) / 3; - } + { return std::__log2p1(__value); } // Generic implementation for arbitrary bases. template @@ -255,8 +220,19 @@ namespace __detail static_assert(is_unsigned<_Tp>::value, "implementation bug"); to_chars_result __res; + unsigned __len; - const unsigned __len = __to_chars_len_8(__val); + if _GLIBCXX17_CONSTEXPR (numeric_limits<_Tp>::digits <= 16) + { + __len = __val > 077777u ? 6u + : __val > 07777u ? 5u + : __val > 0777u ? 4u + : __val > 077u ? 3u + : __val > 07u ? 2u + : 1u; + } + else + __len = (__to_chars_len_2(__val) + 2) / 3; if (__builtin_expect((__last - __first) < __len, 0)) { @@ -397,7 +373,7 @@ namespace __detail __i++; } __first += __i; - return __i <= (sizeof(_Tp) * __CHAR_BIT__); + return __i <= numeric_limits<_Tp>::digits; } /// std::from_chars implementation for integers in bases 3 to 10. -- 2.30.2