Cleanup FP formatting

This commit is contained in:
Victor Zverovich 2019-11-20 13:17:03 -08:00
parent 75108a56f6
commit c7edd8e570

View File

@ -1063,7 +1063,6 @@ namespace internal {
// A floating-point presentation format. // A floating-point presentation format.
enum class float_format { enum class float_format {
shortest, // Shortest round-trip format.
general, // General: exponent notation or fixed point based on magnitude. general, // General: exponent notation or fixed point based on magnitude.
exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3. exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3.
fixed, // Fixed point with the default precision of 6, e.g. 0.0012. fixed, // Fixed point with the default precision of 6, e.g. 0.0012.
@ -1399,6 +1398,20 @@ void arg_map<Context>::init(const basic_format_args<Context>& args) {
} }
} }
template <typename Char> struct inf_or_nan_writer {
sign_t sign;
const char* str;
static constexpr size_t str_size = 3;
size_t size() const { return str_size + (sign ? 1 : 0); }
size_t width() const { return size(); }
template <typename It> void operator()(It&& it) const {
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
it = copy_str<Char>(str, str + str_size, it);
}
};
// This template provides operations for formatting and writing data into a // This template provides operations for formatting and writing data into a
// character range. // character range.
template <typename Range> class basic_writer { template <typename Range> class basic_writer {
@ -1619,24 +1632,6 @@ template <typename Range> class basic_writer {
} }
}; };
enum { inf_size = 3 }; // This is an enum to workaround a bug in MSVC.
struct inf_or_nan_writer {
sign_t sign;
const char* str;
size_t size() const {
return static_cast<std::size_t>(inf_size + (sign ? 1 : 0));
}
size_t width() const { return size(); }
template <typename It> void operator()(It&& it) const {
if (sign) *it++ = static_cast<char_type>(data::signs[sign]);
it = internal::copy_str<char_type>(
str, str + static_cast<std::size_t>(inf_size), it);
}
};
struct double_writer { struct double_writer {
sign_t sign; sign_t sign;
internal::buffer<char>& buffer; internal::buffer<char>& buffer;
@ -1753,11 +1748,9 @@ template <typename Range> class basic_writer {
if (!std::isfinite(value)) { if (!std::isfinite(value)) {
auto str = std::isinf(value) ? (fspec.upper ? "INF" : "inf") auto str = std::isinf(value) ? (fspec.upper ? "INF" : "inf")
: (fspec.upper ? "NAN" : "nan"); : (fspec.upper ? "NAN" : "nan");
return write_padded(specs, inf_or_nan_writer{sign, str}); return write_padded(specs, inf_or_nan_writer<char_type>{sign, str});
} }
if (fspec.percent) value *= 100;
memory_buffer buffer; memory_buffer buffer;
int exp = 0; int exp = 0;
int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6; int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
@ -1767,6 +1760,7 @@ template <typename Range> class basic_writer {
if (fspec.format == float_format::fixed) options |= grisu_options::fixed; if (fspec.format == float_format::fixed) options |= grisu_options::fixed;
if (const_check(sizeof(value) == sizeof(float))) if (const_check(sizeof(value) == sizeof(float)))
options |= grisu_options::binary32; options |= grisu_options::binary32;
if (const_check(FMT_DEPRECATED_PERCENT) && fspec.percent) value *= 100;
bool use_grisu = internal::use_grisu<T>() && bool use_grisu = internal::use_grisu<T>() &&
(specs.type != 'a' && specs.type != 'A') && (specs.type != 'a' && specs.type != 'A') &&
grisu_format(static_cast<double>(value), buffer, grisu_format(static_cast<double>(value), buffer,
@ -1774,7 +1768,7 @@ template <typename Range> class basic_writer {
char* decimal_point_pos = nullptr; char* decimal_point_pos = nullptr;
if (!use_grisu) decimal_point_pos = sprintf_format(value, buffer, specs); if (!use_grisu) decimal_point_pos = sprintf_format(value, buffer, specs);
if (fspec.percent) { if (const_check(FMT_DEPRECATED_PERCENT) && fspec.percent) {
buffer.push_back('%'); buffer.push_back('%');
--exp; // Adjust decimal place position. --exp; // Adjust decimal place position.
} }