From 4239dfe081e8cd7c9f294e55dc3c60279056eb21 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 22 Jul 2024 16:52:55 -0700 Subject: [PATCH] Simplify format_decimal --- include/fmt/chrono.h | 10 ++++----- include/fmt/format.h | 49 ++++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 723b1f00..40f7e8fd 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1147,7 +1147,7 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) { std::chrono::seconds::period>::value) { *out++ = '.'; out = detail::fill_n(out, leading_zeroes, '0'); - out = format_decimal(out, n, num_digits).end; + out = format_decimal(out, n, num_digits); } } else if (precision > 0) { *out++ = '.'; @@ -1158,12 +1158,12 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) { int num_truncated_digits = num_digits - remaining; n /= to_unsigned(detail::pow10(to_unsigned(num_truncated_digits))); if (n) { - out = format_decimal(out, n, remaining).end; + out = format_decimal(out, n, remaining); } return; } if (n) { - out = format_decimal(out, n, num_digits).end; + out = format_decimal(out, n, num_digits); remaining -= num_digits; } out = detail::fill_n(out, remaining, '0'); @@ -1319,7 +1319,7 @@ class tm_writer { const int num_digits = count_digits(n); if (width > num_digits) out_ = detail::fill_n(out_, width - num_digits, '0'); - out_ = format_decimal(out_, n, num_digits).end; + out_ = format_decimal(out_, n, num_digits); } void write_year(long long year) { if (year >= 0 && year < 10000) { @@ -1881,7 +1881,7 @@ struct chrono_formatter { if (width > num_digits) { out = detail::write_padding(out, pad, width - num_digits); } - out = format_decimal(out, n, num_digits).end; + out = format_decimal(out, n, num_digits); } void write_nan() { std::copy_n("nan", 3, out); } diff --git a/include/fmt/format.h b/include/fmt/format.h index 610cb9b9..d9b21710 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1283,45 +1283,45 @@ FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) { *dst = static_cast(*src); } -template struct format_decimal_result { - Iterator begin; - Iterator end; -}; - -// Formats a decimal unsigned integer value writing into out pointing to a -// buffer of specified size. The caller must ensure that the buffer is large -// enough. +// Formats a decimal unsigned integer value writing to out pointing to a buffer +// of specified size. The caller must ensure that the buffer is large enough. template -FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size) - -> format_decimal_result { +FMT_CONSTEXPR20 auto do_format_decimal(Char* out, UInt value, int size) + -> Char* { FMT_ASSERT(size >= count_digits(value), "invalid digit count"); - auto begin = out, end = out + size; unsigned n = to_unsigned(size); while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. n -= 2; - copy2(begin + n, digits2(static_cast(value % 100))); + copy2(out + n, digits2(static_cast(value % 100))); value /= 100; } if (value >= 10) { n -= 2; - copy2(begin + n, digits2(static_cast(value))); + copy2(out + n, digits2(static_cast(value))); } else { - begin[--n] = static_cast('0' + value); + out[--n] = static_cast('0' + value); } - return {begin + n, end}; + return out + n; +} + +template +FMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value, int size) + -> Char* { + do_format_decimal(out, value, size); + return out + size; } template ::value)> FMT_CONSTEXPR inline auto format_decimal(OutputIt out, UInt value, int size) - -> format_decimal_result { + -> OutputIt { // Buffer is large enough to hold all digits (digits10 + 1). - Char buffer[digits10() + 1] = {}; - auto end = format_decimal(buffer, value, size).end; - return {out, detail::copy_noinline(buffer, end, out)}; + char buffer[digits10() + 1] = {}; + do_format_decimal(buffer, value, size); + return detail::copy_noinline(buffer, buffer + size, out); } template @@ -2167,7 +2167,7 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg arg, int num_digits = count_digits(abs_value); return write_int( out, num_digits, prefix, specs, [=](reserve_iterator it) { - return format_decimal(it, abs_value, num_digits).end; + return format_decimal(it, abs_value, num_digits); }); } case presentation_type::hex: { @@ -2295,7 +2295,7 @@ FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { return out; } if (negative) *out++ = static_cast('-'); - return format_decimal(out, abs_value, num_digits).end; + return format_decimal(out, abs_value, num_digits); } // DEPRECATED! @@ -2426,7 +2426,7 @@ constexpr auto write_significand(OutputIt out, const char* significand, template inline auto write_significand(OutputIt out, UInt significand, int significand_size) -> OutputIt { - return format_decimal(out, significand, significand_size).end; + return format_decimal(out, significand, significand_size); } template FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, @@ -2446,8 +2446,7 @@ template ::value)> inline auto write_significand(Char* out, UInt significand, int significand_size, int integral_size, Char decimal_point) -> Char* { - if (!decimal_point) - return format_decimal(out, significand, significand_size).end; + if (!decimal_point) return format_decimal(out, significand, significand_size); out += significand_size + 1; Char* end = out; int floating_size = significand_size - integral_size; @@ -3889,7 +3888,7 @@ class format_int { template FMT_CONSTEXPR20 auto format_unsigned(UInt value) -> char* { auto n = static_cast>(value); - return detail::format_decimal(buffer_, n, buffer_size - 1).begin; + return detail::do_format_decimal(buffer_, n, buffer_size - 1); } template