]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/fmt/include/fmt/format-inl.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / fmt / include / fmt / format-inl.h
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
65 FMT_BEGIN_NAMESPACE
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.
99 int 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 // 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,
158 string_view message) FMT_NOEXCEPT {
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,
185 string_view message) FMT_NOEXCEPT {
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
195 #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
196 class locale {
197 private:
198 std::locale locale_;
199
200 public:
201 explicit locale(std::locale loc = std::locale()) : locale_(loc) {}
202 std::locale get() { return locale_; }
203 };
204
205 FMT_FUNC size_t internal::count_code_points(u8string_view s) {
206 const char8_t *data = s.data();
207 int num_code_points = 0;
208 for (size_t i = 0, size = s.size(); i != size; ++i) {
209 if ((data[i].value & 0xc0) != 0x80)
210 ++num_code_points;
211 }
212 return num_code_points;
213 }
214
215 template <typename Char>
216 FMT_FUNC Char internal::thousands_sep(locale_provider *lp) {
217 std::locale loc = lp ? lp->locale().get() : std::locale();
218 return std::use_facet<std::numpunct<Char>>(loc).thousands_sep();
219 }
220 #else
221 template <typename Char>
222 FMT_FUNC Char internal::thousands_sep(locale_provider *lp) {
223 return FMT_STATIC_THOUSANDS_SEPARATOR;
224 }
225 #endif
226
227 FMT_FUNC void system_error::init(
228 int err_code, string_view format_str, format_args args) {
229 error_code_ = err_code;
230 memory_buffer buffer;
231 format_system_error(buffer, err_code, vformat(format_str, args));
232 std::runtime_error &base = *this;
233 base = std::runtime_error(to_string(buffer));
234 }
235
236 namespace internal {
237 template <typename T>
238 int char_traits<char>::format_float(
239 char *buffer, std::size_t size, const char *format, int precision, T value) {
240 return precision < 0 ?
241 FMT_SNPRINTF(buffer, size, format, value) :
242 FMT_SNPRINTF(buffer, size, format, precision, value);
243 }
244
245 template <typename T>
246 int char_traits<wchar_t>::format_float(
247 wchar_t *buffer, std::size_t size, const wchar_t *format, int precision,
248 T value) {
249 return precision < 0 ?
250 FMT_SWPRINTF(buffer, size, format, value) :
251 FMT_SWPRINTF(buffer, size, format, precision, value);
252 }
253
254 template <typename T>
255 const char basic_data<T>::DIGITS[] =
256 "0001020304050607080910111213141516171819"
257 "2021222324252627282930313233343536373839"
258 "4041424344454647484950515253545556575859"
259 "6061626364656667686970717273747576777879"
260 "8081828384858687888990919293949596979899";
261
262 #define FMT_POWERS_OF_10(factor) \
263 factor * 10, \
264 factor * 100, \
265 factor * 1000, \
266 factor * 10000, \
267 factor * 100000, \
268 factor * 1000000, \
269 factor * 10000000, \
270 factor * 100000000, \
271 factor * 1000000000
272
273 template <typename T>
274 const uint32_t basic_data<T>::POWERS_OF_10_32[] = {
275 1, FMT_POWERS_OF_10(1)
276 };
277
278 template <typename T>
279 const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {
280 0, FMT_POWERS_OF_10(1)
281 };
282
283 template <typename T>
284 const uint64_t basic_data<T>::ZERO_OR_POWERS_OF_10_64[] = {
285 0,
286 FMT_POWERS_OF_10(1),
287 FMT_POWERS_OF_10(1000000000ull),
288 10000000000000000000ull
289 };
290
291 // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
292 // These are generated by support/compute-powers.py.
293 template <typename T>
294 const uint64_t basic_data<T>::POW10_SIGNIFICANDS[] = {
295 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
296 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
297 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
298 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
299 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
300 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
301 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
302 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
303 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
304 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
305 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
306 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
307 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
308 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
309 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
310 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
311 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
312 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
313 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
314 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
315 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
316 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
317 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
318 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
319 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
320 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
321 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
322 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
323 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
324 };
325
326 // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
327 // to significands above.
328 template <typename T>
329 const int16_t basic_data<T>::POW10_EXPONENTS[] = {
330 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
331 -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
332 -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
333 -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
334 -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
335 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
336 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
337 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066
338 };
339
340 template <typename T> const char basic_data<T>::RESET_COLOR[] = "\x1b[0m";
341 template <typename T> const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
342
343 // A handmade floating-point number f * pow(2, e).
344 class fp {
345 private:
346 typedef uint64_t significand_type;
347
348 // All sizes are in bits.
349 static FMT_CONSTEXPR_DECL const int char_size =
350 std::numeric_limits<unsigned char>::digits;
351 // Subtract 1 to account for an implicit most significant bit in the
352 // normalized form.
353 static FMT_CONSTEXPR_DECL const int double_significand_size =
354 std::numeric_limits<double>::digits - 1;
355 static FMT_CONSTEXPR_DECL const uint64_t implicit_bit =
356 1ull << double_significand_size;
357
358 public:
359 significand_type f;
360 int e;
361
362 static FMT_CONSTEXPR_DECL const int significand_size =
363 sizeof(significand_type) * char_size;
364
365 fp(): f(0), e(0) {}
366 fp(uint64_t f, int e): f(f), e(e) {}
367
368 // Constructs fp from an IEEE754 double. It is a template to prevent compile
369 // errors on platforms where double is not IEEE754.
370 template <typename Double>
371 explicit fp(Double d) {
372 // Assume double is in the format [sign][exponent][significand].
373 typedef std::numeric_limits<Double> limits;
374 const int double_size = static_cast<int>(sizeof(Double) * char_size);
375 const int exponent_size =
376 double_size - double_significand_size - 1; // -1 for sign
377 const uint64_t significand_mask = implicit_bit - 1;
378 const uint64_t exponent_mask = (~0ull >> 1) & ~significand_mask;
379 const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1;
380 auto u = bit_cast<uint64_t>(d);
381 auto biased_e = (u & exponent_mask) >> double_significand_size;
382 f = u & significand_mask;
383 if (biased_e != 0)
384 f += implicit_bit;
385 else
386 biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
387 e = static_cast<int>(biased_e - exponent_bias - double_significand_size);
388 }
389
390 // Normalizes the value converted from double and multiplied by (1 << SHIFT).
391 template <int SHIFT = 0>
392 void normalize() {
393 // Handle subnormals.
394 auto shifted_implicit_bit = implicit_bit << SHIFT;
395 while ((f & shifted_implicit_bit) == 0) {
396 f <<= 1;
397 --e;
398 }
399 // Subtract 1 to account for hidden bit.
400 auto offset = significand_size - double_significand_size - SHIFT - 1;
401 f <<= offset;
402 e -= offset;
403 }
404
405 // Compute lower and upper boundaries (m^- and m^+ in the Grisu paper), where
406 // a boundary is a value half way between the number and its predecessor
407 // (lower) or successor (upper). The upper boundary is normalized and lower
408 // has the same exponent but may be not normalized.
409 void compute_boundaries(fp &lower, fp &upper) const {
410 lower = f == implicit_bit ?
411 fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
412 upper = fp((f << 1) + 1, e - 1);
413 upper.normalize<1>(); // 1 is to account for the exponent shift above.
414 lower.f <<= lower.e - upper.e;
415 lower.e = upper.e;
416 }
417 };
418
419 // Returns an fp number representing x - y. Result may not be normalized.
420 inline fp operator-(fp x, fp y) {
421 FMT_ASSERT(x.f >= y.f && x.e == y.e, "invalid operands");
422 return fp(x.f - y.f, x.e);
423 }
424
425 // Computes an fp number r with r.f = x.f * y.f / pow(2, 64) rounded to nearest
426 // with half-up tie breaking, r.e = x.e + y.e + 64. Result may not be normalized.
427 FMT_API fp operator*(fp x, fp y);
428
429 // Returns cached power (of 10) c_k = c_k.f * pow(2, c_k.e) such that its
430 // (binary) exponent satisfies min_exponent <= c_k.e <= min_exponent + 3.
431 FMT_API fp get_cached_power(int min_exponent, int &pow10_exponent);
432
433 FMT_FUNC fp operator*(fp x, fp y) {
434 // Multiply 32-bit parts of significands.
435 uint64_t mask = (1ULL << 32) - 1;
436 uint64_t a = x.f >> 32, b = x.f & mask;
437 uint64_t c = y.f >> 32, d = y.f & mask;
438 uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
439 // Compute mid 64-bit of result and round.
440 uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
441 return fp(ac + (ad >> 32) + (bc >> 32) + (mid >> 32), x.e + y.e + 64);
442 }
443
444 FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) {
445 const double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10)
446 int index = static_cast<int>(std::ceil(
447 (min_exponent + fp::significand_size - 1) * one_over_log2_10));
448 // Decimal exponent of the first (smallest) cached power of 10.
449 const int first_dec_exp = -348;
450 // Difference between 2 consecutive decimal exponents in cached powers of 10.
451 const int dec_exp_step = 8;
452 index = (index - first_dec_exp - 1) / dec_exp_step + 1;
453 pow10_exponent = first_dec_exp + index * dec_exp_step;
454 return fp(data::POW10_SIGNIFICANDS[index], data::POW10_EXPONENTS[index]);
455 }
456
457 // Generates output using Grisu2 digit-gen algorithm.
458 FMT_FUNC void grisu2_gen_digits(
459 const fp &scaled_value, const fp &scaled_upper, uint64_t delta,
460 char *buffer, size_t &size, int &dec_exp) {
461 internal::fp one(1ull << -scaled_upper.e, scaled_upper.e);
462 // hi (p1 in Grisu) contains the most significant digits of scaled_upper.
463 // hi = floor(scaled_upper / one).
464 uint32_t hi = static_cast<uint32_t>(scaled_upper.f >> -one.e);
465 // lo (p2 in Grisu) contains the least significants digits of scaled_upper.
466 // lo = scaled_upper mod 1.
467 uint64_t lo = scaled_upper.f & (one.f - 1);
468 size = 0;
469 auto exp = count_digits(hi); // kappa in Grisu.
470 while (exp > 0) {
471 uint32_t digit = 0;
472 // This optimization by miloyip reduces the number of integer divisions by
473 // one per iteration.
474 switch (exp) {
475 case 10: digit = hi / 1000000000; hi %= 1000000000; break;
476 case 9: digit = hi / 100000000; hi %= 100000000; break;
477 case 8: digit = hi / 10000000; hi %= 10000000; break;
478 case 7: digit = hi / 1000000; hi %= 1000000; break;
479 case 6: digit = hi / 100000; hi %= 100000; break;
480 case 5: digit = hi / 10000; hi %= 10000; break;
481 case 4: digit = hi / 1000; hi %= 1000; break;
482 case 3: digit = hi / 100; hi %= 100; break;
483 case 2: digit = hi / 10; hi %= 10; break;
484 case 1: digit = hi; hi = 0; break;
485 default:
486 FMT_ASSERT(false, "invalid number of digits");
487 }
488 if (digit != 0 || size != 0)
489 buffer[size++] = static_cast<char>('0' + digit);
490 --exp;
491 uint64_t remainder = (static_cast<uint64_t>(hi) << -one.e) + lo;
492 if (remainder <= delta) {
493 dec_exp += exp;
494 // TODO: use scaled_value
495 (void)scaled_value;
496 return;
497 }
498 }
499 for (;;) {
500 lo *= 10;
501 delta *= 10;
502 char digit = static_cast<char>(lo >> -one.e);
503 if (digit != 0 || size != 0)
504 buffer[size++] = static_cast<char>('0' + digit);
505 lo &= one.f - 1;
506 --exp;
507 if (lo < delta) {
508 dec_exp += exp;
509 return;
510 }
511 }
512 }
513
514 FMT_FUNC void grisu2_format_positive(double value, char *buffer, size_t &size,
515 int &dec_exp) {
516 FMT_ASSERT(value > 0, "value is nonpositive");
517 fp fp_value(value);
518 fp lower, upper; // w^- and w^+ in the Grisu paper.
519 fp_value.compute_boundaries(lower, upper);
520 // Find a cached power of 10 close to 1 / upper.
521 const int min_exp = -60; // alpha in Grisu.
522 auto dec_pow = get_cached_power( // \tilde{c}_{-k} in Grisu.
523 min_exp - (upper.e + fp::significand_size), dec_exp);
524 dec_exp = -dec_exp;
525 fp_value.normalize();
526 fp scaled_value = fp_value * dec_pow;
527 fp scaled_lower = lower * dec_pow; // \tilde{M}^- in Grisu.
528 fp scaled_upper = upper * dec_pow; // \tilde{M}^+ in Grisu.
529 ++scaled_lower.f; // \tilde{M}^- + 1 ulp -> M^-_{\uparrow}.
530 --scaled_upper.f; // \tilde{M}^+ - 1 ulp -> M^+_{\downarrow}.
531 uint64_t delta = scaled_upper.f - scaled_lower.f;
532 grisu2_gen_digits(scaled_value, scaled_upper, delta, buffer, size, dec_exp);
533 }
534
535 FMT_FUNC void round(char *buffer, size_t &size, int &exp,
536 int digits_to_remove) {
537 size -= to_unsigned(digits_to_remove);
538 exp += digits_to_remove;
539 int digit = buffer[size] - '0';
540 // TODO: proper rounding and carry
541 if (digit > 5 || (digit == 5 && (digits_to_remove > 1 ||
542 (buffer[size - 1] - '0') % 2) != 0)) {
543 ++buffer[size - 1];
544 }
545 }
546
547 // Writes the exponent exp in the form "[+-]d{1,3}" to buffer.
548 FMT_FUNC char *write_exponent(char *buffer, int exp) {
549 FMT_ASSERT(-1000 < exp && exp < 1000, "exponent out of range");
550 if (exp < 0) {
551 *buffer++ = '-';
552 exp = -exp;
553 } else {
554 *buffer++ = '+';
555 }
556 if (exp >= 100) {
557 *buffer++ = static_cast<char>('0' + exp / 100);
558 exp %= 100;
559 const char *d = data::DIGITS + exp * 2;
560 *buffer++ = d[0];
561 *buffer++ = d[1];
562 } else {
563 const char *d = data::DIGITS + exp * 2;
564 *buffer++ = d[0];
565 *buffer++ = d[1];
566 }
567 return buffer;
568 }
569
570 FMT_FUNC void format_exp_notation(
571 char *buffer, size_t &size, int exp, int precision, bool upper) {
572 // Insert a decimal point after the first digit and add an exponent.
573 std::memmove(buffer + 2, buffer + 1, size - 1);
574 buffer[1] = '.';
575 exp += static_cast<int>(size) - 1;
576 int num_digits = precision - static_cast<int>(size) + 1;
577 if (num_digits > 0) {
578 std::uninitialized_fill_n(buffer + size + 1, num_digits, '0');
579 size += to_unsigned(num_digits);
580 } else if (num_digits < 0) {
581 round(buffer, size, exp, -num_digits);
582 }
583 char *p = buffer + size + 1;
584 *p++ = upper ? 'E' : 'e';
585 size = to_unsigned(write_exponent(p, exp) - buffer);
586 }
587
588 // Prettifies the output of the Grisu2 algorithm.
589 // The number is given as v = buffer * 10^exp.
590 FMT_FUNC void grisu2_prettify(char *buffer, size_t &size, int exp,
591 int precision, bool upper) {
592 // pow(10, full_exp - 1) <= v <= pow(10, full_exp).
593 int int_size = static_cast<int>(size);
594 int full_exp = int_size + exp;
595 const int exp_threshold = 21;
596 if (int_size <= full_exp && full_exp <= exp_threshold) {
597 // 1234e7 -> 12340000000[.0+]
598 std::uninitialized_fill_n(buffer + int_size, full_exp - int_size, '0');
599 char *p = buffer + full_exp;
600 if (precision > 0) {
601 *p++ = '.';
602 std::uninitialized_fill_n(p, precision, '0');
603 p += precision;
604 }
605 size = to_unsigned(p - buffer);
606 } else if (0 < full_exp && full_exp <= exp_threshold) {
607 // 1234e-2 -> 12.34[0+]
608 int fractional_size = -exp;
609 std::memmove(buffer + full_exp + 1, buffer + full_exp,
610 to_unsigned(fractional_size));
611 buffer[full_exp] = '.';
612 int num_zeros = precision - fractional_size;
613 if (num_zeros > 0) {
614 std::uninitialized_fill_n(buffer + size + 1, num_zeros, '0');
615 size += to_unsigned(num_zeros);
616 }
617 ++size;
618 } else if (-6 < full_exp && full_exp <= 0) {
619 // 1234e-6 -> 0.001234
620 int offset = 2 - full_exp;
621 std::memmove(buffer + offset, buffer, size);
622 buffer[0] = '0';
623 buffer[1] = '.';
624 std::uninitialized_fill_n(buffer + 2, -full_exp, '0');
625 size = to_unsigned(int_size + offset);
626 } else {
627 format_exp_notation(buffer, size, exp, precision, upper);
628 }
629 }
630
631 #if FMT_CLANG_VERSION
632 # define FMT_FALLTHROUGH [[clang::fallthrough]];
633 #elif FMT_GCC_VERSION >= 700
634 # define FMT_FALLTHROUGH [[gnu::fallthrough]];
635 #else
636 # define FMT_FALLTHROUGH
637 #endif
638
639 // Formats a nonnegative value using Grisu2 algorithm. Grisu2 doesn't give any
640 // guarantees on the shortness of the result.
641 FMT_FUNC void grisu2_format(double value, char *buffer, size_t &size, char type,
642 int precision, bool write_decimal_point) {
643 FMT_ASSERT(value >= 0, "value is negative");
644 int dec_exp = 0; // K in Grisu.
645 if (value > 0) {
646 grisu2_format_positive(value, buffer, size, dec_exp);
647 } else {
648 *buffer = '0';
649 size = 1;
650 }
651 const int default_precision = 6;
652 if (precision < 0)
653 precision = default_precision;
654 bool upper = false;
655 switch (type) {
656 case 'G':
657 upper = true;
658 FMT_FALLTHROUGH
659 case '\0': case 'g': {
660 int digits_to_remove = static_cast<int>(size) - precision;
661 if (digits_to_remove > 0) {
662 round(buffer, size, dec_exp, digits_to_remove);
663 // Remove trailing zeros.
664 while (size > 0 && buffer[size - 1] == '0') {
665 --size;
666 ++dec_exp;
667 }
668 }
669 precision = 0;
670 break;
671 }
672 case 'F':
673 upper = true;
674 FMT_FALLTHROUGH
675 case 'f': {
676 int digits_to_remove = -dec_exp - precision;
677 if (digits_to_remove > 0) {
678 if (digits_to_remove >= static_cast<int>(size))
679 digits_to_remove = static_cast<int>(size) - 1;
680 round(buffer, size, dec_exp, digits_to_remove);
681 }
682 break;
683 }
684 case 'e': case 'E':
685 format_exp_notation(buffer, size, dec_exp, precision, type == 'E');
686 return;
687 }
688 if (write_decimal_point && precision < 1)
689 precision = 1;
690 grisu2_prettify(buffer, size, dec_exp, precision, upper);
691 }
692 } // namespace internal
693
694 #if FMT_USE_WINDOWS_H
695
696 FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) {
697 static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
698 if (s.size() > INT_MAX)
699 FMT_THROW(windows_error(ERROR_INVALID_PARAMETER, ERROR_MSG));
700 int s_size = static_cast<int>(s.size());
701 if (s_size == 0) {
702 // MultiByteToWideChar does not support zero length, handle separately.
703 buffer_.resize(1);
704 buffer_[0] = 0;
705 return;
706 }
707
708 int length = MultiByteToWideChar(
709 CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0);
710 if (length == 0)
711 FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
712 buffer_.resize(length + 1);
713 length = MultiByteToWideChar(
714 CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
715 if (length == 0)
716 FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
717 buffer_[length] = 0;
718 }
719
720 FMT_FUNC internal::utf16_to_utf8::utf16_to_utf8(wstring_view s) {
721 if (int error_code = convert(s)) {
722 FMT_THROW(windows_error(error_code,
723 "cannot convert string from UTF-16 to UTF-8"));
724 }
725 }
726
727 FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) {
728 if (s.size() > INT_MAX)
729 return ERROR_INVALID_PARAMETER;
730 int s_size = static_cast<int>(s.size());
731 if (s_size == 0) {
732 // WideCharToMultiByte does not support zero length, handle separately.
733 buffer_.resize(1);
734 buffer_[0] = 0;
735 return 0;
736 }
737
738 int length = WideCharToMultiByte(
739 CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL);
740 if (length == 0)
741 return GetLastError();
742 buffer_.resize(length + 1);
743 length = WideCharToMultiByte(
744 CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
745 if (length == 0)
746 return GetLastError();
747 buffer_[length] = 0;
748 return 0;
749 }
750
751 FMT_FUNC void windows_error::init(
752 int err_code, string_view format_str, format_args args) {
753 error_code_ = err_code;
754 memory_buffer buffer;
755 internal::format_windows_error(buffer, err_code, vformat(format_str, args));
756 std::runtime_error &base = *this;
757 base = std::runtime_error(to_string(buffer));
758 }
759
760 FMT_FUNC void internal::format_windows_error(
761 internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
762 FMT_TRY {
763 wmemory_buffer buf;
764 buf.resize(inline_buffer_size);
765 for (;;) {
766 wchar_t *system_message = &buf[0];
767 int result = FormatMessageW(
768 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
769 FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
770 system_message, static_cast<uint32_t>(buf.size()), FMT_NULL);
771 if (result != 0) {
772 utf16_to_utf8 utf8_message;
773 if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
774 writer w(out);
775 w.write(message);
776 w.write(": ");
777 w.write(utf8_message);
778 return;
779 }
780 break;
781 }
782 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
783 break; // Can't get error message, report error code instead.
784 buf.resize(buf.size() * 2);
785 }
786 } FMT_CATCH(...) {}
787 format_error_code(out, error_code, message);
788 }
789
790 #endif // FMT_USE_WINDOWS_H
791
792 FMT_FUNC void format_system_error(
793 internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
794 FMT_TRY {
795 memory_buffer buf;
796 buf.resize(inline_buffer_size);
797 for (;;) {
798 char *system_message = &buf[0];
799 int result = safe_strerror(error_code, system_message, buf.size());
800 if (result == 0) {
801 writer w(out);
802 w.write(message);
803 w.write(": ");
804 w.write(system_message);
805 return;
806 }
807 if (result != ERANGE)
808 break; // Can't get error message, report error code instead.
809 buf.resize(buf.size() * 2);
810 }
811 } FMT_CATCH(...) {}
812 format_error_code(out, error_code, message);
813 }
814
815 template <typename Char>
816 void basic_fixed_buffer<Char>::grow(std::size_t) {
817 FMT_THROW(std::runtime_error("buffer overflow"));
818 }
819
820 FMT_FUNC void internal::error_handler::on_error(const char *message) {
821 FMT_THROW(format_error(message));
822 }
823
824 FMT_FUNC void report_system_error(
825 int error_code, fmt::string_view message) FMT_NOEXCEPT {
826 report_error(format_system_error, error_code, message);
827 }
828
829 #if FMT_USE_WINDOWS_H
830 FMT_FUNC void report_windows_error(
831 int error_code, fmt::string_view message) FMT_NOEXCEPT {
832 report_error(internal::format_windows_error, error_code, message);
833 }
834 #endif
835
836 FMT_FUNC void vprint(std::FILE *f, string_view format_str, format_args args) {
837 memory_buffer buffer;
838 vformat_to(buffer, format_str, args);
839 std::fwrite(buffer.data(), 1, buffer.size(), f);
840 }
841
842 FMT_FUNC void vprint(std::FILE *f, wstring_view format_str, wformat_args args) {
843 wmemory_buffer buffer;
844 vformat_to(buffer, format_str, args);
845 std::fwrite(buffer.data(), sizeof(wchar_t), buffer.size(), f);
846 }
847
848 FMT_FUNC void vprint(string_view format_str, format_args args) {
849 vprint(stdout, format_str, args);
850 }
851
852 FMT_FUNC void vprint(wstring_view format_str, wformat_args args) {
853 vprint(stdout, format_str, args);
854 }
855
856 #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
857 FMT_FUNC locale locale_provider::locale() { return fmt::locale(); }
858 #endif
859
860 FMT_END_NAMESPACE
861
862 #ifdef _MSC_VER
863 # pragma warning(pop)
864 #endif
865
866 #endif // FMT_FORMAT_INL_H_