diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index ee72c61c..52b2206c 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -2231,8 +2231,7 @@ FMT_ALWAYS_INLINE FMT_SAFEBUFFERS decimal_fp shorter_interval_case( } template -FMT_SAFEBUFFERS enable_if_t(), decimal_fp> to_decimal(T x) - FMT_NOEXCEPT { +FMT_SAFEBUFFERS decimal_fp to_decimal(T x) FMT_NOEXCEPT { // Step 1: integer promotion & Schubfach multiplier calculation. using carrier_uint = typename float_info::carrier_uint; diff --git a/include/fmt/format.h b/include/fmt/format.h index e181575a..fe78bbfd 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -587,9 +587,9 @@ inline counting_iterator copy_str(InputIt begin, InputIt end, return it + (end - begin); } -template constexpr bool is_fast_float() { - return std::numeric_limits::is_iec559 && sizeof(T) <= sizeof(double); -} +template +using is_fast_float = bool_constant::is_iec559 && + sizeof(T) <= sizeof(double)>; #ifndef FMT_USE_FULL_CACHE_DRAGONBOX # define FMT_USE_FULL_CACHE_DRAGONBOX 0 @@ -1291,12 +1291,8 @@ template class float_writer { // 1234e-2 -> 12.34[0+] it = copy_str(digits_, digits_ + full_exp, it); if (!specs_.showpoint) { - // Remove trailing zeros. - int num_digits = num_digits_; - while (num_digits > full_exp && digits_[num_digits - 1] == '0') - --num_digits; - if (num_digits != full_exp) *it++ = decimal_point_; - return copy_str(digits_ + full_exp, digits_ + num_digits, it); + if (num_digits_ != full_exp) *it++ = decimal_point_; + return copy_str(digits_ + full_exp, digits_ + num_digits_, it); } *it++ = decimal_point_; it = copy_str(digits_ + full_exp, digits_ + num_digits_, it); @@ -1309,18 +1305,14 @@ template class float_writer { // 1234e-6 -> 0.001234 *it++ = static_cast('0'); int num_zeros = -full_exp; - int num_digits = num_digits_; - if (num_digits == 0 && specs_.precision >= 0 && + if (num_digits_ == 0 && specs_.precision >= 0 && specs_.precision < num_zeros) { num_zeros = specs_.precision; } - // Remove trailing zeros. - if (!specs_.showpoint) - while (num_digits > 0 && digits_[num_digits - 1] == '0') --num_digits; - if (num_zeros != 0 || num_digits != 0 || specs_.showpoint) { + if (num_zeros != 0 || num_digits_ != 0 || specs_.showpoint) { *it++ = decimal_point_; it = std::fill_n(it, num_zeros, static_cast('0')); - it = copy_str(digits_, digits_ + num_digits, it); + it = copy_str(digits_, digits_ + num_digits_, it); } } return it; @@ -1426,13 +1418,7 @@ template struct decimal_fp { int exponent; }; -template -enable_if_t(), decimal_fp> to_decimal(T x) FMT_NOEXCEPT; - -template -inline enable_if_t(), unformattable> to_decimal(T) { - return {}; -} +template decimal_fp to_decimal(T x) FMT_NOEXCEPT; } // namespace dragonbox template @@ -1887,8 +1873,9 @@ OutputIt write(OutputIt out, T value, basic_format_specs specs, return write_padded(out, specs, w.size(), w); } -template ::value)> +template < + typename Char, typename OutputIt, typename T, + FMT_ENABLE_IF(std::is_floating_point::value&& is_fast_float::value)> OutputIt write(OutputIt out, T value) { if (const_check(!is_supported_floating_point(value))) return out; auto fspecs = float_specs(); @@ -1901,17 +1888,22 @@ OutputIt write(OutputIt out, T value) { if (!std::isfinite(value)) return write_nonfinite(out, std::isinf(value), specs, fspecs); - memory_buffer buffer; - int precision = -1; - if (const_check(std::is_same())) fspecs.binary32 = true; - fspecs.use_grisu = is_fast_float(); - int exp = format_float(promote_float(value), precision, fspecs, buffer); - fspecs.precision = precision; - float_writer w(buffer.data(), static_cast(buffer.size()), exp, + using type = conditional_t::value, double, T>; + auto dec = dragonbox::to_decimal(static_cast(value)); + memory_buffer buf; + write(buffer_appender(buf), dec.significand); + float_writer w(buf.data(), static_cast(buf.size()), dec.exponent, fspecs, static_cast('.')); return base_iterator(out, w(reserve(out, w.size()))); } +template ::value && + !is_fast_float::value)> +inline OutputIt write(OutputIt out, T value) { + return write(out, value, basic_format_specs()); +} + template OutputIt write_char(OutputIt out, Char value, const basic_format_specs& specs) {