mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-29 13:21:05 +00:00
Move data out of basic_data
This commit is contained in:
parent
1d4199f46b
commit
841aad95b4
@ -379,7 +379,7 @@ template <typename Char> struct ansi_color_escape {
|
|||||||
// If we have a terminal color, we need to output another escape code
|
// If we have a terminal color, we need to output another escape code
|
||||||
// sequence.
|
// sequence.
|
||||||
if (!text_color.is_rgb) {
|
if (!text_color.is_rgb) {
|
||||||
bool is_background = esc == detail::data::background_color;
|
bool is_background = esc == string_view("\x1b[48;2;");
|
||||||
uint32_t value = text_color.value.term_color;
|
uint32_t value = text_color.value.term_color;
|
||||||
// Background ASCII codes are the same as the foreground ones but with
|
// Background ASCII codes are the same as the foreground ones but with
|
||||||
// 10 more.
|
// 10 more.
|
||||||
@ -451,13 +451,13 @@ template <typename Char> struct ansi_color_escape {
|
|||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
|
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
|
||||||
detail::color_type foreground) FMT_NOEXCEPT {
|
detail::color_type foreground) FMT_NOEXCEPT {
|
||||||
return ansi_color_escape<Char>(foreground, detail::data::foreground_color);
|
return ansi_color_escape<Char>(foreground, "\x1b[38;2;");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
|
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
|
||||||
detail::color_type background) FMT_NOEXCEPT {
|
detail::color_type background) FMT_NOEXCEPT {
|
||||||
return ansi_color_escape<Char>(background, detail::data::background_color);
|
return ansi_color_escape<Char>(background, "\x1b[48;2;");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@ -476,18 +476,17 @@ inline void fputs<wchar_t>(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT {
|
template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT {
|
||||||
fputs(detail::data::reset_color, stream);
|
fputs("\x1b[0m", stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT {
|
template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT {
|
||||||
fputs(detail::data::wreset_color, stream);
|
fputs(L"\x1b[0m", stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline void reset_color(buffer<Char>& buffer) FMT_NOEXCEPT {
|
inline void reset_color(buffer<Char>& buffer) FMT_NOEXCEPT {
|
||||||
const char* begin = data::reset_color;
|
auto reset_color = string_view("\x1b[0m");
|
||||||
const char* end = begin + sizeof(data::reset_color) - 1;
|
buffer.append(reset_color.begin(), reset_color.end());
|
||||||
buffer.append(begin, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
|
@ -249,111 +249,14 @@ const typename basic_data<T>::digit_pair basic_data<T>::digits[] = {
|
|||||||
(factor)*1000000000
|
(factor)*1000000000
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint64_t basic_data<T>::powers_of_10_64[] = {
|
const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0, 0,
|
||||||
1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
|
|
||||||
10000000000000000000ULL};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0,
|
|
||||||
FMT_POWERS_OF_10(1)};
|
FMT_POWERS_OF_10(1)};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint64_t basic_data<T>::zero_or_powers_of_10_64[] = {
|
const uint64_t basic_data<T>::zero_or_powers_of_10_64[] = {
|
||||||
0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
|
|
||||||
10000000000000000000ULL};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const uint32_t basic_data<T>::zero_or_powers_of_10_32_new[] = {
|
|
||||||
0, 0, FMT_POWERS_OF_10(1)};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const uint64_t basic_data<T>::zero_or_powers_of_10_64_new[] = {
|
|
||||||
0, 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
|
0, 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
|
||||||
10000000000000000000ULL};
|
10000000000000000000ULL};
|
||||||
|
|
||||||
// Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
|
|
||||||
// These are generated by support/compute-powers.py.
|
|
||||||
template <typename T>
|
|
||||||
const uint64_t basic_data<T>::grisu_pow10_significands[] = {
|
|
||||||
0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
|
|
||||||
0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
|
|
||||||
0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
|
|
||||||
0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
|
|
||||||
0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
|
|
||||||
0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
|
|
||||||
0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
|
|
||||||
0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
|
|
||||||
0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
|
|
||||||
0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
|
|
||||||
0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
|
|
||||||
0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
|
|
||||||
0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
|
|
||||||
0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
|
|
||||||
0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
|
|
||||||
0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
|
|
||||||
0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
|
|
||||||
0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
|
|
||||||
0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
|
|
||||||
0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
|
|
||||||
0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
|
|
||||||
0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
|
|
||||||
0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
|
|
||||||
0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
|
|
||||||
0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
|
|
||||||
0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
|
|
||||||
0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
|
|
||||||
0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
|
|
||||||
0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
|
|
||||||
// to significands above.
|
|
||||||
template <typename T>
|
|
||||||
const int16_t basic_data<T>::grisu_pow10_exponents[] = {
|
|
||||||
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
|
|
||||||
-927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
|
|
||||||
-635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
|
|
||||||
-343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
|
|
||||||
-50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
|
|
||||||
242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
|
|
||||||
534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
|
|
||||||
827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const divtest_table_entry<uint32_t> basic_data<T>::divtest_table_for_pow5_32[] =
|
|
||||||
{{0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333},
|
|
||||||
{0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba},
|
|
||||||
{0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5},
|
|
||||||
{0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf},
|
|
||||||
{0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897},
|
|
||||||
{0x3ed61f49, 0x000001b7}};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const divtest_table_entry<uint64_t> basic_data<T>::divtest_table_for_pow5_64[] =
|
|
||||||
{{0x0000000000000001, 0xffffffffffffffff},
|
|
||||||
{0xcccccccccccccccd, 0x3333333333333333},
|
|
||||||
{0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70},
|
|
||||||
{0x1cac083126e978d5, 0x020c49ba5e353f7c},
|
|
||||||
{0xd288ce703afb7e91, 0x0068db8bac710cb2},
|
|
||||||
{0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0},
|
|
||||||
{0x790fb65668c26139, 0x000431bde82d7b63},
|
|
||||||
{0xe5032477ae8d46a5, 0x0000d6bf94d5e57a},
|
|
||||||
{0xc767074b22e90e21, 0x00002af31dc46118},
|
|
||||||
{0x8e47ce423a2e9c6d, 0x0000089705f4136b},
|
|
||||||
{0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b},
|
|
||||||
{0x0fee64690c913975, 0x00000057f5ff85e5},
|
|
||||||
{0x3662e0e1cf503eb1, 0x000000119799812d},
|
|
||||||
{0xa47a2cf9f6433fbd, 0x0000000384b84d09},
|
|
||||||
{0x54186f653140a659, 0x00000000b424dc35},
|
|
||||||
{0x7738164770402145, 0x0000000024075f3d},
|
|
||||||
{0xe4a4d1417cd9a041, 0x000000000734aca5},
|
|
||||||
{0xc75429d9e5c5200d, 0x000000000170ef54},
|
|
||||||
{0xc1773b91fac10669, 0x000000000049c977},
|
|
||||||
{0x26b172506559ce15, 0x00000000000ec1e4},
|
|
||||||
{0xd489e3a9addec2d1, 0x000000000002f394},
|
|
||||||
{0x90e860bb892c8d5d, 0x000000000000971d},
|
|
||||||
{0x502e79bf1b6f4f79, 0x0000000000001e39},
|
|
||||||
{0xdcd618596be30fe5, 0x000000000000060b}};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint64_t basic_data<T>::dragonbox_pow10_significands_64[] = {
|
const uint64_t basic_data<T>::dragonbox_pow10_significands_64[] = {
|
||||||
0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,
|
0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,
|
||||||
@ -1056,12 +959,6 @@ const uint32_t basic_data<T>::dragonbox_pow10_recovery_errors[] = {
|
|||||||
0x69514555, 0x05151109, 0x00155555};
|
0x69514555, 0x05151109, 0x00155555};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const char basic_data<T>::foreground_color[] = "\x1b[38;2;";
|
|
||||||
template <typename T>
|
|
||||||
const char basic_data<T>::background_color[] = "\x1b[48;2;";
|
|
||||||
template <typename T> const char basic_data<T>::reset_color[] = "\x1b[0m";
|
|
||||||
template <typename T> const wchar_t basic_data<T>::wreset_color[] = L"\x1b[0m";
|
|
||||||
template <typename T> const char basic_data<T>::signs[] = {0, '-', '+', ' '};
|
template <typename T> const char basic_data<T>::signs[] = {0, '-', '+', ' '};
|
||||||
|
|
||||||
#if __cplusplus < 201703L
|
#if __cplusplus < 201703L
|
||||||
@ -1194,6 +1091,52 @@ inline fp operator*(fp x, fp y) { return {multiply(x.f, y.f), x.e + y.e + 64}; }
|
|||||||
// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
|
// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
|
||||||
// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
|
// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
|
||||||
inline fp get_cached_power(int min_exponent, int& pow10_exponent) {
|
inline fp get_cached_power(int min_exponent, int& pow10_exponent) {
|
||||||
|
// Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
|
||||||
|
// These are generated by support/compute-powers.py.
|
||||||
|
static constexpr const uint64_t pow10_significands[] = {
|
||||||
|
0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
|
||||||
|
0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
|
||||||
|
0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
|
||||||
|
0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
|
||||||
|
0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
|
||||||
|
0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
|
||||||
|
0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
|
||||||
|
0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
|
||||||
|
0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
|
||||||
|
0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
|
||||||
|
0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
|
||||||
|
0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
|
||||||
|
0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
|
||||||
|
0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
|
||||||
|
0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
|
||||||
|
0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
|
||||||
|
0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
|
||||||
|
0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
|
||||||
|
0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
|
||||||
|
0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
|
||||||
|
0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
|
||||||
|
0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
|
||||||
|
0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
|
||||||
|
0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
|
||||||
|
0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
|
||||||
|
0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
|
||||||
|
0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
|
||||||
|
0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
|
||||||
|
0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
|
||||||
|
// to significands above.
|
||||||
|
static constexpr const int16_t pow10_exponents[] = {
|
||||||
|
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
|
||||||
|
-927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
|
||||||
|
-635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
|
||||||
|
-343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
|
||||||
|
-50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
|
||||||
|
242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
|
||||||
|
534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
|
||||||
|
827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
|
||||||
|
|
||||||
const int shift = 32;
|
const int shift = 32;
|
||||||
const auto significand = static_cast<int64_t>(data::log10_2_significand);
|
const auto significand = static_cast<int64_t>(data::log10_2_significand);
|
||||||
int index = static_cast<int>(
|
int index = static_cast<int>(
|
||||||
@ -1207,8 +1150,7 @@ inline fp get_cached_power(int min_exponent, int& pow10_exponent) {
|
|||||||
const int dec_exp_step = 8;
|
const int dec_exp_step = 8;
|
||||||
index = (index - first_dec_exp - 1) / dec_exp_step + 1;
|
index = (index - first_dec_exp - 1) / dec_exp_step + 1;
|
||||||
pow10_exponent = first_dec_exp + index * dec_exp_step;
|
pow10_exponent = first_dec_exp + index * dec_exp_step;
|
||||||
return {data::grisu_pow10_significands[index],
|
return {pow10_significands[index], pow10_exponents[index]};
|
||||||
data::grisu_pow10_exponents[index]};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A simple accumulator to hold the sums of terms in bigint::square if uint128_t
|
// A simple accumulator to hold the sums of terms in bigint::square if uint128_t
|
||||||
@ -1499,6 +1441,13 @@ enum result {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint64_t power_of_10_64(int exp) {
|
||||||
|
static constexpr uint64_t data[] = {1, FMT_POWERS_OF_10(1),
|
||||||
|
FMT_POWERS_OF_10(1000000000ULL),
|
||||||
|
10000000000000000000ULL};
|
||||||
|
return data[exp];
|
||||||
|
}
|
||||||
|
|
||||||
// Generates output using the Grisu digit-gen algorithm.
|
// Generates output using the Grisu digit-gen algorithm.
|
||||||
// error: the size of the region (lower, upper) outside of which numbers
|
// error: the size of the region (lower, upper) outside of which numbers
|
||||||
// definitely do not round to value (Delta in Grisu3).
|
// definitely do not round to value (Delta in Grisu3).
|
||||||
@ -1516,7 +1465,7 @@ FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error,
|
|||||||
uint64_t fractional = value.f & (one.f - 1);
|
uint64_t fractional = value.f & (one.f - 1);
|
||||||
exp = count_digits(integral); // kappa in Grisu.
|
exp = count_digits(integral); // kappa in Grisu.
|
||||||
// Divide by 10 to prevent overflow.
|
// Divide by 10 to prevent overflow.
|
||||||
auto result = handler.on_start(data::powers_of_10_64[exp - 1] << -one.e,
|
auto result = handler.on_start(power_of_10_64(exp - 1) << -one.e,
|
||||||
value.f / 10, error * 10, exp);
|
value.f / 10, error * 10, exp);
|
||||||
if (result != digits::more) return result;
|
if (result != digits::more) return result;
|
||||||
// Generate digits for the integral part. This can produce up to 10 digits.
|
// Generate digits for the integral part. This can produce up to 10 digits.
|
||||||
@ -1566,8 +1515,8 @@ FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error,
|
|||||||
--exp;
|
--exp;
|
||||||
auto remainder = (static_cast<uint64_t>(integral) << -one.e) + fractional;
|
auto remainder = (static_cast<uint64_t>(integral) << -one.e) + fractional;
|
||||||
result = handler.on_digit(static_cast<char>('0' + digit),
|
result = handler.on_digit(static_cast<char>('0' + digit),
|
||||||
data::powers_of_10_64[exp] << -one.e, remainder,
|
power_of_10_64(exp) << -one.e, remainder, error,
|
||||||
error, exp, true);
|
exp, true);
|
||||||
if (result != digits::more) return result;
|
if (result != digits::more) return result;
|
||||||
} while (exp > 0);
|
} while (exp > 0);
|
||||||
// Generate digits for the fractional part.
|
// Generate digits for the fractional part.
|
||||||
@ -1761,16 +1710,52 @@ inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Table entry type for divisibility test.
|
||||||
|
template <typename T> struct divtest_table_entry {
|
||||||
|
T mod_inv;
|
||||||
|
T max_quotient;
|
||||||
|
};
|
||||||
|
|
||||||
// Returns true iff x is divisible by pow(5, exp).
|
// Returns true iff x is divisible by pow(5, exp).
|
||||||
inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT {
|
inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT {
|
||||||
FMT_ASSERT(exp <= 10, "too large exponent");
|
FMT_ASSERT(exp <= 10, "too large exponent");
|
||||||
return x * data::divtest_table_for_pow5_32[exp].mod_inv <=
|
constexpr const divtest_table_entry<uint32_t> divtest_table[] = {
|
||||||
data::divtest_table_for_pow5_32[exp].max_quotient;
|
{0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333},
|
||||||
|
{0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba},
|
||||||
|
{0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5},
|
||||||
|
{0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf},
|
||||||
|
{0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897},
|
||||||
|
{0x3ed61f49, 0x000001b7}};
|
||||||
|
return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient;
|
||||||
}
|
}
|
||||||
inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT {
|
inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT {
|
||||||
FMT_ASSERT(exp <= 23, "too large exponent");
|
FMT_ASSERT(exp <= 23, "too large exponent");
|
||||||
return x * data::divtest_table_for_pow5_64[exp].mod_inv <=
|
constexpr const divtest_table_entry<uint64_t> divtest_table[] = {
|
||||||
data::divtest_table_for_pow5_64[exp].max_quotient;
|
{0x0000000000000001, 0xffffffffffffffff},
|
||||||
|
{0xcccccccccccccccd, 0x3333333333333333},
|
||||||
|
{0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70},
|
||||||
|
{0x1cac083126e978d5, 0x020c49ba5e353f7c},
|
||||||
|
{0xd288ce703afb7e91, 0x0068db8bac710cb2},
|
||||||
|
{0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0},
|
||||||
|
{0x790fb65668c26139, 0x000431bde82d7b63},
|
||||||
|
{0xe5032477ae8d46a5, 0x0000d6bf94d5e57a},
|
||||||
|
{0xc767074b22e90e21, 0x00002af31dc46118},
|
||||||
|
{0x8e47ce423a2e9c6d, 0x0000089705f4136b},
|
||||||
|
{0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b},
|
||||||
|
{0x0fee64690c913975, 0x00000057f5ff85e5},
|
||||||
|
{0x3662e0e1cf503eb1, 0x000000119799812d},
|
||||||
|
{0xa47a2cf9f6433fbd, 0x0000000384b84d09},
|
||||||
|
{0x54186f653140a659, 0x00000000b424dc35},
|
||||||
|
{0x7738164770402145, 0x0000000024075f3d},
|
||||||
|
{0xe4a4d1417cd9a041, 0x000000000734aca5},
|
||||||
|
{0xc75429d9e5c5200d, 0x000000000170ef54},
|
||||||
|
{0xc1773b91fac10669, 0x000000000049c977},
|
||||||
|
{0x26b172506559ce15, 0x00000000000ec1e4},
|
||||||
|
{0xd489e3a9addec2d1, 0x000000000002f394},
|
||||||
|
{0x90e860bb892c8d5d, 0x000000000000971d},
|
||||||
|
{0x502e79bf1b6f4f79, 0x0000000000001e39},
|
||||||
|
{0xdcd618596be30fe5, 0x000000000000060b}};
|
||||||
|
return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replaces n by floor(n / pow(5, N)) returning true if and only if n is
|
// Replaces n by floor(n / pow(5, N)) returning true if and only if n is
|
||||||
|
@ -945,21 +945,10 @@ struct FMT_EXTERN_TEMPLATE_API uint128_wrapper {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Table entry type for divisibility test used internally
|
|
||||||
template <typename T> struct FMT_EXTERN_TEMPLATE_API divtest_table_entry {
|
|
||||||
T mod_inv;
|
|
||||||
T max_quotient;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Static data is placed in this class template for the header-only config.
|
// Static data is placed in this class template for the header-only config.
|
||||||
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
|
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
|
||||||
static const uint64_t powers_of_10_64[];
|
static const uint32_t zero_or_powers_of_10_32[];
|
||||||
static const uint32_t zero_or_powers_of_10_32_new[];
|
static const uint64_t zero_or_powers_of_10_64[];
|
||||||
static const uint64_t zero_or_powers_of_10_64_new[];
|
|
||||||
static const uint64_t grisu_pow10_significands[];
|
|
||||||
static const int16_t grisu_pow10_exponents[];
|
|
||||||
static const divtest_table_entry<uint32_t> divtest_table_for_pow5_32[];
|
|
||||||
static const divtest_table_entry<uint64_t> divtest_table_for_pow5_64[];
|
|
||||||
static const uint64_t dragonbox_pow10_significands_64[];
|
static const uint64_t dragonbox_pow10_significands_64[];
|
||||||
static const uint128_wrapper dragonbox_pow10_significands_128[];
|
static const uint128_wrapper dragonbox_pow10_significands_128[];
|
||||||
// log10(2) = 0x0.4d104d427de7fbcc...
|
// log10(2) = 0x0.4d104d427de7fbcc...
|
||||||
@ -972,19 +961,11 @@ template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
|
|||||||
using digit_pair = char[2];
|
using digit_pair = char[2];
|
||||||
static const digit_pair digits[];
|
static const digit_pair digits[];
|
||||||
static constexpr const char hex_digits[] = "0123456789abcdef";
|
static constexpr const char hex_digits[] = "0123456789abcdef";
|
||||||
static const char foreground_color[];
|
|
||||||
static const char background_color[];
|
|
||||||
static const char reset_color[5];
|
|
||||||
static const wchar_t wreset_color[5];
|
|
||||||
static const char signs[];
|
static const char signs[];
|
||||||
static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
|
static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
|
||||||
0x1000000u | ' '};
|
0x1000000u | ' '};
|
||||||
static constexpr const char left_padding_shifts[] = {31, 31, 0, 1, 0};
|
static constexpr const char left_padding_shifts[] = {31, 31, 0, 1, 0};
|
||||||
static constexpr const char right_padding_shifts[] = {0, 31, 0, 1, 0};
|
static constexpr const char right_padding_shifts[] = {0, 31, 0, 1, 0};
|
||||||
|
|
||||||
// DEPRECATED! These are for ABI compatibility.
|
|
||||||
static const uint32_t zero_or_powers_of_10_32[];
|
|
||||||
static const uint64_t zero_or_powers_of_10_64[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
|
// Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
|
||||||
@ -1034,7 +1015,7 @@ FMT_CONSTEXPR20 inline int count_digits(uint64_t n) {
|
|||||||
#ifdef FMT_BUILTIN_CLZLL
|
#ifdef FMT_BUILTIN_CLZLL
|
||||||
// https://github.com/fmtlib/format-benchmark/blob/master/digits10
|
// https://github.com/fmtlib/format-benchmark/blob/master/digits10
|
||||||
auto t = bsr2log10(FMT_BUILTIN_CLZLL(n | 1) ^ 63);
|
auto t = bsr2log10(FMT_BUILTIN_CLZLL(n | 1) ^ 63);
|
||||||
return t - (n < data::zero_or_powers_of_10_64_new[t]);
|
return t - (n < data::zero_or_powers_of_10_64[t]);
|
||||||
#else
|
#else
|
||||||
return count_digits_fallback(n);
|
return count_digits_fallback(n);
|
||||||
#endif
|
#endif
|
||||||
@ -1070,7 +1051,7 @@ FMT_CONSTEXPR20 inline int count_digits(uint32_t n) {
|
|||||||
return count_digits_fallback(n);
|
return count_digits_fallback(n);
|
||||||
}
|
}
|
||||||
auto t = bsr2log10(FMT_BUILTIN_CLZ(n | 1) ^ 31);
|
auto t = bsr2log10(FMT_BUILTIN_CLZ(n | 1) ^ 31);
|
||||||
return t - (n < data::zero_or_powers_of_10_32_new[t]);
|
return t - (n < data::zero_or_powers_of_10_32[t]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2303,7 +2284,8 @@ class arg_formatter_base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr arg_formatter_base(OutputIt out, const format_specs& s, locale_ref loc)
|
constexpr arg_formatter_base(OutputIt out, const format_specs& s,
|
||||||
|
locale_ref loc)
|
||||||
: out_(out), specs_(s), locale_(loc) {}
|
: out_(out), specs_(s), locale_(loc) {}
|
||||||
|
|
||||||
iterator operator()(monostate) {
|
iterator operator()(monostate) {
|
||||||
|
Loading…
Reference in New Issue
Block a user