mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-07 08:31:16 +00:00
Replace grisu2_specs with core_format_specs
This commit is contained in:
parent
b1ca608bac
commit
bda5f9a556
@ -568,18 +568,18 @@ struct gen_digits_params {
|
||||
|
||||
// Creates digit generation parameters from format specifiers for a number in
|
||||
// the range [pow(10, exp - 1), pow(10, exp) or 0 if exp == 1.
|
||||
gen_digits_params(const grisu2_specs &specs, int exp)
|
||||
: min_digits(specs.precision >= 0 ? to_unsigned(specs.precision) : 6),
|
||||
gen_digits_params(const core_format_specs &specs, int exp)
|
||||
: min_digits(specs.precision_ >= 0 ? to_unsigned(specs.precision_) : 6),
|
||||
fixed(false), upper(false), trailing_zeros(false) {
|
||||
switch (specs.type) {
|
||||
switch (specs.type_) {
|
||||
case 'G':
|
||||
upper = true;
|
||||
FMT_FALLTHROUGH
|
||||
case '\0': case 'g':
|
||||
trailing_zeros = (specs.flags & HASH_FLAG) != 0;
|
||||
trailing_zeros = (specs.flags_ & HASH_FLAG) != 0;
|
||||
if (-4 <= exp && exp < static_cast<int>(min_digits) + 1) {
|
||||
fixed = true;
|
||||
if (!specs.type && trailing_zeros && exp >= 0)
|
||||
if (!specs.type_ && trailing_zeros && exp >= 0)
|
||||
min_digits = to_unsigned(exp) + 1;
|
||||
}
|
||||
break;
|
||||
@ -667,7 +667,7 @@ FMT_FUNC void format_float(char *buffer, size_t &size, int exp,
|
||||
|
||||
template <typename Double>
|
||||
FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
|
||||
grisu2_format(Double value, buffer &buf, grisu2_specs specs) {
|
||||
grisu2_format(Double value, buffer &buf, core_format_specs specs) {
|
||||
FMT_ASSERT(value >= 0, "value is negative");
|
||||
char *buffer = buf.data();
|
||||
if (value == 0) {
|
||||
@ -710,6 +710,7 @@ FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
|
||||
size_t size = 0;
|
||||
if (!grisu2_gen_digits(buffer, size, hi, lo, exp, delta, one, diff,
|
||||
params.max_digits)) {
|
||||
buf.clear();
|
||||
return false;
|
||||
}
|
||||
format_float(buffer, size, cached_exp + exp, params);
|
||||
|
@ -285,25 +285,6 @@ inline dummy_int _finite(...) { return dummy_int(); }
|
||||
inline dummy_int isnan(...) { return dummy_int(); }
|
||||
inline dummy_int _isnan(...) { return dummy_int(); }
|
||||
|
||||
inline bool use_grisu() {
|
||||
return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559;
|
||||
}
|
||||
|
||||
struct grisu2_specs {
|
||||
int precision;
|
||||
char type;
|
||||
uint_least8_t flags;
|
||||
};
|
||||
|
||||
// Formats value using Grisu2 algorithm:
|
||||
// https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
|
||||
template <typename Double>
|
||||
FMT_API typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
|
||||
grisu2_format(Double value, buffer &buf, grisu2_specs);
|
||||
template <typename Double>
|
||||
inline typename std::enable_if<sizeof(Double) != sizeof(uint64_t), bool>::type
|
||||
grisu2_format(Double, buffer &, grisu2_specs) { return false; }
|
||||
|
||||
template <typename Allocator>
|
||||
typename Allocator::value_type *allocate(Allocator& alloc, std::size_t n) {
|
||||
#if __cplusplus >= 201103L || FMT_MSC_VER >= 1700
|
||||
@ -1174,17 +1155,23 @@ struct align_spec {
|
||||
int precision() const { return -1; }
|
||||
};
|
||||
|
||||
// Format specifiers.
|
||||
template <typename Char>
|
||||
class basic_format_specs : public align_spec {
|
||||
public:
|
||||
struct core_format_specs {
|
||||
int precision_;
|
||||
uint_least8_t flags_;
|
||||
char type_;
|
||||
};
|
||||
|
||||
// Format specifiers.
|
||||
template <typename Char>
|
||||
class basic_format_specs : public align_spec, public core_format_specs {
|
||||
public:
|
||||
FMT_CONSTEXPR basic_format_specs(
|
||||
unsigned width = 0, char type = 0, wchar_t fill = ' ')
|
||||
: align_spec(width, fill), precision_(-1), flags_(0), type_(type) {}
|
||||
: align_spec(width, fill) {
|
||||
precision_ = -1;
|
||||
flags_ = 0;
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR bool flag(unsigned f) const { return (flags_ & f) != 0; }
|
||||
FMT_CONSTEXPR int precision() const { return precision_; }
|
||||
@ -1203,6 +1190,19 @@ FMT_CONSTEXPR unsigned basic_parse_context<Char, ErrorHandler>::next_arg_id() {
|
||||
|
||||
namespace internal {
|
||||
|
||||
inline bool use_grisu() {
|
||||
return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559;
|
||||
}
|
||||
|
||||
// Formats value using Grisu2 algorithm:
|
||||
// https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
|
||||
template <typename Double>
|
||||
FMT_API typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
|
||||
grisu2_format(Double value, buffer &buf, core_format_specs);
|
||||
template <typename Double>
|
||||
inline typename std::enable_if<sizeof(Double) != sizeof(uint64_t), bool>::type
|
||||
grisu2_format(Double, buffer &, core_format_specs) { return false; }
|
||||
|
||||
template <typename S>
|
||||
struct format_string_traits<
|
||||
S, typename std::enable_if<std::is_base_of<compile_string, S>::value>::type>:
|
||||
@ -2855,20 +2855,12 @@ void basic_writer<Range>::write_double(T value, const format_specs &spec) {
|
||||
return write_inf_or_nan(handler.upper ? "INF" : "inf");
|
||||
|
||||
memory_buffer buffer;
|
||||
char type = static_cast<char>(spec.type());
|
||||
bool use_grisu = internal::use_grisu() && sizeof(T) <= sizeof(double) &&
|
||||
type != 'a' && type != 'A';
|
||||
if (use_grisu) {
|
||||
auto gs = internal::grisu2_specs();
|
||||
gs.type = type;
|
||||
gs.precision = spec.precision();
|
||||
gs.flags = spec.flags_;
|
||||
use_grisu = internal::grisu2_format(static_cast<double>(value), buffer, gs);
|
||||
}
|
||||
spec.type() != 'a' && spec.type() != 'A' &&
|
||||
internal::grisu2_format(static_cast<double>(value), buffer, spec);
|
||||
if (!use_grisu) {
|
||||
format_specs normalized_spec(spec);
|
||||
normalized_spec.type_ = handler.type;
|
||||
buffer.clear();
|
||||
write_double_sprintf(value, normalized_spec, buffer);
|
||||
}
|
||||
size_t n = buffer.size();
|
||||
|
@ -105,7 +105,7 @@ TEST(FPTest, GetCachedPower) {
|
||||
TEST(FPTest, Grisu2FormatCompilesWithNonIEEEDouble) {
|
||||
size_t size = 0;
|
||||
fmt::memory_buffer buf;
|
||||
grisu2_format(4.2f, buf, fmt::internal::grisu2_specs());
|
||||
grisu2_format(4.2f, buf, fmt::core_format_specs());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
Loading…
Reference in New Issue
Block a user