source: trunk/GDE/SINA/builddir/include/spdlog/fmt/bundled/format-inl.h

Last change on this file was 19170, checked in by westram, 2 years ago
  • sina source
    • unpack + remove tarball
    • no longer ignore sina builddir.
File size: 31.6 KB
Line 
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.
58inline fmt::internal::null<> strerror_r(int, char *, ...) {
59  return fmt::internal::null<>();
60}
61inline fmt::internal::null<> strerror_s(char *, std::size_t, ...) {
62  return fmt::internal::null<>();
63}
64
65FMT_BEGIN_NAMESPACE
66
67namespace {
68
69#ifndef _MSC_VER
70# define FMT_SNPRINTF snprintf
71#else  // _MSC_VER
72inline 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
88typedef 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.
99int safe_strerror(
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
159void 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);
171  if (internal::is_negative(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
186void report_error(FormatFunc func, int error_code,
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
197FMT_FUNC size_t internal::count_code_points(basic_string_view<char8_t> s) {
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)
208namespace internal {
209
210template <typename Locale>
211locale_ref::locale_ref(const Locale &loc) : locale_(&loc) {
212  static_assert(std::is_same<Locale, std::locale>::value, "");
213}
214
215template <typename Locale>
216Locale 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
221template <typename Char>
222FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
223  return std::use_facet<std::numpunct<Char> >(
224    loc.get<std::locale>()).thousands_sep();
225}
226}
227#else
228template <typename Char>
229FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
230  return FMT_STATIC_THOUSANDS_SEPARATOR;
231}
232#endif
233
234FMT_FUNC void system_error::init(
235    int err_code, string_view format_str, format_args args) {
236  error_code_ = err_code;
237  memory_buffer buffer;
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
243namespace internal {
244template <typename T>
245int char_traits<char>::format_float(
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
252template <typename T>
253int char_traits<wchar_t>::format_float(
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
261template <typename T>
262const 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
280template <typename T>
281const uint32_t basic_data<T>::POWERS_OF_10_32[] = {
282  1, FMT_POWERS_OF_10(1)
283};
284
285template <typename T>
286const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {
287  0, FMT_POWERS_OF_10(1)
288};
289
290template <typename T>
291const 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.
300template <typename T>
301const 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.
335template <typename T>
336const 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
347template <typename T> const char basic_data<T>::FOREGROUND_COLOR[] = "\x1b[38;2;";
348template <typename T> const char basic_data<T>::BACKGROUND_COLOR[] = "\x1b[48;2;";
349template <typename T> const char basic_data<T>::RESET_COLOR[] = "\x1b[0m";
350template <typename T> const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
351
352// A handmade floating-point number f * pow(2, e).
353class 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.
429inline 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.
436FMT_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.
440FMT_API fp get_cached_power(int min_exponent, int &pow10_exponent);
441
442FMT_FUNC fp operator*(fp x, fp y) {
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
453FMT_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
466FMT_FUNC bool grisu2_round(
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.
484FMT_FUNC bool grisu2_gen_digits(
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
541struct gen_digits_params {
542  int num_digits;
543  bool fixed;
544  bool upper;
545  bool trailing_zeros;
546};
547
548struct prettify_handler {
549  char *data;
550  ptrdiff_t size;
551  buffer &buf;
552
553  explicit prettify_handler(buffer &b, ptrdiff_t n)
554    : data(b.data()), size(n), buf(b) {}
555  ~prettify_handler() {
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.
586template <typename Handler>
587FMT_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
608struct 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.
618template <typename Handler>
619FMT_FUNC void grisu2_prettify(const gen_digits_params &params,
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
659struct 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.
673FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs,
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;
680    FMT_FALLTHROUGH
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;
691    FMT_FALLTHROUGH
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;
702    FMT_FALLTHROUGH
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
714template <typename Double>
715FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
716    grisu2_format(Double value, buffer &buf, core_format_specs specs) {
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
763template <typename Double>
764void sprintf_format(Double value, internal::buffer &buf,
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];
790    int result = internal::char_traits<char>::format_float(
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
810FMT_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
834FMT_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
841FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) {
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
865FMT_FUNC void windows_error::init(
866    int err_code, string_view format_str, format_args args) {
867  error_code_ = err_code;
868  memory_buffer buffer;
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
874FMT_FUNC void internal::format_windows_error(
875    internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
876  FMT_TRY {
877    wmemory_buffer buf;
878    buf.resize(inline_buffer_size);
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
906FMT_FUNC void format_system_error(
907    internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
908  FMT_TRY {
909    memory_buffer buf;
910    buf.resize(inline_buffer_size);
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
929FMT_FUNC void internal::error_handler::on_error(const char *message) {
930  FMT_THROW(format_error(message));
931}
932
933FMT_FUNC void report_system_error(
934    int error_code, fmt::string_view message) FMT_NOEXCEPT {
935  report_error(format_system_error, error_code, message);
936}
937
938#if FMT_USE_WINDOWS_H
939FMT_FUNC void report_windows_error(
940    int error_code, fmt::string_view message) FMT_NOEXCEPT {
941  report_error(internal::format_windows_error, error_code, message);
942}
943#endif
944
945FMT_FUNC void vprint(std::FILE *f, string_view format_str, format_args args) {
946  memory_buffer buffer;
947  internal::vformat_to(buffer, format_str,
948                       basic_format_args<buffer_context<char>::type>(args));
949  std::fwrite(buffer.data(), 1, buffer.size(), f);
950}
951
952FMT_FUNC void vprint(std::FILE *f, wstring_view format_str, wformat_args args) {
953  wmemory_buffer buffer;
954  internal::vformat_to(buffer, format_str, args);
955  std::fwrite(buffer.data(), sizeof(wchar_t), buffer.size(), f);
956}
957
958FMT_FUNC void vprint(string_view format_str, format_args args) {
959  vprint(stdout, format_str, args);
960}
961
962FMT_FUNC void vprint(wstring_view format_str, wformat_args args) {
963  vprint(stdout, format_str, args);
964}
965
966FMT_END_NAMESPACE
967
968#ifdef _MSC_VER
969# pragma warning(pop)
970#endif
971
972#endif  // FMT_FORMAT_INL_H_
Note: See TracBrowser for help on using the repository browser.