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