8#ifndef FMT_FORMAT_INL_H_
9#define FMT_FORMAT_INL_H_
20#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
31# pragma warning(disable : 4702)
36inline fmt::internal::null<> strerror_r(
int,
char*, ...) {
return {}; }
37inline fmt::internal::null<> strerror_s(
char*, std::size_t, ...) {
return {}; }
42FMT_FUNC
void assert_fail(
const char* file,
int line,
const char* message) {
43 print(stderr,
"{}:{}: assertion failed: {}", file, line, message);
48# define FMT_SNPRINTF snprintf
50inline int fmt_snprintf(
char* buffer,
size_t size,
const char* format, ...) {
52 va_start(args, format);
53 int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
57# define FMT_SNPRINTF fmt_snprintf
69FMT_FUNC
int safe_strerror(
int error_code,
char*& buffer,
70 std::size_t buffer_size) FMT_NOEXCEPT {
71 FMT_ASSERT(buffer !=
nullptr && buffer_size != 0,
"invalid buffer");
77 std::size_t buffer_size_;
80 void operator=(
const dispatcher&) {}
83 int handle(
int result) {
85 return result == -1 ? errno : result;
90 int handle(
char* message) {
92 if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
100 int handle(internal::null<>) {
101 return fallback(strerror_s(buffer_, buffer_size_, error_code_));
106 int fallback(
int result) {
108 return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE
114 int fallback(internal::null<>) {
116 buffer_ = strerror(error_code_);
122 dispatcher(
int err_code,
char*& buf, std::size_t buf_size)
123 : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
125 int run() {
return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
127 return dispatcher(error_code, buffer, buffer_size).run();
136 static const char SEP[] =
": ";
137 static const char ERROR_STR[] =
"error ";
139 std::size_t error_code_size =
sizeof(SEP) +
sizeof(ERROR_STR) - 2;
140 auto abs_value =
static_cast<uint32_or_64_or_128_t<int>
>(error_code);
141 if (internal::is_negative(error_code)) {
142 abs_value = 0 - abs_value;
145 error_code_size += internal::to_unsigned(internal::count_digits(abs_value));
146 internal::writer w(out);
147 if (message.size() <= inline_buffer_size - error_code_size) {
153 assert(out.size() <= inline_buffer_size);
156FMT_FUNC
void report_error(format_func func,
int error_code,
159 func(full_message, error_code, message);
161 (void)std::fwrite(full_message.
data(), full_message.
size(), 1, stderr);
162 std::fputc(
'\n', stderr);
166FMT_FUNC
void fwrite_fully(
const void* ptr,
size_t size,
size_t count,
168 size_t written = std::fwrite(ptr, size, count, stream);
169 if (written < count) FMT_THROW(
system_error(errno,
"cannot write to file"));
173#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
176template <
typename Locale>
177locale_ref::locale_ref(
const Locale& loc) : locale_(&loc) {
178 static_assert(std::is_same<Locale, std::locale>::value,
"");
181template <
typename Locale> Locale locale_ref::get()
const {
182 static_assert(std::is_same<Locale, std::locale>::value,
"");
183 return locale_ ? *
static_cast<const std::locale*
>(locale_) : std::locale();
186template <
typename Char> FMT_FUNC std::string grouping_impl(locale_ref loc) {
187 return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()).grouping();
189template <
typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
190 return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
193template <
typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
194 return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
199template <
typename Char>
200FMT_FUNC std::string internal::grouping_impl(locale_ref) {
203template <
typename Char>
204FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
205 return FMT_STATIC_THOUSANDS_SEPARATOR;
207template <
typename Char>
208FMT_FUNC Char internal::decimal_point_impl(locale_ref) {
213FMT_API FMT_FUNC format_error::~format_error() FMT_NOEXCEPT = default;
218 error_code_ = err_code;
220 format_system_error(buffer, err_code, vformat(format_str, args));
221 std::runtime_error& base = *
this;
222 base = std::runtime_error(to_string(buffer));
227template <> FMT_FUNC
int count_digits<4>(internal::fallback_uintptr n) {
229 int i =
static_cast<int>(
sizeof(
void*)) - 1;
230 while (i > 0 && n.value[i] == 0) --i;
231 auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
232 return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1;
236const char basic_data<T>::digits[] =
237 "0001020304050607080910111213141516171819"
238 "2021222324252627282930313233343536373839"
239 "4041424344454647484950515253545556575859"
240 "6061626364656667686970717273747576777879"
241 "8081828384858687888990919293949596979899";
244const char basic_data<T>::hex_digits[] =
"0123456789abcdef";
246#define FMT_POWERS_OF_10(factor) \
247 factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
248 (factor)*1000000, (factor)*10000000, (factor)*100000000, \
252const uint64_t basic_data<T>::powers_of_10_64[] = {
253 1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
254 10000000000000000000ULL};
257const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0,
258 FMT_POWERS_OF_10(1)};
261const uint64_t basic_data<T>::zero_or_powers_of_10_64[] = {
262 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
263 10000000000000000000ULL};
268const uint64_t basic_data<T>::pow10_significands[] = {
269 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
270 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
271 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
272 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
273 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
274 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
275 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
276 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
277 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
278 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
279 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
280 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
281 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
282 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
283 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
284 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
285 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
286 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
287 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
288 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
289 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
290 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
291 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
292 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
293 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
294 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
295 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
296 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
297 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
303const int16_t basic_data<T>::pow10_exponents[] = {
304 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
305 -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
306 -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
307 -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
308 -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
309 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
310 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
311 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
314const char basic_data<T>::foreground_color[] =
"\x1b[38;2;";
316const char basic_data<T>::background_color[] =
"\x1b[48;2;";
317template <
typename T>
const char basic_data<T>::reset_color[] =
"\x1b[0m";
318template <
typename T>
const wchar_t basic_data<T>::wreset_color[] = L
"\x1b[0m";
319template <
typename T>
const char basic_data<T>::signs[] = {0,
'-',
'+',
' '};
321template <
typename T>
struct bits {
322 static FMT_CONSTEXPR_DECL
const int value =
323 static_cast<int>(
sizeof(T) * std::numeric_limits<unsigned char>::digits);
327template <
int SHIFT = 0> fp normalize(fp value);
340 using significand_type = uint64_t;
349 static FMT_CONSTEXPR_DECL
const int double_significand_size =
350 std::numeric_limits<double>::digits - 1;
351 static FMT_CONSTEXPR_DECL
const uint64_t implicit_bit =
352 1ULL << double_significand_size;
353 static FMT_CONSTEXPR_DECL
const int significand_size =
354 bits<significand_type>::value;
357 fp(uint64_t f_val,
int e_val) : f(f_val), e(e_val) {}
361 template <
typename Double>
explicit fp(Double d) { assign(d); }
364 template <
typename Double, FMT_ENABLE_IF(sizeof(Double) == sizeof(u
int64_t))>
365 bool assign(Double d) {
367 using limits = std::numeric_limits<Double>;
368 const int exponent_size =
369 bits<Double>::value - double_significand_size - 1;
370 const uint64_t significand_mask = implicit_bit - 1;
371 const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask;
372 const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1;
373 auto u = bit_cast<uint64_t>(d);
374 f = u & significand_mask;
376 static_cast<int>((u & exponent_mask) >> double_significand_size);
379 bool is_predecessor_closer = f == 0 && biased_e > 1;
384 e = biased_e - exponent_bias - double_significand_size;
385 return is_predecessor_closer;
388 template <
typename Double, FMT_ENABLE_IF(sizeof(Double) != sizeof(u
int64_t))>
389 bool assign(Double) {
398 template <
typename Double> boundaries assign_with_boundaries(Double d) {
399 bool is_lower_closer = assign(d);
401 is_lower_closer ? fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
403 fp upper = normalize<1>(fp((f << 1) + 1, e - 1));
404 lower.f <<= lower.e - upper.e;
405 return boundaries{lower.f, upper.f};
408 template <
typename Double> boundaries assign_float_with_boundaries(Double d) {
410 constexpr int min_normal_e = std::numeric_limits<float>::min_exponent -
411 std::numeric_limits<double>::digits;
412 significand_type half_ulp = 1 << (std::numeric_limits<double>::digits -
413 std::numeric_limits<float>::digits - 1);
414 if (min_normal_e > e) half_ulp <<= min_normal_e - e;
415 fp upper = normalize<0>(fp(f + half_ulp, e));
417 f - (half_ulp >> ((f == implicit_bit && e > min_normal_e) ? 1 : 0)), e);
418 lower.f <<= lower.e - upper.e;
419 return boundaries{lower.f, upper.f};
424template <
int SHIFT> fp normalize(fp value) {
426 const auto shifted_implicit_bit = fp::implicit_bit << SHIFT;
427 while ((value.f & shifted_implicit_bit) == 0) {
433 fp::significand_size - fp::double_significand_size - SHIFT - 1;
439inline bool operator==(fp x, fp y) {
return x.f == y.f && x.e == y.e; }
442inline uint64_t multiply(uint64_t lhs, uint64_t rhs) {
444 auto product =
static_cast<__uint128_t
>(lhs) * rhs;
445 auto f =
static_cast<uint64_t
>(product >> 64);
446 return (
static_cast<uint64_t
>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
449 uint64_t mask = (1ULL << 32) - 1;
450 uint64_t a = lhs >> 32, b = lhs & mask;
451 uint64_t c = rhs >> 32, d = rhs & mask;
452 uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
454 uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
455 return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
459inline fp operator*(fp x, fp y) {
return {multiply(x.f, y.f), x.e + y.e + 64}; }
463inline fp get_cached_power(
int min_exponent,
int& pow10_exponent) {
464 const int64_t one_over_log2_10 = 0x4d104d42;
465 int index =
static_cast<int>(
466 ((min_exponent + fp::significand_size - 1) * one_over_log2_10 +
467 ((int64_t(1) << 32) - 1))
471 const int first_dec_exp = -348;
473 const int dec_exp_step = 8;
474 index = (index - first_dec_exp - 1) / dec_exp_step + 1;
475 pow10_exponent = first_dec_exp + index * dec_exp_step;
476 return {data::pow10_significands[index], data::pow10_exponents[index]};
485 accumulator() : lower(0), upper(0) {}
486 explicit operator uint32_t()
const {
return static_cast<uint32_t
>(lower); }
488 void operator+=(uint64_t n) {
490 if (lower < n) ++upper;
492 void operator>>=(
int shift) {
495 lower = (upper << 32) | (lower >> 32);
504 using bigit = uint32_t;
505 using double_bigit = uint64_t;
506 enum { bigits_capacity = 32 };
510 bigit operator[](
int index)
const {
return bigits_[to_unsigned(index)]; }
511 bigit& operator[](
int index) {
return bigits_[to_unsigned(index)]; }
513 static FMT_CONSTEXPR_DECL
const int bigit_bits = bits<bigit>::value;
515 friend struct formatter<bigint>;
517 void subtract_bigits(
int index, bigit other, bigit& borrow) {
518 auto result =
static_cast<double_bigit
>((*this)[index]) - other - borrow;
519 (*this)[index] =
static_cast<bigit
>(result);
520 borrow =
static_cast<bigit
>(result >> (bigit_bits * 2 - 1));
523 void remove_leading_zeros() {
524 int num_bigits =
static_cast<int>(bigits_.
size()) - 1;
525 while (num_bigits > 0 && (*
this)[num_bigits] == 0) --num_bigits;
526 bigits_.
resize(to_unsigned(num_bigits + 1));
530 void subtract_aligned(
const bigint& other) {
531 FMT_ASSERT(other.exp_ >= exp_,
"unaligned bigints");
532 FMT_ASSERT(compare(*
this, other) >= 0,
"");
534 int i = other.exp_ - exp_;
535 for (
size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) {
536 subtract_bigits(i, other.bigits_[j], borrow);
538 while (borrow > 0) subtract_bigits(i, 0, borrow);
539 remove_leading_zeros();
542 void multiply(uint32_t value) {
543 const double_bigit wide_value = value;
545 for (
size_t i = 0, n = bigits_.
size(); i < n; ++i) {
546 double_bigit result = bigits_[i] * wide_value + carry;
547 bigits_[i] =
static_cast<bigit
>(result);
548 carry =
static_cast<bigit
>(result >> bigit_bits);
550 if (carry != 0) bigits_.push_back(carry);
553 void multiply(uint64_t value) {
554 const bigit mask = ~bigit(0);
555 const double_bigit lower = value & mask;
556 const double_bigit upper = value >> bigit_bits;
557 double_bigit carry = 0;
558 for (
size_t i = 0, n = bigits_.
size(); i < n; ++i) {
559 double_bigit result = bigits_[i] * lower + (carry & mask);
561 bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits);
562 bigits_[i] =
static_cast<bigit
>(result);
565 bigits_.push_back(carry & mask);
566 carry >>= bigit_bits;
571 bigint() : exp_(0) {}
572 explicit bigint(uint64_t n) { assign(n); }
573 ~bigint() { assert(bigits_.
capacity() <= bigits_capacity); }
575 bigint(
const bigint&) =
delete;
576 void operator=(
const bigint&) =
delete;
578 void assign(
const bigint& other) {
579 bigits_.
resize(other.bigits_.size());
580 auto data = other.bigits_.data();
581 std::copy(data, data + other.bigits_.size(), bigits_.
data());
585 void assign(uint64_t n) {
586 size_t num_bigits = 0;
588 bigits_[num_bigits++] = n & ~bigit(0);
591 bigits_.
resize(num_bigits);
595 int num_bigits()
const {
return static_cast<int>(bigits_.
size()) + exp_; }
597 bigint& operator<<=(
int shift) {
599 exp_ += shift / bigit_bits;
601 if (shift == 0)
return *
this;
603 for (
size_t i = 0, n = bigits_.
size(); i < n; ++i) {
604 bigit c = bigits_[i] >> (bigit_bits - shift);
605 bigits_[i] = (bigits_[i] << shift) + carry;
608 if (carry != 0) bigits_.push_back(carry);
612 template <
typename Int> bigint& operator*=(Int value) {
613 FMT_ASSERT(value > 0,
"");
614 multiply(uint32_or_64_or_128_t<Int>(value));
618 friend int compare(
const bigint& lhs,
const bigint& rhs) {
619 int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
620 if (num_lhs_bigits != num_rhs_bigits)
621 return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
622 int i =
static_cast<int>(lhs.bigits_.size()) - 1;
623 int j =
static_cast<int>(rhs.bigits_.size()) - 1;
625 if (end < 0) end = 0;
626 for (; i >= end; --i, --j) {
627 bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
628 if (lhs_bigit != rhs_bigit)
return lhs_bigit > rhs_bigit ? 1 : -1;
630 if (i != j)
return i > j ? 1 : -1;
635 friend int add_compare(
const bigint& lhs1,
const bigint& lhs2,
637 int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits());
638 int num_rhs_bigits = rhs.num_bigits();
639 if (max_lhs_bigits + 1 < num_rhs_bigits)
return -1;
640 if (max_lhs_bigits > num_rhs_bigits)
return 1;
641 auto get_bigit = [](
const bigint& n,
int i) -> bigit {
642 return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
644 double_bigit borrow = 0;
645 int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_);
646 for (
int i = num_rhs_bigits - 1; i >= min_exp; --i) {
648 static_cast<double_bigit
>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
649 bigit rhs_bigit = get_bigit(rhs, i);
650 if (sum > rhs_bigit + borrow)
return 1;
651 borrow = rhs_bigit + borrow - sum;
652 if (borrow > 1)
return -1;
653 borrow <<= bigit_bits;
655 return borrow != 0 ? -1 : 0;
659 void assign_pow10(
int exp) {
661 if (exp == 0)
return assign(1);
664 while (exp >= bitmask) bitmask <<= 1;
670 while (bitmask != 0) {
672 if ((exp & bitmask) != 0) *
this *= 5;
680 int num_bigits =
static_cast<int>(bigits_.
size());
681 int num_result_bigits = 2 * num_bigits;
682 bigits_.
resize(to_unsigned(num_result_bigits));
683 using accumulator_t = conditional_t<FMT_USE_INT128, uint128_t, accumulator>;
684 auto sum = accumulator_t();
685 for (
int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
688 for (
int i = 0, j = bigit_index; j >= 0; ++i, --j) {
690 sum +=
static_cast<double_bigit
>(n[i]) * n[j];
692 (*this)[bigit_index] =
static_cast<bigit
>(sum);
693 sum >>= bits<bigit>::value;
696 for (
int bigit_index = num_bigits; bigit_index < num_result_bigits;
698 for (
int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
699 sum +=
static_cast<double_bigit
>(n[i++]) * n[j--];
700 (*this)[bigit_index] =
static_cast<bigit
>(sum);
701 sum >>= bits<bigit>::value;
704 remove_leading_zeros();
710 int divmod_assign(
const bigint& divisor) {
711 FMT_ASSERT(
this != &divisor,
"");
712 if (compare(*
this, divisor) < 0)
return 0;
713 int num_bigits =
static_cast<int>(bigits_.
size());
714 FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0,
"");
715 int exp_difference = exp_ - divisor.exp_;
716 if (exp_difference > 0) {
718 bigits_.
resize(to_unsigned(num_bigits + exp_difference));
719 for (
int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
720 bigits_[j] = bigits_[i];
721 std::uninitialized_fill_n(bigits_.
data(), exp_difference, 0);
722 exp_ -= exp_difference;
726 subtract_aligned(divisor);
728 }
while (compare(*
this, divisor) >= 0);
733enum class round_direction { unknown, up, down };
739inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder,
741 FMT_ASSERT(remainder < divisor,
"");
742 FMT_ASSERT(error < divisor,
"");
743 FMT_ASSERT(error < divisor - error,
"");
745 if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
746 return round_direction::down;
748 if (remainder >= error &&
749 remainder - error >= divisor - (remainder - error)) {
750 return round_direction::up;
752 return round_direction::unknown;
764inline int grisu_count_digits(uint32_t n) {
765 if (n < 10)
return 1;
766 if (n < 100)
return 2;
767 if (n < 1000)
return 3;
768 if (n < 10000)
return 4;
769 if (n < 100000)
return 5;
770 if (n < 1000000)
return 6;
771 if (n < 10000000)
return 7;
772 if (n < 100000000)
return 8;
773 if (n < 1000000000)
return 9;
780template <
typename Handler>
781FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error,
782 int& exp, Handler& handler) {
783 const fp one(1ULL << -value.e, value.e);
787 auto integral =
static_cast<uint32_t
>(value.f >> -one.e);
788 FMT_ASSERT(integral != 0,
"");
789 FMT_ASSERT(integral == value.f >> -one.e,
"");
791 uint64_t fractional = value.f & (one.f - 1);
792 exp = grisu_count_digits(integral);
794 auto result = handler.on_start(data::powers_of_10_64[exp - 1] << -one.e,
795 value.f / 10, error * 10, exp);
796 if (result != digits::more)
return result;
800 auto divmod_integral = [&](uint32_t divisor) {
801 digit = integral / divisor;
808 divmod_integral(1000000000);
811 divmod_integral(100000000);
814 divmod_integral(10000000);
817 divmod_integral(1000000);
820 divmod_integral(100000);
823 divmod_integral(10000);
826 divmod_integral(1000);
829 divmod_integral(100);
839 FMT_ASSERT(
false,
"invalid number of digits");
843 (
static_cast<uint64_t
>(integral) << -one.e) + fractional;
844 result = handler.on_digit(
static_cast<char>(
'0' + digit),
845 data::powers_of_10_64[exp] << -one.e, remainder,
847 if (result != digits::more)
return result;
854 static_cast<char>(
'0' +
static_cast<char>(fractional >> -one.e));
855 fractional &= one.f - 1;
857 result = handler.on_digit(digit, one.f, fractional, error, exp,
false);
858 if (result != digits::more)
return result;
863struct fixed_handler {
870 digits::result on_start(uint64_t divisor, uint64_t remainder, uint64_t error,
873 if (!fixed)
return digits::more;
876 precision += exp + exp10;
879 if (precision > 0)
return digits::more;
880 if (precision < 0)
return digits::done;
881 auto dir = get_round_direction(divisor, remainder, error);
882 if (dir == round_direction::unknown)
return digits::error;
883 buf[size++] = dir == round_direction::up ?
'1' :
'0';
887 digits::result on_digit(
char digit, uint64_t divisor, uint64_t remainder,
888 uint64_t error,
int,
bool integral) {
889 FMT_ASSERT(remainder < divisor,
"");
891 if (size < precision)
return digits::more;
896 if (error >= divisor || error >= divisor - error)
return digits::error;
898 FMT_ASSERT(error == 1 && divisor > 2,
"");
900 auto dir = get_round_direction(divisor, remainder, error);
901 if (dir != round_direction::up)
902 return dir == round_direction::down ? digits::done : digits::error;
904 for (
int i = size - 1; i > 0 && buf[i] >
'9'; --i) {
917struct grisu_shortest_handler {
923 digits::result on_start(uint64_t, uint64_t, uint64_t,
int&) {
928 void round(uint64_t d, uint64_t divisor, uint64_t& remainder,
931 remainder < d && error - remainder >= divisor &&
932 (remainder + divisor < d || d - remainder >= remainder + divisor - d)) {
934 remainder += divisor;
939 digits::result on_digit(
char digit, uint64_t divisor, uint64_t remainder,
940 uint64_t error,
int exp,
bool integral) {
942 if (remainder >= error)
return digits::more;
943 uint64_t unit = integral ? 1 : data::powers_of_10_64[-exp];
944 uint64_t up = (diff - 1) * unit;
945 round(up, divisor, remainder, error);
946 uint64_t down = (diff + 1) * unit;
947 if (remainder < down && error - remainder >= divisor &&
948 (remainder + divisor < down ||
949 down - remainder > remainder + divisor - down)) {
950 return digits::error;
952 return 2 * unit <= remainder && remainder <= error - 4 * unit
961template <
typename Double>
962void fallback_format(Double d, buffer<char>& buf,
int& exp10) {
968 bigint* upper =
nullptr;
974 int shift = value.assign(d) ? 2 : 1;
975 uint64_t significand = value.f << shift;
977 numerator.assign(significand);
978 numerator <<= value.e;
982 upper_store.assign(1);
983 upper_store <<= value.e + 1;
984 upper = &upper_store;
986 denominator.assign_pow10(exp10);
988 }
else if (exp10 < 0) {
989 numerator.assign_pow10(-exp10);
990 lower.assign(numerator);
992 upper_store.assign(numerator);
994 upper = &upper_store;
996 numerator *= significand;
997 denominator.assign(1);
998 denominator <<= shift - value.e;
1000 numerator.assign(significand);
1001 denominator.assign_pow10(exp10);
1002 denominator <<= shift - value.e;
1005 upper_store.assign(1ULL << 1);
1006 upper = &upper_store;
1009 if (!upper) upper = &lower;
1011 bool even = (value.f & 1) == 0;
1013 char* data = buf.data();
1015 int digit = numerator.divmod_assign(denominator);
1016 bool low = compare(numerator, lower) - even < 0;
1018 bool high = add_compare(numerator, *upper, denominator) + even > 0;
1019 data[num_digits++] =
static_cast<char>(
'0' + digit);
1022 ++data[num_digits - 1];
1024 int result = add_compare(numerator, numerator, denominator);
1026 if (result > 0 || (result == 0 && (digit % 2) != 0))
1027 ++data[num_digits - 1];
1029 buf.resize(to_unsigned(num_digits));
1030 exp10 -= num_digits - 1;
1035 if (upper != &lower) *upper *= 10;
1042template <
typename T>
1043int format_float(T value,
int precision, float_specs specs, buffer<char>& buf) {
1044 static_assert(!std::is_same<T, float>::value,
"");
1045 FMT_ASSERT(value >= 0,
"value is negative");
1047 const bool fixed = specs.format == float_format::fixed;
1049 if (precision <= 0 || !fixed) {
1053 buf.resize(to_unsigned(precision));
1054 std::uninitialized_fill_n(buf.data(), precision,
'0');
1058 if (!specs.use_grisu)
return snprintf_float(value, precision, specs, buf);
1061 const int min_exp = -60;
1062 int cached_exp10 = 0;
1063 if (precision < 0) {
1065 auto boundaries = specs.binary32
1066 ? fp_value.assign_float_with_boundaries(value)
1067 : fp_value.assign_with_boundaries(value);
1068 fp_value = normalize(fp_value);
1071 const fp cached_pow = get_cached_power(
1072 min_exp - (fp_value.e + fp::significand_size), cached_exp10);
1074 fp_value = fp_value * cached_pow;
1075 boundaries.lower = multiply(boundaries.lower, cached_pow.f);
1076 boundaries.upper = multiply(boundaries.upper, cached_pow.f);
1077 assert(min_exp <= fp_value.e && fp_value.e <= -32);
1081 grisu_shortest_handler handler{buf.data(), 0,
1082 boundaries.upper - fp_value.f};
1084 grisu_gen_digits(fp(boundaries.upper, fp_value.e),
1085 boundaries.upper - boundaries.lower, exp, handler);
1086 if (result == digits::error) {
1087 exp += handler.size - cached_exp10 - 1;
1088 fallback_format(value, buf, exp);
1091 buf.resize(to_unsigned(handler.size));
1093 if (precision > 17)
return snprintf_float(value, precision, specs, buf);
1094 fp normalized = normalize(fp(value));
1095 const auto cached_pow = get_cached_power(
1096 min_exp - (normalized.e + fp::significand_size), cached_exp10);
1097 normalized = normalized * cached_pow;
1098 fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
1099 if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error)
1100 return snprintf_float(value, precision, specs, buf);
1101 int num_digits = handler.size;
1104 while (num_digits > 0 && buf[num_digits - 1] ==
'0') {
1109 buf.resize(to_unsigned(num_digits));
1111 return exp - cached_exp10;
1114template <
typename T>
1115int snprintf_float(T value,
int precision, float_specs specs,
1116 buffer<char>& buf) {
1118 FMT_ASSERT(buf.capacity() > buf.size(),
"empty buffer");
1119 static_assert(!std::is_same<T, float>::value,
"");
1123 if (specs.format == float_format::general ||
1124 specs.format == float_format::exp)
1125 precision = (precision >= 0 ? precision : 6) - 1;
1128 enum { max_format_size = 7 };
1129 char format[max_format_size];
1130 char* format_ptr = format;
1131 *format_ptr++ =
'%';
1132 if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ =
'#';
1133 if (precision >= 0) {
1134 *format_ptr++ =
'.';
1135 *format_ptr++ =
'*';
1137 if (std::is_same<T, long double>()) *format_ptr++ =
'L';
1138 *format_ptr++ = specs.format != float_format::hex
1139 ? (specs.format == float_format::fixed ?
'f' :
'e')
1140 : (specs.upper ?
'A' :
'a');
1144 auto offset = buf.size();
1146 auto begin = buf.data() + offset;
1147 auto capacity = buf.capacity() - offset;
1148#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1149 if (precision > 100000)
1150 throw std::runtime_error(
1151 "fuzz mode - avoid large allocation inside snprintf");
1155 int (*snprintf_ptr)(
char*, size_t,
const char*, ...) = FMT_SNPRINTF;
1156 int result = precision >= 0
1157 ? snprintf_ptr(begin, capacity, format, precision, value)
1158 : snprintf_ptr(begin, capacity, format, value);
1160 buf.reserve(buf.capacity() + 1);
1163 auto size = to_unsigned(result);
1165 if (size >= capacity) {
1166 buf.reserve(size + offset + 1);
1169 auto is_digit = [](
char c) {
return c >=
'0' && c <=
'9'; };
1170 if (specs.format == float_format::fixed) {
1171 if (precision == 0) {
1176 auto end = begin + size, p = end;
1179 }
while (is_digit(*p));
1180 int fraction_size =
static_cast<int>(end - p - 1);
1181 std::memmove(p, p + 1, to_unsigned(fraction_size));
1182 buf.resize(size - 1);
1183 return -fraction_size;
1185 if (specs.format == float_format::hex) {
1186 buf.resize(size + offset);
1190 auto end = begin + size, exp_pos = end;
1193 }
while (*exp_pos !=
'e');
1194 char sign = exp_pos[1];
1195 assert(sign ==
'+' || sign ==
'-');
1197 auto p = exp_pos + 2;
1199 assert(is_digit(*p));
1200 exp = exp * 10 + (*p++ -
'0');
1202 if (sign ==
'-') exp = -exp;
1203 int fraction_size = 0;
1204 if (exp_pos != begin + 1) {
1206 auto fraction_end = exp_pos - 1;
1207 while (*fraction_end ==
'0') --fraction_end;
1209 fraction_size =
static_cast<int>(fraction_end - begin - 1);
1210 std::memmove(begin + 1, begin + 2, to_unsigned(fraction_size));
1212 buf.resize(to_unsigned(fraction_size) + offset + 1);
1213 return exp - fraction_size;
1234FMT_FUNC
const char* utf8_decode(
const char* buf, uint32_t* c,
int* e) {
1235 static const char lengths[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1236 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1237 0, 0, 2, 2, 2, 2, 3, 3, 4, 0};
1238 static const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
1239 static const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
1240 static const int shiftc[] = {0, 18, 12, 6, 0};
1241 static const int shifte[] = {0, 6, 4, 2, 0};
1243 auto s =
reinterpret_cast<const unsigned char*
>(buf);
1244 int len = lengths[s[0] >> 3];
1249 const char* next = buf + len + !len;
1253 *c = uint32_t(s[0] & masks[len]) << 18;
1254 *c |= uint32_t(s[1] & 0x3f) << 12;
1255 *c |= uint32_t(s[2] & 0x3f) << 6;
1256 *c |= uint32_t(s[3] & 0x3f) << 0;
1260 *e = (*c < mins[len]) << 6;
1261 *e |= ((*c >> 11) == 0x1b) << 7;
1262 *e |= (*c > 0x10FFFF) << 8;
1263 *e |= (s[1] & 0xc0) >> 2;
1264 *e |= (s[2] & 0xc0) >> 4;
1273template <>
struct formatter<internal::bigint> {
1278 format_context::iterator format(
const internal::bigint& n,
1279 format_context& ctx) {
1280 auto out = ctx.out();
1282 for (
auto i = n.bigits_.size(); i > 0; --i) {
1283 auto value = n.bigits_[i - 1u];
1285 out = format_to(out,
"{:x}", value);
1289 out = format_to(out,
"{:08x}", value);
1292 out = format_to(out,
"p{}", n.exp_ * internal::bigint::bigit_bits);
1297FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(
string_view s) {
1298 auto transcode = [
this](
const char* p) {
1299 auto cp = uint32_t();
1301 p = utf8_decode(p, &cp, &error);
1302 if (error != 0) FMT_THROW(std::runtime_error(
"invalid utf8"));
1304 buffer_.push_back(
static_cast<wchar_t>(cp));
1307 buffer_.push_back(
static_cast<wchar_t>(0xD800 + (cp >> 10)));
1308 buffer_.push_back(
static_cast<wchar_t>(0xDC00 + (cp & 0x3FF)));
1313 const size_t block_size = 4;
1314 if (s.
size() >= block_size) {
1315 for (
auto end = p + s.
size() - block_size + 1; p < end;) p = transcode(p);
1317 if (
auto num_chars_left = s.
data() + s.
size() - p) {
1318 char buf[2 * block_size - 1] = {};
1319 memcpy(buf, p, to_unsigned(num_chars_left));
1323 }
while (p - buf < num_chars_left);
1325 buffer_.push_back(0);
1332 buf.
resize(inline_buffer_size);
1334 char* system_message = &buf[0];
1336 internal::safe_strerror(error_code, system_message, buf.
size());
1338 internal::writer w(out);
1341 w.write(system_message);
1344 if (result != ERANGE)
1350 format_error_code(out, error_code, message);
1353FMT_FUNC
void internal::error_handler::on_error(
const char* message) {
1357FMT_FUNC
void report_system_error(
int error_code,
1358 fmt::string_view message) FMT_NOEXCEPT {
1359 report_error(format_system_error, error_code, message);
1364 internal::vformat_to(buffer, format_str,
1367 auto fd = _fileno(f);
1370 auto written = DWORD();
1371 if (!WriteConsoleW(
reinterpret_cast<HANDLE
>(_get_osfhandle(fd)),
1372 u16.c_str(),
static_cast<DWORD
>(u16.size()), &written,
1379 internal::fwrite_fully(buffer.
data(), 1, buffer.
size(), f);
1384FMT_FUNC
void internal::vprint_mojibake(std::FILE* f,
string_view format_str,
1387 internal::vformat_to(buffer, format_str,
1389 fwrite_fully(buffer.
data(), 1, buffer.
size(), f);
1394 vprint(stdout, format_str, args);
1400# pragma warning(pop)
FMT_CONSTEXPR iterator begin() const FMT_NOEXCEPT
Definition: core.h:568
FMT_CONSTEXPR size_t size() const
Definition: core.h:397
FMT_CONSTEXPR const Char * data() const
Definition: core.h:394
void resize(std::size_t new_size)
Definition: core.h:698
std::size_t capacity() const FMT_NOEXCEPT
Definition: core.h:687
std::size_t size() const FMT_NOEXCEPT
Definition: core.h:684
T * data() FMT_NOEXCEPT
Definition: core.h:690
Definition: format.h:2786