1 // Formatting library for C++ - implementation
2 //
3 // Copyright (c) 2012 - 2016, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7
8 #ifndef FMT_FORMAT_INL_H_
9 #define FMT_FORMAT_INL_H_
10
11 #include <algorithm>
12 #include <cctype>
13 #include <climits>
14 #include <cmath>
15 #include <cstdarg>
16 #include <cstring> // std::memmove
17 #include <cwchar>
18 #include <exception>
19
20 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
21 # include <locale>
22 #endif
23
24 #ifdef _WIN32
25 # include <io.h> // _isatty
26 #endif
27
28 #include "format.h"
29
30 // Dummy implementations of strerror_r and strerror_s called if corresponding
31 // system functions are not available.
strerror_r(int,char *,...)32 inline axom::fmt::detail::null<> strerror_r(int, char*, ...) { return {}; }
strerror_s(char *,size_t,...)33 inline axom::fmt::detail::null<> strerror_s(char*, size_t, ...) { return {}; }
34
35 FMT_BEGIN_NAMESPACE
36 namespace detail {
37
assert_fail(const char * file,int line,const char * message)38 FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
39 // Use unchecked std::fprintf to avoid triggering another assertion when
40 // writing to stderr fails
41 std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
42 // Chosen instead of std::abort to satisfy Clang in CUDA mode during device
43 // code pass.
44 std::terminate();
45 }
46
47 #ifndef _MSC_VER
48 # define FMT_SNPRINTF snprintf
49 #else // _MSC_VER
fmt_snprintf(char * buffer,size_t size,const char * format,...)50 inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) {
51 va_list args;
52 va_start(args, format);
53 int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
54 va_end(args);
55 return result;
56 }
57 # define FMT_SNPRINTF fmt_snprintf
58 #endif // _MSC_VER
59
60 // A portable thread-safe version of strerror.
61 // Sets buffer to point to a string describing the error code.
62 // This can be either a pointer to a string stored in buffer,
63 // or a pointer to some static immutable string.
64 // Returns one of the following values:
65 // 0 - success
66 // ERANGE - buffer is not large enough to store the error message
67 // other - failure
68 // Buffer should be at least of size 1.
safe_strerror(int error_code,char * & buffer,size_t buffer_size)69 inline int safe_strerror(int error_code, char*& buffer,
70 size_t buffer_size) FMT_NOEXCEPT {
71 FMT_ASSERT(buffer != nullptr && buffer_size != 0, "invalid buffer");
72
73 class dispatcher {
74 private:
75 int error_code_;
76 char*& buffer_;
77 size_t buffer_size_;
78
79 // A noop assignment operator to avoid bogus warnings.
80 void operator=(const dispatcher&) {}
81
82 // Handle the result of XSI-compliant version of strerror_r.
83 int handle(int result) {
84 // glibc versions before 2.13 return result in errno.
85 return result == -1 ? errno : result;
86 }
87
88 // Handle the result of GNU-specific version of strerror_r.
89 FMT_MAYBE_UNUSED
90 int handle(char* message) {
91 // If the buffer is full then the message is probably truncated.
92 if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
93 return ERANGE;
94 buffer_ = message;
95 return 0;
96 }
97
98 // Handle the case when strerror_r is not available.
99 FMT_MAYBE_UNUSED
100 int handle(detail::null<>) {
101 return fallback(strerror_s(buffer_, buffer_size_, error_code_));
102 }
103
104 // Fallback to strerror_s when strerror_r is not available.
105 FMT_MAYBE_UNUSED
106 int fallback(int result) {
107 // If the buffer is full then the message is probably truncated.
108 return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE
109 : result;
110 }
111
112 #if !FMT_MSC_VER
113 // Fallback to strerror if strerror_r and strerror_s are not available.
114 int fallback(detail::null<>) {
115 errno = 0;
116 buffer_ = strerror(error_code_);
117 return errno;
118 }
119 #endif
120
121 public:
122 dispatcher(int err_code, char*& buf, size_t buf_size)
123 : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
124
125 int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
126 };
127 return dispatcher(error_code, buffer, buffer_size).run();
128 }
129
format_error_code(detail::buffer<char> & out,int error_code,string_view message)130 FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
131 string_view message) FMT_NOEXCEPT {
132 // Report error code making sure that the output fits into
133 // inline_buffer_size to avoid dynamic memory allocation and potential
134 // bad_alloc.
135 out.try_resize(0);
136 static const char SEP[] = ": ";
137 static const char ERROR_STR[] = "error ";
138 // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
139 size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
140 auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code);
141 if (detail::is_negative(error_code)) {
142 abs_value = 0 - abs_value;
143 ++error_code_size;
144 }
145 error_code_size += detail::to_unsigned(detail::count_digits(abs_value));
146 auto it = buffer_appender<char>(out);
147 if (message.size() <= inline_buffer_size - error_code_size)
148 format_to(it, FMT_STRING("{}{}"), message, SEP);
149 format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code);
150 FMT_ASSERT(out.size() <= inline_buffer_size, "");
151 }
152
report_error(format_func func,int error_code,string_view message)153 FMT_FUNC void report_error(format_func func, int error_code,
154 string_view message) FMT_NOEXCEPT {
155 memory_buffer full_message;
156 func(full_message, error_code, message);
157 // Don't use fwrite_fully because the latter may throw.
158 (void)std::fwrite(full_message.data(), full_message.size(), 1, stderr);
159 std::fputc('\n', stderr);
160 }
161
162 // A wrapper around fwrite that throws on error.
fwrite_fully(const void * ptr,size_t size,size_t count,FILE * stream)163 inline void fwrite_fully(const void* ptr, size_t size, size_t count,
164 FILE* stream) {
165 size_t written = std::fwrite(ptr, size, count, stream);
166 if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
167 }
168
169 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
170 template <typename Locale>
locale_ref(const Locale & loc)171 locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
172 static_assert(std::is_same<Locale, std::locale>::value, "");
173 }
174
get()175 template <typename Locale> Locale locale_ref::get() const {
176 static_assert(std::is_same<Locale, std::locale>::value, "");
177 return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
178 }
179
grouping_impl(locale_ref loc)180 template <typename Char> FMT_FUNC std::string grouping_impl(locale_ref loc) {
181 return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()).grouping();
182 }
thousands_sep_impl(locale_ref loc)183 template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
184 return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
185 .thousands_sep();
186 }
decimal_point_impl(locale_ref loc)187 template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
188 return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
189 .decimal_point();
190 }
191 #else
grouping_impl(locale_ref)192 template <typename Char> FMT_FUNC std::string grouping_impl(locale_ref) {
193 return "\03";
194 }
thousands_sep_impl(locale_ref)195 template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref) {
196 return FMT_STATIC_THOUSANDS_SEPARATOR;
197 }
decimal_point_impl(locale_ref)198 template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
199 return '.';
200 }
201 #endif
202 } // namespace detail
203
204 FMT_API FMT_FUNC format_error::~format_error() FMT_NOEXCEPT = default;
205 FMT_API FMT_FUNC system_error::~system_error() FMT_NOEXCEPT = default;
206
init(int err_code,string_view format_str,format_args args)207 FMT_FUNC void system_error::init(int err_code, string_view format_str,
208 format_args args) {
209 error_code_ = err_code;
210 memory_buffer buffer;
211 format_system_error(buffer, err_code, vformat(format_str, args));
212 std::runtime_error& base = *this;
213 base = std::runtime_error(to_string(buffer));
214 }
215
216 namespace detail {
217
218 template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) {
219 // fallback_uintptr is always stored in little endian.
220 int i = static_cast<int>(sizeof(void*)) - 1;
221 while (i > 0 && n.value[i] == 0) --i;
222 auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
223 return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1;
224 }
225
226 template <typename T>
227 const typename basic_data<T>::digit_pair basic_data<T>::digits[] = {
228 {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
229 {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
230 {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
231 {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'},
232 {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'},
233 {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'},
234 {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'},
235 {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'},
236 {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'},
237 {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'},
238 {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'},
239 {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'},
240 {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'},
241 {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'},
242 {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'},
243 {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'},
244 {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}};
245
246 #define FMT_POWERS_OF_10(factor) \
247 factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
248 (factor)*1000000, (factor)*10000000, (factor)*100000000, \
249 (factor)*1000000000
250
251 template <typename T>
252 const uint64_t basic_data<T>::powers_of_10_64[] = {
253 1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
254 10000000000000000000ULL};
255
256 template <typename T>
257 const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0,
258 FMT_POWERS_OF_10(1)};
259 template <typename T>
260 const uint64_t basic_data<T>::zero_or_powers_of_10_64[] = {
261 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
262 10000000000000000000ULL};
263
264 template <typename T>
265 const uint32_t basic_data<T>::zero_or_powers_of_10_32_new[] = {
266 0, 0, FMT_POWERS_OF_10(1)};
267
268 template <typename T>
269 const uint64_t basic_data<T>::zero_or_powers_of_10_64_new[] = {
270 0, 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
271 10000000000000000000ULL};
272
273 // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
274 // These are generated by support/compute-powers.py.
275 template <typename T>
276 const uint64_t basic_data<T>::grisu_pow10_significands[] = {
277 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
278 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
279 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
280 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
281 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
282 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
283 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
284 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
285 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
286 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
287 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
288 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
289 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
290 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
291 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
292 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
293 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
294 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
295 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
296 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
297 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
298 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
299 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
300 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
301 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
302 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
303 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
304 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
305 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
306 };
307
308 // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
309 // to significands above.
310 template <typename T>
311 const int16_t basic_data<T>::grisu_pow10_exponents[] = {
312 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
313 -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
314 -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
315 -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
316 -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
317 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
318 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
319 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
320
321 template <typename T>
322 const divtest_table_entry<uint32_t> basic_data<T>::divtest_table_for_pow5_32[] =
323 {{0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333},
324 {0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba},
325 {0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5},
326 {0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf},
327 {0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897},
328 {0x3ed61f49, 0x000001b7}};
329
330 template <typename T>
331 const divtest_table_entry<uint64_t> basic_data<T>::divtest_table_for_pow5_64[] =
332 {{0x0000000000000001, 0xffffffffffffffff},
333 {0xcccccccccccccccd, 0x3333333333333333},
334 {0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70},
335 {0x1cac083126e978d5, 0x020c49ba5e353f7c},
336 {0xd288ce703afb7e91, 0x0068db8bac710cb2},
337 {0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0},
338 {0x790fb65668c26139, 0x000431bde82d7b63},
339 {0xe5032477ae8d46a5, 0x0000d6bf94d5e57a},
340 {0xc767074b22e90e21, 0x00002af31dc46118},
341 {0x8e47ce423a2e9c6d, 0x0000089705f4136b},
342 {0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b},
343 {0x0fee64690c913975, 0x00000057f5ff85e5},
344 {0x3662e0e1cf503eb1, 0x000000119799812d},
345 {0xa47a2cf9f6433fbd, 0x0000000384b84d09},
346 {0x54186f653140a659, 0x00000000b424dc35},
347 {0x7738164770402145, 0x0000000024075f3d},
348 {0xe4a4d1417cd9a041, 0x000000000734aca5},
349 {0xc75429d9e5c5200d, 0x000000000170ef54},
350 {0xc1773b91fac10669, 0x000000000049c977},
351 {0x26b172506559ce15, 0x00000000000ec1e4},
352 {0xd489e3a9addec2d1, 0x000000000002f394},
353 {0x90e860bb892c8d5d, 0x000000000000971d},
354 {0x502e79bf1b6f4f79, 0x0000000000001e39},
355 {0xdcd618596be30fe5, 0x000000000000060b}};
356
357 template <typename T>
358 const uint64_t basic_data<T>::dragonbox_pow10_significands_64[] = {
359 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,
360 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb,
361 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28,
362 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb,
363 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a,
364 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810,
365 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff,
366 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd,
367 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424,
368 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b,
369 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000,
370 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000,
371 0xc350000000000000, 0xf424000000000000, 0x9896800000000000,
372 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000,
373 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000,
374 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000,
375 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000,
376 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000,
377 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0,
378 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984,
379 0xa18f07d736b90be5, 0xc9f2c9cd04674ede, 0xfc6f7c4045812296,
380 0x9dc5ada82b70b59d, 0xc5371912364ce305, 0xf684df56c3e01bc6,
381 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20,
382 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd,
383 0x92efd1b8d0cf37be, 0xb7abc627050305ad, 0xe596b7b0c643c719,
384 0x8f7e32ce7bea5c6f, 0xb35dbf821ae4f38b, 0xe0352f62a19e306e};
385
386 template <typename T>
387 const uint128_wrapper basic_data<T>::dragonbox_pow10_significands_128[] = {
388 #if FMT_USE_FULL_CACHE_DRAGONBOX
389 {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
390 {0x9faacf3df73609b1, 0x77b191618c54e9ad},
391 {0xc795830d75038c1d, 0xd59df5b9ef6a2418},
392 {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e},
393 {0x9becce62836ac577, 0x4ee367f9430aec33},
394 {0xc2e801fb244576d5, 0x229c41f793cda740},
395 {0xf3a20279ed56d48a, 0x6b43527578c11110},
396 {0x9845418c345644d6, 0x830a13896b78aaaa},
397 {0xbe5691ef416bd60c, 0x23cc986bc656d554},
398 {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9},
399 {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa},
400 {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54},
401 {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69},
402 {0x91376c36d99995be, 0x23100809b9c21fa2},
403 {0xb58547448ffffb2d, 0xabd40a0c2832a78b},
404 {0xe2e69915b3fff9f9, 0x16c90c8f323f516d},
405 {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4},
406 {0xb1442798f49ffb4a, 0x99cd11cfdf41779d},
407 {0xdd95317f31c7fa1d, 0x40405643d711d584},
408 {0x8a7d3eef7f1cfc52, 0x482835ea666b2573},
409 {0xad1c8eab5ee43b66, 0xda3243650005eed0},
410 {0xd863b256369d4a40, 0x90bed43e40076a83},
411 {0x873e4f75e2224e68, 0x5a7744a6e804a292},
412 {0xa90de3535aaae202, 0x711515d0a205cb37},
413 {0xd3515c2831559a83, 0x0d5a5b44ca873e04},
414 {0x8412d9991ed58091, 0xe858790afe9486c3},
415 {0xa5178fff668ae0b6, 0x626e974dbe39a873},
416 {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
417 {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a},
418 {0xa139029f6a239f72, 0x1c1fffc1ebc44e81},
419 {0xc987434744ac874e, 0xa327ffb266b56221},
420 {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9},
421 {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa},
422 {0xc4ce17b399107c22, 0xcb550fb4384d21d4},
423 {0xf6019da07f549b2b, 0x7e2a53a146606a49},
424 {0x99c102844f94e0fb, 0x2eda7444cbfc426e},
425 {0xc0314325637a1939, 0xfa911155fefb5309},
426 {0xf03d93eebc589f88, 0x793555ab7eba27cb},
427 {0x96267c7535b763b5, 0x4bc1558b2f3458df},
428 {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17},
429 {0xea9c227723ee8bcb, 0x465e15a979c1cadd},
430 {0x92a1958a7675175f, 0x0bfacd89ec191eca},
431 {0xb749faed14125d36, 0xcef980ec671f667c},
432 {0xe51c79a85916f484, 0x82b7e12780e7401b},
433 {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811},
434 {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16},
435 {0xdfbdcece67006ac9, 0x67a791e093e1d49b},
436 {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1},
437 {0xaecc49914078536d, 0x58fae9f773886e19},
438 {0xda7f5bf590966848, 0xaf39a475506a899f},
439 {0x888f99797a5e012d, 0x6d8406c952429604},
440 {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84},
441 {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65},
442 {0x855c3be0a17fcd26, 0x5cf2eea09a550680},
443 {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},
444 {0xd0601d8efc57b08b, 0xf13b94daf124da27},
445 {0x823c12795db6ce57, 0x76c53d08d6b70859},
446 {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f},
447 {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a},
448 {0xfe5d54150b090b02, 0xd3f93b35435d7c4d},
449 {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0},
450 {0xc6b8e9b0709f109a, 0x359ab6419ca1091c},
451 {0xf867241c8cc6d4c0, 0xc30163d203c94b63},
452 {0x9b407691d7fc44f8, 0x79e0de63425dcf1e},
453 {0xc21094364dfb5636, 0x985915fc12f542e5},
454 {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e},
455 {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43},
456 {0xbd8430bd08277231, 0x50c6ff782a838354},
457 {0xece53cec4a314ebd, 0xa4f8bf5635246429},
458 {0x940f4613ae5ed136, 0x871b7795e136be9a},
459 {0xb913179899f68584, 0x28e2557b59846e40},
460 {0xe757dd7ec07426e5, 0x331aeada2fe589d0},
461 {0x9096ea6f3848984f, 0x3ff0d2c85def7622},
462 {0xb4bca50b065abe63, 0x0fed077a756b53aa},
463 {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895},
464 {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d},
465 {0xb080392cc4349dec, 0xbd8d794d96aacfb4},
466 {0xdca04777f541c567, 0xecf0d7a0fc5583a1},
467 {0x89e42caaf9491b60, 0xf41686c49db57245},
468 {0xac5d37d5b79b6239, 0x311c2875c522ced6},
469 {0xd77485cb25823ac7, 0x7d633293366b828c},
470 {0x86a8d39ef77164bc, 0xae5dff9c02033198},
471 {0xa8530886b54dbdeb, 0xd9f57f830283fdfd},
472 {0xd267caa862a12d66, 0xd072df63c324fd7c},
473 {0x8380dea93da4bc60, 0x4247cb9e59f71e6e},
474 {0xa46116538d0deb78, 0x52d9be85f074e609},
475 {0xcd795be870516656, 0x67902e276c921f8c},
476 {0x806bd9714632dff6, 0x00ba1cd8a3db53b7},
477 {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5},
478 {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce},
479 {0xfad2a4b13d1b5d6c, 0x796b805720085f82},
480 {0x9cc3a6eec6311a63, 0xcbe3303674053bb1},
481 {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d},
482 {0xf4f1b4d515acb93b, 0xee92fb5515482d45},
483 {0x991711052d8bf3c5, 0x751bdd152d4d1c4b},
484 {0xbf5cd54678eef0b6, 0xd262d45a78a0635e},
485 {0xef340a98172aace4, 0x86fb897116c87c35},
486 {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1},
487 {0xbae0a846d2195712, 0x8974836059cca10a},
488 {0xe998d258869facd7, 0x2bd1a438703fc94c},
489 {0x91ff83775423cc06, 0x7b6306a34627ddd0},
490 {0xb67f6455292cbf08, 0x1a3bc84c17b1d543},
491 {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94},
492 {0x8e938662882af53e, 0x547eb47b7282ee9d},
493 {0xb23867fb2a35b28d, 0xe99e619a4f23aa44},
494 {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5},
495 {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05},
496 {0xae0b158b4738705e, 0x9624ab50b148d446},
497 {0xd98ddaee19068c76, 0x3badd624dd9b0958},
498 {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7},
499 {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d},
500 {0xd47487cc8470652b, 0x7647c32000696720},
501 {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074},
502 {0xa5fb0a17c777cf09, 0xf468107100525891},
503 {0xcf79cc9db955c2cc, 0x7182148d4066eeb5},
504 {0x81ac1fe293d599bf, 0xc6f14cd848405531},
505 {0xa21727db38cb002f, 0xb8ada00e5a506a7d},
506 {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d},
507 {0xfd442e4688bd304a, 0x908f4a166d1da664},
508 {0x9e4a9cec15763e2e, 0x9a598e4e043287ff},
509 {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe},
510 {0xf7549530e188c128, 0xd12bee59e68ef47d},
511 {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf},
512 {0xc13a148e3032d6e7, 0xe36a52363c1faf02},
513 {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2},
514 {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba},
515 {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8},
516 {0xebdf661791d60f56, 0x111b495b3464ad22},
517 {0x936b9fcebb25c995, 0xcab10dd900beec35},
518 {0xb84687c269ef3bfb, 0x3d5d514f40eea743},
519 {0xe65829b3046b0afa, 0x0cb4a5a3112a5113},
520 {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac},
521 {0xb3f4e093db73a093, 0x59ed216765690f57},
522 {0xe0f218b8d25088b8, 0x306869c13ec3532d},
523 {0x8c974f7383725573, 0x1e414218c73a13fc},
524 {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
525 {0xdbac6c247d62a583, 0xdf45f746b74abf3a},
526 {0x894bc396ce5da772, 0x6b8bba8c328eb784},
527 {0xab9eb47c81f5114f, 0x066ea92f3f326565},
528 {0xd686619ba27255a2, 0xc80a537b0efefebe},
529 {0x8613fd0145877585, 0xbd06742ce95f5f37},
530 {0xa798fc4196e952e7, 0x2c48113823b73705},
531 {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6},
532 {0x82ef85133de648c4, 0x9a984d73dbe722fc},
533 {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb},
534 {0xcc963fee10b7d1b3, 0x318df905079926a9},
535 {0xffbbcfe994e5c61f, 0xfdf17746497f7053},
536 {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634},
537 {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1},
538 {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1},
539 {0x9c1661a651213e2d, 0x06bea10ca65c084f},
540 {0xc31bfa0fe5698db8, 0x486e494fcff30a63},
541 {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb},
542 {0x986ddb5c6b3a76b7, 0xf89629465a75e01d},
543 {0xbe89523386091465, 0xf6bbb397f1135824},
544 {0xee2ba6c0678b597f, 0x746aa07ded582e2d},
545 {0x94db483840b717ef, 0xa8c2a44eb4571cdd},
546 {0xba121a4650e4ddeb, 0x92f34d62616ce414},
547 {0xe896a0d7e51e1566, 0x77b020baf9c81d18},
548 {0x915e2486ef32cd60, 0x0ace1474dc1d122f},
549 {0xb5b5ada8aaff80b8, 0x0d819992132456bb},
550 {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a},
551 {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},
552 {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3},
553 {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf},
554 {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c},
555 {0xad4ab7112eb3929d, 0x86c16c98d2c953c7},
556 {0xd89d64d57a607744, 0xe871c7bf077ba8b8},
557 {0x87625f056c7c4a8b, 0x11471cd764ad4973},
558 {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0},
559 {0xd389b47879823479, 0x4aff1d108d4ec2c4},
560 {0x843610cb4bf160cb, 0xcedf722a585139bb},
561 {0xa54394fe1eedb8fe, 0xc2974eb4ee658829},
562 {0xce947a3da6a9273e, 0x733d226229feea33},
563 {0x811ccc668829b887, 0x0806357d5a3f5260},
564 {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8},
565 {0xc9bcff6034c13052, 0xfc89b393dd02f0b6},
566 {0xfc2c3f3841f17c67, 0xbbac2078d443ace3},
567 {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e},
568 {0xc5029163f384a931, 0x0a9e795e65d4df12},
569 {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6},
570 {0x99ea0196163fa42e, 0x504bced1bf8e4e46},
571 {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7},
572 {0xf07da27a82c37088, 0x5d767327bb4e5a4d},
573 {0x964e858c91ba2655, 0x3a6a07f8d510f870},
574 {0xbbe226efb628afea, 0x890489f70a55368c},
575 {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f},
576 {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e},
577 {0xb77ada0617e3bbcb, 0x09ce6ebb40173745},
578 {0xe55990879ddcaabd, 0xcc420a6a101d0516},
579 {0x8f57fa54c2a9eab6, 0x9fa946824a12232e},
580 {0xb32df8e9f3546564, 0x47939822dc96abfa},
581 {0xdff9772470297ebd, 0x59787e2b93bc56f8},
582 {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b},
583 {0xaefae51477a06b03, 0xede622920b6b23f2},
584 {0xdab99e59958885c4, 0xe95fab368e45ecee},
585 {0x88b402f7fd75539b, 0x11dbcb0218ebb415},
586 {0xaae103b5fcd2a881, 0xd652bdc29f26a11a},
587 {0xd59944a37c0752a2, 0x4be76d3346f04960},
588 {0x857fcae62d8493a5, 0x6f70a4400c562ddc},
589 {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953},
590 {0xd097ad07a71f26b2, 0x7e2000a41346a7a8},
591 {0x825ecc24c873782f, 0x8ed400668c0c28c9},
592 {0xa2f67f2dfa90563b, 0x728900802f0f32fb},
593 {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba},
594 {0xfea126b7d78186bc, 0xe2f610c84987bfa9},
595 {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca},
596 {0xc6ede63fa05d3143, 0x91503d1c79720dbc},
597 {0xf8a95fcf88747d94, 0x75a44c6397ce912b},
598 {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb},
599 {0xc24452da229b021b, 0xfbe85badce996169},
600 {0xf2d56790ab41c2a2, 0xfae27299423fb9c4},
601 {0x97c560ba6b0919a5, 0xdccd879fc967d41b},
602 {0xbdb6b8e905cb600f, 0x5400e987bbc1c921},
603 {0xed246723473e3813, 0x290123e9aab23b69},
604 {0x9436c0760c86e30b, 0xf9a0b6720aaf6522},
605 {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},
606 {0xe7958cb87392c2c2, 0xb60b1d1230b20e05},
607 {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3},
608 {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4},
609 {0xe2280b6c20dd5232, 0x25c6da63c38de1b1},
610 {0x8d590723948a535f, 0x579c487e5a38ad0f},
611 {0xb0af48ec79ace837, 0x2d835a9df0c6d852},
612 {0xdcdb1b2798182244, 0xf8e431456cf88e66},
613 {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900},
614 {0xac8b2d36eed2dac5, 0xe272467e3d222f40},
615 {0xd7adf884aa879177, 0x5b0ed81dcc6abb10},
616 {0x86ccbb52ea94baea, 0x98e947129fc2b4ea},
617 {0xa87fea27a539e9a5, 0x3f2398d747b36225},
618 {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae},
619 {0x83a3eeeef9153e89, 0x1953cf68300424ad},
620 {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8},
621 {0xcdb02555653131b6, 0x3792f412cb06794e},
622 {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1},
623 {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5},
624 {0xc8de047564d20a8b, 0xf245825a5a445276},
625 {0xfb158592be068d2e, 0xeed6e2f0f0d56713},
626 {0x9ced737bb6c4183d, 0x55464dd69685606c},
627 {0xc428d05aa4751e4c, 0xaa97e14c3c26b887},
628 {0xf53304714d9265df, 0xd53dd99f4b3066a9},
629 {0x993fe2c6d07b7fab, 0xe546a8038efe402a},
630 {0xbf8fdb78849a5f96, 0xde98520472bdd034},
631 {0xef73d256a5c0f77c, 0x963e66858f6d4441},
632 {0x95a8637627989aad, 0xdde7001379a44aa9},
633 {0xbb127c53b17ec159, 0x5560c018580d5d53},
634 {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7},
635 {0x9226712162ab070d, 0xcab3961304ca70e9},
636 {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23},
637 {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b},
638 {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243},
639 {0xb267ed1940f1c61c, 0x55f038b237591ed4},
640 {0xdf01e85f912e37a3, 0x6b6c46dec52f6689},
641 {0x8b61313bbabce2c6, 0x2323ac4b3b3da016},
642 {0xae397d8aa96c1b77, 0xabec975e0a0d081b},
643 {0xd9c7dced53c72255, 0x96e7bd358c904a22},
644 {0x881cea14545c7575, 0x7e50d64177da2e55},
645 {0xaa242499697392d2, 0xdde50bd1d5d0b9ea},
646 {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865},
647 {0x84ec3c97da624ab4, 0xbd5af13bef0b113f},
648 {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f},
649 {0xcfb11ead453994ba, 0x67de18eda5814af3},
650 {0x81ceb32c4b43fcf4, 0x80eacf948770ced8},
651 {0xa2425ff75e14fc31, 0xa1258379a94d028e},
652 {0xcad2f7f5359a3b3e, 0x096ee45813a04331},
653 {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd},
654 {0x9e74d1b791e07e48, 0x775ea264cf55347e},
655 {0xc612062576589dda, 0x95364afe032a819e},
656 {0xf79687aed3eec551, 0x3a83ddbd83f52205},
657 {0x9abe14cd44753b52, 0xc4926a9672793543},
658 {0xc16d9a0095928a27, 0x75b7053c0f178294},
659 {0xf1c90080baf72cb1, 0x5324c68b12dd6339},
660 {0x971da05074da7bee, 0xd3f6fc16ebca5e04},
661 {0xbce5086492111aea, 0x88f4bb1ca6bcf585},
662 {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6},
663 {0x9392ee8e921d5d07, 0x3aff322e62439fd0},
664 {0xb877aa3236a4b449, 0x09befeb9fad487c3},
665 {0xe69594bec44de15b, 0x4c2ebe687989a9b4},
666 {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11},
667 {0xb424dc35095cd80f, 0x538484c19ef38c95},
668 {0xe12e13424bb40e13, 0x2865a5f206b06fba},
669 {0x8cbccc096f5088cb, 0xf93f87b7442e45d4},
670 {0xafebff0bcb24aafe, 0xf78f69a51539d749},
671 {0xdbe6fecebdedd5be, 0xb573440e5a884d1c},
672 {0x89705f4136b4a597, 0x31680a88f8953031},
673 {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e},
674 {0xd6bf94d5e57a42bc, 0x3d32907604691b4d},
675 {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110},
676 {0xa7c5ac471b478423, 0x0fcf80dc33721d54},
677 {0xd1b71758e219652b, 0xd3c36113404ea4a9},
678 {0x83126e978d4fdf3b, 0x645a1cac083126ea},
679 {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4},
680 {0xcccccccccccccccc, 0xcccccccccccccccd},
681 {0x8000000000000000, 0x0000000000000000},
682 {0xa000000000000000, 0x0000000000000000},
683 {0xc800000000000000, 0x0000000000000000},
684 {0xfa00000000000000, 0x0000000000000000},
685 {0x9c40000000000000, 0x0000000000000000},
686 {0xc350000000000000, 0x0000000000000000},
687 {0xf424000000000000, 0x0000000000000000},
688 {0x9896800000000000, 0x0000000000000000},
689 {0xbebc200000000000, 0x0000000000000000},
690 {0xee6b280000000000, 0x0000000000000000},
691 {0x9502f90000000000, 0x0000000000000000},
692 {0xba43b74000000000, 0x0000000000000000},
693 {0xe8d4a51000000000, 0x0000000000000000},
694 {0x9184e72a00000000, 0x0000000000000000},
695 {0xb5e620f480000000, 0x0000000000000000},
696 {0xe35fa931a0000000, 0x0000000000000000},
697 {0x8e1bc9bf04000000, 0x0000000000000000},
698 {0xb1a2bc2ec5000000, 0x0000000000000000},
699 {0xde0b6b3a76400000, 0x0000000000000000},
700 {0x8ac7230489e80000, 0x0000000000000000},
701 {0xad78ebc5ac620000, 0x0000000000000000},
702 {0xd8d726b7177a8000, 0x0000000000000000},
703 {0x878678326eac9000, 0x0000000000000000},
704 {0xa968163f0a57b400, 0x0000000000000000},
705 {0xd3c21bcecceda100, 0x0000000000000000},
706 {0x84595161401484a0, 0x0000000000000000},
707 {0xa56fa5b99019a5c8, 0x0000000000000000},
708 {0xcecb8f27f4200f3a, 0x0000000000000000},
709 {0x813f3978f8940984, 0x4000000000000000},
710 {0xa18f07d736b90be5, 0x5000000000000000},
711 {0xc9f2c9cd04674ede, 0xa400000000000000},
712 {0xfc6f7c4045812296, 0x4d00000000000000},
713 {0x9dc5ada82b70b59d, 0xf020000000000000},
714 {0xc5371912364ce305, 0x6c28000000000000},
715 {0xf684df56c3e01bc6, 0xc732000000000000},
716 {0x9a130b963a6c115c, 0x3c7f400000000000},
717 {0xc097ce7bc90715b3, 0x4b9f100000000000},
718 {0xf0bdc21abb48db20, 0x1e86d40000000000},
719 {0x96769950b50d88f4, 0x1314448000000000},
720 {0xbc143fa4e250eb31, 0x17d955a000000000},
721 {0xeb194f8e1ae525fd, 0x5dcfab0800000000},
722 {0x92efd1b8d0cf37be, 0x5aa1cae500000000},
723 {0xb7abc627050305ad, 0xf14a3d9e40000000},
724 {0xe596b7b0c643c719, 0x6d9ccd05d0000000},
725 {0x8f7e32ce7bea5c6f, 0xe4820023a2000000},
726 {0xb35dbf821ae4f38b, 0xdda2802c8a800000},
727 {0xe0352f62a19e306e, 0xd50b2037ad200000},
728 {0x8c213d9da502de45, 0x4526f422cc340000},
729 {0xaf298d050e4395d6, 0x9670b12b7f410000},
730 {0xdaf3f04651d47b4c, 0x3c0cdd765f114000},
731 {0x88d8762bf324cd0f, 0xa5880a69fb6ac800},
732 {0xab0e93b6efee0053, 0x8eea0d047a457a00},
733 {0xd5d238a4abe98068, 0x72a4904598d6d880},
734 {0x85a36366eb71f041, 0x47a6da2b7f864750},
735 {0xa70c3c40a64e6c51, 0x999090b65f67d924},
736 {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d},
737 {0x82818f1281ed449f, 0xbff8f10e7a8921a4},
738 {0xa321f2d7226895c7, 0xaff72d52192b6a0d},
739 {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490},
740 {0xfee50b7025c36a08, 0x02f236d04753d5b4},
741 {0x9f4f2726179a2245, 0x01d762422c946590},
742 {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5},
743 {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2},
744 {0x9b934c3b330c8577, 0x63cc55f49f88eb2f},
745 {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb},
746 {0xf316271c7fc3908a, 0x8bef464e3945ef7a},
747 {0x97edd871cfda3a56, 0x97758bf0e3cbb5ac},
748 {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317},
749 {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd},
750 {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a},
751 {0xb975d6b6ee39e436, 0xb3e2fd538e122b44},
752 {0xe7d34c64a9c85d44, 0x60dbbca87196b616},
753 {0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd},
754 {0xb51d13aea4a488dd, 0x6babab6398bdbe41},
755 {0xe264589a4dcdab14, 0xc696963c7eed2dd1},
756 {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2},
757 {0xb0de65388cc8ada8, 0x3b25a55f43294bcb},
758 {0xdd15fe86affad912, 0x49ef0eb713f39ebe},
759 {0x8a2dbf142dfcc7ab, 0x6e3569326c784337},
760 {0xacb92ed9397bf996, 0x49c2c37f07965404},
761 {0xd7e77a8f87daf7fb, 0xdc33745ec97be906},
762 {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3},
763 {0xa8acd7c0222311bc, 0xc40832ea0d68ce0c},
764 {0xd2d80db02aabd62b, 0xf50a3fa490c30190},
765 {0x83c7088e1aab65db, 0x792667c6da79e0fa},
766 {0xa4b8cab1a1563f52, 0x577001b891185938},
767 {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86},
768 {0x80b05e5ac60b6178, 0x544f8158315b05b4},
769 {0xa0dc75f1778e39d6, 0x696361ae3db1c721},
770 {0xc913936dd571c84c, 0x03bc3a19cd1e38e9},
771 {0xfb5878494ace3a5f, 0x04ab48a04065c723},
772 {0x9d174b2dcec0e47b, 0x62eb0d64283f9c76},
773 {0xc45d1df942711d9a, 0x3ba5d0bd324f8394},
774 {0xf5746577930d6500, 0xca8f44ec7ee36479},
775 {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb},
776 {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e},
777 {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e},
778 {0x95d04aee3b80ece5, 0xbba1f1d158724a12},
779 {0xbb445da9ca61281f, 0x2a8a6e45ae8edc97},
780 {0xea1575143cf97226, 0xf52d09d71a3293bd},
781 {0x924d692ca61be758, 0x593c2626705f9c56},
782 {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c},
783 {0xe498f455c38b997a, 0x0b6dfb9c0f956447},
784 {0x8edf98b59a373fec, 0x4724bd4189bd5eac},
785 {0xb2977ee300c50fe7, 0x58edec91ec2cb657},
786 {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed},
787 {0x8b865b215899f46c, 0xbd79e0d20082ee74},
788 {0xae67f1e9aec07187, 0xecd8590680a3aa11},
789 {0xda01ee641a708de9, 0xe80e6f4820cc9495},
790 {0x884134fe908658b2, 0x3109058d147fdcdd},
791 {0xaa51823e34a7eede, 0xbd4b46f0599fd415},
792 {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a},
793 {0x850fadc09923329e, 0x03e2cf6bc604ddb0},
794 {0xa6539930bf6bff45, 0x84db8346b786151c},
795 {0xcfe87f7cef46ff16, 0xe612641865679a63},
796 {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e},
797 {0xa26da3999aef7749, 0xe3be5e330f38f09d},
798 {0xcb090c8001ab551c, 0x5cadf5bfd3072cc5},
799 {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6},
800 {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa},
801 {0xc646d63501a1511d, 0xb281e1fd541501b8},
802 {0xf7d88bc24209a565, 0x1f225a7ca91a4226},
803 {0x9ae757596946075f, 0x3375788de9b06958},
804 {0xc1a12d2fc3978937, 0x0052d6b1641c83ae},
805 {0xf209787bb47d6b84, 0xc0678c5dbd23a49a},
806 {0x9745eb4d50ce6332, 0xf840b7ba963646e0},
807 {0xbd176620a501fbff, 0xb650e5a93bc3d898},
808 {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe},
809 {0x93ba47c980e98cdf, 0xc66f336c36b10137},
810 {0xb8a8d9bbe123f017, 0xb80b0047445d4184},
811 {0xe6d3102ad96cec1d, 0xa60dc059157491e5},
812 {0x9043ea1ac7e41392, 0x87c89837ad68db2f},
813 {0xb454e4a179dd1877, 0x29babe4598c311fb},
814 {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a},
815 {0x8ce2529e2734bb1d, 0x1899e4a65f58660c},
816 {0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f},
817 {0xdc21a1171d42645d, 0x76707543f4fa1f73},
818 {0x899504ae72497eba, 0x6a06494a791c53a8},
819 {0xabfa45da0edbde69, 0x0487db9d17636892},
820 {0xd6f8d7509292d603, 0x45a9d2845d3c42b6},
821 {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2},
822 {0xa7f26836f282b732, 0x8e6cac7768d7141e},
823 {0xd1ef0244af2364ff, 0x3207d795430cd926},
824 {0x8335616aed761f1f, 0x7f44e6bd49e807b8},
825 {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6},
826 {0xcd036837130890a1, 0x36dba887c37a8c0f},
827 {0x802221226be55a64, 0xc2494954da2c9789},
828 {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c},
829 {0xc83553c5c8965d3d, 0x6f92829494e5acc7},
830 {0xfa42a8b73abbf48c, 0xcb772339ba1f17f9},
831 {0x9c69a97284b578d7, 0xff2a760414536efb},
832 {0xc38413cf25e2d70d, 0xfef5138519684aba},
833 {0xf46518c2ef5b8cd1, 0x7eb258665fc25d69},
834 {0x98bf2f79d5993802, 0xef2f773ffbd97a61},
835 {0xbeeefb584aff8603, 0xaafb550ffacfd8fa},
836 {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38},
837 {0x952ab45cfa97a0b2, 0xdd945a747bf26183},
838 {0xba756174393d88df, 0x94f971119aeef9e4},
839 {0xe912b9d1478ceb17, 0x7a37cd5601aab85d},
840 {0x91abb422ccb812ee, 0xac62e055c10ab33a},
841 {0xb616a12b7fe617aa, 0x577b986b314d6009},
842 {0xe39c49765fdf9d94, 0xed5a7e85fda0b80b},
843 {0x8e41ade9fbebc27d, 0x14588f13be847307},
844 {0xb1d219647ae6b31c, 0x596eb2d8ae258fc8},
845 {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb},
846 {0x8aec23d680043bee, 0x25de7bb9480d5854},
847 {0xada72ccc20054ae9, 0xaf561aa79a10ae6a},
848 {0xd910f7ff28069da4, 0x1b2ba1518094da04},
849 {0x87aa9aff79042286, 0x90fb44d2f05d0842},
850 {0xa99541bf57452b28, 0x353a1607ac744a53},
851 {0xd3fa922f2d1675f2, 0x42889b8997915ce8},
852 {0x847c9b5d7c2e09b7, 0x69956135febada11},
853 {0xa59bc234db398c25, 0x43fab9837e699095},
854 {0xcf02b2c21207ef2e, 0x94f967e45e03f4bb},
855 {0x8161afb94b44f57d, 0x1d1be0eebac278f5},
856 {0xa1ba1ba79e1632dc, 0x6462d92a69731732},
857 {0xca28a291859bbf93, 0x7d7b8f7503cfdcfe},
858 {0xfcb2cb35e702af78, 0x5cda735244c3d43e},
859 {0x9defbf01b061adab, 0x3a0888136afa64a7},
860 {0xc56baec21c7a1916, 0x088aaa1845b8fdd0},
861 {0xf6c69a72a3989f5b, 0x8aad549e57273d45},
862 {0x9a3c2087a63f6399, 0x36ac54e2f678864b},
863 {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd},
864 {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5},
865 {0x969eb7c47859e743, 0x9f644ae5a4b1b325},
866 {0xbc4665b596706114, 0x873d5d9f0dde1fee},
867 {0xeb57ff22fc0c7959, 0xa90cb506d155a7ea},
868 {0x9316ff75dd87cbd8, 0x09a7f12442d588f2},
869 {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb2f},
870 {0xe5d3ef282a242e81, 0x8f1668c8a86da5fa},
871 {0x8fa475791a569d10, 0xf96e017d694487bc},
872 {0xb38d92d760ec4455, 0x37c981dcc395a9ac},
873 {0xe070f78d3927556a, 0x85bbe253f47b1417},
874 {0x8c469ab843b89562, 0x93956d7478ccec8e},
875 {0xaf58416654a6babb, 0x387ac8d1970027b2},
876 {0xdb2e51bfe9d0696a, 0x06997b05fcc0319e},
877 {0x88fcf317f22241e2, 0x441fece3bdf81f03},
878 {0xab3c2fddeeaad25a, 0xd527e81cad7626c3},
879 {0xd60b3bd56a5586f1, 0x8a71e223d8d3b074},
880 {0x85c7056562757456, 0xf6872d5667844e49},
881 {0xa738c6bebb12d16c, 0xb428f8ac016561db},
882 {0xd106f86e69d785c7, 0xe13336d701beba52},
883 {0x82a45b450226b39c, 0xecc0024661173473},
884 {0xa34d721642b06084, 0x27f002d7f95d0190},
885 {0xcc20ce9bd35c78a5, 0x31ec038df7b441f4},
886 {0xff290242c83396ce, 0x7e67047175a15271},
887 {0x9f79a169bd203e41, 0x0f0062c6e984d386},
888 {0xc75809c42c684dd1, 0x52c07b78a3e60868},
889 {0xf92e0c3537826145, 0xa7709a56ccdf8a82},
890 {0x9bbcc7a142b17ccb, 0x88a66076400bb691},
891 {0xc2abf989935ddbfe, 0x6acff893d00ea435},
892 {0xf356f7ebf83552fe, 0x0583f6b8c4124d43},
893 {0x98165af37b2153de, 0xc3727a337a8b704a},
894 {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c},
895 {0xeda2ee1c7064130c, 0x1162def06f79df73},
896 {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8},
897 {0xb9a74a0637ce2ee1, 0x6d953e2bd7173692},
898 {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437},
899 {0x910ab1d4db9914a0, 0x1d9c9892400a22a2},
900 {0xb54d5e4a127f59c8, 0x2503beb6d00cab4b},
901 {0xe2a0b5dc971f303a, 0x2e44ae64840fd61d},
902 {0x8da471a9de737e24, 0x5ceaecfed289e5d2},
903 {0xb10d8e1456105dad, 0x7425a83e872c5f47},
904 {0xdd50f1996b947518, 0xd12f124e28f77719},
905 {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f},
906 {0xace73cbfdc0bfb7b, 0x636cc64d1001550b},
907 {0xd8210befd30efa5a, 0x3c47f7e05401aa4e},
908 {0x8714a775e3e95c78, 0x65acfaec34810a71},
909 {0xa8d9d1535ce3b396, 0x7f1839a741a14d0d},
910 {0xd31045a8341ca07c, 0x1ede48111209a050},
911 {0x83ea2b892091e44d, 0x934aed0aab460432},
912 {0xa4e4b66b68b65d60, 0xf81da84d5617853f},
913 {0xce1de40642e3f4b9, 0x36251260ab9d668e},
914 {0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019},
915 {0xa1075a24e4421730, 0xb24cf65b8612f81f},
916 {0xc94930ae1d529cfc, 0xdee033f26797b627},
917 {0xfb9b7cd9a4a7443c, 0x169840ef017da3b1},
918 {0x9d412e0806e88aa5, 0x8e1f289560ee864e},
919 {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2},
920 {0xf5b5d7ec8acb58a2, 0xae10af696774b1db},
921 {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29},
922 {0xbff610b0cc6edd3f, 0x17fd090a58d32af3},
923 {0xeff394dcff8a948e, 0xddfc4b4cef07f5b0},
924 {0x95f83d0a1fb69cd9, 0x4abdaf101564f98e},
925 {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1},
926 {0xea53df5fd18d5513, 0x84c86189216dc5ed},
927 {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4},
928 {0xb7118682dbb66a77, 0x3fbc8c33221dc2a1},
929 {0xe4d5e82392a40515, 0x0fabaf3feaa5334a},
930 {0x8f05b1163ba6832d, 0x29cb4d87f2a7400e},
931 {0xb2c71d5bca9023f8, 0x743e20e9ef511012},
932 {0xdf78e4b2bd342cf6, 0x914da9246b255416},
933 {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e},
934 {0xae9672aba3d0c320, 0xa184ac2473b529b1},
935 {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e},
936 {0x8865899617fb1871, 0x7e2fa67c7a658892},
937 {0xaa7eebfb9df9de8d, 0xddbb901b98feeab7},
938 {0xd51ea6fa85785631, 0x552a74227f3ea565},
939 {0x8533285c936b35de, 0xd53a88958f87275f},
940 {0xa67ff273b8460356, 0x8a892abaf368f137},
941 {0xd01fef10a657842c, 0x2d2b7569b0432d85},
942 {0x8213f56a67f6b29b, 0x9c3b29620e29fc73},
943 {0xa298f2c501f45f42, 0x8349f3ba91b47b8f},
944 {0xcb3f2f7642717713, 0x241c70a936219a73},
945 {0xfe0efb53d30dd4d7, 0xed238cd383aa0110},
946 {0x9ec95d1463e8a506, 0xf4363804324a40aa},
947 {0xc67bb4597ce2ce48, 0xb143c6053edcd0d5},
948 {0xf81aa16fdc1b81da, 0xdd94b7868e94050a},
949 {0x9b10a4e5e9913128, 0xca7cf2b4191c8326},
950 {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0},
951 {0xf24a01a73cf2dccf, 0xbc633b39673c8cec},
952 {0x976e41088617ca01, 0xd5be0503e085d813},
953 {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18},
954 {0xec9c459d51852ba2, 0xddf8e7d60ed1219e},
955 {0x93e1ab8252f33b45, 0xcabb90e5c942b503},
956 {0xb8da1662e7b00a17, 0x3d6a751f3b936243},
957 {0xe7109bfba19c0c9d, 0x0cc512670a783ad4},
958 {0x906a617d450187e2, 0x27fb2b80668b24c5},
959 {0xb484f9dc9641e9da, 0xb1f9f660802dedf6},
960 {0xe1a63853bbd26451, 0x5e7873f8a0396973},
961 {0x8d07e33455637eb2, 0xdb0b487b6423e1e8},
962 {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62},
963 {0xdc5c5301c56b75f7, 0x7641a140cc7810fb},
964 {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d},
965 {0xac2820d9623bf429, 0x546345fa9fbdcd44},
966 {0xd732290fbacaf133, 0xa97c177947ad4095},
967 {0x867f59a9d4bed6c0, 0x49ed8eabcccc485d},
968 {0xa81f301449ee8c70, 0x5c68f256bfff5a74},
969 {0xd226fc195c6a2f8c, 0x73832eec6fff3111},
970 {0x83585d8fd9c25db7, 0xc831fd53c5ff7eab},
971 {0xa42e74f3d032f525, 0xba3e7ca8b77f5e55},
972 {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb},
973 {0x80444b5e7aa7cf85, 0x7980d163cf5b81b3},
974 {0xa0555e361951c366, 0xd7e105bcc332621f},
975 {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7},
976 {0xfa856334878fc150, 0xb14f98f6f0feb951},
977 {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3},
978 {0xc3b8358109e84f07, 0x0a862f80ec4700c8},
979 {0xf4a642e14c6262c8, 0xcd27bb612758c0fa},
980 {0x98e7e9cccfbd7dbd, 0x8038d51cb897789c},
981 {0xbf21e44003acdd2c, 0xe0470a63e6bd56c3},
982 {0xeeea5d5004981478, 0x1858ccfce06cac74},
983 {0x95527a5202df0ccb, 0x0f37801e0c43ebc8},
984 {0xbaa718e68396cffd, 0xd30560258f54e6ba},
985 {0xe950df20247c83fd, 0x47c6b82ef32a2069},
986 {0x91d28b7416cdd27e, 0x4cdc331d57fa5441},
987 {0xb6472e511c81471d, 0xe0133fe4adf8e952},
988 {0xe3d8f9e563a198e5, 0x58180fddd97723a6},
989 {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648},
990 {0xb201833b35d63f73, 0x2cd2cc6551e513da},
991 {0xde81e40a034bcf4f, 0xf8077f7ea65e58d1},
992 {0x8b112e86420f6191, 0xfb04afaf27faf782},
993 {0xadd57a27d29339f6, 0x79c5db9af1f9b563},
994 {0xd94ad8b1c7380874, 0x18375281ae7822bc},
995 {0x87cec76f1c830548, 0x8f2293910d0b15b5},
996 {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb22},
997 {0xd433179d9c8cb841, 0x5fa60692a46151eb},
998 {0x849feec281d7f328, 0xdbc7c41ba6bcd333},
999 {0xa5c7ea73224deff3, 0x12b9b522906c0800},
1000 {0xcf39e50feae16bef, 0xd768226b34870a00},
1001 {0x81842f29f2cce375, 0xe6a1158300d46640},
1002 {0xa1e53af46f801c53, 0x60495ae3c1097fd0},
1003 {0xca5e89b18b602368, 0x385bb19cb14bdfc4},
1004 {0xfcf62c1dee382c42, 0x46729e03dd9ed7b5},
1005 {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d1},
1006 {0xc5a05277621be293, 0xc7098b7305241885},
1007 {0xf70867153aa2db38, 0xb8cbee4fc66d1ea7}
1008 #else
1009 {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
1010 {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
1011 {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},
1012 {0x86a8d39ef77164bc, 0xae5dff9c02033198},
1013 {0xd98ddaee19068c76, 0x3badd624dd9b0958},
1014 {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
1015 {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},
1016 {0xe55990879ddcaabd, 0xcc420a6a101d0516},
1017 {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},
1018 {0x95a8637627989aad, 0xdde7001379a44aa9},
1019 {0xf1c90080baf72cb1, 0x5324c68b12dd6339},
1020 {0xc350000000000000, 0x0000000000000000},
1021 {0x9dc5ada82b70b59d, 0xf020000000000000},
1022 {0xfee50b7025c36a08, 0x02f236d04753d5b4},
1023 {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86},
1024 {0xa6539930bf6bff45, 0x84db8346b786151c},
1025 {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2},
1026 {0xd910f7ff28069da4, 0x1b2ba1518094da04},
1027 {0xaf58416654a6babb, 0x387ac8d1970027b2},
1028 {0x8da471a9de737e24, 0x5ceaecfed289e5d2},
1029 {0xe4d5e82392a40515, 0x0fabaf3feaa5334a},
1030 {0xb8da1662e7b00a17, 0x3d6a751f3b936243},
1031 {0x95527a5202df0ccb, 0x0f37801e0c43ebc8}
1032 #endif
1033 };
1034
1035 #if !FMT_USE_FULL_CACHE_DRAGONBOX
1036 template <typename T>
1037 const uint64_t basic_data<T>::powers_of_5_64[] = {
1038 0x0000000000000001, 0x0000000000000005, 0x0000000000000019,
1039 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35,
1040 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1,
1041 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd,
1042 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9,
1043 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5,
1044 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631,
1045 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed,
1046 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9};
1047
1048 template <typename T>
1049 const uint32_t basic_data<T>::dragonbox_pow10_recovery_errors[] = {
1050 0x50001400, 0x54044100, 0x54014555, 0x55954415, 0x54115555, 0x00000001,
1051 0x50000000, 0x00104000, 0x54010004, 0x05004001, 0x55555544, 0x41545555,
1052 0x54040551, 0x15445545, 0x51555514, 0x10000015, 0x00101100, 0x01100015,
1053 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04450514, 0x45414110,
1054 0x55555145, 0x50544050, 0x15040155, 0x11054140, 0x50111514, 0x11451454,
1055 0x00400541, 0x00000000, 0x55555450, 0x10056551, 0x10054011, 0x55551014,
1056 0x69514555, 0x05151109, 0x00155555};
1057 #endif
1058
1059 template <typename T>
1060 const char basic_data<T>::foreground_color[] = "\x1b[38;2;";
1061 template <typename T>
1062 const char basic_data<T>::background_color[] = "\x1b[48;2;";
1063 template <typename T> const char basic_data<T>::reset_color[] = "\x1b[0m";
1064 template <typename T> const wchar_t basic_data<T>::wreset_color[] = L"\x1b[0m";
1065 template <typename T> const char basic_data<T>::signs[] = {0, '-', '+', ' '};
1066
1067 #if __cplusplus < 201703L
1068 template <typename T> constexpr const char basic_data<T>::hex_digits[];
1069 template <typename T> constexpr const unsigned basic_data<T>::prefixes[];
1070 template <typename T> constexpr const char basic_data<T>::left_padding_shifts[];
1071 template <typename T>
1072 constexpr const char basic_data<T>::right_padding_shifts[];
1073 #endif
1074
1075 template <typename T> struct bits {
1076 static FMT_CONSTEXPR_DECL const int value =
1077 static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits);
1078 };
1079
1080 class fp;
1081 template <int SHIFT = 0> fp normalize(fp value);
1082
1083 // Lower (upper) boundary is a value half way between a floating-point value
1084 // and its predecessor (successor). Boundaries have the same exponent as the
1085 // value so only significands are stored.
1086 struct boundaries {
1087 uint64_t lower;
1088 uint64_t upper;
1089 };
1090
1091 // A handmade floating-point number f * pow(2, e).
1092 class fp {
1093 private:
1094 using significand_type = uint64_t;
1095
1096 template <typename Float>
1097 using is_supported_float = bool_constant<sizeof(Float) == sizeof(uint64_t) ||
1098 sizeof(Float) == sizeof(uint32_t)>;
1099
1100 public:
1101 significand_type f;
1102 int e;
1103
1104 // All sizes are in bits.
1105 // Subtract 1 to account for an implicit most significant bit in the
1106 // normalized form.
1107 static FMT_CONSTEXPR_DECL const int double_significand_size =
1108 std::numeric_limits<double>::digits - 1;
1109 static FMT_CONSTEXPR_DECL const uint64_t implicit_bit =
1110 1ULL << double_significand_size;
1111 static FMT_CONSTEXPR_DECL const int significand_size =
1112 bits<significand_type>::value;
1113
fp()1114 fp() : f(0), e(0) {}
fp(uint64_t f_val,int e_val)1115 fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
1116
1117 // Constructs fp from an IEEE754 double. It is a template to prevent compile
1118 // errors on platforms where double is not IEEE754.
fp(Double d)1119 template <typename Double> explicit fp(Double d) { assign(d); }
1120
1121 // Assigns d to this and return true iff predecessor is closer than successor.
1122 template <typename Float, FMT_ENABLE_IF(is_supported_float<Float>::value)>
assign(Float d)1123 bool assign(Float d) {
1124 // Assume float is in the format [sign][exponent][significand].
1125 using limits = std::numeric_limits<Float>;
1126 const int float_significand_size = limits::digits - 1;
1127 const int exponent_size =
1128 bits<Float>::value - float_significand_size - 1; // -1 for sign
1129 const uint64_t float_implicit_bit = 1ULL << float_significand_size;
1130 const uint64_t significand_mask = float_implicit_bit - 1;
1131 const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask;
1132 const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1;
1133 constexpr bool is_double = sizeof(Float) == sizeof(uint64_t);
1134 auto u = bit_cast<conditional_t<is_double, uint64_t, uint32_t>>(d);
1135 f = u & significand_mask;
1136 int biased_e =
1137 static_cast<int>((u & exponent_mask) >> float_significand_size);
1138 // Predecessor is closer if d is a normalized power of 2 (f == 0) other than
1139 // the smallest normalized number (biased_e > 1).
1140 bool is_predecessor_closer = f == 0 && biased_e > 1;
1141 if (biased_e != 0)
1142 f += float_implicit_bit;
1143 else
1144 biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
1145 e = biased_e - exponent_bias - float_significand_size;
1146 return is_predecessor_closer;
1147 }
1148
1149 template <typename Float, FMT_ENABLE_IF(!is_supported_float<Float>::value)>
assign(Float)1150 bool assign(Float) {
1151 *this = fp();
1152 return false;
1153 }
1154 };
1155
1156 // Normalizes the value converted from double and multiplied by (1 << SHIFT).
normalize(fp value)1157 template <int SHIFT> fp normalize(fp value) {
1158 // Handle subnormals.
1159 const auto shifted_implicit_bit = fp::implicit_bit << SHIFT;
1160 while ((value.f & shifted_implicit_bit) == 0) {
1161 value.f <<= 1;
1162 --value.e;
1163 }
1164 // Subtract 1 to account for hidden bit.
1165 const auto offset =
1166 fp::significand_size - fp::double_significand_size - SHIFT - 1;
1167 value.f <<= offset;
1168 value.e -= offset;
1169 return value;
1170 }
1171
1172 inline bool operator==(fp x, fp y) { return x.f == y.f && x.e == y.e; }
1173
1174 // Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
multiply(uint64_t lhs,uint64_t rhs)1175 inline uint64_t multiply(uint64_t lhs, uint64_t rhs) {
1176 #if FMT_USE_INT128
1177 auto product = static_cast<__uint128_t>(lhs) * rhs;
1178 auto f = static_cast<uint64_t>(product >> 64);
1179 return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1180 #else
1181 // Multiply 32-bit parts of significands.
1182 uint64_t mask = (1ULL << 32) - 1;
1183 uint64_t a = lhs >> 32, b = lhs & mask;
1184 uint64_t c = rhs >> 32, d = rhs & mask;
1185 uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
1186 // Compute mid 64-bit of result and round.
1187 uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1188 return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1189 #endif
1190 }
1191
1192 inline fp operator*(fp x, fp y) { return {multiply(x.f, y.f), x.e + y.e + 64}; }
1193
1194 // Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
1195 // (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
get_cached_power(int min_exponent,int & pow10_exponent)1196 inline fp get_cached_power(int min_exponent, int& pow10_exponent) {
1197 const int shift = 32;
1198 const auto significand = static_cast<int64_t>(data::log10_2_significand);
1199 int index = static_cast<int>(
1200 ((min_exponent + fp::significand_size - 1) * (significand >> shift) +
1201 ((int64_t(1) << shift) - 1)) // ceil
1202 >> 32 // arithmetic shift
1203 );
1204 // Decimal exponent of the first (smallest) cached power of 10.
1205 const int first_dec_exp = -348;
1206 // Difference between 2 consecutive decimal exponents in cached powers of 10.
1207 const int dec_exp_step = 8;
1208 index = (index - first_dec_exp - 1) / dec_exp_step + 1;
1209 pow10_exponent = first_dec_exp + index * dec_exp_step;
1210 return {data::grisu_pow10_significands[index],
1211 data::grisu_pow10_exponents[index]};
1212 }
1213
1214 // A simple accumulator to hold the sums of terms in bigint::square if uint128_t
1215 // is not available.
1216 struct accumulator {
1217 uint64_t lower;
1218 uint64_t upper;
1219
accumulatoraccumulator1220 accumulator() : lower(0), upper(0) {}
uint32_taccumulator1221 explicit operator uint32_t() const { return static_cast<uint32_t>(lower); }
1222
1223 void operator+=(uint64_t n) {
1224 lower += n;
1225 if (lower < n) ++upper;
1226 }
1227 void operator>>=(int shift) {
1228 FMT_ASSERT(shift == 32, "");
1229 (void)shift;
1230 lower = (upper << 32) | (lower >> 32);
1231 upper >>= 32;
1232 }
1233 };
1234
1235 class bigint {
1236 private:
1237 // A bigint is stored as an array of bigits (big digits), with bigit at index
1238 // 0 being the least significant one.
1239 using bigit = uint32_t;
1240 using double_bigit = uint64_t;
1241 enum { bigits_capacity = 32 };
1242 basic_memory_buffer<bigit, bigits_capacity> bigits_;
1243 int exp_;
1244
1245 bigit operator[](int index) const { return bigits_[to_unsigned(index)]; }
1246 bigit& operator[](int index) { return bigits_[to_unsigned(index)]; }
1247
1248 static FMT_CONSTEXPR_DECL const int bigit_bits = bits<bigit>::value;
1249
1250 friend struct formatter<bigint>;
1251
1252 void subtract_bigits(int index, bigit other, bigit& borrow) {
1253 auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
1254 (*this)[index] = static_cast<bigit>(result);
1255 borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
1256 }
1257
1258 void remove_leading_zeros() {
1259 int num_bigits = static_cast<int>(bigits_.size()) - 1;
1260 while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
1261 bigits_.resize(to_unsigned(num_bigits + 1));
1262 }
1263
1264 // Computes *this -= other assuming aligned bigints and *this >= other.
1265 void subtract_aligned(const bigint& other) {
1266 FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
1267 FMT_ASSERT(compare(*this, other) >= 0, "");
1268 bigit borrow = 0;
1269 int i = other.exp_ - exp_;
1270 for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
1271 subtract_bigits(i, other.bigits_[j], borrow);
1272 while (borrow > 0) subtract_bigits(i, 0, borrow);
1273 remove_leading_zeros();
1274 }
1275
1276 void multiply(uint32_t value) {
1277 const double_bigit wide_value = value;
1278 bigit carry = 0;
1279 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
1280 double_bigit result = bigits_[i] * wide_value + carry;
1281 bigits_[i] = static_cast<bigit>(result);
1282 carry = static_cast<bigit>(result >> bigit_bits);
1283 }
1284 if (carry != 0) bigits_.push_back(carry);
1285 }
1286
1287 void multiply(uint64_t value) {
1288 const bigit mask = ~bigit(0);
1289 const double_bigit lower = value & mask;
1290 const double_bigit upper = value >> bigit_bits;
1291 double_bigit carry = 0;
1292 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
1293 double_bigit result = bigits_[i] * lower + (carry & mask);
1294 carry =
1295 bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits);
1296 bigits_[i] = static_cast<bigit>(result);
1297 }
1298 while (carry != 0) {
1299 bigits_.push_back(carry & mask);
1300 carry >>= bigit_bits;
1301 }
1302 }
1303
1304 public:
1305 bigint() : exp_(0) {}
1306 explicit bigint(uint64_t n) { assign(n); }
1307 ~bigint() { FMT_ASSERT(bigits_.capacity() <= bigits_capacity, ""); }
1308
1309 bigint(const bigint&) = delete;
1310 void operator=(const bigint&) = delete;
1311
1312 void assign(const bigint& other) {
1313 auto size = other.bigits_.size();
1314 bigits_.resize(size);
1315 auto data = other.bigits_.data();
1316 std::copy(data, data + size, make_checked(bigits_.data(), size));
1317 exp_ = other.exp_;
1318 }
1319
1320 void assign(uint64_t n) {
1321 size_t num_bigits = 0;
1322 do {
1323 bigits_[num_bigits++] = n & ~bigit(0);
1324 n >>= bigit_bits;
1325 } while (n != 0);
1326 bigits_.resize(num_bigits);
1327 exp_ = 0;
1328 }
1329
1330 int num_bigits() const { return static_cast<int>(bigits_.size()) + exp_; }
1331
1332 FMT_NOINLINE bigint& operator<<=(int shift) {
1333 FMT_ASSERT(shift >= 0, "");
1334 exp_ += shift / bigit_bits;
1335 shift %= bigit_bits;
1336 if (shift == 0) return *this;
1337 bigit carry = 0;
1338 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
1339 bigit c = bigits_[i] >> (bigit_bits - shift);
1340 bigits_[i] = (bigits_[i] << shift) + carry;
1341 carry = c;
1342 }
1343 if (carry != 0) bigits_.push_back(carry);
1344 return *this;
1345 }
1346
1347 template <typename Int> bigint& operator*=(Int value) {
1348 FMT_ASSERT(value > 0, "");
1349 multiply(uint32_or_64_or_128_t<Int>(value));
1350 return *this;
1351 }
1352
1353 friend int compare(const bigint& lhs, const bigint& rhs) {
1354 int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
1355 if (num_lhs_bigits != num_rhs_bigits)
1356 return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
1357 int i = static_cast<int>(lhs.bigits_.size()) - 1;
1358 int j = static_cast<int>(rhs.bigits_.size()) - 1;
1359 int end = i - j;
1360 if (end < 0) end = 0;
1361 for (; i >= end; --i, --j) {
1362 bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
1363 if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
1364 }
1365 if (i != j) return i > j ? 1 : -1;
1366 return 0;
1367 }
1368
1369 // Returns compare(lhs1 + lhs2, rhs).
1370 friend int add_compare(const bigint& lhs1, const bigint& lhs2,
1371 const bigint& rhs) {
1372 int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits());
1373 int num_rhs_bigits = rhs.num_bigits();
1374 if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
1375 if (max_lhs_bigits > num_rhs_bigits) return 1;
1376 auto get_bigit = [](const bigint& n, int i) -> bigit {
1377 return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
1378 };
1379 double_bigit borrow = 0;
1380 int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_);
1381 for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
1382 double_bigit sum =
1383 static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
1384 bigit rhs_bigit = get_bigit(rhs, i);
1385 if (sum > rhs_bigit + borrow) return 1;
1386 borrow = rhs_bigit + borrow - sum;
1387 if (borrow > 1) return -1;
1388 borrow <<= bigit_bits;
1389 }
1390 return borrow != 0 ? -1 : 0;
1391 }
1392
1393 // Assigns pow(10, exp) to this bigint.
1394 void assign_pow10(int exp) {
1395 FMT_ASSERT(exp >= 0, "");
1396 if (exp == 0) return assign(1);
1397 // Find the top bit.
1398 int bitmask = 1;
1399 while (exp >= bitmask) bitmask <<= 1;
1400 bitmask >>= 1;
1401 // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
1402 // repeated squaring and multiplication.
1403 assign(5);
1404 bitmask >>= 1;
1405 while (bitmask != 0) {
1406 square();
1407 if ((exp & bitmask) != 0) *this *= 5;
1408 bitmask >>= 1;
1409 }
1410 *this <<= exp; // Multiply by pow(2, exp) by shifting.
1411 }
1412
1413 void square() {
1414 basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
1415 int num_bigits = static_cast<int>(bigits_.size());
1416 int num_result_bigits = 2 * num_bigits;
1417 bigits_.resize(to_unsigned(num_result_bigits));
1418 using accumulator_t = conditional_t<FMT_USE_INT128, uint128_t, accumulator>;
1419 auto sum = accumulator_t();
1420 for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
1421 // Compute bigit at position bigit_index of the result by adding
1422 // cross-product terms n[i] * n[j] such that i + j == bigit_index.
1423 for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
1424 // Most terms are multiplied twice which can be optimized in the future.
1425 sum += static_cast<double_bigit>(n[i]) * n[j];
1426 }
1427 (*this)[bigit_index] = static_cast<bigit>(sum);
1428 sum >>= bits<bigit>::value; // Compute the carry.
1429 }
1430 // Do the same for the top half.
1431 for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
1432 ++bigit_index) {
1433 for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
1434 sum += static_cast<double_bigit>(n[i++]) * n[j--];
1435 (*this)[bigit_index] = static_cast<bigit>(sum);
1436 sum >>= bits<bigit>::value;
1437 }
1438 --num_result_bigits;
1439 remove_leading_zeros();
1440 exp_ *= 2;
1441 }
1442
1443 // If this bigint has a bigger exponent than other, adds trailing zero to make
1444 // exponents equal. This simplifies some operations such as subtraction.
1445 void align(const bigint& other) {
1446 int exp_difference = exp_ - other.exp_;
1447 if (exp_difference <= 0) return;
1448 int num_bigits = static_cast<int>(bigits_.size());
1449 bigits_.resize(to_unsigned(num_bigits + exp_difference));
1450 for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
1451 bigits_[j] = bigits_[i];
1452 std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
1453 exp_ -= exp_difference;
1454 }
1455
1456 // Divides this bignum by divisor, assigning the remainder to this and
1457 // returning the quotient.
1458 int divmod_assign(const bigint& divisor) {
1459 FMT_ASSERT(this != &divisor, "");
1460 if (compare(*this, divisor) < 0) return 0;
1461 FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
1462 align(divisor);
1463 int quotient = 0;
1464 do {
1465 subtract_aligned(divisor);
1466 ++quotient;
1467 } while (compare(*this, divisor) >= 0);
1468 return quotient;
1469 }
1470 };
1471
1472 enum class round_direction { unknown, up, down };
1473
1474 // Given the divisor (normally a power of 10), the remainder = v % divisor for
1475 // some number v and the error, returns whether v should be rounded up, down, or
1476 // whether the rounding direction can't be determined due to error.
1477 // error should be less than divisor / 2.
1478 inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder,
1479 uint64_t error) {
1480 FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow.
1481 FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow.
1482 FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow.
1483 // Round down if (remainder + error) * 2 <= divisor.
1484 if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
1485 return round_direction::down;
1486 // Round up if (remainder - error) * 2 >= divisor.
1487 if (remainder >= error &&
1488 remainder - error >= divisor - (remainder - error)) {
1489 return round_direction::up;
1490 }
1491 return round_direction::unknown;
1492 }
1493
1494 namespace digits {
1495 enum result {
1496 more, // Generate more digits.
1497 done, // Done generating digits.
1498 error // Digit generation cancelled due to an error.
1499 };
1500 }
1501
1502 // Generates output using the Grisu digit-gen algorithm.
1503 // error: the size of the region (lower, upper) outside of which numbers
1504 // definitely do not round to value (Delta in Grisu3).
1505 template <typename Handler>
1506 FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error,
1507 int& exp, Handler& handler) {
1508 const fp one(1ULL << -value.e, value.e);
1509 // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be
1510 // zero because it contains a product of two 64-bit numbers with MSB set (due
1511 // to normalization) - 1, shifted right by at most 60 bits.
1512 auto integral = static_cast<uint32_t>(value.f >> -one.e);
1513 FMT_ASSERT(integral != 0, "");
1514 FMT_ASSERT(integral == value.f >> -one.e, "");
1515 // The fractional part of scaled value (p2 in Grisu) c = value % one.
1516 uint64_t fractional = value.f & (one.f - 1);
1517 exp = count_digits(integral); // kappa in Grisu.
1518 // Divide by 10 to prevent overflow.
1519 auto result = handler.on_start(data::powers_of_10_64[exp - 1] << -one.e,
1520 value.f / 10, error * 10, exp);
1521 if (result != digits::more) return result;
1522 // Generate digits for the integral part. This can produce up to 10 digits.
1523 do {
1524 uint32_t digit = 0;
1525 auto divmod_integral = [&](uint32_t divisor) {
1526 digit = integral / divisor;
1527 integral %= divisor;
1528 };
1529 // This optimization by Milo Yip reduces the number of integer divisions by
1530 // one per iteration.
1531 switch (exp) {
1532 case 10:
1533 divmod_integral(1000000000);
1534 break;
1535 case 9:
1536 divmod_integral(100000000);
1537 break;
1538 case 8:
1539 divmod_integral(10000000);
1540 break;
1541 case 7:
1542 divmod_integral(1000000);
1543 break;
1544 case 6:
1545 divmod_integral(100000);
1546 break;
1547 case 5:
1548 divmod_integral(10000);
1549 break;
1550 case 4:
1551 divmod_integral(1000);
1552 break;
1553 case 3:
1554 divmod_integral(100);
1555 break;
1556 case 2:
1557 divmod_integral(10);
1558 break;
1559 case 1:
1560 digit = integral;
1561 integral = 0;
1562 break;
1563 default:
1564 FMT_ASSERT(false, "invalid number of digits");
1565 }
1566 --exp;
1567 auto remainder = (static_cast<uint64_t>(integral) << -one.e) + fractional;
1568 result = handler.on_digit(static_cast<char>('0' + digit),
1569 data::powers_of_10_64[exp] << -one.e, remainder,
1570 error, exp, true);
1571 if (result != digits::more) return result;
1572 } while (exp > 0);
1573 // Generate digits for the fractional part.
1574 for (;;) {
1575 fractional *= 10;
1576 error *= 10;
1577 char digit = static_cast<char>('0' + (fractional >> -one.e));
1578 fractional &= one.f - 1;
1579 --exp;
1580 result = handler.on_digit(digit, one.f, fractional, error, exp, false);
1581 if (result != digits::more) return result;
1582 }
1583 }
1584
1585 // The fixed precision digit handler.
1586 struct fixed_handler {
1587 char* buf;
1588 int size;
1589 int precision;
1590 int exp10;
1591 bool fixed;
1592
1593 digits::result on_start(uint64_t divisor, uint64_t remainder, uint64_t error,
1594 int& exp) {
1595 // Non-fixed formats require at least one digit and no precision adjustment.
1596 if (!fixed) return digits::more;
1597 // Adjust fixed precision by exponent because it is relative to decimal
1598 // point.
1599 precision += exp + exp10;
1600 // Check if precision is satisfied just by leading zeros, e.g.
1601 // format("{:.2f}", 0.001) gives "0.00" without generating any digits.
1602 if (precision > 0) return digits::more;
1603 if (precision < 0) return digits::done;
1604 auto dir = get_round_direction(divisor, remainder, error);
1605 if (dir == round_direction::unknown) return digits::error;
1606 buf[size++] = dir == round_direction::up ? '1' : '0';
1607 return digits::done;
1608 }
1609
1610 digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder,
1611 uint64_t error, int, bool integral) {
1612 FMT_ASSERT(remainder < divisor, "");
1613 buf[size++] = digit;
1614 if (!integral && error >= remainder) return digits::error;
1615 if (size < precision) return digits::more;
1616 if (!integral) {
1617 // Check if error * 2 < divisor with overflow prevention.
1618 // The check is not needed for the integral part because error = 1
1619 // and divisor > (1 << 32) there.
1620 if (error >= divisor || error >= divisor - error) return digits::error;
1621 } else {
1622 FMT_ASSERT(error == 1 && divisor > 2, "");
1623 }
1624 auto dir = get_round_direction(divisor, remainder, error);
1625 if (dir != round_direction::up)
1626 return dir == round_direction::down ? digits::done : digits::error;
1627 ++buf[size - 1];
1628 for (int i = size - 1; i > 0 && buf[i] > '9'; --i) {
1629 buf[i] = '0';
1630 ++buf[i - 1];
1631 }
1632 if (buf[0] > '9') {
1633 buf[0] = '1';
1634 if (fixed)
1635 buf[size++] = '0';
1636 else
1637 ++exp10;
1638 }
1639 return digits::done;
1640 }
1641 };
1642
1643 // Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox.
1644 namespace dragonbox {
1645 // Computes 128-bit result of multiplication of two 64-bit unsigned integers.
1646 inline uint128_wrapper umul128(uint64_t x, uint64_t y) FMT_NOEXCEPT {
1647 #if FMT_USE_INT128
1648 return static_cast<uint128_t>(x) * static_cast<uint128_t>(y);
1649 #elif defined(_MSC_VER) && defined(_M_X64)
1650 uint128_wrapper result;
1651 result.low_ = _umul128(x, y, &result.high_);
1652 return result;
1653 #else
1654 const uint64_t mask = (uint64_t(1) << 32) - uint64_t(1);
1655
1656 uint64_t a = x >> 32;
1657 uint64_t b = x & mask;
1658 uint64_t c = y >> 32;
1659 uint64_t d = y & mask;
1660
1661 uint64_t ac = a * c;
1662 uint64_t bc = b * c;
1663 uint64_t ad = a * d;
1664 uint64_t bd = b * d;
1665
1666 uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask);
1667
1668 return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
1669 (intermediate << 32) + (bd & mask)};
1670 #endif
1671 }
1672
1673 // Computes upper 64 bits of multiplication of two 64-bit unsigned integers.
1674 inline uint64_t umul128_upper64(uint64_t x, uint64_t y) FMT_NOEXCEPT {
1675 #if FMT_USE_INT128
1676 auto p = static_cast<uint128_t>(x) * static_cast<uint128_t>(y);
1677 return static_cast<uint64_t>(p >> 64);
1678 #elif defined(_MSC_VER) && defined(_M_X64)
1679 return __umulh(x, y);
1680 #else
1681 return umul128(x, y).high();
1682 #endif
1683 }
1684
1685 // Computes upper 64 bits of multiplication of a 64-bit unsigned integer and a
1686 // 128-bit unsigned integer.
1687 inline uint64_t umul192_upper64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT {
1688 uint128_wrapper g0 = umul128(x, y.high());
1689 g0 += umul128_upper64(x, y.low());
1690 return g0.high();
1691 }
1692
1693 // Computes upper 32 bits of multiplication of a 32-bit unsigned integer and a
1694 // 64-bit unsigned integer.
1695 inline uint32_t umul96_upper32(uint32_t x, uint64_t y) FMT_NOEXCEPT {
1696 return static_cast<uint32_t>(umul128_upper64(x, y));
1697 }
1698
1699 // Computes middle 64 bits of multiplication of a 64-bit unsigned integer and a
1700 // 128-bit unsigned integer.
1701 inline uint64_t umul192_middle64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT {
1702 uint64_t g01 = x * y.high();
1703 uint64_t g10 = umul128_upper64(x, y.low());
1704 return g01 + g10;
1705 }
1706
1707 // Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a
1708 // 64-bit unsigned integer.
1709 inline uint64_t umul96_lower64(uint32_t x, uint64_t y) FMT_NOEXCEPT {
1710 return x * y;
1711 }
1712
1713 // Computes floor(log10(pow(2, e))) for e in [-1700, 1700] using the method from
1714 // https://fmt.dev/papers/Grisu-Exact.pdf#page=5, section 3.4.
1715 inline int floor_log10_pow2(int e) FMT_NOEXCEPT {
1716 FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent");
1717 const int shift = 22;
1718 return (e * static_cast<int>(data::log10_2_significand >> (64 - shift))) >>
1719 shift;
1720 }
1721
1722 // Various fast log computations.
1723 inline int floor_log2_pow10(int e) FMT_NOEXCEPT {
1724 FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent");
1725 const uint64_t log2_10_integer_part = 3;
1726 const uint64_t log2_10_fractional_digits = 0x5269e12f346e2bf9;
1727 const int shift_amount = 19;
1728 return (e * static_cast<int>(
1729 (log2_10_integer_part << shift_amount) |
1730 (log2_10_fractional_digits >> (64 - shift_amount)))) >>
1731 shift_amount;
1732 }
1733 inline int floor_log10_pow2_minus_log10_4_over_3(int e) FMT_NOEXCEPT {
1734 FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent");
1735 const uint64_t log10_4_over_3_fractional_digits = 0x1ffbfc2bbc780375;
1736 const int shift_amount = 22;
1737 return (e * static_cast<int>(data::log10_2_significand >>
1738 (64 - shift_amount)) -
1739 static_cast<int>(log10_4_over_3_fractional_digits >>
1740 (64 - shift_amount))) >>
1741 shift_amount;
1742 }
1743
1744 // Returns true iff x is divisible by pow(2, exp).
1745 inline bool divisible_by_power_of_2(uint32_t x, int exp) FMT_NOEXCEPT {
1746 FMT_ASSERT(exp >= 1, "");
1747 FMT_ASSERT(x != 0, "");
1748 #ifdef FMT_BUILTIN_CTZ
1749 return FMT_BUILTIN_CTZ(x) >= exp;
1750 #else
1751 return exp < num_bits<uint32_t>() && x == ((x >> exp) << exp);
1752 #endif
1753 }
1754 inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT {
1755 FMT_ASSERT(exp >= 1, "");
1756 FMT_ASSERT(x != 0, "");
1757 #ifdef FMT_BUILTIN_CTZLL
1758 return FMT_BUILTIN_CTZLL(x) >= exp;
1759 #else
1760 return exp < num_bits<uint64_t>() && x == ((x >> exp) << exp);
1761 #endif
1762 }
1763
1764 // Returns true iff x is divisible by pow(5, exp).
1765 inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT {
1766 FMT_ASSERT(exp <= 10, "too large exponent");
1767 return x * data::divtest_table_for_pow5_32[exp].mod_inv <=
1768 data::divtest_table_for_pow5_32[exp].max_quotient;
1769 }
1770 inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT {
1771 FMT_ASSERT(exp <= 23, "too large exponent");
1772 return x * data::divtest_table_for_pow5_64[exp].mod_inv <=
1773 data::divtest_table_for_pow5_64[exp].max_quotient;
1774 }
1775
1776 // Replaces n by floor(n / pow(5, N)) returning true if and only if n is
1777 // divisible by pow(5, N).
1778 // Precondition: n <= 2 * pow(5, N + 1).
1779 template <int N>
1780 bool check_divisibility_and_divide_by_pow5(uint32_t& n) FMT_NOEXCEPT {
1781 static constexpr struct {
1782 uint32_t magic_number;
1783 int bits_for_comparison;
1784 uint32_t threshold;
1785 int shift_amount;
1786 } infos[] = {{0xcccd, 16, 0x3333, 18}, {0xa429, 8, 0x0a, 20}};
1787 constexpr auto info = infos[N - 1];
1788 n *= info.magic_number;
1789 const uint32_t comparison_mask = (1u << info.bits_for_comparison) - 1;
1790 bool result = (n & comparison_mask) <= info.threshold;
1791 n >>= info.shift_amount;
1792 return result;
1793 }
1794
1795 // Computes floor(n / pow(10, N)) for small n and N.
1796 // Precondition: n <= pow(10, N + 1).
1797 template <int N> uint32_t small_division_by_pow10(uint32_t n) FMT_NOEXCEPT {
1798 static constexpr struct {
1799 uint32_t magic_number;
1800 int shift_amount;
1801 uint32_t divisor_times_10;
1802 } infos[] = {{0xcccd, 19, 100}, {0xa3d8, 22, 1000}};
1803 constexpr auto info = infos[N - 1];
1804 FMT_ASSERT(n <= info.divisor_times_10, "n is too large");
1805 return n * info.magic_number >> info.shift_amount;
1806 }
1807
1808 // Computes floor(n / 10^(kappa + 1)) (float)
1809 inline uint32_t divide_by_10_to_kappa_plus_1(uint32_t n) FMT_NOEXCEPT {
1810 return n / float_info<float>::big_divisor;
1811 }
1812 // Computes floor(n / 10^(kappa + 1)) (double)
1813 inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) FMT_NOEXCEPT {
1814 return umul128_upper64(n, 0x83126e978d4fdf3c) >> 9;
1815 }
1816
1817 // Various subroutines using pow10 cache
1818 template <class T> struct cache_accessor;
1819
1820 template <> struct cache_accessor<float> {
1821 using carrier_uint = float_info<float>::carrier_uint;
1822 using cache_entry_type = uint64_t;
1823
1824 static uint64_t get_cached_power(int k) FMT_NOEXCEPT {
1825 FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k,
1826 "k is out of range");
1827 return data::dragonbox_pow10_significands_64[k - float_info<float>::min_k];
1828 }
1829
1830 static carrier_uint compute_mul(carrier_uint u,
1831 const cache_entry_type& cache) FMT_NOEXCEPT {
1832 return umul96_upper32(u, cache);
1833 }
1834
1835 static uint32_t compute_delta(const cache_entry_type& cache,
1836 int beta_minus_1) FMT_NOEXCEPT {
1837 return static_cast<uint32_t>(cache >> (64 - 1 - beta_minus_1));
1838 }
1839
1840 static bool compute_mul_parity(carrier_uint two_f,
1841 const cache_entry_type& cache,
1842 int beta_minus_1) FMT_NOEXCEPT {
1843 FMT_ASSERT(beta_minus_1 >= 1, "");
1844 FMT_ASSERT(beta_minus_1 < 64, "");
1845
1846 return ((umul96_lower64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0;
1847 }
1848
1849 static carrier_uint compute_left_endpoint_for_shorter_interval_case(
1850 const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
1851 return static_cast<carrier_uint>(
1852 (cache - (cache >> (float_info<float>::significand_bits + 2))) >>
1853 (64 - float_info<float>::significand_bits - 1 - beta_minus_1));
1854 }
1855
1856 static carrier_uint compute_right_endpoint_for_shorter_interval_case(
1857 const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
1858 return static_cast<carrier_uint>(
1859 (cache + (cache >> (float_info<float>::significand_bits + 1))) >>
1860 (64 - float_info<float>::significand_bits - 1 - beta_minus_1));
1861 }
1862
1863 static carrier_uint compute_round_up_for_shorter_interval_case(
1864 const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
1865 return (static_cast<carrier_uint>(
1866 cache >>
1867 (64 - float_info<float>::significand_bits - 2 - beta_minus_1)) +
1868 1) /
1869 2;
1870 }
1871 };
1872
1873 template <> struct cache_accessor<double> {
1874 using carrier_uint = float_info<double>::carrier_uint;
1875 using cache_entry_type = uint128_wrapper;
1876
1877 static uint128_wrapper get_cached_power(int k) FMT_NOEXCEPT {
1878 FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k,
1879 "k is out of range");
1880
1881 #if FMT_USE_FULL_CACHE_DRAGONBOX
1882 return data::dragonbox_pow10_significands_128[k -
1883 float_info<double>::min_k];
1884 #else
1885 static const int compression_ratio = 27;
1886
1887 // Compute base index.
1888 int cache_index = (k - float_info<double>::min_k) / compression_ratio;
1889 int kb = cache_index * compression_ratio + float_info<double>::min_k;
1890 int offset = k - kb;
1891
1892 // Get base cache.
1893 uint128_wrapper base_cache =
1894 data::dragonbox_pow10_significands_128[cache_index];
1895 if (offset == 0) return base_cache;
1896
1897 // Compute the required amount of bit-shift.
1898 int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset;
1899 FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected");
1900
1901 // Try to recover the real cache.
1902 uint64_t pow5 = data::powers_of_5_64[offset];
1903 uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5);
1904 uint128_wrapper middle_low =
1905 umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5);
1906
1907 recovered_cache += middle_low.high();
1908
1909 uint64_t high_to_middle = recovered_cache.high() << (64 - alpha);
1910 uint64_t middle_to_low = recovered_cache.low() << (64 - alpha);
1911
1912 recovered_cache =
1913 uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle,
1914 ((middle_low.low() >> alpha) | middle_to_low)};
1915
1916 if (kb < 0) recovered_cache += 1;
1917
1918 // Get error.
1919 int error_idx = (k - float_info<double>::min_k) / 16;
1920 uint32_t error = (data::dragonbox_pow10_recovery_errors[error_idx] >>
1921 ((k - float_info<double>::min_k) % 16) * 2) &
1922 0x3;
1923
1924 // Add the error back.
1925 FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), "");
1926 return {recovered_cache.high(), recovered_cache.low() + error};
1927 #endif
1928 }
1929
1930 static carrier_uint compute_mul(carrier_uint u,
1931 const cache_entry_type& cache) FMT_NOEXCEPT {
1932 return umul192_upper64(u, cache);
1933 }
1934
1935 static uint32_t compute_delta(cache_entry_type const& cache,
1936 int beta_minus_1) FMT_NOEXCEPT {
1937 return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta_minus_1));
1938 }
1939
1940 static bool compute_mul_parity(carrier_uint two_f,
1941 const cache_entry_type& cache,
1942 int beta_minus_1) FMT_NOEXCEPT {
1943 FMT_ASSERT(beta_minus_1 >= 1, "");
1944 FMT_ASSERT(beta_minus_1 < 64, "");
1945
1946 return ((umul192_middle64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0;
1947 }
1948
1949 static carrier_uint compute_left_endpoint_for_shorter_interval_case(
1950 const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
1951 return (cache.high() -
1952 (cache.high() >> (float_info<double>::significand_bits + 2))) >>
1953 (64 - float_info<double>::significand_bits - 1 - beta_minus_1);
1954 }
1955
1956 static carrier_uint compute_right_endpoint_for_shorter_interval_case(
1957 const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
1958 return (cache.high() +
1959 (cache.high() >> (float_info<double>::significand_bits + 1))) >>
1960 (64 - float_info<double>::significand_bits - 1 - beta_minus_1);
1961 }
1962
1963 static carrier_uint compute_round_up_for_shorter_interval_case(
1964 const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
1965 return ((cache.high() >>
1966 (64 - float_info<double>::significand_bits - 2 - beta_minus_1)) +
1967 1) /
1968 2;
1969 }
1970 };
1971
1972 // Various integer checks
1973 template <class T>
1974 bool is_left_endpoint_integer_shorter_interval(int exponent) FMT_NOEXCEPT {
1975 return exponent >=
1976 float_info<
1977 T>::case_shorter_interval_left_endpoint_lower_threshold &&
1978 exponent <=
1979 float_info<T>::case_shorter_interval_left_endpoint_upper_threshold;
1980 }
1981 template <class T>
1982 bool is_endpoint_integer(typename float_info<T>::carrier_uint two_f,
1983 int exponent, int minus_k) FMT_NOEXCEPT {
1984 if (exponent < float_info<T>::case_fc_pm_half_lower_threshold) return false;
1985 // For k >= 0.
1986 if (exponent <= float_info<T>::case_fc_pm_half_upper_threshold) return true;
1987 // For k < 0.
1988 if (exponent > float_info<T>::divisibility_check_by_5_threshold) return false;
1989 return divisible_by_power_of_5(two_f, minus_k);
1990 }
1991
1992 template <class T>
1993 bool is_center_integer(typename float_info<T>::carrier_uint two_f, int exponent,
1994 int minus_k) FMT_NOEXCEPT {
1995 // Exponent for 5 is negative.
1996 if (exponent > float_info<T>::divisibility_check_by_5_threshold) return false;
1997 if (exponent > float_info<T>::case_fc_upper_threshold)
1998 return divisible_by_power_of_5(two_f, minus_k);
1999 // Both exponents are nonnegative.
2000 if (exponent >= float_info<T>::case_fc_lower_threshold) return true;
2001 // Exponent for 2 is negative.
2002 return divisible_by_power_of_2(two_f, minus_k - exponent + 1);
2003 }
2004
2005 // Remove trailing zeros from n and return the number of zeros removed (float)
2006 FMT_ALWAYS_INLINE int remove_trailing_zeros(uint32_t& n) FMT_NOEXCEPT {
2007 #ifdef FMT_BUILTIN_CTZ
2008 int t = FMT_BUILTIN_CTZ(n);
2009 #else
2010 int t = ctz(n);
2011 #endif
2012 if (t > float_info<float>::max_trailing_zeros)
2013 t = float_info<float>::max_trailing_zeros;
2014
2015 const uint32_t mod_inv1 = 0xcccccccd;
2016 const uint32_t max_quotient1 = 0x33333333;
2017 const uint32_t mod_inv2 = 0xc28f5c29;
2018 const uint32_t max_quotient2 = 0x0a3d70a3;
2019
2020 int s = 0;
2021 for (; s < t - 1; s += 2) {
2022 if (n * mod_inv2 > max_quotient2) break;
2023 n *= mod_inv2;
2024 }
2025 if (s < t && n * mod_inv1 <= max_quotient1) {
2026 n *= mod_inv1;
2027 ++s;
2028 }
2029 n >>= s;
2030 return s;
2031 }
2032
2033 // Removes trailing zeros and returns the number of zeros removed (double)
2034 FMT_ALWAYS_INLINE int remove_trailing_zeros(uint64_t& n) FMT_NOEXCEPT {
2035 #ifdef FMT_BUILTIN_CTZLL
2036 int t = FMT_BUILTIN_CTZLL(n);
2037 #else
2038 int t = ctzll(n);
2039 #endif
2040 if (t > float_info<double>::max_trailing_zeros)
2041 t = float_info<double>::max_trailing_zeros;
2042 // Divide by 10^8 and reduce to 32-bits
2043 // Since ret_value.significand <= (2^64 - 1) / 1000 < 10^17,
2044 // both of the quotient and the r should fit in 32-bits
2045
2046 const uint32_t mod_inv1 = 0xcccccccd;
2047 const uint32_t max_quotient1 = 0x33333333;
2048 const uint64_t mod_inv8 = 0xc767074b22e90e21;
2049 const uint64_t max_quotient8 = 0x00002af31dc46118;
2050
2051 // If the number is divisible by 1'0000'0000, work with the quotient
2052 if (t >= 8) {
2053 auto quotient_candidate = n * mod_inv8;
2054
2055 if (quotient_candidate <= max_quotient8) {
2056 auto quotient = static_cast<uint32_t>(quotient_candidate >> 8);
2057
2058 int s = 8;
2059 for (; s < t; ++s) {
2060 if (quotient * mod_inv1 > max_quotient1) break;
2061 quotient *= mod_inv1;
2062 }
2063 quotient >>= (s - 8);
2064 n = quotient;
2065 return s;
2066 }
2067 }
2068
2069 // Otherwise, work with the remainder
2070 auto quotient = static_cast<uint32_t>(n / 100000000);
2071 auto remainder = static_cast<uint32_t>(n - 100000000 * quotient);
2072
2073 if (t == 0 || remainder * mod_inv1 > max_quotient1) {
2074 return 0;
2075 }
2076 remainder *= mod_inv1;
2077
2078 if (t == 1 || remainder * mod_inv1 > max_quotient1) {
2079 n = (remainder >> 1) + quotient * 10000000ull;
2080 return 1;
2081 }
2082 remainder *= mod_inv1;
2083
2084 if (t == 2 || remainder * mod_inv1 > max_quotient1) {
2085 n = (remainder >> 2) + quotient * 1000000ull;
2086 return 2;
2087 }
2088 remainder *= mod_inv1;
2089
2090 if (t == 3 || remainder * mod_inv1 > max_quotient1) {
2091 n = (remainder >> 3) + quotient * 100000ull;
2092 return 3;
2093 }
2094 remainder *= mod_inv1;
2095
2096 if (t == 4 || remainder * mod_inv1 > max_quotient1) {
2097 n = (remainder >> 4) + quotient * 10000ull;
2098 return 4;
2099 }
2100 remainder *= mod_inv1;
2101
2102 if (t == 5 || remainder * mod_inv1 > max_quotient1) {
2103 n = (remainder >> 5) + quotient * 1000ull;
2104 return 5;
2105 }
2106 remainder *= mod_inv1;
2107
2108 if (t == 6 || remainder * mod_inv1 > max_quotient1) {
2109 n = (remainder >> 6) + quotient * 100ull;
2110 return 6;
2111 }
2112 remainder *= mod_inv1;
2113
2114 n = (remainder >> 7) + quotient * 10ull;
2115 return 7;
2116 }
2117
2118 // The main algorithm for shorter interval case
2119 template <class T>
2120 FMT_ALWAYS_INLINE decimal_fp<T> shorter_interval_case(int exponent)
2121 FMT_NOEXCEPT {
2122 decimal_fp<T> ret_value;
2123 // Compute k and beta
2124 const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent);
2125 const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k);
2126
2127 // Compute xi and zi
2128 using cache_entry_type = typename cache_accessor<T>::cache_entry_type;
2129 const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);
2130
2131 auto xi = cache_accessor<T>::compute_left_endpoint_for_shorter_interval_case(
2132 cache, beta_minus_1);
2133 auto zi = cache_accessor<T>::compute_right_endpoint_for_shorter_interval_case(
2134 cache, beta_minus_1);
2135
2136 // If the left endpoint is not an integer, increase it
2137 if (!is_left_endpoint_integer_shorter_interval<T>(exponent)) ++xi;
2138
2139 // Try bigger divisor
2140 ret_value.significand = zi / 10;
2141
2142 // If succeed, remove trailing zeros if necessary and return
2143 if (ret_value.significand * 10 >= xi) {
2144 ret_value.exponent = minus_k + 1;
2145 ret_value.exponent += remove_trailing_zeros(ret_value.significand);
2146 return ret_value;
2147 }
2148
2149 // Otherwise, compute the round-up of y
2150 ret_value.significand =
2151 cache_accessor<T>::compute_round_up_for_shorter_interval_case(
2152 cache, beta_minus_1);
2153 ret_value.exponent = minus_k;
2154
2155 // When tie occurs, choose one of them according to the rule
2156 if (exponent >= float_info<T>::shorter_interval_tie_lower_threshold &&
2157 exponent <= float_info<T>::shorter_interval_tie_upper_threshold) {
2158 ret_value.significand = ret_value.significand % 2 == 0
2159 ? ret_value.significand
2160 : ret_value.significand - 1;
2161 } else if (ret_value.significand < xi) {
2162 ++ret_value.significand;
2163 }
2164 return ret_value;
2165 }
2166
2167 template <typename T> decimal_fp<T> to_decimal(T x) FMT_NOEXCEPT {
2168 // Step 1: integer promotion & Schubfach multiplier calculation.
2169
2170 using carrier_uint = typename float_info<T>::carrier_uint;
2171 using cache_entry_type = typename cache_accessor<T>::cache_entry_type;
2172 auto br = bit_cast<carrier_uint>(x);
2173
2174 // Extract significand bits and exponent bits.
2175 const carrier_uint significand_mask =
2176 (static_cast<carrier_uint>(1) << float_info<T>::significand_bits) - 1;
2177 carrier_uint significand = (br & significand_mask);
2178 int exponent = static_cast<int>((br & exponent_mask<T>()) >>
2179 float_info<T>::significand_bits);
2180
2181 if (exponent != 0) { // Check if normal.
2182 exponent += float_info<T>::exponent_bias - float_info<T>::significand_bits;
2183
2184 // Shorter interval case; proceed like Schubfach.
2185 if (significand == 0) return shorter_interval_case<T>(exponent);
2186
2187 significand |=
2188 (static_cast<carrier_uint>(1) << float_info<T>::significand_bits);
2189 } else {
2190 // Subnormal case; the interval is always regular.
2191 if (significand == 0) return {0, 0};
2192 exponent = float_info<T>::min_exponent - float_info<T>::significand_bits;
2193 }
2194
2195 const bool include_left_endpoint = (significand % 2 == 0);
2196 const bool include_right_endpoint = include_left_endpoint;
2197
2198 // Compute k and beta.
2199 const int minus_k = floor_log10_pow2(exponent) - float_info<T>::kappa;
2200 const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);
2201 const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k);
2202
2203 // Compute zi and deltai
2204 // 10^kappa <= deltai < 10^(kappa + 1)
2205 const uint32_t deltai = cache_accessor<T>::compute_delta(cache, beta_minus_1);
2206 const carrier_uint two_fc = significand << 1;
2207 const carrier_uint two_fr = two_fc | 1;
2208 const carrier_uint zi =
2209 cache_accessor<T>::compute_mul(two_fr << beta_minus_1, cache);
2210
2211 // Step 2: Try larger divisor; remove trailing zeros if necessary
2212
2213 // Using an upper bound on zi, we might be able to optimize the division
2214 // better than the compiler; we are computing zi / big_divisor here
2215 decimal_fp<T> ret_value;
2216 ret_value.significand = divide_by_10_to_kappa_plus_1(zi);
2217 uint32_t r = static_cast<uint32_t>(zi - float_info<T>::big_divisor *
2218 ret_value.significand);
2219
2220 if (r > deltai) {
2221 goto small_divisor_case_label;
2222 } else if (r < deltai) {
2223 // Exclude the right endpoint if necessary
2224 if (r == 0 && !include_right_endpoint &&
2225 is_endpoint_integer<T>(two_fr, exponent, minus_k)) {
2226 --ret_value.significand;
2227 r = float_info<T>::big_divisor;
2228 goto small_divisor_case_label;
2229 }
2230 } else {
2231 // r == deltai; compare fractional parts
2232 // Check conditions in the order different from the paper
2233 // to take advantage of short-circuiting
2234 const carrier_uint two_fl = two_fc - 1;
2235 if ((!include_left_endpoint ||
2236 !is_endpoint_integer<T>(two_fl, exponent, minus_k)) &&
2237 !cache_accessor<T>::compute_mul_parity(two_fl, cache, beta_minus_1)) {
2238 goto small_divisor_case_label;
2239 }
2240 }
2241 ret_value.exponent = minus_k + float_info<T>::kappa + 1;
2242
2243 // We may need to remove trailing zeros
2244 ret_value.exponent += remove_trailing_zeros(ret_value.significand);
2245 return ret_value;
2246
2247 // Step 3: Find the significand with the smaller divisor
2248
2249 small_divisor_case_label:
2250 ret_value.significand *= 10;
2251 ret_value.exponent = minus_k + float_info<T>::kappa;
2252
2253 const uint32_t mask = (1u << float_info<T>::kappa) - 1;
2254 auto dist = r - (deltai / 2) + (float_info<T>::small_divisor / 2);
2255
2256 // Is dist divisible by 2^kappa?
2257 if ((dist & mask) == 0) {
2258 const bool approx_y_parity =
2259 ((dist ^ (float_info<T>::small_divisor / 2)) & 1) != 0;
2260 dist >>= float_info<T>::kappa;
2261
2262 // Is dist divisible by 5^kappa?
2263 if (check_divisibility_and_divide_by_pow5<float_info<T>::kappa>(dist)) {
2264 ret_value.significand += dist;
2265
2266 // Check z^(f) >= epsilon^(f)
2267 // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1,
2268 // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f)
2269 // Since there are only 2 possibilities, we only need to care about the
2270 // parity. Also, zi and r should have the same parity since the divisor
2271 // is an even number
2272 if (cache_accessor<T>::compute_mul_parity(two_fc, cache, beta_minus_1) !=
2273 approx_y_parity) {
2274 --ret_value.significand;
2275 } else {
2276 // If z^(f) >= epsilon^(f), we might have a tie
2277 // when z^(f) == epsilon^(f), or equivalently, when y is an integer
2278 if (is_center_integer<T>(two_fc, exponent, minus_k)) {
2279 ret_value.significand = ret_value.significand % 2 == 0
2280 ? ret_value.significand
2281 : ret_value.significand - 1;
2282 }
2283 }
2284 }
2285 // Is dist not divisible by 5^kappa?
2286 else {
2287 ret_value.significand += dist;
2288 }
2289 }
2290 // Is dist not divisible by 2^kappa?
2291 else {
2292 // Since we know dist is small, we might be able to optimize the division
2293 // better than the compiler; we are computing dist / small_divisor here
2294 ret_value.significand +=
2295 small_division_by_pow10<float_info<T>::kappa>(dist);
2296 }
2297 return ret_value;
2298 }
2299 } // namespace dragonbox
2300
2301 // Formats value using a variation of the Fixed-Precision Positive
2302 // Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
2303 // https://fmt.dev/p372-steele.pdf.
2304 template <typename Double>
2305 void fallback_format(Double d, int num_digits, bool binary32, buffer<char>& buf,
2306 int& exp10) {
2307 bigint numerator; // 2 * R in (FPP)^2.
2308 bigint denominator; // 2 * S in (FPP)^2.
2309 // lower and upper are differences between value and corresponding boundaries.
2310 bigint lower; // (M^- in (FPP)^2).
2311 bigint upper_store; // upper's value if different from lower.
2312 bigint* upper = nullptr; // (M^+ in (FPP)^2).
2313 fp value;
2314 // Shift numerator and denominator by an extra bit or two (if lower boundary
2315 // is closer) to make lower and upper integers. This eliminates multiplication
2316 // by 2 during later computations.
2317 const bool is_predecessor_closer =
2318 binary32 ? value.assign(static_cast<float>(d)) : value.assign(d);
2319 int shift = is_predecessor_closer ? 2 : 1;
2320 uint64_t significand = value.f << shift;
2321 if (value.e >= 0) {
2322 numerator.assign(significand);
2323 numerator <<= value.e;
2324 lower.assign(1);
2325 lower <<= value.e;
2326 if (shift != 1) {
2327 upper_store.assign(1);
2328 upper_store <<= value.e + 1;
2329 upper = &upper_store;
2330 }
2331 denominator.assign_pow10(exp10);
2332 denominator <<= shift;
2333 } else if (exp10 < 0) {
2334 numerator.assign_pow10(-exp10);
2335 lower.assign(numerator);
2336 if (shift != 1) {
2337 upper_store.assign(numerator);
2338 upper_store <<= 1;
2339 upper = &upper_store;
2340 }
2341 numerator *= significand;
2342 denominator.assign(1);
2343 denominator <<= shift - value.e;
2344 } else {
2345 numerator.assign(significand);
2346 denominator.assign_pow10(exp10);
2347 denominator <<= shift - value.e;
2348 lower.assign(1);
2349 if (shift != 1) {
2350 upper_store.assign(1ULL << 1);
2351 upper = &upper_store;
2352 }
2353 }
2354 // Invariant: value == (numerator / denominator) * pow(10, exp10).
2355 if (num_digits < 0) {
2356 // Generate the shortest representation.
2357 if (!upper) upper = &lower;
2358 bool even = (value.f & 1) == 0;
2359 num_digits = 0;
2360 char* data = buf.data();
2361 for (;;) {
2362 int digit = numerator.divmod_assign(denominator);
2363 bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower.
2364 // numerator + upper >[=] pow10:
2365 bool high = add_compare(numerator, *upper, denominator) + even > 0;
2366 data[num_digits++] = static_cast<char>('0' + digit);
2367 if (low || high) {
2368 if (!low) {
2369 ++data[num_digits - 1];
2370 } else if (high) {
2371 int result = add_compare(numerator, numerator, denominator);
2372 // Round half to even.
2373 if (result > 0 || (result == 0 && (digit % 2) != 0))
2374 ++data[num_digits - 1];
2375 }
2376 buf.try_resize(to_unsigned(num_digits));
2377 exp10 -= num_digits - 1;
2378 return;
2379 }
2380 numerator *= 10;
2381 lower *= 10;
2382 if (upper != &lower) *upper *= 10;
2383 }
2384 }
2385 // Generate the given number of digits.
2386 exp10 -= num_digits - 1;
2387 if (num_digits == 0) {
2388 buf.try_resize(1);
2389 denominator *= 10;
2390 buf[0] = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
2391 return;
2392 }
2393 buf.try_resize(to_unsigned(num_digits));
2394 for (int i = 0; i < num_digits - 1; ++i) {
2395 int digit = numerator.divmod_assign(denominator);
2396 buf[i] = static_cast<char>('0' + digit);
2397 numerator *= 10;
2398 }
2399 int digit = numerator.divmod_assign(denominator);
2400 auto result = add_compare(numerator, numerator, denominator);
2401 if (result > 0 || (result == 0 && (digit % 2) != 0)) {
2402 if (digit == 9) {
2403 const auto overflow = '0' + 10;
2404 buf[num_digits - 1] = overflow;
2405 // Propagate the carry.
2406 for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
2407 buf[i] = '0';
2408 ++buf[i - 1];
2409 }
2410 if (buf[0] == overflow) {
2411 buf[0] = '1';
2412 ++exp10;
2413 }
2414 return;
2415 }
2416 ++digit;
2417 }
2418 buf[num_digits - 1] = static_cast<char>('0' + digit);
2419 }
2420
2421 template <typename T>
2422 int format_float(T value, int precision, float_specs specs, buffer<char>& buf) {
2423 static_assert(!std::is_same<T, float>::value, "");
2424 FMT_ASSERT(value >= 0, "value is negative");
2425
2426 const bool fixed = specs.format == float_format::fixed;
2427 if (value <= 0) { // <= instead of == to silence a warning.
2428 if (precision <= 0 || !fixed) {
2429 buf.push_back('0');
2430 return 0;
2431 }
2432 buf.try_resize(to_unsigned(precision));
2433 std::uninitialized_fill_n(buf.data(), precision, '0');
2434 return -precision;
2435 }
2436
2437 if (!specs.use_grisu) return snprintf_float(value, precision, specs, buf);
2438
2439 if (precision < 0) {
2440 // Use Dragonbox for the shortest format.
2441 if (specs.binary32) {
2442 auto dec = dragonbox::to_decimal(static_cast<float>(value));
2443 write<char>(buffer_appender<char>(buf), dec.significand);
2444 return dec.exponent;
2445 }
2446 auto dec = dragonbox::to_decimal(static_cast<double>(value));
2447 write<char>(buffer_appender<char>(buf), dec.significand);
2448 return dec.exponent;
2449 }
2450
2451 // Use Grisu + Dragon4 for the given precision:
2452 // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf.
2453 int exp = 0;
2454 const int min_exp = -60; // alpha in Grisu.
2455 int cached_exp10 = 0; // K in Grisu.
2456 fp normalized = normalize(fp(value));
2457 const auto cached_pow = get_cached_power(
2458 min_exp - (normalized.e + fp::significand_size), cached_exp10);
2459 normalized = normalized * cached_pow;
2460 // Limit precision to the maximum possible number of significant digits in an
2461 // IEEE754 double because we don't need to generate zeros.
2462 const int max_double_digits = 767;
2463 if (precision > max_double_digits) precision = max_double_digits;
2464 fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
2465 if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error) {
2466 exp += handler.size - cached_exp10 - 1;
2467 fallback_format(value, handler.precision, specs.binary32, buf, exp);
2468 } else {
2469 exp += handler.exp10;
2470 buf.try_resize(to_unsigned(handler.size));
2471 }
2472 if (!fixed && !specs.showpoint) {
2473 // Remove trailing zeros.
2474 auto num_digits = buf.size();
2475 while (num_digits > 0 && buf[num_digits - 1] == '0') {
2476 --num_digits;
2477 ++exp;
2478 }
2479 buf.try_resize(num_digits);
2480 }
2481 return exp;
2482 } // namespace detail
2483
2484 template <typename T>
2485 int snprintf_float(T value, int precision, float_specs specs,
2486 buffer<char>& buf) {
2487 // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
2488 FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer");
2489 static_assert(!std::is_same<T, float>::value, "");
2490
2491 // Subtract 1 to account for the difference in precision since we use %e for
2492 // both general and exponent format.
2493 if (specs.format == float_format::general ||
2494 specs.format == float_format::exp)
2495 precision = (precision >= 0 ? precision : 6) - 1;
2496
2497 // Build the format string.
2498 enum { max_format_size = 7 }; // The longest format is "%#.*Le".
2499 char format[max_format_size];
2500 char* format_ptr = format;
2501 *format_ptr++ = '%';
2502 if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ = '#';
2503 if (precision >= 0) {
2504 *format_ptr++ = '.';
2505 *format_ptr++ = '*';
2506 }
2507 if (std::is_same<T, long double>()) *format_ptr++ = 'L';
2508 *format_ptr++ = specs.format != float_format::hex
2509 ? (specs.format == float_format::fixed ? 'f' : 'e')
2510 : (specs.upper ? 'A' : 'a');
2511 *format_ptr = '\0';
2512
2513 // Format using snprintf.
2514 auto offset = buf.size();
2515 for (;;) {
2516 auto begin = buf.data() + offset;
2517 auto capacity = buf.capacity() - offset;
2518 #ifdef FMT_FUZZ
2519 if (precision > 100000)
2520 throw std::runtime_error(
2521 "fuzz mode - avoid large allocation inside snprintf");
2522 #endif
2523 // Suppress the warning about a nonliteral format string.
2524 // Cannot use auto because of a bug in MinGW (#1532).
2525 int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
2526 int result = precision >= 0
2527 ? snprintf_ptr(begin, capacity, format, precision, value)
2528 : snprintf_ptr(begin, capacity, format, value);
2529 if (result < 0) {
2530 // The buffer will grow exponentially.
2531 buf.try_reserve(buf.capacity() + 1);
2532 continue;
2533 }
2534 auto size = to_unsigned(result);
2535 // Size equal to capacity means that the last character was truncated.
2536 if (size >= capacity) {
2537 buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'.
2538 continue;
2539 }
2540 auto is_digit = [](char c) { return c >= '0' && c <= '9'; };
2541 if (specs.format == float_format::fixed) {
2542 if (precision == 0) {
2543 buf.try_resize(size);
2544 return 0;
2545 }
2546 // Find and remove the decimal point.
2547 auto end = begin + size, p = end;
2548 do {
2549 --p;
2550 } while (is_digit(*p));
2551 int fraction_size = static_cast<int>(end - p - 1);
2552 std::memmove(p, p + 1, to_unsigned(fraction_size));
2553 buf.try_resize(size - 1);
2554 return -fraction_size;
2555 }
2556 if (specs.format == float_format::hex) {
2557 buf.try_resize(size + offset);
2558 return 0;
2559 }
2560 // Find and parse the exponent.
2561 auto end = begin + size, exp_pos = end;
2562 do {
2563 --exp_pos;
2564 } while (*exp_pos != 'e');
2565 char sign = exp_pos[1];
2566 FMT_ASSERT(sign == '+' || sign == '-', "");
2567 int exp = 0;
2568 auto p = exp_pos + 2; // Skip 'e' and sign.
2569 do {
2570 FMT_ASSERT(is_digit(*p), "");
2571 exp = exp * 10 + (*p++ - '0');
2572 } while (p != end);
2573 if (sign == '-') exp = -exp;
2574 int fraction_size = 0;
2575 if (exp_pos != begin + 1) {
2576 // Remove trailing zeros.
2577 auto fraction_end = exp_pos - 1;
2578 while (*fraction_end == '0') --fraction_end;
2579 // Move the fractional part left to get rid of the decimal point.
2580 fraction_size = static_cast<int>(fraction_end - begin - 1);
2581 std::memmove(begin + 1, begin + 2, to_unsigned(fraction_size));
2582 }
2583 buf.try_resize(to_unsigned(fraction_size) + offset + 1);
2584 return exp - fraction_size;
2585 }
2586 }
2587
2588 struct stringifier {
2589 template <typename T> FMT_INLINE std::string operator()(T value) const {
2590 return to_string(value);
2591 }
2592 std::string operator()(basic_format_arg<format_context>::handle h) const {
2593 memory_buffer buf;
2594 format_parse_context parse_ctx({});
2595 format_context format_ctx(buffer_appender<char>(buf), {}, {});
2596 h.format(parse_ctx, format_ctx);
2597 return to_string(buf);
2598 }
2599 };
2600 } // namespace detail
2601
2602 template <> struct formatter<detail::bigint> {
2603 FMT_CONSTEXPR format_parse_context::iterator parse(
2604 format_parse_context& ctx) {
2605 return ctx.begin();
2606 }
2607
2608 format_context::iterator format(const detail::bigint& n,
2609 format_context& ctx) {
2610 auto out = ctx.out();
2611 bool first = true;
2612 for (auto i = n.bigits_.size(); i > 0; --i) {
2613 auto value = n.bigits_[i - 1u];
2614 if (first) {
2615 out = format_to(out, FMT_STRING("{:x}"), value);
2616 first = false;
2617 continue;
2618 }
2619 out = format_to(out, FMT_STRING("{:08x}"), value);
2620 }
2621 if (n.exp_ > 0)
2622 out = format_to(out, FMT_STRING("p{}"),
2623 n.exp_ * detail::bigint::bigit_bits);
2624 return out;
2625 }
2626 };
2627
2628 FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) {
2629 for_each_codepoint(s, [this](uint32_t cp, int error) {
2630 if (error != 0) FMT_THROW(std::runtime_error("invalid utf8"));
2631 if (cp <= 0xFFFF) {
2632 buffer_.push_back(static_cast<wchar_t>(cp));
2633 } else {
2634 cp -= 0x10000;
2635 buffer_.push_back(static_cast<wchar_t>(0xD800 + (cp >> 10)));
2636 buffer_.push_back(static_cast<wchar_t>(0xDC00 + (cp & 0x3FF)));
2637 }
2638 });
2639 buffer_.push_back(0);
2640 }
2641
2642 FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
2643 string_view message) FMT_NOEXCEPT {
2644 FMT_TRY {
2645 memory_buffer buf;
2646 buf.resize(inline_buffer_size);
2647 for (;;) {
2648 char* system_message = &buf[0];
2649 int result =
2650 detail::safe_strerror(error_code, system_message, buf.size());
2651 if (result == 0) {
2652 format_to(detail::buffer_appender<char>(out), FMT_STRING("{}: {}"),
2653 message, system_message);
2654 return;
2655 }
2656 if (result != ERANGE)
2657 break; // Can't get error message, report error code instead.
2658 buf.resize(buf.size() * 2);
2659 }
2660 }
2661 FMT_CATCH(...) {}
2662 format_error_code(out, error_code, message);
2663 }
2664
2665 FMT_FUNC void detail::error_handler::on_error(const char* message) {
2666 FMT_THROW(format_error(message));
2667 }
2668
2669 FMT_FUNC void report_system_error(int error_code,
2670 axom::fmt::string_view message) FMT_NOEXCEPT {
2671 report_error(format_system_error, error_code, message);
2672 }
2673
2674 FMT_FUNC std::string detail::vformat(string_view format_str, format_args args) {
2675 if (format_str.size() == 2 && equal2(format_str.data(), "{}")) {
2676 auto arg = args.get(0);
2677 if (!arg) error_handler().on_error("argument not found");
2678 return visit_format_arg(stringifier(), arg);
2679 }
2680 memory_buffer buffer;
2681 detail::vformat_to(buffer, format_str, args);
2682 return to_string(buffer);
2683 }
2684
2685 #ifdef _WIN32
2686 namespace detail {
2687 using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;
2688 extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
2689 void*, const void*, dword, dword*, void*);
2690 } // namespace detail
2691 #endif
2692
2693 FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
2694 memory_buffer buffer;
2695 detail::vformat_to(buffer, format_str,
2696 basic_format_args<buffer_context<char>>(args));
2697 #ifdef _WIN32
2698 auto fd = _fileno(f);
2699 if (_isatty(fd)) {
2700 detail::utf8_to_utf16 u16(string_view(buffer.data(), buffer.size()));
2701 auto written = detail::dword();
2702 if (detail::WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fd)),
2703 u16.c_str(), static_cast<uint32_t>(u16.size()),
2704 &written, nullptr)) {
2705 return;
2706 }
2707 // Fallback to fwrite on failure. It can happen if the output has been
2708 // redirected to NUL.
2709 }
2710 #endif
2711 detail::fwrite_fully(buffer.data(), 1, buffer.size(), f);
2712 }
2713
2714 #ifdef _WIN32
2715 // Print assuming legacy (non-Unicode) encoding.
2716 FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str,
2717 format_args args) {
2718 memory_buffer buffer;
2719 detail::vformat_to(buffer, format_str,
2720 basic_format_args<buffer_context<char>>(args));
2721 fwrite_fully(buffer.data(), 1, buffer.size(), f);
2722 }
2723 #endif
2724
2725 FMT_FUNC void vprint(string_view format_str, format_args args) {
2726 vprint(stdout, format_str, args);
2727 }
2728
2729 FMT_END_NAMESPACE
2730
2731 #endif // FMT_FORMAT_INL_H_
2732