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