Make dragonbox::to_decimal available in format.h
This commit is contained in:
parent
2213a7110c
commit
63e0c35412
@ -1776,67 +1776,6 @@ inline int floor_log10_pow2_minus_log10_4_over_3(int e) FMT_NOEXCEPT {
|
||||
shift_amount;
|
||||
}
|
||||
|
||||
// Type-specific information that Dragonbox uses.
|
||||
template <class T> struct float_info;
|
||||
|
||||
template <> struct float_info<float> {
|
||||
using carrier_uint = uint32_t;
|
||||
static const int significand_bits = 23;
|
||||
static const int exponent_bits = 8;
|
||||
static const int min_exponent = -126;
|
||||
static const int max_exponent = 127;
|
||||
static const int exponent_bias = -127;
|
||||
static const int decimal_digits = 9;
|
||||
static const int kappa = 1;
|
||||
static const int big_divisor = 100;
|
||||
static const int small_divisor = 10;
|
||||
static const int min_k = -31;
|
||||
static const int max_k = 46;
|
||||
static const int cache_bits = 64;
|
||||
static const int divisibility_check_by_5_threshold = 39;
|
||||
static const int case_fc_pm_half_lower_threshold = -1;
|
||||
static const int case_fc_pm_half_upper_threshold = 6;
|
||||
static const int case_fc_lower_threshold = -2;
|
||||
static const int case_fc_upper_threshold = 6;
|
||||
static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
|
||||
static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
|
||||
static const int shorter_interval_tie_lower_threshold = -35;
|
||||
static const int shorter_interval_tie_upper_threshold = -35;
|
||||
static const int max_trailing_zeros = 7;
|
||||
};
|
||||
|
||||
template <> struct float_info<double> {
|
||||
using carrier_uint = uint64_t;
|
||||
static const int significand_bits = 52;
|
||||
static const int exponent_bits = 11;
|
||||
static const int min_exponent = -1022;
|
||||
static const int max_exponent = 1023;
|
||||
static const int exponent_bias = -1023;
|
||||
static const int decimal_digits = 17;
|
||||
static const int kappa = 2;
|
||||
static const int big_divisor = 1000;
|
||||
static const int small_divisor = 100;
|
||||
static const int min_k = -292;
|
||||
static const int max_k = 326;
|
||||
static const int cache_bits = 128;
|
||||
static const int divisibility_check_by_5_threshold = 86;
|
||||
static const int case_fc_pm_half_lower_threshold = -2;
|
||||
static const int case_fc_pm_half_upper_threshold = 9;
|
||||
static const int case_fc_lower_threshold = -4;
|
||||
static const int case_fc_upper_threshold = 9;
|
||||
static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
|
||||
static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
|
||||
static const int shorter_interval_tie_lower_threshold = -77;
|
||||
static const int shorter_interval_tie_upper_threshold = -77;
|
||||
static const int max_trailing_zeros = 16;
|
||||
};
|
||||
|
||||
template <class T> struct decimal_fp {
|
||||
using significand_type = typename float_info<T>::carrier_uint;
|
||||
significand_type significand;
|
||||
int exponent;
|
||||
};
|
||||
|
||||
// Returns true iff x is divisible by pow(2, exp).
|
||||
inline bool divisible_by_power_of_2(uint32_t x, int exp) FMT_NOEXCEPT {
|
||||
FMT_ASSERT(exp >= 1, "");
|
||||
@ -2291,7 +2230,9 @@ FMT_ALWAYS_INLINE FMT_SAFEBUFFERS decimal_fp<T> shorter_interval_case(
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
template <class T> FMT_SAFEBUFFERS decimal_fp<T> to_decimal(T x) FMT_NOEXCEPT {
|
||||
template <typename T>
|
||||
FMT_SAFEBUFFERS enable_if_t<is_fast_float<T>(), decimal_fp<T>> to_decimal(T x)
|
||||
FMT_NOEXCEPT {
|
||||
// Step 1: integer promotion & Schubfach multiplier calculation.
|
||||
|
||||
using carrier_uint = typename float_info<T>::carrier_uint;
|
||||
|
@ -587,13 +587,8 @@ inline counting_iterator copy_str(InputIt begin, InputIt end,
|
||||
return it + (end - begin);
|
||||
}
|
||||
|
||||
#ifndef FMT_USE_GRISU
|
||||
# define FMT_USE_GRISU 1
|
||||
#endif
|
||||
|
||||
template <typename T> constexpr bool use_grisu() {
|
||||
return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559 &&
|
||||
sizeof(T) <= sizeof(double);
|
||||
template <typename T> constexpr bool is_fast_float() {
|
||||
return std::numeric_limits<T>::is_iec559 && sizeof(T) <= sizeof(double);
|
||||
}
|
||||
|
||||
#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
|
||||
@ -1368,6 +1363,78 @@ int snprintf_float(T value, int precision, float_specs specs,
|
||||
template <typename T> T promote_float(T value) { return value; }
|
||||
inline double promote_float(float value) { return static_cast<double>(value); }
|
||||
|
||||
namespace dragonbox {
|
||||
|
||||
// Type-specific information that Dragonbox uses.
|
||||
template <class T> struct float_info;
|
||||
|
||||
template <> struct float_info<float> {
|
||||
using carrier_uint = uint32_t;
|
||||
static const int significand_bits = 23;
|
||||
static const int exponent_bits = 8;
|
||||
static const int min_exponent = -126;
|
||||
static const int max_exponent = 127;
|
||||
static const int exponent_bias = -127;
|
||||
static const int decimal_digits = 9;
|
||||
static const int kappa = 1;
|
||||
static const int big_divisor = 100;
|
||||
static const int small_divisor = 10;
|
||||
static const int min_k = -31;
|
||||
static const int max_k = 46;
|
||||
static const int cache_bits = 64;
|
||||
static const int divisibility_check_by_5_threshold = 39;
|
||||
static const int case_fc_pm_half_lower_threshold = -1;
|
||||
static const int case_fc_pm_half_upper_threshold = 6;
|
||||
static const int case_fc_lower_threshold = -2;
|
||||
static const int case_fc_upper_threshold = 6;
|
||||
static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
|
||||
static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
|
||||
static const int shorter_interval_tie_lower_threshold = -35;
|
||||
static const int shorter_interval_tie_upper_threshold = -35;
|
||||
static const int max_trailing_zeros = 7;
|
||||
};
|
||||
|
||||
template <> struct float_info<double> {
|
||||
using carrier_uint = uint64_t;
|
||||
static const int significand_bits = 52;
|
||||
static const int exponent_bits = 11;
|
||||
static const int min_exponent = -1022;
|
||||
static const int max_exponent = 1023;
|
||||
static const int exponent_bias = -1023;
|
||||
static const int decimal_digits = 17;
|
||||
static const int kappa = 2;
|
||||
static const int big_divisor = 1000;
|
||||
static const int small_divisor = 100;
|
||||
static const int min_k = -292;
|
||||
static const int max_k = 326;
|
||||
static const int cache_bits = 128;
|
||||
static const int divisibility_check_by_5_threshold = 86;
|
||||
static const int case_fc_pm_half_lower_threshold = -2;
|
||||
static const int case_fc_pm_half_upper_threshold = 9;
|
||||
static const int case_fc_lower_threshold = -4;
|
||||
static const int case_fc_upper_threshold = 9;
|
||||
static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
|
||||
static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
|
||||
static const int shorter_interval_tie_lower_threshold = -77;
|
||||
static const int shorter_interval_tie_upper_threshold = -77;
|
||||
static const int max_trailing_zeros = 16;
|
||||
};
|
||||
|
||||
template <typename T> struct decimal_fp {
|
||||
using significand_type = typename float_info<T>::carrier_uint;
|
||||
significand_type significand;
|
||||
int exponent;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
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
|
||||
|
||||
template <typename Handler>
|
||||
FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) {
|
||||
switch (spec) {
|
||||
@ -1810,7 +1877,7 @@ OutputIt write(OutputIt out, T value, basic_format_specs<Char> specs,
|
||||
++precision;
|
||||
}
|
||||
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
||||
fspecs.use_grisu = use_grisu<T>();
|
||||
fspecs.use_grisu = is_fast_float<T>();
|
||||
int exp = format_float(promote_float(value), precision, fspecs, buffer);
|
||||
fspecs.precision = precision;
|
||||
Char point =
|
||||
@ -1837,7 +1904,7 @@ OutputIt write(OutputIt out, T value) {
|
||||
memory_buffer buffer;
|
||||
int precision = -1;
|
||||
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
||||
fspecs.use_grisu = use_grisu<T>();
|
||||
fspecs.use_grisu = is_fast_float<T>();
|
||||
int exp = format_float(promote_float(value), precision, fspecs, buffer);
|
||||
fspecs.precision = precision;
|
||||
float_writer<Char> w(buffer.data(), static_cast<int>(buffer.size()), exp,
|
||||
|
Loading…
Reference in New Issue
Block a user