WireCellToolkit
Wire Cell Simulation, Signal Process and Reconstruction Toolki for Liquid Argon Detectors
format-inl.h
Go to the documentation of this file.
1 // Formatting library for C++
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 "format.h"
12 
13 #include <string.h>
14 
15 #include <cctype>
16 #include <cerrno>
17 #include <climits>
18 #include <cmath>
19 #include <cstdarg>
20 #include <cstddef> // for std::ptrdiff_t
21 #include <cstring> // for std::memmove
22 #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
23 # include <locale>
24 #endif
25 
26 #if FMT_USE_WINDOWS_H
27 # if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
28 # define WIN32_LEAN_AND_MEAN
29 # endif
30 # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
31 # include <windows.h>
32 # else
33 # define NOMINMAX
34 # include <windows.h>
35 # undef NOMINMAX
36 # endif
37 #endif
38 
39 #if FMT_EXCEPTIONS
40 # define FMT_TRY try
41 # define FMT_CATCH(x) catch (x)
42 #else
43 # define FMT_TRY if (true)
44 # define FMT_CATCH(x) if (false)
45 #endif
46 
47 #ifdef _MSC_VER
48 # pragma warning(push)
49 # pragma warning(disable: 4127) // conditional expression is constant
50 # pragma warning(disable: 4702) // unreachable code
51 // Disable deprecation warning for strerror. The latter is not called but
52 // MSVC fails to detect it.
53 # pragma warning(disable: 4996)
54 #endif
55 
56 // Dummy implementations of strerror_r and strerror_s called if corresponding
57 // system functions are not available.
58 inline fmt::internal::null<> strerror_r(int, char *, ...) {
59  return fmt::internal::null<>();
60 }
61 inline fmt::internal::null<> strerror_s(char *, std::size_t, ...) {
62  return fmt::internal::null<>();
63 }
64 
66 
67 namespace {
68 
69 #ifndef _MSC_VER
70 # define FMT_SNPRINTF snprintf
71 #else // _MSC_VER
72 inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
73  va_list args;
74  va_start(args, format);
75  int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
76  va_end(args);
77  return result;
78 }
79 # define FMT_SNPRINTF fmt_snprintf
80 #endif // _MSC_VER
81 
82 #if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
83 # define FMT_SWPRINTF snwprintf
84 #else
85 # define FMT_SWPRINTF swprintf
86 #endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
87 
88 typedef void (*FormatFunc)(internal::buffer &, int, string_view);
89 
90 // Portable thread-safe version of strerror.
91 // Sets buffer to point to a string describing the error code.
92 // This can be either a pointer to a string stored in buffer,
93 // or a pointer to some static immutable string.
94 // Returns one of the following values:
95 // 0 - success
96 // ERANGE - buffer is not large enough to store the error message
97 // other - failure
98 // Buffer should be at least of size 1.
100  int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
101  FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
102 
103  class dispatcher {
104  private:
105  int error_code_;
106  char *&buffer_;
107  std::size_t buffer_size_;
108 
109  // A noop assignment operator to avoid bogus warnings.
110  void operator=(const dispatcher &) {}
111 
112  // Handle the result of XSI-compliant version of strerror_r.
113  int handle(int result) {
114  // glibc versions before 2.13 return result in errno.
115  return result == -1 ? errno : result;
116  }
117 
118  // Handle the result of GNU-specific version of strerror_r.
119  int handle(char *message) {
120  // If the buffer is full then the message is probably truncated.
121  if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
122  return ERANGE;
123  buffer_ = message;
124  return 0;
125  }
126 
127  // Handle the case when strerror_r is not available.
128  int handle(internal::null<>) {
129  return fallback(strerror_s(buffer_, buffer_size_, error_code_));
130  }
131 
132  // Fallback to strerror_s when strerror_r is not available.
133  int fallback(int result) {
134  // If the buffer is full then the message is probably truncated.
135  return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
136  ERANGE : result;
137  }
138 
139 #if !FMT_MSC_VER
140  // Fallback to strerror if strerror_r and strerror_s are not available.
141  int fallback(internal::null<>) {
142  errno = 0;
143  buffer_ = strerror(error_code_);
144  return errno;
145  }
146 #endif
147 
148  public:
149  dispatcher(int err_code, char *&buf, std::size_t buf_size)
150  : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
151 
152  int run() {
153  return handle(strerror_r(error_code_, buffer_, buffer_size_));
154  }
155  };
156  return dispatcher(error_code, buffer, buffer_size).run();
157 }
158 
159 void format_error_code(internal::buffer &out, int error_code,
160  string_view message) FMT_NOEXCEPT {
161  // Report error code making sure that the output fits into
162  // inline_buffer_size to avoid dynamic memory allocation and potential
163  // bad_alloc.
164  out.resize(0);
165  static const char SEP[] = ": ";
166  static const char ERROR_STR[] = "error ";
167  // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
168  std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
169  typedef internal::int_traits<int>::main_type main_type;
170  main_type abs_value = static_cast<main_type>(error_code);
172  abs_value = 0 - abs_value;
173  ++error_code_size;
174  }
175  error_code_size += internal::to_unsigned(internal::count_digits(abs_value));
176  writer w(out);
177  if (message.size() <= inline_buffer_size - error_code_size) {
178  w.write(message);
179  w.write(SEP);
180  }
181  w.write(ERROR_STR);
182  w.write(error_code);
183  assert(out.size() <= inline_buffer_size);
184 }
185 
187  string_view message) FMT_NOEXCEPT {
188  memory_buffer full_message;
189  func(full_message, error_code, message);
190  // Use Writer::data instead of Writer::c_str to avoid potential memory
191  // allocation.
192  std::fwrite(full_message.data(), full_message.size(), 1, stderr);
193  std::fputc('\n', stderr);
194 }
195 } // namespace
196 
198  const char8_t *data = s.data();
199  size_t num_code_points = 0;
200  for (size_t i = 0, size = s.size(); i != size; ++i) {
201  if ((data[i] & 0xc0) != 0x80)
202  ++num_code_points;
203  }
204  return num_code_points;
205 }
206 
207 #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
208 namespace internal {
209 
210 template <typename Locale>
211 locale_ref::locale_ref(const Locale &loc) : locale_(&loc) {
212  static_assert(std::is_same<Locale, std::locale>::value, "");
213 }
214 
215 template <typename Locale>
216 Locale locale_ref::get() const {
217  static_assert(std::is_same<Locale, std::locale>::value, "");
218  return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
219 }
220 
221 template <typename Char>
223  return std::use_facet<std::numpunct<Char> >(
224  loc.get<std::locale>()).thousands_sep();
225 }
226 }
227 #else
228 template <typename Char>
230  return FMT_STATIC_THOUSANDS_SEPARATOR;
231 }
232 #endif
233 
234 FMT_FUNC void system_error::init(
235  int err_code, string_view format_str, format_args args) {
236  error_code_ = err_code;
238  format_system_error(buffer, err_code, vformat(format_str, args));
239  std::runtime_error &base = *this;
240  base = std::runtime_error(to_string(buffer));
241 }
242 
243 namespace internal {
244 template <typename T>
246  char *buf, std::size_t size, const char *format, int precision, T value) {
247  return precision < 0 ?
248  FMT_SNPRINTF(buf, size, format, value) :
249  FMT_SNPRINTF(buf, size, format, precision, value);
250 }
251 
252 template <typename T>
254  wchar_t *buf, std::size_t size, const wchar_t *format, int precision,
255  T value) {
256  return precision < 0 ?
257  FMT_SWPRINTF(buf, size, format, value) :
258  FMT_SWPRINTF(buf, size, format, precision, value);
259 }
260 
261 template <typename T>
262 const char basic_data<T>::DIGITS[] =
263  "0001020304050607080910111213141516171819"
264  "2021222324252627282930313233343536373839"
265  "4041424344454647484950515253545556575859"
266  "6061626364656667686970717273747576777879"
267  "8081828384858687888990919293949596979899";
268 
269 #define FMT_POWERS_OF_10(factor) \
270  factor * 10, \
271  factor * 100, \
272  factor * 1000, \
273  factor * 10000, \
274  factor * 100000, \
275  factor * 1000000, \
276  factor * 10000000, \
277  factor * 100000000, \
278  factor * 1000000000
279 
280 template <typename T>
281 const uint32_t basic_data<T>::POWERS_OF_10_32[] = {
282  1, FMT_POWERS_OF_10(1)
283 };
284 
285 template <typename T>
286 const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {
287  0, FMT_POWERS_OF_10(1)
288 };
289 
290 template <typename T>
291 const uint64_t basic_data<T>::ZERO_OR_POWERS_OF_10_64[] = {
292  0,
293  FMT_POWERS_OF_10(1),
294  FMT_POWERS_OF_10(1000000000ull),
295  10000000000000000000ull
296 };
297 
298 // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
299 // These are generated by support/compute-powers.py.
300 template <typename T>
301 const uint64_t basic_data<T>::POW10_SIGNIFICANDS[] = {
302  0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
303  0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
304  0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
305  0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
306  0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
307  0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
308  0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
309  0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
310  0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
311  0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
312  0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
313  0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
314  0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
315  0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
316  0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
317  0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
318  0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
319  0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
320  0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
321  0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
322  0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
323  0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
324  0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
325  0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
326  0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
327  0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
328  0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
329  0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
330  0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
331 };
332 
333 // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
334 // to significands above.
335 template <typename T>
336 const int16_t basic_data<T>::POW10_EXPONENTS[] = {
337  -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
338  -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
339  -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
340  -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
341  -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
342  242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
343  534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
344  827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066
345 };
346 
347 template <typename T> const char basic_data<T>::FOREGROUND_COLOR[] = "\x1b[38;2;";
348 template <typename T> const char basic_data<T>::BACKGROUND_COLOR[] = "\x1b[48;2;";
349 template <typename T> const char basic_data<T>::RESET_COLOR[] = "\x1b[0m";
350 template <typename T> const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
351 
352 // A handmade floating-point number f * pow(2, e).
353 class fp {
354  private:
355  typedef uint64_t significand_type;
356 
357  // All sizes are in bits.
358  static FMT_CONSTEXPR_DECL const int char_size =
359  std::numeric_limits<unsigned char>::digits;
360  // Subtract 1 to account for an implicit most significant bit in the
361  // normalized form.
362  static FMT_CONSTEXPR_DECL const int double_significand_size =
363  std::numeric_limits<double>::digits - 1;
364  static FMT_CONSTEXPR_DECL const uint64_t implicit_bit =
365  1ull << double_significand_size;
366 
367  public:
368  significand_type f;
369  int e;
370 
371  static FMT_CONSTEXPR_DECL const int significand_size =
372  sizeof(significand_type) * char_size;
373 
374  fp(): f(0), e(0) {}
375  fp(uint64_t f_val, int e_val): f(f_val), e(e_val) {}
376 
377  // Constructs fp from an IEEE754 double. It is a template to prevent compile
378  // errors on platforms where double is not IEEE754.
379  template <typename Double>
380  explicit fp(Double d) {
381  // Assume double is in the format [sign][exponent][significand].
382  typedef std::numeric_limits<Double> limits;
383  const int double_size = static_cast<int>(sizeof(Double) * char_size);
384  const int exponent_size =
385  double_size - double_significand_size - 1; // -1 for sign
386  const uint64_t significand_mask = implicit_bit - 1;
387  const uint64_t exponent_mask = (~0ull >> 1) & ~significand_mask;
388  const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1;
389  auto u = bit_cast<uint64_t>(d);
390  auto biased_e = (u & exponent_mask) >> double_significand_size;
391  f = u & significand_mask;
392  if (biased_e != 0)
393  f += implicit_bit;
394  else
395  biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
396  e = static_cast<int>(biased_e - exponent_bias - double_significand_size);
397  }
398 
399  // Normalizes the value converted from double and multiplied by (1 << SHIFT).
400  template <int SHIFT = 0>
401  void normalize() {
402  // Handle subnormals.
403  auto shifted_implicit_bit = implicit_bit << SHIFT;
404  while ((f & shifted_implicit_bit) == 0) {
405  f <<= 1;
406  --e;
407  }
408  // Subtract 1 to account for hidden bit.
409  auto offset = significand_size - double_significand_size - SHIFT - 1;
410  f <<= offset;
411  e -= offset;
412  }
413 
414  // Compute lower and upper boundaries (m^- and m^+ in the Grisu paper), where
415  // a boundary is a value half way between the number and its predecessor
416  // (lower) or successor (upper). The upper boundary is normalized and lower
417  // has the same exponent but may be not normalized.
418  void compute_boundaries(fp &lower, fp &upper) const {
419  lower = f == implicit_bit ?
420  fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
421  upper = fp((f << 1) + 1, e - 1);
422  upper.normalize<1>(); // 1 is to account for the exponent shift above.
423  lower.f <<= lower.e - upper.e;
424  lower.e = upper.e;
425  }
426 };
427 
428 // Returns an fp number representing x - y. Result may not be normalized.
429 inline fp operator-(fp x, fp y) {
430  FMT_ASSERT(x.f >= y.f && x.e == y.e, "invalid operands");
431  return fp(x.f - y.f, x.e);
432 }
433 
434 // Computes an fp number r with r.f = x.f * y.f / pow(2, 64) rounded to nearest
435 // with half-up tie breaking, r.e = x.e + y.e + 64. Result may not be normalized.
436 FMT_API fp operator*(fp x, fp y);
437 
438 // Returns cached power (of 10) c_k = c_k.f * pow(2, c_k.e) such that its
439 // (binary) exponent satisfies min_exponent <= c_k.e <= min_exponent + 3.
440 FMT_API fp get_cached_power(int min_exponent, int &pow10_exponent);
441 
443  // Multiply 32-bit parts of significands.
444  uint64_t mask = (1ULL << 32) - 1;
445  uint64_t a = x.f >> 32, b = x.f & mask;
446  uint64_t c = y.f >> 32, d = y.f & mask;
447  uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
448  // Compute mid 64-bit of result and round.
449  uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
450  return fp(ac + (ad >> 32) + (bc >> 32) + (mid >> 32), x.e + y.e + 64);
451 }
452 
453 FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) {
454  const double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10)
455  int index = static_cast<int>(std::ceil(
456  (min_exponent + fp::significand_size - 1) * one_over_log2_10));
457  // Decimal exponent of the first (smallest) cached power of 10.
458  const int first_dec_exp = -348;
459  // Difference between 2 consecutive decimal exponents in cached powers of 10.
460  const int dec_exp_step = 8;
461  index = (index - first_dec_exp - 1) / dec_exp_step + 1;
462  pow10_exponent = first_dec_exp + index * dec_exp_step;
463  return fp(data::POW10_SIGNIFICANDS[index], data::POW10_EXPONENTS[index]);
464 }
465 
467  char *buf, int &size, int max_digits, uint64_t delta,
468  uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10) {
469  while (remainder < diff && delta - remainder >= exp &&
470  (remainder + exp < diff || diff - remainder > remainder + exp - diff)) {
471  --buf[size - 1];
472  remainder += exp;
473  }
474  if (size > max_digits) {
475  --size;
476  ++exp10;
477  if (buf[size] >= '5')
478  return false;
479  }
480  return true;
481 }
482 
483 // Generates output using Grisu2 digit-gen algorithm.
485  char *buf, int &size, uint32_t hi, uint64_t lo, int &exp,
486  uint64_t delta, const fp &one, const fp &diff, int max_digits) {
487  // Generate digits for the most significant part (hi).
488  while (exp > 0) {
489  uint32_t digit = 0;
490  // This optimization by miloyip reduces the number of integer divisions by
491  // one per iteration.
492  switch (exp) {
493  case 10: digit = hi / 1000000000; hi %= 1000000000; break;
494  case 9: digit = hi / 100000000; hi %= 100000000; break;
495  case 8: digit = hi / 10000000; hi %= 10000000; break;
496  case 7: digit = hi / 1000000; hi %= 1000000; break;
497  case 6: digit = hi / 100000; hi %= 100000; break;
498  case 5: digit = hi / 10000; hi %= 10000; break;
499  case 4: digit = hi / 1000; hi %= 1000; break;
500  case 3: digit = hi / 100; hi %= 100; break;
501  case 2: digit = hi / 10; hi %= 10; break;
502  case 1: digit = hi; hi = 0; break;
503  default:
504  FMT_ASSERT(false, "invalid number of digits");
505  }
506  if (digit != 0 || size != 0)
507  buf[size++] = static_cast<char>('0' + digit);
508  --exp;
509  uint64_t remainder = (static_cast<uint64_t>(hi) << -one.e) + lo;
510  if (remainder <= delta || size > max_digits) {
511  return grisu2_round(
512  buf, size, max_digits, delta, remainder,
513  static_cast<uint64_t>(data::POWERS_OF_10_32[exp]) << -one.e,
514  diff.f, exp);
515  }
516  }
517  // Generate digits for the least significant part (lo).
518  for (;;) {
519  lo *= 10;
520  delta *= 10;
521  char digit = static_cast<char>(lo >> -one.e);
522  if (digit != 0 || size != 0)
523  buf[size++] = static_cast<char>('0' + digit);
524  lo &= one.f - 1;
525  --exp;
526  if (lo < delta || size > max_digits) {
527  return grisu2_round(buf, size, max_digits, delta, lo, one.f,
528  diff.f * data::POWERS_OF_10_32[-exp], exp);
529  }
530  }
531 }
532 
533 #if FMT_CLANG_VERSION
534 # define FMT_FALLTHROUGH [[clang::fallthrough]];
535 #elif FMT_GCC_VERSION >= 700
536 # define FMT_FALLTHROUGH [[gnu::fallthrough]];
537 #else
538 # define FMT_FALLTHROUGH
539 #endif
540 
543  bool fixed;
544  bool upper;
546 };
547 
549  char *data;
550  ptrdiff_t size;
552 
553  explicit prettify_handler(buffer &b, ptrdiff_t n)
554  : data(b.data()), size(n), buf(b) {}
556  assert(buf.size() >= to_unsigned(size));
557  buf.resize(to_unsigned(size));
558  }
559 
560  template <typename F>
561  void insert(ptrdiff_t pos, ptrdiff_t n, F f) {
562  std::memmove(data + pos + n, data + pos, to_unsigned(size - pos));
563  f(data + pos);
564  size += n;
565  }
566 
567  void insert(ptrdiff_t pos, char c) {
568  std::memmove(data + pos + 1, data + pos, to_unsigned(size - pos));
569  data[pos] = c;
570  ++size;
571  }
572 
573  void append(ptrdiff_t n, char c) {
574  std::uninitialized_fill_n(data + size, n, c);
575  size += n;
576  }
577 
578  void append(char c) { data[size++] = c; }
579 
580  void remove_trailing(char c) {
581  while (data[size - 1] == c) --size;
582  }
583 };
584 
585 // Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
586 template <typename Handler>
587 FMT_FUNC void write_exponent(int exp, Handler &&h) {
588  FMT_ASSERT(-1000 < exp && exp < 1000, "exponent out of range");
589  if (exp < 0) {
590  h.append('-');
591  exp = -exp;
592  } else {
593  h.append('+');
594  }
595  if (exp >= 100) {
596  h.append(static_cast<char>('0' + exp / 100));
597  exp %= 100;
598  const char *d = data::DIGITS + exp * 2;
599  h.append(d[0]);
600  h.append(d[1]);
601  } else {
602  const char *d = data::DIGITS + exp * 2;
603  h.append(d[0]);
604  h.append(d[1]);
605  }
606 }
607 
608 struct fill {
609  size_t n;
610  void operator()(char *buf) const {
611  buf[0] = '0';
612  buf[1] = '.';
613  std::uninitialized_fill_n(buf + 2, n, '0');
614  }
615 };
616 
617 // The number is given as v = f * pow(10, exp), where f has size digits.
618 template <typename Handler>
620  int size, int exp, Handler &&handler) {
621  if (!params.fixed) {
622  // Insert a decimal point after the first digit and add an exponent.
623  handler.insert(1, '.');
624  exp += size - 1;
625  if (size < params.num_digits)
626  handler.append(params.num_digits - size, '0');
627  handler.append(params.upper ? 'E' : 'e');
628  write_exponent(exp, handler);
629  return;
630  }
631  // pow(10, full_exp - 1) <= v <= pow(10, full_exp).
632  int full_exp = size + exp;
633  const int exp_threshold = 21;
634  if (size <= full_exp && full_exp <= exp_threshold) {
635  // 1234e7 -> 12340000000[.0+]
636  handler.append(full_exp - size, '0');
637  int num_zeros = params.num_digits - full_exp;
638  if (num_zeros > 0 && params.trailing_zeros) {
639  handler.append('.');
640  handler.append(num_zeros, '0');
641  }
642  } else if (full_exp > 0) {
643  // 1234e-2 -> 12.34[0+]
644  handler.insert(full_exp, '.');
645  if (!params.trailing_zeros) {
646  // Remove trailing zeros.
647  handler.remove_trailing('0');
648  } else if (params.num_digits > size) {
649  // Add trailing zeros.
650  ptrdiff_t num_zeros = params.num_digits - size;
651  handler.append(num_zeros, '0');
652  }
653  } else {
654  // 1234e-6 -> 0.001234
655  handler.insert(0, 2 - full_exp, fill{to_unsigned(-full_exp)});
656  }
657 }
658 
659 struct char_counter {
660  ptrdiff_t size;
661 
662  template <typename F>
663  void insert(ptrdiff_t, ptrdiff_t n, F) { size += n; }
664  void insert(ptrdiff_t, char) { ++size; }
665  void append(ptrdiff_t n, char) { size += n; }
666  void append(char) { ++size; }
667  void remove_trailing(char) {}
668 };
669 
670 // Converts format specifiers into parameters for digit generation and computes
671 // output buffer size for a number in the range [pow(10, exp - 1), pow(10, exp)
672 // or 0 if exp == 1.
674  int exp, buffer &buf) {
675  auto params = gen_digits_params();
676  int num_digits = specs.precision >= 0 ? specs.precision : 6;
677  switch (specs.type) {
678  case 'G':
679  params.upper = true;
681  case '\0': case 'g':
682  params.trailing_zeros = (specs.flags & HASH_FLAG) != 0;
683  if (-4 <= exp && exp < num_digits + 1) {
684  params.fixed = true;
685  if (!specs.type && params.trailing_zeros && exp >= 0)
686  num_digits = exp + 1;
687  }
688  break;
689  case 'F':
690  params.upper = true;
692  case 'f': {
693  params.fixed = true;
694  params.trailing_zeros = true;
695  int adjusted_min_digits = num_digits + exp;
696  if (adjusted_min_digits > 0)
697  num_digits = adjusted_min_digits;
698  break;
699  }
700  case 'E':
701  params.upper = true;
703  case 'e':
704  ++num_digits;
705  break;
706  }
707  params.num_digits = num_digits;
708  char_counter counter{num_digits};
709  grisu2_prettify(params, params.num_digits, exp - num_digits, counter);
710  buf.resize(to_unsigned(counter.size));
711  return params;
712 }
713 
714 template <typename Double>
717  FMT_ASSERT(value >= 0, "value is negative");
718  if (value == 0) {
719  gen_digits_params params = process_specs(specs, 1, buf);
720  const size_t size = 1;
721  buf[0] = '0';
722  grisu2_prettify(params, size, 0, prettify_handler(buf, size));
723  return true;
724  }
725 
726  fp fp_value(value);
727  fp lower, upper; // w^- and w^+ in the Grisu paper.
728  fp_value.compute_boundaries(lower, upper);
729 
730  // Find a cached power of 10 close to 1 / upper and use it to scale upper.
731  const int min_exp = -60; // alpha in Grisu.
732  int cached_exp = 0; // K in Grisu.
733  auto cached_pow = get_cached_power( // \tilde{c}_{-k} in Grisu.
734  min_exp - (upper.e + fp::significand_size), cached_exp);
735  cached_exp = -cached_exp;
736  upper = upper * cached_pow; // \tilde{M}^+ in Grisu.
737  --upper.f; // \tilde{M}^+ - 1 ulp -> M^+_{\downarrow}.
738  fp one(1ull << -upper.e, upper.e);
739  // hi (p1 in Grisu) contains the most significant digits of scaled_upper.
740  // hi = floor(upper / one).
741  uint32_t hi = static_cast<uint32_t>(upper.f >> -one.e);
742  int exp = count_digits(hi); // kappa in Grisu.
743  gen_digits_params params = process_specs(specs, cached_exp + exp, buf);
744  fp_value.normalize();
745  fp scaled_value = fp_value * cached_pow;
746  lower = lower * cached_pow; // \tilde{M}^- in Grisu.
747  ++lower.f; // \tilde{M}^- + 1 ulp -> M^-_{\uparrow}.
748  uint64_t delta = upper.f - lower.f;
749  fp diff = upper - scaled_value; // wp_w in Grisu.
750  // lo (p2 in Grisu) contains the least significants digits of scaled_upper.
751  // lo = supper % one.
752  uint64_t lo = upper.f & (one.f - 1);
753  int size = 0;
754  if (!grisu2_gen_digits(buf.data(), size, hi, lo, exp, delta, one, diff,
755  params.num_digits)) {
756  buf.clear();
757  return false;
758  }
759  grisu2_prettify(params, size, cached_exp + exp, prettify_handler(buf, size));
760  return true;
761 }
762 
763 template <typename Double>
765  core_format_specs spec) {
766  // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
767  FMT_ASSERT(buf.capacity() != 0, "empty buffer");
768 
769  // Build format string.
770  enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg
771  char format[MAX_FORMAT_SIZE];
772  char *format_ptr = format;
773  *format_ptr++ = '%';
774  if (spec.has(HASH_FLAG))
775  *format_ptr++ = '#';
776  if (spec.precision >= 0) {
777  *format_ptr++ = '.';
778  *format_ptr++ = '*';
779  }
780  if (std::is_same<Double, long double>::value)
781  *format_ptr++ = 'L';
782  *format_ptr++ = spec.type;
783  *format_ptr = '\0';
784 
785  // Format using snprintf.
786  char *start = FMT_NULL;
787  for (;;) {
788  std::size_t buffer_size = buf.capacity();
789  start = &buf[0];
791  start, buffer_size, format, spec.precision, value);
792  if (result >= 0) {
793  unsigned n = internal::to_unsigned(result);
794  if (n < buf.capacity()) {
795  buf.resize(n);
796  break; // The buffer is large enough - continue with formatting.
797  }
798  buf.reserve(n + 1);
799  } else {
800  // If result is negative we ask to increase the capacity by at least 1,
801  // but as std::vector, the buffer grows exponentially.
802  buf.reserve(buf.capacity() + 1);
803  }
804  }
805 }
806 } // namespace internal
807 
808 #if FMT_USE_WINDOWS_H
809 
810 FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) {
811  static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
812  if (s.size() > INT_MAX)
813  FMT_THROW(windows_error(ERROR_INVALID_PARAMETER, ERROR_MSG));
814  int s_size = static_cast<int>(s.size());
815  if (s_size == 0) {
816  // MultiByteToWideChar does not support zero length, handle separately.
817  buffer_.resize(1);
818  buffer_[0] = 0;
819  return;
820  }
821 
822  int length = MultiByteToWideChar(
823  CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0);
824  if (length == 0)
825  FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
826  buffer_.resize(length + 1);
827  length = MultiByteToWideChar(
828  CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
829  if (length == 0)
830  FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
831  buffer_[length] = 0;
832 }
833 
834 FMT_FUNC internal::utf16_to_utf8::utf16_to_utf8(wstring_view s) {
835  if (int error_code = convert(s)) {
836  FMT_THROW(windows_error(error_code,
837  "cannot convert string from UTF-16 to UTF-8"));
838  }
839 }
840 
842  if (s.size() > INT_MAX)
843  return ERROR_INVALID_PARAMETER;
844  int s_size = static_cast<int>(s.size());
845  if (s_size == 0) {
846  // WideCharToMultiByte does not support zero length, handle separately.
847  buffer_.resize(1);
848  buffer_[0] = 0;
849  return 0;
850  }
851 
852  int length = WideCharToMultiByte(
853  CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL);
854  if (length == 0)
855  return GetLastError();
856  buffer_.resize(length + 1);
857  length = WideCharToMultiByte(
858  CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
859  if (length == 0)
860  return GetLastError();
861  buffer_[length] = 0;
862  return 0;
863 }
864 
865 FMT_FUNC void windows_error::init(
866  int err_code, string_view format_str, format_args args) {
867  error_code_ = err_code;
869  internal::format_windows_error(buffer, err_code, vformat(format_str, args));
870  std::runtime_error &base = *this;
871  base = std::runtime_error(to_string(buffer));
872 }
873 
874 FMT_FUNC void internal::format_windows_error(
876  FMT_TRY {
877  wmemory_buffer buf;
879  for (;;) {
880  wchar_t *system_message = &buf[0];
881  int result = FormatMessageW(
882  FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
883  FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
884  system_message, static_cast<uint32_t>(buf.size()), FMT_NULL);
885  if (result != 0) {
886  utf16_to_utf8 utf8_message;
887  if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
888  writer w(out);
889  w.write(message);
890  w.write(": ");
891  w.write(utf8_message);
892  return;
893  }
894  break;
895  }
896  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
897  break; // Can't get error message, report error code instead.
898  buf.resize(buf.size() * 2);
899  }
900  } FMT_CATCH(...) {}
901  format_error_code(out, error_code, message);
902 }
903 
904 #endif // FMT_USE_WINDOWS_H
905 
908  FMT_TRY {
909  memory_buffer buf;
911  for (;;) {
912  char *system_message = &buf[0];
913  int result = safe_strerror(error_code, system_message, buf.size());
914  if (result == 0) {
915  writer w(out);
916  w.write(message);
917  w.write(": ");
918  w.write(system_message);
919  return;
920  }
921  if (result != ERANGE)
922  break; // Can't get error message, report error code instead.
923  buf.resize(buf.size() * 2);
924  }
925  } FMT_CATCH(...) {}
926  format_error_code(out, error_code, message);
927 }
928 
929 FMT_FUNC void internal::error_handler::on_error(const char *message) {
930  FMT_THROW(format_error(message));
931 }
932 
936 }
937 
938 #if FMT_USE_WINDOWS_H
939 FMT_FUNC void report_windows_error(
941  report_error(internal::format_windows_error, error_code, message);
942 }
943 #endif
944 
945 FMT_FUNC void vprint(std::FILE *f, string_view format_str, format_args args) {
947  internal::vformat_to(buffer, format_str,
949  std::fwrite(buffer.data(), 1, buffer.size(), f);
950 }
951 
952 FMT_FUNC void vprint(std::FILE *f, wstring_view format_str, wformat_args args) {
954  internal::vformat_to(buffer, format_str, args);
955  std::fwrite(buffer.data(), sizeof(wchar_t), buffer.size(), f);
956 }
957 
958 FMT_FUNC void vprint(string_view format_str, format_args args) {
959  vprint(stdout, format_str, args);
960 }
961 
962 FMT_FUNC void vprint(wstring_view format_str, wformat_args args) {
963  vprint(stdout, format_str, args);
964 }
965 
967 
968 #ifdef _MSC_VER
969 # pragma warning(pop)
970 #endif
971 
972 #endif // FMT_FORMAT_INL_H_
#define FMT_TRY
Definition: format-inl.h:40
Locale get() const
Definition: format-inl.h:216
prettify_handler(buffer &b, ptrdiff_t n)
Definition: format-inl.h:553
FMT_FUNC void vprint(std::FILE *f, string_view format_str, format_args args)
Definition: format-inl.h:945
void insert(ptrdiff_t, ptrdiff_t n, F)
Definition: format-inl.h:663
FMT_API void on_error(const char *message)
Definition: format-inl.h:929
void normalize()
Definition: format-inl.h:401
fmt::internal::null strerror_s(char *, std::size_t,...)
Definition: format-inl.h:61
significand_type f
Definition: format-inl.h:368
void insert(ptrdiff_t pos, ptrdiff_t n, F f)
Definition: format-inl.h:561
const S & format_str
Definition: format.h:3342
void insert(ptrdiff_t, char)
Definition: format-inl.h:664
size_t count_code_points(basic_string_view< Char > s)
Definition: format.h:794
#define FMT_CONSTEXPR_DECL
Definition: core.h:70
void sprintf_format(Double value, internal::buffer &buf, core_format_specs spec)
Definition: format-inl.h:764
void remove_trailing(char)
Definition: format-inl.h:667
FMT_FUNC void format_system_error(internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT
Definition: format-inl.h:906
void resize(std::size_t new_size)
Definition: core.h:264
FMT_CONSTEXPR size_t size() const
Definition: core.h:389
static const int16_t POW10_EXPONENTS[]
Definition: format.h:752
static const uint64_t ZERO_OR_POWERS_OF_10_64[]
Definition: format.h:750
FMT_API fp get_cached_power(int min_exponent, int &pow10_exponent)
Definition: format-inl.h:453
static const wchar_t WRESET_COLOR[]
Definition: format.h:757
void operator()(char *buf) const
Definition: format-inl.h:610
#define FMT_END_NAMESPACE
Definition: core.h:153
#define FMT_THROW(x)
Definition: format.h:115
FMT_FUNC void report_system_error(int error_code, fmt::string_view message) FMT_NOEXCEPT
Definition: format-inl.h:933
void append(ptrdiff_t n, char c)
Definition: format-inl.h:573
void format_error_code(internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT
Definition: format-inl.h:159
std::basic_string< FMT_CHAR(S)> format(const S &format_str, const Args &... args)
Definition: core.h:1454
T * data() FMT_NOEXCEPT
Definition: core.h:256
Dest bit_cast(const Source &source)
Definition: format.h:242
buffer_context< Char >::type::iterator vformat_to(internal::basic_buffer< Char > &buf, basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
Definition: format.h:3233
static const uint64_t POW10_SIGNIFICANDS[]
Definition: format.h:751
FMT_FUNC void grisu2_prettify(const gen_digits_params &params, int size, int exp, Handler &&handler)
Definition: format-inl.h:619
static const char BACKGROUND_COLOR[]
Definition: format.h:755
fp(uint64_t f_val, int e_val)
Definition: format-inl.h:375
#define FMT_FUNC
Definition: format.h:3547
FMT_FUNC bool grisu2_gen_digits(char *buf, int &size, uint32_t hi, uint64_t lo, int &exp, uint64_t delta, const fp &one, const fp &diff, int max_digits)
Definition: format-inl.h:484
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
Definition: format.h:3410
#define FMT_SNPRINTF
Definition: format-inl.h:70
void report_error(FormatFunc func, int error_code, string_view message) FMT_NOEXCEPT
Definition: format-inl.h:186
basic_string_view< char > string_view
Definition: core.h:428
void append(ptrdiff_t n, char)
Definition: format-inl.h:665
std::size_t size() const FMT_NOEXCEPT
Definition: core.h:250
void compute_boundaries(fp &lower, fp &upper) const
Definition: format-inl.h:418
std::size_t capacity() const FMT_NOEXCEPT
Definition: core.h:253
#define FMT_API
Definition: core.h:166
fmt::internal::null strerror_r(int, char *,...)
Definition: format-inl.h:58
void reserve(std::size_t new_capacity)
Definition: core.h:273
static const char RESET_COLOR[]
Definition: format.h:756
FMT_FUNC void write_exponent(int exp, Handler &&h)
Definition: format-inl.h:587
static const char DIGITS[]
Definition: format.h:753
fp operator-(fp x, fp y)
Definition: format-inl.h:429
#define FMT_CATCH(x)
Definition: format-inl.h:41
basic_buffer< char > buffer
Definition: core.h:291
void remove_trailing(char c)
Definition: format-inl.h:580
#define FMT_SWPRINTF
Definition: format-inl.h:85
FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs, int exp, buffer &buf)
Definition: format-inl.h:673
static const uint32_t POWERS_OF_10_32[]
Definition: format.h:748
#define FMT_NULL
Definition: core.h:107
FMT_CONSTEXPR std::enable_if< std::numeric_limits< T >::is_signed, bool >::type is_negative(T value)
Definition: format.h:727
std::string to_string(const T &value)
Definition: format.h:3209
uint_least8_t flags
Definition: format.h:1102
void(* FormatFunc)(internal::buffer &, int, string_view)
Definition: format-inl.h:88
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
Definition: core.h:208
FMT_FUNC Char thousands_sep_impl(locale_ref loc)
Definition: format-inl.h:222
static const uint32_t ZERO_OR_POWERS_OF_10_32[]
Definition: format.h:749
FMT_CONSTEXPR bool has(unsigned f) const
Definition: format.h:1106
int safe_strerror(int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT
Definition: format-inl.h:99
#define FMT_FALLTHROUGH
Definition: format-inl.h:538
FMT_FUNC bool grisu2_round(char *buf, int &size, int max_digits, uint64_t delta, uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10)
Definition: format-inl.h:466
#define FMT_NOEXCEPT
Definition: core.h:140
FMT_FUNC std::enable_if< sizeof(Double)==sizeof(uint64_t), bool >::type grisu2_format(Double value, buffer &buf, core_format_specs specs)
Definition: format-inl.h:716
#define FMT_ASSERT(condition, message)
Definition: core.h:170
static const char FOREGROUND_COLOR[]
Definition: format.h:754
char8_t
Definition: format.h:407
FMT_API fp operator*(fp x, fp y)
Definition: format-inl.h:442
std::size_t n
Definition: format.h:3399
void insert(ptrdiff_t pos, char c)
Definition: format-inl.h:567
fp(Double d)
Definition: format-inl.h:380
static FMT_CONSTEXPR_DECL const int significand_size
Definition: format-inl.h:371
#define FMT_POWERS_OF_10(factor)
Definition: format-inl.h:269
void write(int value)
Definition: format.h:2573
T convert(const Configuration &cfg, const T &def=T())
Convert a configuration value to a particular type.
Definition: Configuration.h:63
const Args & args
Definition: core.h:1496
int count_digits(uint64_t n)
Definition: format.h:777
type
Definition: core.h:530
FMT_CONSTEXPR const Char * data() const
Definition: core.h:386