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