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 <cerrno> // errno
13 #include <climits>
14 #include <cmath>
15 #include <exception>
16
17 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
18 # include <locale>
19 #endif
20
21 #if defined(_WIN32) && !defined(FMT_WINDOWS_NO_WCHAR)
22 # include <io.h> // _isatty
23 #endif
24
25 #include "format.h"
26
27 FMT_BEGIN_NAMESPACE
28 namespace detail {
29
assert_fail(const char * file,int line,const char * message)30 FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
31 // Use unchecked std::fprintf to avoid triggering another assertion when
32 // writing to stderr fails
33 std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
34 // Chosen instead of std::abort to satisfy Clang in CUDA mode during device
35 // code pass.
36 std::terminate();
37 }
38
throw_format_error(const char * message)39 FMT_FUNC void throw_format_error(const char* message) {
40 FMT_THROW(format_error(message));
41 }
42
format_error_code(detail::buffer<char> & out,int error_code,string_view message)43 FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
44 string_view message) noexcept {
45 // Report error code making sure that the output fits into
46 // inline_buffer_size to avoid dynamic memory allocation and potential
47 // bad_alloc.
48 out.try_resize(0);
49 static const char SEP[] = ": ";
50 static const char ERROR_STR[] = "error ";
51 // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
52 size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
53 auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code);
54 if (detail::is_negative(error_code)) {
55 abs_value = 0 - abs_value;
56 ++error_code_size;
57 }
58 error_code_size += detail::to_unsigned(detail::count_digits(abs_value));
59 auto it = buffer_appender<char>(out);
60 if (message.size() <= inline_buffer_size - error_code_size)
61 fmt::format_to(it, FMT_STRING("{}{}"), message, SEP);
62 fmt::format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code);
63 FMT_ASSERT(out.size() <= inline_buffer_size, "");
64 }
65
report_error(format_func func,int error_code,const char * message)66 FMT_FUNC void report_error(format_func func, int error_code,
67 const char* message) noexcept {
68 memory_buffer full_message;
69 func(full_message, error_code, message);
70 // Don't use fwrite_fully because the latter may throw.
71 if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0)
72 std::fputc('\n', stderr);
73 }
74
75 // A wrapper around fwrite that throws on error.
fwrite_fully(const void * ptr,size_t count,FILE * stream)76 inline void fwrite_fully(const void* ptr, size_t count, FILE* stream) {
77 size_t written = std::fwrite(ptr, 1, count, stream);
78 if (written < count)
79 FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
80 }
81
82 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
83 template <typename Locale>
locale_ref(const Locale & loc)84 locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
85 static_assert(std::is_same<Locale, std::locale>::value, "");
86 }
87
88 template <typename Locale> auto locale_ref::get() const -> Locale {
89 static_assert(std::is_same<Locale, std::locale>::value, "");
90 return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
91 }
92
93 template <typename Char>
94 FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
95 auto& facet = std::use_facet<std::numpunct<Char>>(loc.get<std::locale>());
96 auto grouping = facet.grouping();
97 auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep();
98 return {std::move(grouping), thousands_sep};
99 }
100 template <typename Char>
101 FMT_FUNC auto decimal_point_impl(locale_ref loc) -> Char {
102 return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
103 .decimal_point();
104 }
105 #else
106 template <typename Char>
107 FMT_FUNC auto thousands_sep_impl(locale_ref) -> thousands_sep_result<Char> {
108 return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR};
109 }
decimal_point_impl(locale_ref)110 template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
111 return '.';
112 }
113 #endif
114
115 FMT_FUNC auto write_loc(appender out, loc_value value,
116 const format_specs<>& specs, locale_ref loc) -> bool {
117 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
118 auto locale = loc.get<std::locale>();
119 // We cannot use the num_put<char> facet because it may produce output in
120 // a wrong encoding.
121 using facet = format_facet<std::locale>;
122 if (std::has_facet<facet>(locale))
123 return std::use_facet<facet>(locale).put(out, value, specs);
124 return facet(locale).put(out, value, specs);
125 #endif
126 return false;
127 }
128 } // namespace detail
129
130 template <typename Locale> typename Locale::id format_facet<Locale>::id;
131
132 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
format_facet(Locale & loc)133 template <typename Locale> format_facet<Locale>::format_facet(Locale& loc) {
134 auto& numpunct = std::use_facet<std::numpunct<char>>(loc);
135 grouping_ = numpunct.grouping();
136 if (!grouping_.empty()) separator_ = std::string(1, numpunct.thousands_sep());
137 }
138
139 template <>
140 FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
141 appender out, loc_value val, const format_specs<>& specs) const -> bool {
142 return val.visit(
143 detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_});
144 }
145 #endif
146
147 FMT_FUNC auto vsystem_error(int error_code, string_view fmt, format_args args)
148 -> std::system_error {
149 auto ec = std::error_code(error_code, std::generic_category());
150 return std::system_error(ec, vformat(fmt, args));
151 }
152
153 namespace detail {
154
155 template <typename F>
156 inline auto operator==(basic_fp<F> x, basic_fp<F> y) -> bool {
157 return x.f == y.f && x.e == y.e;
158 }
159
160 // Compilers should be able to optimize this into the ror instruction.
161 FMT_CONSTEXPR inline auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t {
162 r &= 31;
163 return (n >> r) | (n << (32 - r));
164 }
165 FMT_CONSTEXPR inline auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t {
166 r &= 63;
167 return (n >> r) | (n << (64 - r));
168 }
169
170 // Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox.
171 namespace dragonbox {
172 // Computes upper 64 bits of multiplication of a 32-bit unsigned integer and a
173 // 64-bit unsigned integer.
174 inline auto umul96_upper64(uint32_t x, uint64_t y) noexcept -> uint64_t {
175 return umul128_upper64(static_cast<uint64_t>(x) << 32, y);
176 }
177
178 // Computes lower 128 bits of multiplication of a 64-bit unsigned integer and a
179 // 128-bit unsigned integer.
180 inline auto umul192_lower128(uint64_t x, uint128_fallback y) noexcept
181 -> uint128_fallback {
182 uint64_t high = x * y.high();
183 uint128_fallback high_low = umul128(x, y.low());
184 return {high + high_low.high(), high_low.low()};
185 }
186
187 // Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a
188 // 64-bit unsigned integer.
189 inline auto umul96_lower64(uint32_t x, uint64_t y) noexcept -> uint64_t {
190 return x * y;
191 }
192
193 // Various fast log computations.
194 inline auto floor_log10_pow2_minus_log10_4_over_3(int e) noexcept -> int {
195 FMT_ASSERT(e <= 2936 && e >= -2985, "too large exponent");
196 return (e * 631305 - 261663) >> 21;
197 }
198
199 FMT_INLINE_VARIABLE constexpr struct {
200 uint32_t divisor;
201 int shift_amount;
202 } div_small_pow10_infos[] = {{10, 16}, {100, 16}};
203
204 // Replaces n by floor(n / pow(10, N)) returning true if and only if n is
205 // divisible by pow(10, N).
206 // Precondition: n <= pow(10, N + 1).
207 template <int N>
208 auto check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept -> bool {
209 // The numbers below are chosen such that:
210 // 1. floor(n/d) = floor(nm / 2^k) where d=10 or d=100,
211 // 2. nm mod 2^k < m if and only if n is divisible by d,
212 // where m is magic_number, k is shift_amount
213 // and d is divisor.
214 //
215 // Item 1 is a common technique of replacing division by a constant with
216 // multiplication, see e.g. "Division by Invariant Integers Using
217 // Multiplication" by Granlund and Montgomery (1994). magic_number (m) is set
218 // to ceil(2^k/d) for large enough k.
219 // The idea for item 2 originates from Schubfach.
220 constexpr auto info = div_small_pow10_infos[N - 1];
221 FMT_ASSERT(n <= info.divisor * 10, "n is too large");
222 constexpr uint32_t magic_number =
223 (1u << info.shift_amount) / info.divisor + 1;
224 n *= magic_number;
225 const uint32_t comparison_mask = (1u << info.shift_amount) - 1;
226 bool result = (n & comparison_mask) < magic_number;
227 n >>= info.shift_amount;
228 return result;
229 }
230
231 // Computes floor(n / pow(10, N)) for small n and N.
232 // Precondition: n <= pow(10, N + 1).
233 template <int N> auto small_division_by_pow10(uint32_t n) noexcept -> uint32_t {
234 constexpr auto info = div_small_pow10_infos[N - 1];
235 FMT_ASSERT(n <= info.divisor * 10, "n is too large");
236 constexpr uint32_t magic_number =
237 (1u << info.shift_amount) / info.divisor + 1;
238 return (n * magic_number) >> info.shift_amount;
239 }
240
241 // Computes floor(n / 10^(kappa + 1)) (float)
242 inline auto divide_by_10_to_kappa_plus_1(uint32_t n) noexcept -> uint32_t {
243 // 1374389535 = ceil(2^37/100)
244 return static_cast<uint32_t>((static_cast<uint64_t>(n) * 1374389535) >> 37);
245 }
246 // Computes floor(n / 10^(kappa + 1)) (double)
247 inline auto divide_by_10_to_kappa_plus_1(uint64_t n) noexcept -> uint64_t {
248 // 2361183241434822607 = ceil(2^(64+7)/1000)
249 return umul128_upper64(n, 2361183241434822607ull) >> 7;
250 }
251
252 // Various subroutines using pow10 cache
253 template <typename T> struct cache_accessor;
254
255 template <> struct cache_accessor<float> {
256 using carrier_uint = float_info<float>::carrier_uint;
257 using cache_entry_type = uint64_t;
258
259 static auto get_cached_power(int k) noexcept -> uint64_t {
260 FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k,
261 "k is out of range");
262 static constexpr const uint64_t pow10_significands[] = {
263 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,
264 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb,
265 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28,
266 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb,
267 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a,
268 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810,
269 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff,
270 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd,
271 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424,
272 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b,
273 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000,
274 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000,
275 0xc350000000000000, 0xf424000000000000, 0x9896800000000000,
276 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000,
277 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000,
278 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000,
279 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000,
280 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000,
281 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0,
282 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940985,
283 0xa18f07d736b90be6, 0xc9f2c9cd04674edf, 0xfc6f7c4045812297,
284 0x9dc5ada82b70b59e, 0xc5371912364ce306, 0xf684df56c3e01bc7,
285 0x9a130b963a6c115d, 0xc097ce7bc90715b4, 0xf0bdc21abb48db21,
286 0x96769950b50d88f5, 0xbc143fa4e250eb32, 0xeb194f8e1ae525fe,
287 0x92efd1b8d0cf37bf, 0xb7abc627050305ae, 0xe596b7b0c643c71a,
288 0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f};
289 return pow10_significands[k - float_info<float>::min_k];
290 }
291
292 struct compute_mul_result {
293 carrier_uint result;
294 bool is_integer;
295 };
296 struct compute_mul_parity_result {
297 bool parity;
298 bool is_integer;
299 };
300
301 static auto compute_mul(carrier_uint u,
302 const cache_entry_type& cache) noexcept
303 -> compute_mul_result {
304 auto r = umul96_upper64(u, cache);
305 return {static_cast<carrier_uint>(r >> 32),
306 static_cast<carrier_uint>(r) == 0};
307 }
308
309 static auto compute_delta(const cache_entry_type& cache, int beta) noexcept
310 -> uint32_t {
311 return static_cast<uint32_t>(cache >> (64 - 1 - beta));
312 }
313
314 static auto compute_mul_parity(carrier_uint two_f,
315 const cache_entry_type& cache,
316 int beta) noexcept
317 -> compute_mul_parity_result {
318 FMT_ASSERT(beta >= 1, "");
319 FMT_ASSERT(beta < 64, "");
320
321 auto r = umul96_lower64(two_f, cache);
322 return {((r >> (64 - beta)) & 1) != 0,
323 static_cast<uint32_t>(r >> (32 - beta)) == 0};
324 }
325
326 static auto compute_left_endpoint_for_shorter_interval_case(
327 const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
328 return static_cast<carrier_uint>(
329 (cache - (cache >> (num_significand_bits<float>() + 2))) >>
330 (64 - num_significand_bits<float>() - 1 - beta));
331 }
332
333 static auto compute_right_endpoint_for_shorter_interval_case(
334 const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
335 return static_cast<carrier_uint>(
336 (cache + (cache >> (num_significand_bits<float>() + 1))) >>
337 (64 - num_significand_bits<float>() - 1 - beta));
338 }
339
340 static auto compute_round_up_for_shorter_interval_case(
341 const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
342 return (static_cast<carrier_uint>(
343 cache >> (64 - num_significand_bits<float>() - 2 - beta)) +
344 1) /
345 2;
346 }
347 };
348
349 template <> struct cache_accessor<double> {
350 using carrier_uint = float_info<double>::carrier_uint;
351 using cache_entry_type = uint128_fallback;
352
353 static auto get_cached_power(int k) noexcept -> uint128_fallback {
354 FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k,
355 "k is out of range");
356
357 static constexpr const uint128_fallback pow10_significands[] = {
358 #if FMT_USE_FULL_CACHE_DRAGONBOX
359 {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
360 {0x9faacf3df73609b1, 0x77b191618c54e9ad},
361 {0xc795830d75038c1d, 0xd59df5b9ef6a2418},
362 {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e},
363 {0x9becce62836ac577, 0x4ee367f9430aec33},
364 {0xc2e801fb244576d5, 0x229c41f793cda740},
365 {0xf3a20279ed56d48a, 0x6b43527578c11110},
366 {0x9845418c345644d6, 0x830a13896b78aaaa},
367 {0xbe5691ef416bd60c, 0x23cc986bc656d554},
368 {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9},
369 {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa},
370 {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54},
371 {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69},
372 {0x91376c36d99995be, 0x23100809b9c21fa2},
373 {0xb58547448ffffb2d, 0xabd40a0c2832a78b},
374 {0xe2e69915b3fff9f9, 0x16c90c8f323f516d},
375 {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4},
376 {0xb1442798f49ffb4a, 0x99cd11cfdf41779d},
377 {0xdd95317f31c7fa1d, 0x40405643d711d584},
378 {0x8a7d3eef7f1cfc52, 0x482835ea666b2573},
379 {0xad1c8eab5ee43b66, 0xda3243650005eed0},
380 {0xd863b256369d4a40, 0x90bed43e40076a83},
381 {0x873e4f75e2224e68, 0x5a7744a6e804a292},
382 {0xa90de3535aaae202, 0x711515d0a205cb37},
383 {0xd3515c2831559a83, 0x0d5a5b44ca873e04},
384 {0x8412d9991ed58091, 0xe858790afe9486c3},
385 {0xa5178fff668ae0b6, 0x626e974dbe39a873},
386 {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
387 {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a},
388 {0xa139029f6a239f72, 0x1c1fffc1ebc44e81},
389 {0xc987434744ac874e, 0xa327ffb266b56221},
390 {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9},
391 {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa},
392 {0xc4ce17b399107c22, 0xcb550fb4384d21d4},
393 {0xf6019da07f549b2b, 0x7e2a53a146606a49},
394 {0x99c102844f94e0fb, 0x2eda7444cbfc426e},
395 {0xc0314325637a1939, 0xfa911155fefb5309},
396 {0xf03d93eebc589f88, 0x793555ab7eba27cb},
397 {0x96267c7535b763b5, 0x4bc1558b2f3458df},
398 {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17},
399 {0xea9c227723ee8bcb, 0x465e15a979c1cadd},
400 {0x92a1958a7675175f, 0x0bfacd89ec191eca},
401 {0xb749faed14125d36, 0xcef980ec671f667c},
402 {0xe51c79a85916f484, 0x82b7e12780e7401b},
403 {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811},
404 {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16},
405 {0xdfbdcece67006ac9, 0x67a791e093e1d49b},
406 {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1},
407 {0xaecc49914078536d, 0x58fae9f773886e19},
408 {0xda7f5bf590966848, 0xaf39a475506a899f},
409 {0x888f99797a5e012d, 0x6d8406c952429604},
410 {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84},
411 {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65},
412 {0x855c3be0a17fcd26, 0x5cf2eea09a550680},
413 {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},
414 {0xd0601d8efc57b08b, 0xf13b94daf124da27},
415 {0x823c12795db6ce57, 0x76c53d08d6b70859},
416 {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f},
417 {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a},
418 {0xfe5d54150b090b02, 0xd3f93b35435d7c4d},
419 {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0},
420 {0xc6b8e9b0709f109a, 0x359ab6419ca1091c},
421 {0xf867241c8cc6d4c0, 0xc30163d203c94b63},
422 {0x9b407691d7fc44f8, 0x79e0de63425dcf1e},
423 {0xc21094364dfb5636, 0x985915fc12f542e5},
424 {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e},
425 {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43},
426 {0xbd8430bd08277231, 0x50c6ff782a838354},
427 {0xece53cec4a314ebd, 0xa4f8bf5635246429},
428 {0x940f4613ae5ed136, 0x871b7795e136be9a},
429 {0xb913179899f68584, 0x28e2557b59846e40},
430 {0xe757dd7ec07426e5, 0x331aeada2fe589d0},
431 {0x9096ea6f3848984f, 0x3ff0d2c85def7622},
432 {0xb4bca50b065abe63, 0x0fed077a756b53aa},
433 {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895},
434 {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d},
435 {0xb080392cc4349dec, 0xbd8d794d96aacfb4},
436 {0xdca04777f541c567, 0xecf0d7a0fc5583a1},
437 {0x89e42caaf9491b60, 0xf41686c49db57245},
438 {0xac5d37d5b79b6239, 0x311c2875c522ced6},
439 {0xd77485cb25823ac7, 0x7d633293366b828c},
440 {0x86a8d39ef77164bc, 0xae5dff9c02033198},
441 {0xa8530886b54dbdeb, 0xd9f57f830283fdfd},
442 {0xd267caa862a12d66, 0xd072df63c324fd7c},
443 {0x8380dea93da4bc60, 0x4247cb9e59f71e6e},
444 {0xa46116538d0deb78, 0x52d9be85f074e609},
445 {0xcd795be870516656, 0x67902e276c921f8c},
446 {0x806bd9714632dff6, 0x00ba1cd8a3db53b7},
447 {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5},
448 {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce},
449 {0xfad2a4b13d1b5d6c, 0x796b805720085f82},
450 {0x9cc3a6eec6311a63, 0xcbe3303674053bb1},
451 {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d},
452 {0xf4f1b4d515acb93b, 0xee92fb5515482d45},
453 {0x991711052d8bf3c5, 0x751bdd152d4d1c4b},
454 {0xbf5cd54678eef0b6, 0xd262d45a78a0635e},
455 {0xef340a98172aace4, 0x86fb897116c87c35},
456 {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1},
457 {0xbae0a846d2195712, 0x8974836059cca10a},
458 {0xe998d258869facd7, 0x2bd1a438703fc94c},
459 {0x91ff83775423cc06, 0x7b6306a34627ddd0},
460 {0xb67f6455292cbf08, 0x1a3bc84c17b1d543},
461 {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94},
462 {0x8e938662882af53e, 0x547eb47b7282ee9d},
463 {0xb23867fb2a35b28d, 0xe99e619a4f23aa44},
464 {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5},
465 {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05},
466 {0xae0b158b4738705e, 0x9624ab50b148d446},
467 {0xd98ddaee19068c76, 0x3badd624dd9b0958},
468 {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7},
469 {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d},
470 {0xd47487cc8470652b, 0x7647c32000696720},
471 {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074},
472 {0xa5fb0a17c777cf09, 0xf468107100525891},
473 {0xcf79cc9db955c2cc, 0x7182148d4066eeb5},
474 {0x81ac1fe293d599bf, 0xc6f14cd848405531},
475 {0xa21727db38cb002f, 0xb8ada00e5a506a7d},
476 {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d},
477 {0xfd442e4688bd304a, 0x908f4a166d1da664},
478 {0x9e4a9cec15763e2e, 0x9a598e4e043287ff},
479 {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe},
480 {0xf7549530e188c128, 0xd12bee59e68ef47d},
481 {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf},
482 {0xc13a148e3032d6e7, 0xe36a52363c1faf02},
483 {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2},
484 {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba},
485 {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8},
486 {0xebdf661791d60f56, 0x111b495b3464ad22},
487 {0x936b9fcebb25c995, 0xcab10dd900beec35},
488 {0xb84687c269ef3bfb, 0x3d5d514f40eea743},
489 {0xe65829b3046b0afa, 0x0cb4a5a3112a5113},
490 {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac},
491 {0xb3f4e093db73a093, 0x59ed216765690f57},
492 {0xe0f218b8d25088b8, 0x306869c13ec3532d},
493 {0x8c974f7383725573, 0x1e414218c73a13fc},
494 {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
495 {0xdbac6c247d62a583, 0xdf45f746b74abf3a},
496 {0x894bc396ce5da772, 0x6b8bba8c328eb784},
497 {0xab9eb47c81f5114f, 0x066ea92f3f326565},
498 {0xd686619ba27255a2, 0xc80a537b0efefebe},
499 {0x8613fd0145877585, 0xbd06742ce95f5f37},
500 {0xa798fc4196e952e7, 0x2c48113823b73705},
501 {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6},
502 {0x82ef85133de648c4, 0x9a984d73dbe722fc},
503 {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb},
504 {0xcc963fee10b7d1b3, 0x318df905079926a9},
505 {0xffbbcfe994e5c61f, 0xfdf17746497f7053},
506 {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634},
507 {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1},
508 {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1},
509 {0x9c1661a651213e2d, 0x06bea10ca65c084f},
510 {0xc31bfa0fe5698db8, 0x486e494fcff30a63},
511 {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb},
512 {0x986ddb5c6b3a76b7, 0xf89629465a75e01d},
513 {0xbe89523386091465, 0xf6bbb397f1135824},
514 {0xee2ba6c0678b597f, 0x746aa07ded582e2d},
515 {0x94db483840b717ef, 0xa8c2a44eb4571cdd},
516 {0xba121a4650e4ddeb, 0x92f34d62616ce414},
517 {0xe896a0d7e51e1566, 0x77b020baf9c81d18},
518 {0x915e2486ef32cd60, 0x0ace1474dc1d122f},
519 {0xb5b5ada8aaff80b8, 0x0d819992132456bb},
520 {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a},
521 {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},
522 {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3},
523 {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf},
524 {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c},
525 {0xad4ab7112eb3929d, 0x86c16c98d2c953c7},
526 {0xd89d64d57a607744, 0xe871c7bf077ba8b8},
527 {0x87625f056c7c4a8b, 0x11471cd764ad4973},
528 {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0},
529 {0xd389b47879823479, 0x4aff1d108d4ec2c4},
530 {0x843610cb4bf160cb, 0xcedf722a585139bb},
531 {0xa54394fe1eedb8fe, 0xc2974eb4ee658829},
532 {0xce947a3da6a9273e, 0x733d226229feea33},
533 {0x811ccc668829b887, 0x0806357d5a3f5260},
534 {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8},
535 {0xc9bcff6034c13052, 0xfc89b393dd02f0b6},
536 {0xfc2c3f3841f17c67, 0xbbac2078d443ace3},
537 {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e},
538 {0xc5029163f384a931, 0x0a9e795e65d4df12},
539 {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6},
540 {0x99ea0196163fa42e, 0x504bced1bf8e4e46},
541 {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7},
542 {0xf07da27a82c37088, 0x5d767327bb4e5a4d},
543 {0x964e858c91ba2655, 0x3a6a07f8d510f870},
544 {0xbbe226efb628afea, 0x890489f70a55368c},
545 {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f},
546 {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e},
547 {0xb77ada0617e3bbcb, 0x09ce6ebb40173745},
548 {0xe55990879ddcaabd, 0xcc420a6a101d0516},
549 {0x8f57fa54c2a9eab6, 0x9fa946824a12232e},
550 {0xb32df8e9f3546564, 0x47939822dc96abfa},
551 {0xdff9772470297ebd, 0x59787e2b93bc56f8},
552 {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b},
553 {0xaefae51477a06b03, 0xede622920b6b23f2},
554 {0xdab99e59958885c4, 0xe95fab368e45ecee},
555 {0x88b402f7fd75539b, 0x11dbcb0218ebb415},
556 {0xaae103b5fcd2a881, 0xd652bdc29f26a11a},
557 {0xd59944a37c0752a2, 0x4be76d3346f04960},
558 {0x857fcae62d8493a5, 0x6f70a4400c562ddc},
559 {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953},
560 {0xd097ad07a71f26b2, 0x7e2000a41346a7a8},
561 {0x825ecc24c873782f, 0x8ed400668c0c28c9},
562 {0xa2f67f2dfa90563b, 0x728900802f0f32fb},
563 {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba},
564 {0xfea126b7d78186bc, 0xe2f610c84987bfa9},
565 {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca},
566 {0xc6ede63fa05d3143, 0x91503d1c79720dbc},
567 {0xf8a95fcf88747d94, 0x75a44c6397ce912b},
568 {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb},
569 {0xc24452da229b021b, 0xfbe85badce996169},
570 {0xf2d56790ab41c2a2, 0xfae27299423fb9c4},
571 {0x97c560ba6b0919a5, 0xdccd879fc967d41b},
572 {0xbdb6b8e905cb600f, 0x5400e987bbc1c921},
573 {0xed246723473e3813, 0x290123e9aab23b69},
574 {0x9436c0760c86e30b, 0xf9a0b6720aaf6522},
575 {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},
576 {0xe7958cb87392c2c2, 0xb60b1d1230b20e05},
577 {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3},
578 {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4},
579 {0xe2280b6c20dd5232, 0x25c6da63c38de1b1},
580 {0x8d590723948a535f, 0x579c487e5a38ad0f},
581 {0xb0af48ec79ace837, 0x2d835a9df0c6d852},
582 {0xdcdb1b2798182244, 0xf8e431456cf88e66},
583 {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900},
584 {0xac8b2d36eed2dac5, 0xe272467e3d222f40},
585 {0xd7adf884aa879177, 0x5b0ed81dcc6abb10},
586 {0x86ccbb52ea94baea, 0x98e947129fc2b4ea},
587 {0xa87fea27a539e9a5, 0x3f2398d747b36225},
588 {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae},
589 {0x83a3eeeef9153e89, 0x1953cf68300424ad},
590 {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8},
591 {0xcdb02555653131b6, 0x3792f412cb06794e},
592 {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1},
593 {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5},
594 {0xc8de047564d20a8b, 0xf245825a5a445276},
595 {0xfb158592be068d2e, 0xeed6e2f0f0d56713},
596 {0x9ced737bb6c4183d, 0x55464dd69685606c},
597 {0xc428d05aa4751e4c, 0xaa97e14c3c26b887},
598 {0xf53304714d9265df, 0xd53dd99f4b3066a9},
599 {0x993fe2c6d07b7fab, 0xe546a8038efe402a},
600 {0xbf8fdb78849a5f96, 0xde98520472bdd034},
601 {0xef73d256a5c0f77c, 0x963e66858f6d4441},
602 {0x95a8637627989aad, 0xdde7001379a44aa9},
603 {0xbb127c53b17ec159, 0x5560c018580d5d53},
604 {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7},
605 {0x9226712162ab070d, 0xcab3961304ca70e9},
606 {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23},
607 {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b},
608 {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243},
609 {0xb267ed1940f1c61c, 0x55f038b237591ed4},
610 {0xdf01e85f912e37a3, 0x6b6c46dec52f6689},
611 {0x8b61313bbabce2c6, 0x2323ac4b3b3da016},
612 {0xae397d8aa96c1b77, 0xabec975e0a0d081b},
613 {0xd9c7dced53c72255, 0x96e7bd358c904a22},
614 {0x881cea14545c7575, 0x7e50d64177da2e55},
615 {0xaa242499697392d2, 0xdde50bd1d5d0b9ea},
616 {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865},
617 {0x84ec3c97da624ab4, 0xbd5af13bef0b113f},
618 {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f},
619 {0xcfb11ead453994ba, 0x67de18eda5814af3},
620 {0x81ceb32c4b43fcf4, 0x80eacf948770ced8},
621 {0xa2425ff75e14fc31, 0xa1258379a94d028e},
622 {0xcad2f7f5359a3b3e, 0x096ee45813a04331},
623 {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd},
624 {0x9e74d1b791e07e48, 0x775ea264cf55347e},
625 {0xc612062576589dda, 0x95364afe032a819e},
626 {0xf79687aed3eec551, 0x3a83ddbd83f52205},
627 {0x9abe14cd44753b52, 0xc4926a9672793543},
628 {0xc16d9a0095928a27, 0x75b7053c0f178294},
629 {0xf1c90080baf72cb1, 0x5324c68b12dd6339},
630 {0x971da05074da7bee, 0xd3f6fc16ebca5e04},
631 {0xbce5086492111aea, 0x88f4bb1ca6bcf585},
632 {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6},
633 {0x9392ee8e921d5d07, 0x3aff322e62439fd0},
634 {0xb877aa3236a4b449, 0x09befeb9fad487c3},
635 {0xe69594bec44de15b, 0x4c2ebe687989a9b4},
636 {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11},
637 {0xb424dc35095cd80f, 0x538484c19ef38c95},
638 {0xe12e13424bb40e13, 0x2865a5f206b06fba},
639 {0x8cbccc096f5088cb, 0xf93f87b7442e45d4},
640 {0xafebff0bcb24aafe, 0xf78f69a51539d749},
641 {0xdbe6fecebdedd5be, 0xb573440e5a884d1c},
642 {0x89705f4136b4a597, 0x31680a88f8953031},
643 {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e},
644 {0xd6bf94d5e57a42bc, 0x3d32907604691b4d},
645 {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110},
646 {0xa7c5ac471b478423, 0x0fcf80dc33721d54},
647 {0xd1b71758e219652b, 0xd3c36113404ea4a9},
648 {0x83126e978d4fdf3b, 0x645a1cac083126ea},
649 {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4},
650 {0xcccccccccccccccc, 0xcccccccccccccccd},
651 {0x8000000000000000, 0x0000000000000000},
652 {0xa000000000000000, 0x0000000000000000},
653 {0xc800000000000000, 0x0000000000000000},
654 {0xfa00000000000000, 0x0000000000000000},
655 {0x9c40000000000000, 0x0000000000000000},
656 {0xc350000000000000, 0x0000000000000000},
657 {0xf424000000000000, 0x0000000000000000},
658 {0x9896800000000000, 0x0000000000000000},
659 {0xbebc200000000000, 0x0000000000000000},
660 {0xee6b280000000000, 0x0000000000000000},
661 {0x9502f90000000000, 0x0000000000000000},
662 {0xba43b74000000000, 0x0000000000000000},
663 {0xe8d4a51000000000, 0x0000000000000000},
664 {0x9184e72a00000000, 0x0000000000000000},
665 {0xb5e620f480000000, 0x0000000000000000},
666 {0xe35fa931a0000000, 0x0000000000000000},
667 {0x8e1bc9bf04000000, 0x0000000000000000},
668 {0xb1a2bc2ec5000000, 0x0000000000000000},
669 {0xde0b6b3a76400000, 0x0000000000000000},
670 {0x8ac7230489e80000, 0x0000000000000000},
671 {0xad78ebc5ac620000, 0x0000000000000000},
672 {0xd8d726b7177a8000, 0x0000000000000000},
673 {0x878678326eac9000, 0x0000000000000000},
674 {0xa968163f0a57b400, 0x0000000000000000},
675 {0xd3c21bcecceda100, 0x0000000000000000},
676 {0x84595161401484a0, 0x0000000000000000},
677 {0xa56fa5b99019a5c8, 0x0000000000000000},
678 {0xcecb8f27f4200f3a, 0x0000000000000000},
679 {0x813f3978f8940984, 0x4000000000000000},
680 {0xa18f07d736b90be5, 0x5000000000000000},
681 {0xc9f2c9cd04674ede, 0xa400000000000000},
682 {0xfc6f7c4045812296, 0x4d00000000000000},
683 {0x9dc5ada82b70b59d, 0xf020000000000000},
684 {0xc5371912364ce305, 0x6c28000000000000},
685 {0xf684df56c3e01bc6, 0xc732000000000000},
686 {0x9a130b963a6c115c, 0x3c7f400000000000},
687 {0xc097ce7bc90715b3, 0x4b9f100000000000},
688 {0xf0bdc21abb48db20, 0x1e86d40000000000},
689 {0x96769950b50d88f4, 0x1314448000000000},
690 {0xbc143fa4e250eb31, 0x17d955a000000000},
691 {0xeb194f8e1ae525fd, 0x5dcfab0800000000},
692 {0x92efd1b8d0cf37be, 0x5aa1cae500000000},
693 {0xb7abc627050305ad, 0xf14a3d9e40000000},
694 {0xe596b7b0c643c719, 0x6d9ccd05d0000000},
695 {0x8f7e32ce7bea5c6f, 0xe4820023a2000000},
696 {0xb35dbf821ae4f38b, 0xdda2802c8a800000},
697 {0xe0352f62a19e306e, 0xd50b2037ad200000},
698 {0x8c213d9da502de45, 0x4526f422cc340000},
699 {0xaf298d050e4395d6, 0x9670b12b7f410000},
700 {0xdaf3f04651d47b4c, 0x3c0cdd765f114000},
701 {0x88d8762bf324cd0f, 0xa5880a69fb6ac800},
702 {0xab0e93b6efee0053, 0x8eea0d047a457a00},
703 {0xd5d238a4abe98068, 0x72a4904598d6d880},
704 {0x85a36366eb71f041, 0x47a6da2b7f864750},
705 {0xa70c3c40a64e6c51, 0x999090b65f67d924},
706 {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d},
707 {0x82818f1281ed449f, 0xbff8f10e7a8921a5},
708 {0xa321f2d7226895c7, 0xaff72d52192b6a0e},
709 {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764491},
710 {0xfee50b7025c36a08, 0x02f236d04753d5b5},
711 {0x9f4f2726179a2245, 0x01d762422c946591},
712 {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef6},
713 {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb3},
714 {0x9b934c3b330c8577, 0x63cc55f49f88eb30},
715 {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fc},
716 {0xf316271c7fc3908a, 0x8bef464e3945ef7b},
717 {0x97edd871cfda3a56, 0x97758bf0e3cbb5ad},
718 {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea318},
719 {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bde},
720 {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6b},
721 {0xb975d6b6ee39e436, 0xb3e2fd538e122b45},
722 {0xe7d34c64a9c85d44, 0x60dbbca87196b617},
723 {0x90e40fbeea1d3a4a, 0xbc8955e946fe31ce},
724 {0xb51d13aea4a488dd, 0x6babab6398bdbe42},
725 {0xe264589a4dcdab14, 0xc696963c7eed2dd2},
726 {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca3},
727 {0xb0de65388cc8ada8, 0x3b25a55f43294bcc},
728 {0xdd15fe86affad912, 0x49ef0eb713f39ebf},
729 {0x8a2dbf142dfcc7ab, 0x6e3569326c784338},
730 {0xacb92ed9397bf996, 0x49c2c37f07965405},
731 {0xd7e77a8f87daf7fb, 0xdc33745ec97be907},
732 {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a4},
733 {0xa8acd7c0222311bc, 0xc40832ea0d68ce0d},
734 {0xd2d80db02aabd62b, 0xf50a3fa490c30191},
735 {0x83c7088e1aab65db, 0x792667c6da79e0fb},
736 {0xa4b8cab1a1563f52, 0x577001b891185939},
737 {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87},
738 {0x80b05e5ac60b6178, 0x544f8158315b05b5},
739 {0xa0dc75f1778e39d6, 0x696361ae3db1c722},
740 {0xc913936dd571c84c, 0x03bc3a19cd1e38ea},
741 {0xfb5878494ace3a5f, 0x04ab48a04065c724},
742 {0x9d174b2dcec0e47b, 0x62eb0d64283f9c77},
743 {0xc45d1df942711d9a, 0x3ba5d0bd324f8395},
744 {0xf5746577930d6500, 0xca8f44ec7ee3647a},
745 {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecc},
746 {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67f},
747 {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101f},
748 {0x95d04aee3b80ece5, 0xbba1f1d158724a13},
749 {0xbb445da9ca61281f, 0x2a8a6e45ae8edc98},
750 {0xea1575143cf97226, 0xf52d09d71a3293be},
751 {0x924d692ca61be758, 0x593c2626705f9c57},
752 {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836d},
753 {0xe498f455c38b997a, 0x0b6dfb9c0f956448},
754 {0x8edf98b59a373fec, 0x4724bd4189bd5ead},
755 {0xb2977ee300c50fe7, 0x58edec91ec2cb658},
756 {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ee},
757 {0x8b865b215899f46c, 0xbd79e0d20082ee75},
758 {0xae67f1e9aec07187, 0xecd8590680a3aa12},
759 {0xda01ee641a708de9, 0xe80e6f4820cc9496},
760 {0x884134fe908658b2, 0x3109058d147fdcde},
761 {0xaa51823e34a7eede, 0xbd4b46f0599fd416},
762 {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91b},
763 {0x850fadc09923329e, 0x03e2cf6bc604ddb1},
764 {0xa6539930bf6bff45, 0x84db8346b786151d},
765 {0xcfe87f7cef46ff16, 0xe612641865679a64},
766 {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07f},
767 {0xa26da3999aef7749, 0xe3be5e330f38f09e},
768 {0xcb090c8001ab551c, 0x5cadf5bfd3072cc6},
769 {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f7},
770 {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afb},
771 {0xc646d63501a1511d, 0xb281e1fd541501b9},
772 {0xf7d88bc24209a565, 0x1f225a7ca91a4227},
773 {0x9ae757596946075f, 0x3375788de9b06959},
774 {0xc1a12d2fc3978937, 0x0052d6b1641c83af},
775 {0xf209787bb47d6b84, 0xc0678c5dbd23a49b},
776 {0x9745eb4d50ce6332, 0xf840b7ba963646e1},
777 {0xbd176620a501fbff, 0xb650e5a93bc3d899},
778 {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebf},
779 {0x93ba47c980e98cdf, 0xc66f336c36b10138},
780 {0xb8a8d9bbe123f017, 0xb80b0047445d4185},
781 {0xe6d3102ad96cec1d, 0xa60dc059157491e6},
782 {0x9043ea1ac7e41392, 0x87c89837ad68db30},
783 {0xb454e4a179dd1877, 0x29babe4598c311fc},
784 {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67b},
785 {0x8ce2529e2734bb1d, 0x1899e4a65f58660d},
786 {0xb01ae745b101e9e4, 0x5ec05dcff72e7f90},
787 {0xdc21a1171d42645d, 0x76707543f4fa1f74},
788 {0x899504ae72497eba, 0x6a06494a791c53a9},
789 {0xabfa45da0edbde69, 0x0487db9d17636893},
790 {0xd6f8d7509292d603, 0x45a9d2845d3c42b7},
791 {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3},
792 {0xa7f26836f282b732, 0x8e6cac7768d7141f},
793 {0xd1ef0244af2364ff, 0x3207d795430cd927},
794 {0x8335616aed761f1f, 0x7f44e6bd49e807b9},
795 {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a7},
796 {0xcd036837130890a1, 0x36dba887c37a8c10},
797 {0x802221226be55a64, 0xc2494954da2c978a},
798 {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6d},
799 {0xc83553c5c8965d3d, 0x6f92829494e5acc8},
800 {0xfa42a8b73abbf48c, 0xcb772339ba1f17fa},
801 {0x9c69a97284b578d7, 0xff2a760414536efc},
802 {0xc38413cf25e2d70d, 0xfef5138519684abb},
803 {0xf46518c2ef5b8cd1, 0x7eb258665fc25d6a},
804 {0x98bf2f79d5993802, 0xef2f773ffbd97a62},
805 {0xbeeefb584aff8603, 0xaafb550ffacfd8fb},
806 {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf39},
807 {0x952ab45cfa97a0b2, 0xdd945a747bf26184},
808 {0xba756174393d88df, 0x94f971119aeef9e5},
809 {0xe912b9d1478ceb17, 0x7a37cd5601aab85e},
810 {0x91abb422ccb812ee, 0xac62e055c10ab33b},
811 {0xb616a12b7fe617aa, 0x577b986b314d600a},
812 {0xe39c49765fdf9d94, 0xed5a7e85fda0b80c},
813 {0x8e41ade9fbebc27d, 0x14588f13be847308},
814 {0xb1d219647ae6b31c, 0x596eb2d8ae258fc9},
815 {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bc},
816 {0x8aec23d680043bee, 0x25de7bb9480d5855},
817 {0xada72ccc20054ae9, 0xaf561aa79a10ae6b},
818 {0xd910f7ff28069da4, 0x1b2ba1518094da05},
819 {0x87aa9aff79042286, 0x90fb44d2f05d0843},
820 {0xa99541bf57452b28, 0x353a1607ac744a54},
821 {0xd3fa922f2d1675f2, 0x42889b8997915ce9},
822 {0x847c9b5d7c2e09b7, 0x69956135febada12},
823 {0xa59bc234db398c25, 0x43fab9837e699096},
824 {0xcf02b2c21207ef2e, 0x94f967e45e03f4bc},
825 {0x8161afb94b44f57d, 0x1d1be0eebac278f6},
826 {0xa1ba1ba79e1632dc, 0x6462d92a69731733},
827 {0xca28a291859bbf93, 0x7d7b8f7503cfdcff},
828 {0xfcb2cb35e702af78, 0x5cda735244c3d43f},
829 {0x9defbf01b061adab, 0x3a0888136afa64a8},
830 {0xc56baec21c7a1916, 0x088aaa1845b8fdd1},
831 {0xf6c69a72a3989f5b, 0x8aad549e57273d46},
832 {0x9a3c2087a63f6399, 0x36ac54e2f678864c},
833 {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7de},
834 {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d6},
835 {0x969eb7c47859e743, 0x9f644ae5a4b1b326},
836 {0xbc4665b596706114, 0x873d5d9f0dde1fef},
837 {0xeb57ff22fc0c7959, 0xa90cb506d155a7eb},
838 {0x9316ff75dd87cbd8, 0x09a7f12442d588f3},
839 {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30},
840 {0xe5d3ef282a242e81, 0x8f1668c8a86da5fb},
841 {0x8fa475791a569d10, 0xf96e017d694487bd},
842 {0xb38d92d760ec4455, 0x37c981dcc395a9ad},
843 {0xe070f78d3927556a, 0x85bbe253f47b1418},
844 {0x8c469ab843b89562, 0x93956d7478ccec8f},
845 {0xaf58416654a6babb, 0x387ac8d1970027b3},
846 {0xdb2e51bfe9d0696a, 0x06997b05fcc0319f},
847 {0x88fcf317f22241e2, 0x441fece3bdf81f04},
848 {0xab3c2fddeeaad25a, 0xd527e81cad7626c4},
849 {0xd60b3bd56a5586f1, 0x8a71e223d8d3b075},
850 {0x85c7056562757456, 0xf6872d5667844e4a},
851 {0xa738c6bebb12d16c, 0xb428f8ac016561dc},
852 {0xd106f86e69d785c7, 0xe13336d701beba53},
853 {0x82a45b450226b39c, 0xecc0024661173474},
854 {0xa34d721642b06084, 0x27f002d7f95d0191},
855 {0xcc20ce9bd35c78a5, 0x31ec038df7b441f5},
856 {0xff290242c83396ce, 0x7e67047175a15272},
857 {0x9f79a169bd203e41, 0x0f0062c6e984d387},
858 {0xc75809c42c684dd1, 0x52c07b78a3e60869},
859 {0xf92e0c3537826145, 0xa7709a56ccdf8a83},
860 {0x9bbcc7a142b17ccb, 0x88a66076400bb692},
861 {0xc2abf989935ddbfe, 0x6acff893d00ea436},
862 {0xf356f7ebf83552fe, 0x0583f6b8c4124d44},
863 {0x98165af37b2153de, 0xc3727a337a8b704b},
864 {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5d},
865 {0xeda2ee1c7064130c, 0x1162def06f79df74},
866 {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba9},
867 {0xb9a74a0637ce2ee1, 0x6d953e2bd7173693},
868 {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0438},
869 {0x910ab1d4db9914a0, 0x1d9c9892400a22a3},
870 {0xb54d5e4a127f59c8, 0x2503beb6d00cab4c},
871 {0xe2a0b5dc971f303a, 0x2e44ae64840fd61e},
872 {0x8da471a9de737e24, 0x5ceaecfed289e5d3},
873 {0xb10d8e1456105dad, 0x7425a83e872c5f48},
874 {0xdd50f1996b947518, 0xd12f124e28f7771a},
875 {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa70},
876 {0xace73cbfdc0bfb7b, 0x636cc64d1001550c},
877 {0xd8210befd30efa5a, 0x3c47f7e05401aa4f},
878 {0x8714a775e3e95c78, 0x65acfaec34810a72},
879 {0xa8d9d1535ce3b396, 0x7f1839a741a14d0e},
880 {0xd31045a8341ca07c, 0x1ede48111209a051},
881 {0x83ea2b892091e44d, 0x934aed0aab460433},
882 {0xa4e4b66b68b65d60, 0xf81da84d56178540},
883 {0xce1de40642e3f4b9, 0x36251260ab9d668f},
884 {0x80d2ae83e9ce78f3, 0xc1d72b7c6b42601a},
885 {0xa1075a24e4421730, 0xb24cf65b8612f820},
886 {0xc94930ae1d529cfc, 0xdee033f26797b628},
887 {0xfb9b7cd9a4a7443c, 0x169840ef017da3b2},
888 {0x9d412e0806e88aa5, 0x8e1f289560ee864f},
889 {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e3},
890 {0xf5b5d7ec8acb58a2, 0xae10af696774b1dc},
891 {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef2a},
892 {0xbff610b0cc6edd3f, 0x17fd090a58d32af4},
893 {0xeff394dcff8a948e, 0xddfc4b4cef07f5b1},
894 {0x95f83d0a1fb69cd9, 0x4abdaf101564f98f},
895 {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f2},
896 {0xea53df5fd18d5513, 0x84c86189216dc5ee},
897 {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb5},
898 {0xb7118682dbb66a77, 0x3fbc8c33221dc2a2},
899 {0xe4d5e82392a40515, 0x0fabaf3feaa5334b},
900 {0x8f05b1163ba6832d, 0x29cb4d87f2a7400f},
901 {0xb2c71d5bca9023f8, 0x743e20e9ef511013},
902 {0xdf78e4b2bd342cf6, 0x914da9246b255417},
903 {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f},
904 {0xae9672aba3d0c320, 0xa184ac2473b529b2},
905 {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741f},
906 {0x8865899617fb1871, 0x7e2fa67c7a658893},
907 {0xaa7eebfb9df9de8d, 0xddbb901b98feeab8},
908 {0xd51ea6fa85785631, 0x552a74227f3ea566},
909 {0x8533285c936b35de, 0xd53a88958f872760},
910 {0xa67ff273b8460356, 0x8a892abaf368f138},
911 {0xd01fef10a657842c, 0x2d2b7569b0432d86},
912 {0x8213f56a67f6b29b, 0x9c3b29620e29fc74},
913 {0xa298f2c501f45f42, 0x8349f3ba91b47b90},
914 {0xcb3f2f7642717713, 0x241c70a936219a74},
915 {0xfe0efb53d30dd4d7, 0xed238cd383aa0111},
916 {0x9ec95d1463e8a506, 0xf4363804324a40ab},
917 {0xc67bb4597ce2ce48, 0xb143c6053edcd0d6},
918 {0xf81aa16fdc1b81da, 0xdd94b7868e94050b},
919 {0x9b10a4e5e9913128, 0xca7cf2b4191c8327},
920 {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f1},
921 {0xf24a01a73cf2dccf, 0xbc633b39673c8ced},
922 {0x976e41088617ca01, 0xd5be0503e085d814},
923 {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e19},
924 {0xec9c459d51852ba2, 0xddf8e7d60ed1219f},
925 {0x93e1ab8252f33b45, 0xcabb90e5c942b504},
926 {0xb8da1662e7b00a17, 0x3d6a751f3b936244},
927 {0xe7109bfba19c0c9d, 0x0cc512670a783ad5},
928 {0x906a617d450187e2, 0x27fb2b80668b24c6},
929 {0xb484f9dc9641e9da, 0xb1f9f660802dedf7},
930 {0xe1a63853bbd26451, 0x5e7873f8a0396974},
931 {0x8d07e33455637eb2, 0xdb0b487b6423e1e9},
932 {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda63},
933 {0xdc5c5301c56b75f7, 0x7641a140cc7810fc},
934 {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9e},
935 {0xac2820d9623bf429, 0x546345fa9fbdcd45},
936 {0xd732290fbacaf133, 0xa97c177947ad4096},
937 {0x867f59a9d4bed6c0, 0x49ed8eabcccc485e},
938 {0xa81f301449ee8c70, 0x5c68f256bfff5a75},
939 {0xd226fc195c6a2f8c, 0x73832eec6fff3112},
940 {0x83585d8fd9c25db7, 0xc831fd53c5ff7eac},
941 {0xa42e74f3d032f525, 0xba3e7ca8b77f5e56},
942 {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35ec},
943 {0x80444b5e7aa7cf85, 0x7980d163cf5b81b4},
944 {0xa0555e361951c366, 0xd7e105bcc3326220},
945 {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa8},
946 {0xfa856334878fc150, 0xb14f98f6f0feb952},
947 {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d4},
948 {0xc3b8358109e84f07, 0x0a862f80ec4700c9},
949 {0xf4a642e14c6262c8, 0xcd27bb612758c0fb},
950 {0x98e7e9cccfbd7dbd, 0x8038d51cb897789d},
951 {0xbf21e44003acdd2c, 0xe0470a63e6bd56c4},
952 {0xeeea5d5004981478, 0x1858ccfce06cac75},
953 {0x95527a5202df0ccb, 0x0f37801e0c43ebc9},
954 {0xbaa718e68396cffd, 0xd30560258f54e6bb},
955 {0xe950df20247c83fd, 0x47c6b82ef32a206a},
956 {0x91d28b7416cdd27e, 0x4cdc331d57fa5442},
957 {0xb6472e511c81471d, 0xe0133fe4adf8e953},
958 {0xe3d8f9e563a198e5, 0x58180fddd97723a7},
959 {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7649},
960 {0xb201833b35d63f73, 0x2cd2cc6551e513db},
961 {0xde81e40a034bcf4f, 0xf8077f7ea65e58d2},
962 {0x8b112e86420f6191, 0xfb04afaf27faf783},
963 {0xadd57a27d29339f6, 0x79c5db9af1f9b564},
964 {0xd94ad8b1c7380874, 0x18375281ae7822bd},
965 {0x87cec76f1c830548, 0x8f2293910d0b15b6},
966 {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb23},
967 {0xd433179d9c8cb841, 0x5fa60692a46151ec},
968 {0x849feec281d7f328, 0xdbc7c41ba6bcd334},
969 {0xa5c7ea73224deff3, 0x12b9b522906c0801},
970 {0xcf39e50feae16bef, 0xd768226b34870a01},
971 {0x81842f29f2cce375, 0xe6a1158300d46641},
972 {0xa1e53af46f801c53, 0x60495ae3c1097fd1},
973 {0xca5e89b18b602368, 0x385bb19cb14bdfc5},
974 {0xfcf62c1dee382c42, 0x46729e03dd9ed7b6},
975 {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d2},
976 {0xc5a05277621be293, 0xc7098b7305241886},
977 {0xf70867153aa2db38, 0xb8cbee4fc66d1ea8},
978 {0x9a65406d44a5c903, 0x737f74f1dc043329},
979 {0xc0fe908895cf3b44, 0x505f522e53053ff3},
980 {0xf13e34aabb430a15, 0x647726b9e7c68ff0},
981 {0x96c6e0eab509e64d, 0x5eca783430dc19f6},
982 {0xbc789925624c5fe0, 0xb67d16413d132073},
983 {0xeb96bf6ebadf77d8, 0xe41c5bd18c57e890},
984 {0x933e37a534cbaae7, 0x8e91b962f7b6f15a},
985 {0xb80dc58e81fe95a1, 0x723627bbb5a4adb1},
986 {0xe61136f2227e3b09, 0xcec3b1aaa30dd91d},
987 {0x8fcac257558ee4e6, 0x213a4f0aa5e8a7b2},
988 {0xb3bd72ed2af29e1f, 0xa988e2cd4f62d19e},
989 {0xe0accfa875af45a7, 0x93eb1b80a33b8606},
990 {0x8c6c01c9498d8b88, 0xbc72f130660533c4},
991 {0xaf87023b9bf0ee6a, 0xeb8fad7c7f8680b5},
992 {0xdb68c2ca82ed2a05, 0xa67398db9f6820e2},
993 #else
994 {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
995 {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
996 {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},
997 {0x86a8d39ef77164bc, 0xae5dff9c02033198},
998 {0xd98ddaee19068c76, 0x3badd624dd9b0958},
999 {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
1000 {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},
1001 {0xe55990879ddcaabd, 0xcc420a6a101d0516},
1002 {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},
1003 {0x95a8637627989aad, 0xdde7001379a44aa9},
1004 {0xf1c90080baf72cb1, 0x5324c68b12dd6339},
1005 {0xc350000000000000, 0x0000000000000000},
1006 {0x9dc5ada82b70b59d, 0xf020000000000000},
1007 {0xfee50b7025c36a08, 0x02f236d04753d5b5},
1008 {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87},
1009 {0xa6539930bf6bff45, 0x84db8346b786151d},
1010 {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3},
1011 {0xd910f7ff28069da4, 0x1b2ba1518094da05},
1012 {0xaf58416654a6babb, 0x387ac8d1970027b3},
1013 {0x8da471a9de737e24, 0x5ceaecfed289e5d3},
1014 {0xe4d5e82392a40515, 0x0fabaf3feaa5334b},
1015 {0xb8da1662e7b00a17, 0x3d6a751f3b936244},
1016 {0x95527a5202df0ccb, 0x0f37801e0c43ebc9},
1017 {0xf13e34aabb430a15, 0x647726b9e7c68ff0}
1018 #endif
1019 };
1020
1021 #if FMT_USE_FULL_CACHE_DRAGONBOX
1022 return pow10_significands[k - float_info<double>::min_k];
1023 #else
1024 static constexpr const uint64_t powers_of_5_64[] = {
1025 0x0000000000000001, 0x0000000000000005, 0x0000000000000019,
1026 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35,
1027 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1,
1028 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd,
1029 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9,
1030 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5,
1031 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631,
1032 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed,
1033 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9};
1034
1035 static const int compression_ratio = 27;
1036
1037 // Compute base index.
1038 int cache_index = (k - float_info<double>::min_k) / compression_ratio;
1039 int kb = cache_index * compression_ratio + float_info<double>::min_k;
1040 int offset = k - kb;
1041
1042 // Get base cache.
1043 uint128_fallback base_cache = pow10_significands[cache_index];
1044 if (offset == 0) return base_cache;
1045
1046 // Compute the required amount of bit-shift.
1047 int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset;
1048 FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected");
1049
1050 // Try to recover the real cache.
1051 uint64_t pow5 = powers_of_5_64[offset];
1052 uint128_fallback recovered_cache = umul128(base_cache.high(), pow5);
1053 uint128_fallback middle_low = umul128(base_cache.low(), pow5);
1054
1055 recovered_cache += middle_low.high();
1056
1057 uint64_t high_to_middle = recovered_cache.high() << (64 - alpha);
1058 uint64_t middle_to_low = recovered_cache.low() << (64 - alpha);
1059
1060 recovered_cache =
1061 uint128_fallback{(recovered_cache.low() >> alpha) | high_to_middle,
1062 ((middle_low.low() >> alpha) | middle_to_low)};
1063 FMT_ASSERT(recovered_cache.low() + 1 != 0, "");
1064 return {recovered_cache.high(), recovered_cache.low() + 1};
1065 #endif
1066 }
1067
1068 struct compute_mul_result {
1069 carrier_uint result;
1070 bool is_integer;
1071 };
1072 struct compute_mul_parity_result {
1073 bool parity;
1074 bool is_integer;
1075 };
1076
1077 static auto compute_mul(carrier_uint u,
1078 const cache_entry_type& cache) noexcept
1079 -> compute_mul_result {
1080 auto r = umul192_upper128(u, cache);
1081 return {r.high(), r.low() == 0};
1082 }
1083
1084 static auto compute_delta(cache_entry_type const& cache, int beta) noexcept
1085 -> uint32_t {
1086 return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta));
1087 }
1088
1089 static auto compute_mul_parity(carrier_uint two_f,
1090 const cache_entry_type& cache,
1091 int beta) noexcept
1092 -> compute_mul_parity_result {
1093 FMT_ASSERT(beta >= 1, "");
1094 FMT_ASSERT(beta < 64, "");
1095
1096 auto r = umul192_lower128(two_f, cache);
1097 return {((r.high() >> (64 - beta)) & 1) != 0,
1098 ((r.high() << beta) | (r.low() >> (64 - beta))) == 0};
1099 }
1100
1101 static auto compute_left_endpoint_for_shorter_interval_case(
1102 const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
1103 return (cache.high() -
1104 (cache.high() >> (num_significand_bits<double>() + 2))) >>
1105 (64 - num_significand_bits<double>() - 1 - beta);
1106 }
1107
1108 static auto compute_right_endpoint_for_shorter_interval_case(
1109 const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
1110 return (cache.high() +
1111 (cache.high() >> (num_significand_bits<double>() + 1))) >>
1112 (64 - num_significand_bits<double>() - 1 - beta);
1113 }
1114
1115 static auto compute_round_up_for_shorter_interval_case(
1116 const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
1117 return ((cache.high() >> (64 - num_significand_bits<double>() - 2 - beta)) +
1118 1) /
1119 2;
1120 }
1121 };
1122
1123 FMT_FUNC auto get_cached_power(int k) noexcept -> uint128_fallback {
1124 return cache_accessor<double>::get_cached_power(k);
1125 }
1126
1127 // Various integer checks
1128 template <typename T>
1129 auto is_left_endpoint_integer_shorter_interval(int exponent) noexcept -> bool {
1130 const int case_shorter_interval_left_endpoint_lower_threshold = 2;
1131 const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1132 return exponent >= case_shorter_interval_left_endpoint_lower_threshold &&
1133 exponent <= case_shorter_interval_left_endpoint_upper_threshold;
1134 }
1135
1136 // Remove trailing zeros from n and return the number of zeros removed (float)
1137 FMT_INLINE int remove_trailing_zeros(uint32_t& n, int s = 0) noexcept {
1138 FMT_ASSERT(n != 0, "");
1139 // Modular inverse of 5 (mod 2^32): (mod_inv_5 * 5) mod 2^32 = 1.
1140 constexpr uint32_t mod_inv_5 = 0xcccccccd;
1141 constexpr uint32_t mod_inv_25 = 0xc28f5c29; // = mod_inv_5 * mod_inv_5
1142
1143 while (true) {
1144 auto q = rotr(n * mod_inv_25, 2);
1145 if (q > max_value<uint32_t>() / 100) break;
1146 n = q;
1147 s += 2;
1148 }
1149 auto q = rotr(n * mod_inv_5, 1);
1150 if (q <= max_value<uint32_t>() / 10) {
1151 n = q;
1152 s |= 1;
1153 }
1154 return s;
1155 }
1156
1157 // Removes trailing zeros and returns the number of zeros removed (double)
1158 FMT_INLINE int remove_trailing_zeros(uint64_t& n) noexcept {
1159 FMT_ASSERT(n != 0, "");
1160
1161 // This magic number is ceil(2^90 / 10^8).
1162 constexpr uint64_t magic_number = 12379400392853802749ull;
1163 auto nm = umul128(n, magic_number);
1164
1165 // Is n is divisible by 10^8?
1166 if ((nm.high() & ((1ull << (90 - 64)) - 1)) == 0 && nm.low() < magic_number) {
1167 // If yes, work with the quotient...
1168 auto n32 = static_cast<uint32_t>(nm.high() >> (90 - 64));
1169 // ... and use the 32 bit variant of the function
1170 int s = remove_trailing_zeros(n32, 8);
1171 n = n32;
1172 return s;
1173 }
1174
1175 // If n is not divisible by 10^8, work with n itself.
1176 constexpr uint64_t mod_inv_5 = 0xcccccccccccccccd;
1177 constexpr uint64_t mod_inv_25 = 0x8f5c28f5c28f5c29; // mod_inv_5 * mod_inv_5
1178
1179 int s = 0;
1180 while (true) {
1181 auto q = rotr(n * mod_inv_25, 2);
1182 if (q > max_value<uint64_t>() / 100) break;
1183 n = q;
1184 s += 2;
1185 }
1186 auto q = rotr(n * mod_inv_5, 1);
1187 if (q <= max_value<uint64_t>() / 10) {
1188 n = q;
1189 s |= 1;
1190 }
1191
1192 return s;
1193 }
1194
1195 // The main algorithm for shorter interval case
1196 template <typename T>
1197 FMT_INLINE decimal_fp<T> shorter_interval_case(int exponent) noexcept {
1198 decimal_fp<T> ret_value;
1199 // Compute k and beta
1200 const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent);
1201 const int beta = exponent + floor_log2_pow10(-minus_k);
1202
1203 // Compute xi and zi
1204 using cache_entry_type = typename cache_accessor<T>::cache_entry_type;
1205 const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);
1206
1207 auto xi = cache_accessor<T>::compute_left_endpoint_for_shorter_interval_case(
1208 cache, beta);
1209 auto zi = cache_accessor<T>::compute_right_endpoint_for_shorter_interval_case(
1210 cache, beta);
1211
1212 // If the left endpoint is not an integer, increase it
1213 if (!is_left_endpoint_integer_shorter_interval<T>(exponent)) ++xi;
1214
1215 // Try bigger divisor
1216 ret_value.significand = zi / 10;
1217
1218 // If succeed, remove trailing zeros if necessary and return
1219 if (ret_value.significand * 10 >= xi) {
1220 ret_value.exponent = minus_k + 1;
1221 ret_value.exponent += remove_trailing_zeros(ret_value.significand);
1222 return ret_value;
1223 }
1224
1225 // Otherwise, compute the round-up of y
1226 ret_value.significand =
1227 cache_accessor<T>::compute_round_up_for_shorter_interval_case(cache,
1228 beta);
1229 ret_value.exponent = minus_k;
1230
1231 // When tie occurs, choose one of them according to the rule
1232 if (exponent >= float_info<T>::shorter_interval_tie_lower_threshold &&
1233 exponent <= float_info<T>::shorter_interval_tie_upper_threshold) {
1234 ret_value.significand = ret_value.significand % 2 == 0
1235 ? ret_value.significand
1236 : ret_value.significand - 1;
1237 } else if (ret_value.significand < xi) {
1238 ++ret_value.significand;
1239 }
1240 return ret_value;
1241 }
1242
1243 template <typename T> auto to_decimal(T x) noexcept -> decimal_fp<T> {
1244 // Step 1: integer promotion & Schubfach multiplier calculation.
1245
1246 using carrier_uint = typename float_info<T>::carrier_uint;
1247 using cache_entry_type = typename cache_accessor<T>::cache_entry_type;
1248 auto br = bit_cast<carrier_uint>(x);
1249
1250 // Extract significand bits and exponent bits.
1251 const carrier_uint significand_mask =
1252 (static_cast<carrier_uint>(1) << num_significand_bits<T>()) - 1;
1253 carrier_uint significand = (br & significand_mask);
1254 int exponent =
1255 static_cast<int>((br & exponent_mask<T>()) >> num_significand_bits<T>());
1256
1257 if (exponent != 0) { // Check if normal.
1258 exponent -= exponent_bias<T>() + num_significand_bits<T>();
1259
1260 // Shorter interval case; proceed like Schubfach.
1261 // In fact, when exponent == 1 and significand == 0, the interval is
1262 // regular. However, it can be shown that the end-results are anyway same.
1263 if (significand == 0) return shorter_interval_case<T>(exponent);
1264
1265 significand |= (static_cast<carrier_uint>(1) << num_significand_bits<T>());
1266 } else {
1267 // Subnormal case; the interval is always regular.
1268 if (significand == 0) return {0, 0};
1269 exponent =
1270 std::numeric_limits<T>::min_exponent - num_significand_bits<T>() - 1;
1271 }
1272
1273 const bool include_left_endpoint = (significand % 2 == 0);
1274 const bool include_right_endpoint = include_left_endpoint;
1275
1276 // Compute k and beta.
1277 const int minus_k = floor_log10_pow2(exponent) - float_info<T>::kappa;
1278 const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);
1279 const int beta = exponent + floor_log2_pow10(-minus_k);
1280
1281 // Compute zi and deltai.
1282 // 10^kappa <= deltai < 10^(kappa + 1)
1283 const uint32_t deltai = cache_accessor<T>::compute_delta(cache, beta);
1284 const carrier_uint two_fc = significand << 1;
1285
1286 // For the case of binary32, the result of integer check is not correct for
1287 // 29711844 * 2^-82
1288 // = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18
1289 // and 29711844 * 2^-81
1290 // = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17,
1291 // and they are the unique counterexamples. However, since 29711844 is even,
1292 // this does not cause any problem for the endpoints calculations; it can only
1293 // cause a problem when we need to perform integer check for the center.
1294 // Fortunately, with these inputs, that branch is never executed, so we are
1295 // fine.
1296 const typename cache_accessor<T>::compute_mul_result z_mul =
1297 cache_accessor<T>::compute_mul((two_fc | 1) << beta, cache);
1298
1299 // Step 2: Try larger divisor; remove trailing zeros if necessary.
1300
1301 // Using an upper bound on zi, we might be able to optimize the division
1302 // better than the compiler; we are computing zi / big_divisor here.
1303 decimal_fp<T> ret_value;
1304 ret_value.significand = divide_by_10_to_kappa_plus_1(z_mul.result);
1305 uint32_t r = static_cast<uint32_t>(z_mul.result - float_info<T>::big_divisor *
1306 ret_value.significand);
1307
1308 if (r < deltai) {
1309 // Exclude the right endpoint if necessary.
1310 if (r == 0 && (z_mul.is_integer & !include_right_endpoint)) {
1311 --ret_value.significand;
1312 r = float_info<T>::big_divisor;
1313 goto small_divisor_case_label;
1314 }
1315 } else if (r > deltai) {
1316 goto small_divisor_case_label;
1317 } else {
1318 // r == deltai; compare fractional parts.
1319 const typename cache_accessor<T>::compute_mul_parity_result x_mul =
1320 cache_accessor<T>::compute_mul_parity(two_fc - 1, cache, beta);
1321
1322 if (!(x_mul.parity | (x_mul.is_integer & include_left_endpoint)))
1323 goto small_divisor_case_label;
1324 }
1325 ret_value.exponent = minus_k + float_info<T>::kappa + 1;
1326
1327 // We may need to remove trailing zeros.
1328 ret_value.exponent += remove_trailing_zeros(ret_value.significand);
1329 return ret_value;
1330
1331 // Step 3: Find the significand with the smaller divisor.
1332
1333 small_divisor_case_label:
1334 ret_value.significand *= 10;
1335 ret_value.exponent = minus_k + float_info<T>::kappa;
1336
1337 uint32_t dist = r - (deltai / 2) + (float_info<T>::small_divisor / 2);
1338 const bool approx_y_parity =
1339 ((dist ^ (float_info<T>::small_divisor / 2)) & 1) != 0;
1340
1341 // Is dist divisible by 10^kappa?
1342 const bool divisible_by_small_divisor =
1343 check_divisibility_and_divide_by_pow10<float_info<T>::kappa>(dist);
1344
1345 // Add dist / 10^kappa to the significand.
1346 ret_value.significand += dist;
1347
1348 if (!divisible_by_small_divisor) return ret_value;
1349
1350 // Check z^(f) >= epsilon^(f).
1351 // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1,
1352 // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f).
1353 // Since there are only 2 possibilities, we only need to care about the
1354 // parity. Also, zi and r should have the same parity since the divisor
1355 // is an even number.
1356 const auto y_mul = cache_accessor<T>::compute_mul_parity(two_fc, cache, beta);
1357
1358 // If z^(f) >= epsilon^(f), we might have a tie when z^(f) == epsilon^(f),
1359 // or equivalently, when y is an integer.
1360 if (y_mul.parity != approx_y_parity)
1361 --ret_value.significand;
1362 else if (y_mul.is_integer & (ret_value.significand % 2 != 0))
1363 --ret_value.significand;
1364 return ret_value;
1365 }
1366 } // namespace dragonbox
1367 } // namespace detail
1368
1369 template <> struct formatter<detail::bigint> {
1370 FMT_CONSTEXPR auto parse(format_parse_context& ctx)
1371 -> format_parse_context::iterator {
1372 return ctx.begin();
1373 }
1374
1375 auto format(const detail::bigint& n, format_context& ctx) const
1376 -> format_context::iterator {
1377 auto out = ctx.out();
1378 bool first = true;
1379 for (auto i = n.bigits_.size(); i > 0; --i) {
1380 auto value = n.bigits_[i - 1u];
1381 if (first) {
1382 out = fmt::format_to(out, FMT_STRING("{:x}"), value);
1383 first = false;
1384 continue;
1385 }
1386 out = fmt::format_to(out, FMT_STRING("{:08x}"), value);
1387 }
1388 if (n.exp_ > 0)
1389 out = fmt::format_to(out, FMT_STRING("p{}"),
1390 n.exp_ * detail::bigint::bigit_bits);
1391 return out;
1392 }
1393 };
1394
1395 FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) {
1396 for_each_codepoint(s, [this](uint32_t cp, string_view) {
1397 if (cp == invalid_code_point) FMT_THROW(std::runtime_error("invalid utf8"));
1398 if (cp <= 0xFFFF) {
1399 buffer_.push_back(static_cast<wchar_t>(cp));
1400 } else {
1401 cp -= 0x10000;
1402 buffer_.push_back(static_cast<wchar_t>(0xD800 + (cp >> 10)));
1403 buffer_.push_back(static_cast<wchar_t>(0xDC00 + (cp & 0x3FF)));
1404 }
1405 return true;
1406 });
1407 buffer_.push_back(0);
1408 }
1409
1410 FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
1411 const char* message) noexcept {
1412 FMT_TRY {
1413 auto ec = std::error_code(error_code, std::generic_category());
1414 write(std::back_inserter(out), std::system_error(ec, message).what());
1415 return;
1416 }
1417 FMT_CATCH(...) {}
1418 format_error_code(out, error_code, message);
1419 }
1420
1421 FMT_FUNC void report_system_error(int error_code,
1422 const char* message) noexcept {
1423 report_error(format_system_error, error_code, message);
1424 }
1425
1426 FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
1427 // Don't optimize the "{}" case to keep the binary size small and because it
1428 // can be better optimized in fmt::format anyway.
1429 auto buffer = memory_buffer();
1430 detail::vformat_to(buffer, fmt, args);
1431 return to_string(buffer);
1432 }
1433
1434 namespace detail {
1435 #if !defined(_WIN32) || defined(FMT_WINDOWS_NO_WCHAR)
1436 FMT_FUNC auto write_console(int, string_view) -> bool { return false; }
1437 #else
1438 using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;
1439 extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
1440 void*, const void*, dword, dword*, void*);
1441
1442 FMT_FUNC bool write_console(int fd, string_view text) {
1443 auto u16 = utf8_to_utf16(text);
1444 return WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fd)), u16.c_str(),
1445 static_cast<dword>(u16.size()), nullptr, nullptr) != 0;
1446 }
1447 #endif
1448
1449 #ifdef _WIN32
1450 // Print assuming legacy (non-Unicode) encoding.
1451 FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args) {
1452 auto buffer = memory_buffer();
1453 detail::vformat_to(buffer, fmt, args);
1454 fwrite_fully(buffer.data(), buffer.size(), f);
1455 }
1456 #endif
1457
1458 FMT_FUNC void print(std::FILE* f, string_view text) {
1459 #ifdef _WIN32
1460 int fd = _fileno(f);
1461 if (_isatty(fd)) {
1462 std::fflush(f);
1463 if (write_console(fd, text)) return;
1464 }
1465 #endif
1466 fwrite_fully(text.data(), text.size(), f);
1467 }
1468 } // namespace detail
1469
1470 FMT_FUNC void vprint(std::FILE* f, string_view fmt, format_args args) {
1471 auto buffer = memory_buffer();
1472 detail::vformat_to(buffer, fmt, args);
1473 detail::print(f, {buffer.data(), buffer.size()});
1474 }
1475
1476 FMT_FUNC void vprint(string_view fmt, format_args args) {
1477 vprint(stdout, fmt, args);
1478 }
1479
1480 namespace detail {
1481
1482 struct singleton {
1483 unsigned char upper;
1484 unsigned char lower_count;
1485 };
1486
1487 inline auto is_printable(uint16_t x, const singleton* singletons,
1488 size_t singletons_size,
1489 const unsigned char* singleton_lowers,
1490 const unsigned char* normal, size_t normal_size)
1491 -> bool {
1492 auto upper = x >> 8;
1493 auto lower_start = 0;
1494 for (size_t i = 0; i < singletons_size; ++i) {
1495 auto s = singletons[i];
1496 auto lower_end = lower_start + s.lower_count;
1497 if (upper < s.upper) break;
1498 if (upper == s.upper) {
1499 for (auto j = lower_start; j < lower_end; ++j) {
1500 if (singleton_lowers[j] == (x & 0xff)) return false;
1501 }
1502 }
1503 lower_start = lower_end;
1504 }
1505
1506 auto xsigned = static_cast<int>(x);
1507 auto current = true;
1508 for (size_t i = 0; i < normal_size; ++i) {
1509 auto v = static_cast<int>(normal[i]);
1510 auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v;
1511 xsigned -= len;
1512 if (xsigned < 0) break;
1513 current = !current;
1514 }
1515 return current;
1516 }
1517
1518 // This code is generated by support/printable.py.
1519 FMT_FUNC auto is_printable(uint32_t cp) -> bool {
1520 static constexpr singleton singletons0[] = {
1521 {0x00, 1}, {0x03, 5}, {0x05, 6}, {0x06, 3}, {0x07, 6}, {0x08, 8},
1522 {0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13},
1523 {0x0f, 4}, {0x10, 3}, {0x12, 18}, {0x13, 9}, {0x16, 1}, {0x17, 5},
1524 {0x18, 2}, {0x19, 3}, {0x1a, 7}, {0x1c, 2}, {0x1d, 1}, {0x1f, 22},
1525 {0x20, 3}, {0x2b, 3}, {0x2c, 2}, {0x2d, 11}, {0x2e, 1}, {0x30, 3},
1526 {0x31, 2}, {0x32, 1}, {0xa7, 2}, {0xa9, 2}, {0xaa, 4}, {0xab, 8},
1527 {0xfa, 2}, {0xfb, 5}, {0xfd, 4}, {0xfe, 3}, {0xff, 9},
1528 };
1529 static constexpr unsigned char singletons0_lower[] = {
1530 0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90,
1531 0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
1532 0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1,
1533 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,
1534 0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d,
1535 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,
1536 0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
1537 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,
1538 0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d,
1539 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d,
1540 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,
1541 0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7,
1542 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49,
1543 0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7,
1544 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7,
1545 0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e,
1546 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16,
1547 0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e,
1548 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f,
1549 0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
1550 0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0,
1551 0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27,
1552 0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91,
1553 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,
1554 0xfe, 0xff,
1555 };
1556 static constexpr singleton singletons1[] = {
1557 {0x00, 6}, {0x01, 1}, {0x03, 1}, {0x04, 2}, {0x08, 8}, {0x09, 2},
1558 {0x0a, 5}, {0x0b, 2}, {0x0e, 4}, {0x10, 1}, {0x11, 2}, {0x12, 5},
1559 {0x13, 17}, {0x14, 1}, {0x15, 2}, {0x17, 2}, {0x19, 13}, {0x1c, 5},
1560 {0x1d, 8}, {0x24, 1}, {0x6a, 3}, {0x6b, 2}, {0xbc, 2}, {0xd1, 2},
1561 {0xd4, 12}, {0xd5, 9}, {0xd6, 2}, {0xd7, 2}, {0xda, 1}, {0xe0, 5},
1562 {0xe1, 2}, {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2}, {0xf9, 2},
1563 {0xfa, 2}, {0xfb, 1},
1564 };
1565 static constexpr unsigned char singletons1_lower[] = {
1566 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07,
1567 0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
1568 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87,
1569 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
1570 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b,
1571 0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9,
1572 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66,
1573 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27,
1574 0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc,
1575 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7,
1576 0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6,
1577 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c,
1578 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66,
1579 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0,
1580 0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93,
1581 };
1582 static constexpr unsigned char normal0[] = {
1583 0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04,
1584 0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0,
1585 0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01,
1586 0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03,
1587 0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03,
1588 0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a,
1589 0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15,
1590 0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f,
1591 0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80,
1592 0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07,
1593 0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06,
1594 0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04,
1595 0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac,
1596 0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c,
1597 0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11,
1598 0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c,
1599 0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b,
1600 0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6,
1601 0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03,
1602 0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80,
1603 0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06,
1604 0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c,
1605 0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17,
1606 0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80,
1607 0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80,
1608 0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d,
1609 };
1610 static constexpr unsigned char normal1[] = {
1611 0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f,
1612 0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e,
1613 0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04,
1614 0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09,
1615 0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16,
1616 0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f,
1617 0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36,
1618 0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33,
1619 0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08,
1620 0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e,
1621 0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41,
1622 0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03,
1623 0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22,
1624 0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04,
1625 0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45,
1626 0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03,
1627 0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81,
1628 0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75,
1629 0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1,
1630 0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a,
1631 0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11,
1632 0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09,
1633 0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89,
1634 0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6,
1635 0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09,
1636 0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50,
1637 0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05,
1638 0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83,
1639 0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05,
1640 0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80,
1641 0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80,
1642 0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07,
1643 0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e,
1644 0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07,
1645 0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06,
1646 };
1647 auto lower = static_cast<uint16_t>(cp);
1648 if (cp < 0x10000) {
1649 return is_printable(lower, singletons0,
1650 sizeof(singletons0) / sizeof(*singletons0),
1651 singletons0_lower, normal0, sizeof(normal0));
1652 }
1653 if (cp < 0x20000) {
1654 return is_printable(lower, singletons1,
1655 sizeof(singletons1) / sizeof(*singletons1),
1656 singletons1_lower, normal1, sizeof(normal1));
1657 }
1658 if (0x2a6de <= cp && cp < 0x2a700) return false;
1659 if (0x2b735 <= cp && cp < 0x2b740) return false;
1660 if (0x2b81e <= cp && cp < 0x2b820) return false;
1661 if (0x2cea2 <= cp && cp < 0x2ceb0) return false;
1662 if (0x2ebe1 <= cp && cp < 0x2f800) return false;
1663 if (0x2fa1e <= cp && cp < 0x30000) return false;
1664 if (0x3134b <= cp && cp < 0xe0100) return false;
1665 if (0xe01f0 <= cp && cp < 0x110000) return false;
1666 return cp < 0x110000;
1667 }
1668
1669 } // namespace detail
1670
1671 FMT_END_NAMESPACE
1672
1673 #endif // FMT_FORMAT_INL_H_
1674