8 #ifndef FMT_FORMAT_INL_H_ 9 #define FMT_FORMAT_INL_H_ 22 #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) 27 # if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN) 28 # define WIN32_LEAN_AND_MEAN 30 # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX) 41 # define FMT_CATCH(x) catch (x) 43 # define FMT_TRY if (true) 44 # define FMT_CATCH(x) if (false) 48 # pragma warning(push) 49 # pragma warning(disable: 4127) // conditional expression is constant 50 # pragma warning(disable: 4702) // unreachable code 53 # pragma warning(disable: 4996) 58 inline fmt::internal::null<>
strerror_r(
int,
char *, ...) {
59 return fmt::internal::null<>();
61 inline fmt::internal::null<>
strerror_s(
char *, std::size_t, ...) {
62 return fmt::internal::null<>();
70 # define FMT_SNPRINTF snprintf 72 inline int fmt_snprintf(
char *
buffer,
size_t size,
const char *
format, ...) {
74 va_start(args, format);
75 int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
79 # define FMT_SNPRINTF fmt_snprintf 82 #if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT) 83 # define FMT_SWPRINTF snwprintf 85 # define FMT_SWPRINTF swprintf 86 #endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT) 107 std::size_t buffer_size_;
110 void operator=(
const dispatcher &) {}
113 int handle(
int result) {
115 return result == -1 ? errno : result;
119 int handle(
char *message) {
121 if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
128 int handle(internal::null<>) {
129 return fallback(
strerror_s(buffer_, buffer_size_, error_code_));
133 int fallback(
int result) {
135 return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
141 int fallback(internal::null<>) {
143 buffer_ = strerror(error_code_);
149 dispatcher(
int err_code,
char *&buf, std::size_t buf_size)
150 : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
153 return handle(
strerror_r(error_code_, buffer_, buffer_size_));
156 return dispatcher(error_code,
buffer, buffer_size).run();
159 void format_error_code(internal::buffer &out,
int error_code,
165 static const char SEP[] =
": ";
166 static const char ERROR_STR[] =
"error ";
168 std::size_t error_code_size =
sizeof(SEP) +
sizeof(ERROR_STR) - 2;
169 typedef internal::int_traits<int>::main_type main_type;
170 main_type abs_value =
static_cast<main_type
>(error_code);
172 abs_value = 0 - abs_value;
186 void report_error(FormatFunc func,
int error_code,
189 func(full_message, error_code, message);
192 std::fwrite(full_message.data(), full_message.size(), 1, stderr);
193 std::fputc(
'\n', stderr);
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)
204 return num_code_points;
207 #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) 210 template <
typename Locale>
211 locale_ref::locale_ref(
const Locale &loc) : locale_(&loc) {
212 static_assert(std::is_same<Locale, std::locale>::value,
"");
215 template <
typename Locale>
217 static_assert(std::is_same<Locale, std::locale>::value,
"");
218 return locale_ ? *
static_cast<const std::locale*
>(locale_) : std::locale();
221 template <
typename Char>
223 return std::use_facet<std::numpunct<Char> >(
224 loc.
get<std::locale>()).thousands_sep();
228 template <
typename Char>
230 return FMT_STATIC_THOUSANDS_SEPARATOR;
236 error_code_ = err_code;
239 std::runtime_error &base = *
this;
240 base = std::runtime_error(
to_string(buffer));
244 template <
typename T>
246 char *buf, std::size_t size,
const char *
format,
int precision, T
value) {
247 return precision < 0 ?
252 template <
typename T>
254 wchar_t *buf, std::size_t size,
const wchar_t *
format,
int precision,
256 return precision < 0 ?
261 template <
typename T>
263 "0001020304050607080910111213141516171819" 264 "2021222324252627282930313233343536373839" 265 "4041424344454647484950515253545556575859" 266 "6061626364656667686970717273747576777879" 267 "8081828384858687888990919293949596979899";
269 #define FMT_POWERS_OF_10(factor) \ 277 factor * 100000000, \ 280 template <
typename T>
285 template <
typename T>
290 template <
typename T>
295 10000000000000000000ull
300 template <
typename T>
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,
335 template <
typename T>
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
355 typedef uint64_t significand_type;
359 std::numeric_limits<unsigned char>::digits;
363 std::numeric_limits<double>::digits - 1;
365 1ull << double_significand_size;
372 sizeof(significand_type) * char_size;
375 fp(uint64_t f_val,
int e_val): f(f_val), e(e_val) {}
379 template <
typename Double>
380 explicit fp(Double d) {
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;
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;
390 auto biased_e = (u & exponent_mask) >> double_significand_size;
391 f = u & significand_mask;
396 e =
static_cast<int>(biased_e - exponent_bias - double_significand_size);
400 template <
int SHIFT = 0>
403 auto shifted_implicit_bit = implicit_bit << SHIFT;
404 while ((f & shifted_implicit_bit) == 0) {
409 auto offset = significand_size - double_significand_size - SHIFT - 1;
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);
423 lower.
f <<= lower.
e - upper.
e;
431 return fp(x.
f - y.
f, x.
e);
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;
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);
454 const double one_over_log2_10 = 0.30102999566398114;
455 int index =
static_cast<int>(std::ceil(
458 const int first_dec_exp = -348;
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;
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)) {
474 if (size > max_digits) {
477 if (buf[size] >=
'5')
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) {
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;
504 FMT_ASSERT(
false,
"invalid number of digits");
506 if (digit != 0 || size != 0)
507 buf[size++] =
static_cast<char>(
'0' + digit);
509 uint64_t remainder = (
static_cast<uint64_t
>(hi) << -one.
e) + lo;
510 if (remainder <= delta || size > max_digits) {
512 buf, size, max_digits, delta, remainder,
521 char digit =
static_cast<char>(lo >> -one.
e);
522 if (digit != 0 || size != 0)
523 buf[size++] =
static_cast<char>(
'0' + digit);
526 if (lo < delta || size > max_digits) {
533 #if FMT_CLANG_VERSION 534 # define FMT_FALLTHROUGH [[clang::fallthrough]]; 535 #elif FMT_GCC_VERSION >= 700 536 # define FMT_FALLTHROUGH [[gnu::fallthrough]]; 538 # define FMT_FALLTHROUGH 554 : data(b.data()), size(n), buf(b) {}
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));
568 std::memmove(data + pos + 1, data + pos,
to_unsigned(size - pos));
574 std::uninitialized_fill_n(data + size, n, c);
578 void append(
char c) { data[size++] = c; }
581 while (data[size - 1] == c) --size;
586 template <
typename Handler>
588 FMT_ASSERT(-1000 < exp && exp < 1000,
"exponent out of range");
596 h.append(static_cast<char>(
'0' + exp / 100));
613 std::uninitialized_fill_n(buf + 2, n,
'0');
618 template <
typename Handler>
620 int size,
int exp, Handler &&handler) {
623 handler.insert(1,
'.');
626 handler.append(params.
num_digits - size,
'0');
627 handler.append(params.
upper ?
'E' :
'e');
632 int full_exp = size + exp;
633 const int exp_threshold = 21;
634 if (size <= full_exp && full_exp <= exp_threshold) {
636 handler.append(full_exp - size,
'0');
640 handler.append(num_zeros,
'0');
642 }
else if (full_exp > 0) {
644 handler.insert(full_exp,
'.');
647 handler.remove_trailing(
'0');
650 ptrdiff_t num_zeros = params.
num_digits - size;
651 handler.append(num_zeros,
'0');
662 template <
typename F>
663 void insert(ptrdiff_t, ptrdiff_t n, F) { size += n; }
665 void append(ptrdiff_t n,
char) { size += n; }
677 switch (specs.
type) {
683 if (-4 <= exp && exp < num_digits + 1) {
685 if (!specs.
type && params.trailing_zeros && exp >= 0)
686 num_digits = exp + 1;
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;
707 params.num_digits = num_digits;
714 template <
typename Double>
720 const size_t size = 1;
731 const int min_exp = -60;
735 cached_exp = -cached_exp;
736 upper = upper * cached_pow;
738 fp one(1ull << -upper.
e, upper.
e);
741 uint32_t hi =
static_cast<uint32_t
>(upper.
f >> -one.
e);
745 fp scaled_value = fp_value * cached_pow;
746 lower = lower * cached_pow;
748 uint64_t delta = upper.
f - lower.
f;
749 fp diff = upper - scaled_value;
752 uint64_t lo = upper.
f & (one.
f - 1);
763 template <
typename Double>
770 enum { MAX_FORMAT_SIZE = 10};
771 char format[MAX_FORMAT_SIZE];
772 char *format_ptr =
format;
780 if (std::is_same<Double, long double>::value)
782 *format_ptr++ = spec.
type;
788 std::size_t buffer_size = buf.
capacity();
791 start, buffer_size, format, spec.
precision, value);
808 #if FMT_USE_WINDOWS_H 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());
822 int length = MultiByteToWideChar(
823 CP_UTF8, MB_ERR_INVALID_CHARS, s.
data(), s_size,
FMT_NULL, 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);
830 FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
837 "cannot convert string from UTF-16 to UTF-8"));
842 if (s.
size() > INT_MAX)
843 return ERROR_INVALID_PARAMETER;
844 int s_size =
static_cast<int>(s.
size());
852 int length = WideCharToMultiByte(
855 return GetLastError();
856 buffer_.resize(length + 1);
857 length = WideCharToMultiByte(
860 return GetLastError();
867 error_code_ = err_code;
869 internal::format_windows_error(buffer, err_code,
vformat(format_str, args));
870 std::runtime_error &base = *
this;
871 base = std::runtime_error(
to_string(buffer));
874 FMT_FUNC void internal::format_windows_error(
880 wchar_t *system_message = &buf[0];
881 int result = FormatMessageW(
882 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
884 system_message, static_cast<uint32_t>(buf.
size()),
FMT_NULL);
886 utf16_to_utf8 utf8_message;
887 if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
891 w.
write(utf8_message);
896 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
904 #endif // FMT_USE_WINDOWS_H 912 char *system_message = &buf[0];
913 int result = safe_strerror(
error_code, system_message, buf.
size());
918 w.
write(system_message);
921 if (result != ERANGE)
938 #if FMT_USE_WINDOWS_H 941 report_error(internal::format_windows_error,
error_code, message);
949 std::fwrite(buffer.
data(), 1, buffer.
size(), f);
955 std::fwrite(buffer.
data(),
sizeof(wchar_t), buffer.
size(), f);
959 vprint(stdout, format_str, args);
963 vprint(stdout, format_str, args);
969 # pragma warning(pop) 972 #endif // FMT_FORMAT_INL_H_ void append(ptrdiff_t n, char)
std::size_t capacity() const
void insert(ptrdiff_t, ptrdiff_t n, F)
void vprint(std::FILE *f, const text_style &ts, const S &format, basic_format_args< typename buffer_context< Char >::type > args)
Dest bit_cast(const Source &source)
static const char RESET_COLOR[]
bool grisu2_round(char *buf, int &size, int max_digits, uint64_t delta, uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10)
void insert(ptrdiff_t pos, char c)
void remove_trailing(char)
prettify_handler(buffer &b, ptrdiff_t n)
std::enable_if< sizeof(Double)==sizeof(uint64_t), bool >::type grisu2_format(Double value, buffer &buf, core_format_specs specs)
#define FMT_CONSTEXPR_DECL
gen_digits_params process_specs(const core_format_specs &specs, int exp, buffer &buf)
void compute_boundaries(fp &lower, fp &upper) const
void operator()(char *buf) const
void report_system_error(int error_code, fmt::string_view message)
fp get_cached_power(int min_exponent, int &pow10_exponent)
#define FMT_END_NAMESPACE
int count_digits(uint64_t n)
void write_exponent(int exp, Handler &&h)
buffer_context< Char >::type::iterator vformat_to(internal::basic_buffer< Char > &buf, basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
basic_memory_buffer< char > memory_buffer
static const wchar_t WRESET_COLOR[]
fp(uint64_t f_val, int e_val)
basic_buffer< char > buffer
static const char FOREGROUND_COLOR[]
void resize(std::size_t new_size)
void on_error(const char *message)
static const uint32_t ZERO_OR_POWERS_OF_10_32[]
std::make_unsigned< Int >::type to_unsigned(Int value)
std::basic_string< typename char_t< S >::type > format(const S &format_str, const Args &...args)
void remove_trailing(char c)
basic_writer< back_insert_range< internal::buffer > > writer
static const uint64_t ZERO_OR_POWERS_OF_10_64[]
Char thousands_sep_impl(locale_ref loc)
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type is_negative(T value)
bool grisu2_gen_digits(char *buf, int &size, uint32_t hi, uint64_t lo, int &exp, uint64_t delta, const fp &one, const fp &diff, int max_digits)
static const int16_t POW10_EXPONENTS[]
void reserve(std::size_t new_capacity)
void sprintf_format(Double value, internal::buffer &buf, core_format_specs spec)
size_t count_code_points(basic_string_view< Char > s)
static const uint64_t POW10_SIGNIFICANDS[]
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
static const char BACKGROUND_COLOR[]
static const uint32_t POWERS_OF_10_32[]
static const char DIGITS[]
std::string to_string(const T &value)
#define FMT_ASSERT(condition, message)
const Char * data() const
#define FMT_BEGIN_NAMESPACE
void grisu2_prettify(const gen_digits_params ¶ms, int size, int exp, Handler &&handler)
void format_system_error(internal::buffer &out, int error_code, string_view message)
static const int significand_size
unsigned count_digits(T n)
void append(ptrdiff_t n, char c)
basic_string_view< char > string_view
void insert(ptrdiff_t, char)
void insert(ptrdiff_t pos, ptrdiff_t n, F f)