mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-15 03:40:24 +00:00
Improve dragonbox integration
This commit is contained in:
parent
79694d424c
commit
6417952574
@ -2231,8 +2231,7 @@ FMT_ALWAYS_INLINE FMT_SAFEBUFFERS decimal_fp<T> shorter_interval_case(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FMT_SAFEBUFFERS enable_if_t<is_fast_float<T>(), decimal_fp<T>> to_decimal(T x)
|
FMT_SAFEBUFFERS decimal_fp<T> to_decimal(T x) FMT_NOEXCEPT {
|
||||||
FMT_NOEXCEPT {
|
|
||||||
// Step 1: integer promotion & Schubfach multiplier calculation.
|
// Step 1: integer promotion & Schubfach multiplier calculation.
|
||||||
|
|
||||||
using carrier_uint = typename float_info<T>::carrier_uint;
|
using carrier_uint = typename float_info<T>::carrier_uint;
|
||||||
|
@ -587,9 +587,9 @@ inline counting_iterator copy_str(InputIt begin, InputIt end,
|
|||||||
return it + (end - begin);
|
return it + (end - begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> constexpr bool is_fast_float() {
|
template <typename T>
|
||||||
return std::numeric_limits<T>::is_iec559 && sizeof(T) <= sizeof(double);
|
using is_fast_float = bool_constant<std::numeric_limits<T>::is_iec559 &&
|
||||||
}
|
sizeof(T) <= sizeof(double)>;
|
||||||
|
|
||||||
#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
|
#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
|
||||||
# define FMT_USE_FULL_CACHE_DRAGONBOX 0
|
# define FMT_USE_FULL_CACHE_DRAGONBOX 0
|
||||||
@ -1291,12 +1291,8 @@ template <typename Char> class float_writer {
|
|||||||
// 1234e-2 -> 12.34[0+]
|
// 1234e-2 -> 12.34[0+]
|
||||||
it = copy_str<Char>(digits_, digits_ + full_exp, it);
|
it = copy_str<Char>(digits_, digits_ + full_exp, it);
|
||||||
if (!specs_.showpoint) {
|
if (!specs_.showpoint) {
|
||||||
// Remove trailing zeros.
|
if (num_digits_ != full_exp) *it++ = decimal_point_;
|
||||||
int num_digits = num_digits_;
|
return copy_str<Char>(digits_ + full_exp, digits_ + num_digits_, it);
|
||||||
while (num_digits > full_exp && digits_[num_digits - 1] == '0')
|
|
||||||
--num_digits;
|
|
||||||
if (num_digits != full_exp) *it++ = decimal_point_;
|
|
||||||
return copy_str<Char>(digits_ + full_exp, digits_ + num_digits, it);
|
|
||||||
}
|
}
|
||||||
*it++ = decimal_point_;
|
*it++ = decimal_point_;
|
||||||
it = copy_str<Char>(digits_ + full_exp, digits_ + num_digits_, it);
|
it = copy_str<Char>(digits_ + full_exp, digits_ + num_digits_, it);
|
||||||
@ -1309,18 +1305,14 @@ template <typename Char> class float_writer {
|
|||||||
// 1234e-6 -> 0.001234
|
// 1234e-6 -> 0.001234
|
||||||
*it++ = static_cast<Char>('0');
|
*it++ = static_cast<Char>('0');
|
||||||
int num_zeros = -full_exp;
|
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) {
|
specs_.precision < num_zeros) {
|
||||||
num_zeros = specs_.precision;
|
num_zeros = specs_.precision;
|
||||||
}
|
}
|
||||||
// Remove trailing zeros.
|
if (num_zeros != 0 || num_digits_ != 0 || specs_.showpoint) {
|
||||||
if (!specs_.showpoint)
|
|
||||||
while (num_digits > 0 && digits_[num_digits - 1] == '0') --num_digits;
|
|
||||||
if (num_zeros != 0 || num_digits != 0 || specs_.showpoint) {
|
|
||||||
*it++ = decimal_point_;
|
*it++ = decimal_point_;
|
||||||
it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
|
it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
|
||||||
it = copy_str<Char>(digits_, digits_ + num_digits, it);
|
it = copy_str<Char>(digits_, digits_ + num_digits_, it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return it;
|
return it;
|
||||||
@ -1426,13 +1418,7 @@ template <typename T> struct decimal_fp {
|
|||||||
int exponent;
|
int exponent;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> decimal_fp<T> to_decimal(T x) FMT_NOEXCEPT;
|
||||||
enable_if_t<is_fast_float<T>(), decimal_fp<T>> to_decimal(T x) FMT_NOEXCEPT;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline enable_if_t<!is_fast_float<T>(), unformattable> to_decimal(T) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
} // namespace dragonbox
|
} // namespace dragonbox
|
||||||
|
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
@ -1887,8 +1873,9 @@ OutputIt write(OutputIt out, T value, basic_format_specs<Char> specs,
|
|||||||
return write_padded<align::right>(out, specs, w.size(), w);
|
return write_padded<align::right>(out, specs, w.size(), w);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char, typename OutputIt, typename T,
|
template <
|
||||||
FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
typename Char, typename OutputIt, typename T,
|
||||||
|
FMT_ENABLE_IF(std::is_floating_point<T>::value&& is_fast_float<T>::value)>
|
||||||
OutputIt write(OutputIt out, T value) {
|
OutputIt write(OutputIt out, T value) {
|
||||||
if (const_check(!is_supported_floating_point(value))) return out;
|
if (const_check(!is_supported_floating_point(value))) return out;
|
||||||
auto fspecs = float_specs();
|
auto fspecs = float_specs();
|
||||||
@ -1901,17 +1888,22 @@ OutputIt write(OutputIt out, T value) {
|
|||||||
if (!std::isfinite(value))
|
if (!std::isfinite(value))
|
||||||
return write_nonfinite(out, std::isinf(value), specs, fspecs);
|
return write_nonfinite(out, std::isinf(value), specs, fspecs);
|
||||||
|
|
||||||
memory_buffer buffer;
|
using type = conditional_t<std::is_same<T, long double>::value, double, T>;
|
||||||
int precision = -1;
|
auto dec = dragonbox::to_decimal(static_cast<type>(value));
|
||||||
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
memory_buffer buf;
|
||||||
fspecs.use_grisu = is_fast_float<T>();
|
write<char>(buffer_appender<char>(buf), dec.significand);
|
||||||
int exp = format_float(promote_float(value), precision, fspecs, buffer);
|
float_writer<Char> w(buf.data(), static_cast<int>(buf.size()), dec.exponent,
|
||||||
fspecs.precision = precision;
|
|
||||||
float_writer<Char> w(buffer.data(), static_cast<int>(buffer.size()), exp,
|
|
||||||
fspecs, static_cast<Char>('.'));
|
fspecs, static_cast<Char>('.'));
|
||||||
return base_iterator(out, w(reserve(out, w.size())));
|
return base_iterator(out, w(reserve(out, w.size())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Char, typename OutputIt, typename T,
|
||||||
|
FMT_ENABLE_IF(std::is_floating_point<T>::value &&
|
||||||
|
!is_fast_float<T>::value)>
|
||||||
|
inline OutputIt write(OutputIt out, T value) {
|
||||||
|
return write(out, value, basic_format_specs<Char>());
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Char, typename OutputIt>
|
template <typename Char, typename OutputIt>
|
||||||
OutputIt write_char(OutputIt out, Char value,
|
OutputIt write_char(OutputIt out, Char value,
|
||||||
const basic_format_specs<Char>& specs) {
|
const basic_format_specs<Char>& specs) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user