diff --git a/include/fmt/format.h b/include/fmt/format.h index c7a387c2..70c7ff4d 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2528,6 +2528,26 @@ inline auto write_exponent_significand(Char* out, UInt significand, return out; } +template ::value)> +inline auto write_default_fp(Char* out, UInt significand, int significand_size, + int decimal_exponent, sign s) -> Char* { + if (s != sign::none) *out++ = Char('-'); + int exp = decimal_exponent + significand_size; + if (decimal_exponent >= 0) { + out = write_significand(out, significand, significand_size); + return detail::fill_n(out, decimal_exponent, Char('0')); + } + if (exp > 0) { + return write_significand(out, significand, significand_size, exp, + Char('.')); + } + *out++ = Char('0'); + *out++ = Char('.'); + out = detail::fill_n(out, -exp, Char('0')); + return write_significand(out, significand, significand_size); +} + template FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand, int significand_size, int integral_size, @@ -3605,6 +3625,21 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt { int significand_size = count_digits(significand); int exponent = dec.exponent + significand_size - 1; if (use_fixed(exponent, detail::exp_upper())) { + size_t size = std::is_pointer::value + ? 0u + : to_unsigned((s != sign::none ? 1 : 0) + + (dec.exponent >= 0 + ? significand_size + dec.exponent + : exponent >= 0 + ? significand_size + 1 + : significand_size + 2 - + (dec.exponent + + significand_size))); + if (auto ptr = to_pointer(out, size)) { + ptr = write_default_fp(ptr, significand, significand_size, dec.exponent, + s); + return select::value>(ptr, out); + } return write_fixed>( out, dec, significand_size, Char('.'), {}, s); }