From 91533d3c3332d0adb76d0f70f82983ceb3f0497b Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 9 Dec 2021 06:55:31 -0800 Subject: [PATCH] Minor tweaks to chrono subsecond formatting --- include/fmt/chrono.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index b71195d0..5285d420 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1459,11 +1459,13 @@ inline std::chrono::duration get_milliseconds( #endif } -// Returns the number of digits according to the c++ 20 spec -// In the range [0, 18], if more than 18 fractional digits are required, -// then we return 6 for microseconds precision. -constexpr int num_digits(long long num, long long den, int n = 0) { - return num % den == 0 ? n : (n > 18 ? 6 : num_digits(num * 10, den, n + 1)); +// Returns the number of fractional digits in the range [0, 18] according to the +// C++20 spec. If more than 18 fractional digits are required then returns 6 for +// microseconds precision. +constexpr int count_fractional_digits(long long num, long long den, int n = 0) { + return num % den == 0 + ? n + : (n > 18 ? 6 : count_fractional_digits(num * 10, den, n + 1)); } constexpr long long pow10(std::uint32_t n) { @@ -1479,13 +1481,13 @@ constexpr std::chrono::duration abs( // when -Wzero-as-null-pointer-constant is enabled. // In clang-12 the bug has been fixed. See // https://bugs.llvm.org/show_bug.cgi?id=46235 and the reproducible example: - // https://www.godbolt.org/z/Knbb5joYx + // https://www.godbolt.org/z/Knbb5joYx. return d.count() >= d.zero().count() ? d : -d; } template ::is_signed)> -static constexpr std::chrono::duration abs( +constexpr std::chrono::duration abs( std::chrono::duration d) { return d; } @@ -1651,14 +1653,13 @@ struct chrono_formatter { } template void write_fractional_seconds(Duration d) { - constexpr auto fractional_width = - detail::num_digits(Duration::period::num, Duration::period::den); + constexpr auto num_fractional_digits = + count_fractional_digits(Duration::period::num, Duration::period::den); using subsecond_precision = std::chrono::duration< typename std::common_type::type, - std::ratio<1, detail::pow10(fractional_width)>>; - // We could use c++ 17 if constexpr here. + std::ratio<1, detail::pow10(num_fractional_digits)>>; if (std::ratio_less::value) { *out++ = '.'; @@ -1675,9 +1676,8 @@ struct chrono_formatter { uint32_or_64_or_128_t n = to_unsigned(to_nonnegative_int(subseconds, max_value())); int num_digits = detail::count_digits(n); - if (fractional_width > num_digits) { - out = std::fill_n(out, fractional_width - num_digits, '0'); - } + if (num_fractional_digits > num_digits) + out = std::fill_n(out, num_fractional_digits - num_digits, '0'); out = format_decimal(out, n, num_digits).end; } }