42#include <system_error>
44#ifdef __cpp_lib_bit_cast
51#define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
53#define FMT_GCC_VISIBILITY_HIDDEN
57#define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
59#define FMT_CUDA_VERSION 0
63#define FMT_HAS_BUILTIN(x) __has_builtin(x)
65#define FMT_HAS_BUILTIN(x) 0
68#if FMT_GCC_VERSION || FMT_CLANG_VERSION
69#define FMT_NOINLINE __attribute__((noinline))
75#define FMT_MSC_DEFAULT = default
77#define FMT_MSC_DEFAULT
82#if FMT_MSC_VERSION || defined(__NVCC__)
86 template <
typename Exception>
87 inline void do_throw(
const Exception& x)
91 volatile bool b =
true;
97#define FMT_THROW(x) detail::do_throw(x)
99#define FMT_THROW(x) throw x
102#define FMT_THROW(x) \
105 FMT_ASSERT(false, (x).what()); \
112#define FMT_CATCH(x) catch (x)
114#define FMT_TRY if (true)
115#define FMT_CATCH(x) if (false)
118#ifndef FMT_MAYBE_UNUSED
119#if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
120#define FMT_MAYBE_UNUSED [[maybe_unused]]
122#define FMT_MAYBE_UNUSED
126#ifndef FMT_USE_USER_DEFINED_LITERALS
128#if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
129 FMT_MSC_VERSION >= 1900) && \
130 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 480)
131#define FMT_USE_USER_DEFINED_LITERALS 1
133#define FMT_USE_USER_DEFINED_LITERALS 0
141#if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
142#define FMT_REDUCE_INT_INSTANTIATIONS 0
148#if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
149#define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
151#if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
152#define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
159#if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION || \
160 defined(__NVCOMPILER)
161#define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
163#if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || \
164 FMT_ICC_VERSION || defined(__NVCOMPILER)
165#define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
176#if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) && \
177 !defined(FMT_BUILTIN_CTZLL)
182#if !defined(__clang__)
183#pragma intrinsic(_BitScanForward)
184#pragma intrinsic(_BitScanReverse)
186#pragma intrinsic(_BitScanForward64)
187#pragma intrinsic(_BitScanReverse64)
191 inline auto clz(uint32_t x) ->
int
194 _BitScanReverse(&r, x);
200 return 31 ^
static_cast<int>(r);
202#define FMT_BUILTIN_CLZ(n) detail::clz(n)
204 inline auto clzll(uint64_t x) ->
int
208 _BitScanReverse64(&r, x);
211 if (_BitScanReverse(&r,
static_cast<uint32_t
>(x >> 32)))
212 return 63 ^ (r + 32);
214 _BitScanReverse(&r,
static_cast<uint32_t
>(x));
218 return 63 ^
static_cast<int>(r);
220#define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
222 inline auto ctz(uint32_t x) ->
int
225 _BitScanForward(&r, x);
228 return static_cast<int>(r);
230#define FMT_BUILTIN_CTZ(n) detail::ctz(n)
232 inline auto ctzll(uint64_t x) ->
int
238 _BitScanForward64(&r, x);
241 if (_BitScanForward(&r,
static_cast<uint32_t
>(x)))
242 return static_cast<int>(r);
244 _BitScanForward(&r,
static_cast<uint32_t
>(x >> 32));
247 return static_cast<int>(r);
249#define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
263 throw std::runtime_error(
"fuzzing limit reached");
267 template <
typename CharT, CharT... C>
270 static constexpr CharT
value[
sizeof...(C)] = {C...};
273 return {
value,
sizeof...(C)};
277#if FMT_CPLUSPLUS < 201703L
278 template <
typename CharT, CharT... C>
279 constexpr CharT string_literal<CharT, C...>
::value[
sizeof...(C)];
282 template <
typename Streambuf>
287 using streamsize =
decltype(std::declval<Streambuf>().sputn(
nullptr, 0));
308 if (!traits_type::eq_int_type(ch, traits_type::eof()))
321 template <
typename To,
typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>
324#ifdef __cpp_lib_bit_cast
326 return std::bit_cast<To>(from);
330 std::memcpy(
static_cast<void*
>(&to), &from,
sizeof(to));
338#elif defined(__BIG_ENDIAN__)
340#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
341 return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
345 char data[
sizeof(int)];
347 return bit_cast<bytes>(1).data[0] == 0;
368 constexpr uint64_t
high() const noexcept
372 constexpr uint64_t
low() const noexcept
377 template <
typename T, FMT_ENABLE_IF(std::is_
integral<T>::value)>
378 constexpr explicit operator T()
const
380 return static_cast<T
>(
lo_);
386 return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
391 return !(lhs == rhs);
396 return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;
402 return {lhs.
hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};
408 return {lhs.
hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
421 uint64_t hi = (lhs.lo_ >> 32) * rhs;
422 uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;
423 uint64_t new_lo = (hi << 32) + lo;
424 return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};
429 return {lhs.
hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};
437 return {
hi_ >> shift, (
hi_ << (64 - shift)) | (
lo_ >> shift)};
445 return {
hi_ << shift | (
lo_ >> (64 - shift)), (
lo_ << shift)};
449 return *
this = *
this >> shift;
453 uint64_t new_lo =
lo_ + n.
lo_;
454 uint64_t new_hi =
hi_ + n.
hi_ + (new_lo <
lo_ ? 1 : 0);
468#if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)
469 unsigned long long carry;
470 lo_ = __builtin_addcll(
lo_, n, 0, &carry);
472#elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)
473 unsigned long long result;
474 auto carry = __builtin_ia32_addcarryx_u64(0,
lo_, n, &result);
477#elif defined(_MSC_VER) && defined(_M_X64)
478 auto carry = _addcarry_u64(0,
lo_, n, &
lo_);
479 _addcarry_u64(carry,
hi_, 0, &
hi_);
498 template <
typename T>
501 return (std::numeric_limits<T>::max)();
503 template <
typename T>
506 return std::numeric_limits<T>::digits;
522 template <
typename To,
typename From, FMT_ENABLE_IF(sizeof(To) >
sizeof(From))>
525 constexpr auto size =
static_cast<int>(
sizeof(From) /
sizeof(
unsigned));
528 unsigned value[
static_cast<unsigned>(size)];
529 }
data = bit_cast<data_t>(from);
533 for (
int i = 0;
i < size; ++
i)
534 result = (result << num_bits<unsigned>()) |
data.value[
i];
538 for (
int i = size - 1;
i >= 0; --
i)
539 result = (result << num_bits<unsigned>()) |
data.value[
i];
547#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
548 __builtin_assume(condition);
553 template <
typename T>
555 template <
typename T>
559 template <
typename Char>
560 inline auto get_data(std::basic_string<Char>&
s) -> Char*
564 template <
typename Container>
565 inline auto get_data(Container& c) ->
typename Container::value_type*
570#if defined(_SECURE_SCL) && _SECURE_SCL
572 template <
typename T>
573 using checked_ptr = stdext::checked_array_iterator<T*>;
574 template <
typename T>
575 constexpr auto make_checked(T*
p,
size_t size) -> checked_ptr<T>
580 template <
typename T>
582 template <
typename T>
591 template <
typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
592#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
593 __attribute__((no_sanitize(
"undefined")))
596 reserve(std::back_insert_iterator<Container> it,
size_t n)
600 size_t size = c.size();
605 template <
typename T>
609 buf.try_reserve(buf.size() + n);
613 template <
typename Iterator>
614 constexpr auto reserve(Iterator& it,
size_t) -> Iterator&
619 template <
typename OutputIt>
623 template <
typename T,
typename OutputIt>
628 template <
typename T>
632 auto size = buf.size();
633 if (buf.capacity() < size + n)
635 buf.try_resize(size + n);
636 return buf.data() + size;
639 template <
typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
642 -> std::back_insert_iterator<Container>
647 template <
typename Iterator>
655 template <
typename OutputIt,
typename Size,
typename T>
663 template <
typename T,
typename Size>
682 template <
typename OutChar,
typename InputIt,
typename OutputIt>
685 return copy_str<OutChar>(begin, end,
out);
708 constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
709 constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
710 constexpr const int shiftc[] = {0, 18, 12, 6, 0};
711 constexpr const int shifte[] = {0, 6, 4, 2, 0};
717 const char* next =
s + len + !len;
719 using uchar =
unsigned char;
723 *c = uint32_t(uchar(
s[0]) & masks[len]) << 18;
724 *c |= uint32_t(uchar(
s[1]) & 0x3f) << 12;
725 *c |= uint32_t(uchar(
s[2]) & 0x3f) << 6;
726 *c |= uint32_t(uchar(
s[3]) & 0x3f) << 0;
730 *e = (*c < mins[len]) << 6;
731 *e |= ((*c >> 11) == 0x1b) << 7;
732 *e |= (*c > 0x10FFFF) << 8;
733 *e |= (uchar(
s[1]) & 0xc0) >> 2;
734 *e |= (uchar(
s[2]) & 0xc0) >> 4;
735 *e |= uchar(
s[3]) >> 6;
746 template <
typename F>
749 auto decode = [f](
const char* buf_ptr,
const char*
ptr) {
750 auto cp = uint32_t();
755 return result ? (error ? buf_ptr + 1 : end) :
nullptr;
758 const size_t block_size = 4;
759 if (
s.size() >= block_size)
761 for (
auto end =
p +
s.size() - block_size + 1;
p < end;)
768 if (
auto num_chars_left =
s.data() +
s.size() -
p)
770 char buf[2 * block_size - 1] = {};
771 copy_str<char>(
p,
p + num_chars_left, buf);
772 const char* buf_ptr = buf;
775 auto end = decode(buf_ptr,
p);
780 }
while (buf_ptr - buf < num_chars_left);
784 template <
typename Char>
793 size_t num_code_points = 0;
795 struct count_code_points
800 *
count += detail::to_unsigned(
807 (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
808 (cp >= 0xac00 && cp <= 0xd7a3) ||
809 (cp >= 0xf900 && cp <= 0xfaff) ||
810 (cp >= 0xfe10 && cp <= 0xfe19) ||
811 (cp >= 0xfe30 && cp <= 0xfe6f) ||
812 (cp >= 0xff00 && cp <= 0xff60) ||
813 (cp >= 0xffe0 && cp <= 0xffe6) ||
814 (cp >= 0x20000 && cp <= 0x2fffd) ||
815 (cp >= 0x30000 && cp <= 0x3fffd) ||
817 (cp >= 0x1f300 && cp <= 0x1f64f) ||
819 (cp >= 0x1f900 && cp <= 0x1f9ff))));
824 return num_code_points;
830 string_view(
reinterpret_cast<const char*
>(
s.data()),
s.size()));
833 template <
typename Char>
836 size_t size =
s.size();
837 return n < size ? n : size;
843 const char*
data =
s.data();
844 size_t num_code_points = 0;
845 for (
size_t i = 0, size =
s.size();
i != size; ++
i)
847 if ((
data[
i] & 0xc0) != 0x80 && ++num_code_points > n)
857 string_view(
reinterpret_cast<const char*
>(
s.data()),
s.size()), n);
860#ifndef FMT_USE_FLOAT128
861#ifdef __SIZEOF_FLOAT128__
862#define FMT_USE_FLOAT128 1
864#define FMT_USE_FLOAT128 0
872 template <
typename T>
875 template <
typename T>
879 template <typename T, bool = std::is_floating_point<T>::value>
880 struct is_fast_float :
bool_constant<std::numeric_limits<T>::is_iec559 &&
881 sizeof(T) <= sizeof(double)>
884 template <typename T>
885 struct is_fast_float<T, false> : std::false_type
889 template <typename T>
890 using is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;
892#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
893#define FMT_USE_FULL_CACHE_DRAGONBOX 0
896 template <typename T>
897 template <typename U>
898 void buffer<T>::append(const U* begin, const U* end)
902 auto count = to_unsigned(end - begin);
903 try_reserve(size_ + count);
904 auto free_cap = capacity_ - size_;
905 if (free_cap < count)
907 std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
913 template <typename T, typename Enable = void>
914 struct is_locale : std::false_type
917 template <typename T>
918 struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type
923FMT_MODULE_EXPORT_BEGIN
929 inline_buffer_size = 500
953template <typename T, size_t SIZE = inline_buffer_size, typename Allocator = std::allocator<T>>
954class basic_memory_buffer final : public detail::buffer<T>
963 FMT_CONSTEXPR20 void deallocate()
965 T* data = this->data();
967 alloc_.deallocate(data, this->capacity());
978 const Allocator& alloc = Allocator())
981 this->
set(store_, SIZE);
982 if (detail::is_constant_evaluated())
994 alloc_ = std::move(other.
alloc_);
995 T*
data = other.data();
996 size_t size = other.size(), capacity = other.capacity();
999 this->
set(store_, capacity);
1005 this->
set(data, capacity);
1008 other.set(other.
store_, 0);
1051 this->try_resize(
count);
1057 this->try_reserve(new_capacity);
1061 using detail::buffer<T>::append;
1062 template <
typename ContiguousRange>
1065 append(range.data(), range.data() + range.size());
1069template <
typename T,
size_t SIZE,
typename Allocator>
1074 const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
1075 size_t old_capacity = this->capacity();
1076 size_t new_capacity = old_capacity + old_capacity / 2;
1077 if (size > new_capacity)
1078 new_capacity = size;
1079 else if (new_capacity > max_size)
1080 new_capacity = size > max_size ? size : max_size;
1081 T* old_data = this->
data();
1083 std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
1085 std::uninitialized_copy(old_data, old_data + this->size(),
1087 this->
set(new_data, new_capacity);
1091 if (old_data != store_)
1092 alloc_.deallocate(old_data, old_capacity);
1097template <
typename T,
size_t SIZE,
typename Allocator>
1116 :
std::runtime_error(message)
1120 :
std::runtime_error(message)
1132#if FMT_USE_NONTYPE_TEMPLATE_ARGS
1133 template <
typename Char,
size_t N>
1136 constexpr fixed_string(
const Char (&str)[N])
1138 detail::copy_str<Char, const Char*, Char*>(
static_cast<const Char*
>(str),
1146 template <
typename Char,
size_t N>
1152 return {
s, N - (std::char_traits<Char>::to_int_type(
s[N - 1]) == 0 ? 1 : 0)};
1154 template <
typename Char>
1158 return {
s.
data(),
s.size()};
1164template <
typename T>
1177template <
typename T>
1179 std::integral_constant<bool, std::numeric_limits<T>::is_signed || std::is_same<T, int128_opt>::value>;
1183template <
typename T, FMT_ENABLE_IF(is_
signed<T>::value)>
1188template <
typename T, FMT_ENABLE_IF(!is_
signed<T>::value)>
1194template <
typename T>
1197 if (std::is_same<T, float>())
1199 if (std::is_same<T, double>())
1201 if (std::is_same<T, long double>())
1208template <
typename T>
1213template <
typename T>
1216#define FMT_POWERS_OF_10(factor) \
1217 factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, (factor) * 100000, \
1218 (factor) * 1000000, (factor) * 10000000, (factor) * 100000000, \
1219 (factor) * 1000000000
1225 return &
"0001020304050607080910111213141516171819"
1226 "2021222324252627282930313233343536373839"
1227 "4041424344454647484950515253545556575859"
1228 "6061626364656667686970717273747576777879"
1229 "8081828384858687888990919293949596979899"[
value * 2];
1233template <
typename Char,
typename Sign>
1236#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604
1237 static_assert(std::is_same<Sign, sign_t>::value,
"");
1239 return static_cast<Char
>(
"\0-+ "[
s]);
1242template <
typename T>
1270#ifdef FMT_BUILTIN_CLZLL
1273inline auto do_count_digits(uint64_t n) ->
int
1279 static constexpr uint8_t bsr2log10[] = {
1280 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
1281 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
1282 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1283 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1284 auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
1285 static constexpr const uint64_t zero_or_powers_of_10[] = {
1287 10000000000000000000ULL};
1288 return t - (n < zero_or_powers_of_10[t]);
1296#ifdef FMT_BUILTIN_CLZLL
1299 return do_count_digits(n);
1306template <
int BITS,
typename UInt>
1309#ifdef FMT_BUILTIN_CLZ
1311 return (FMT_BUILTIN_CLZ(
static_cast<uint32_t
>(n) | 1) ^ 31) / BITS + 1;
1319 }
while ((m >>= BITS) != 0);
1324#ifdef FMT_BUILTIN_CLZ
1327FMT_INLINE auto do_count_digits(uint32_t n) ->
int
1331#define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)
1332 static constexpr uint64_t
table[] = {
1333 FMT_INC(0), FMT_INC(0), FMT_INC(0),
1334 FMT_INC(10), FMT_INC(10), FMT_INC(10),
1335 FMT_INC(100), FMT_INC(100), FMT_INC(100),
1336 FMT_INC(1000), FMT_INC(1000), FMT_INC(1000),
1337 FMT_INC(10000), FMT_INC(10000), FMT_INC(10000),
1338 FMT_INC(100000), FMT_INC(100000), FMT_INC(100000),
1339 FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000),
1340 FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000),
1341 FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000),
1342 FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000),
1343 FMT_INC(1000000000), FMT_INC(1000000000)
1345 auto inc =
table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
1346 return static_cast<int>((n + inc) >> 32);
1353#ifdef FMT_BUILTIN_CLZ
1356 return do_count_digits(n);
1362template <
typename Int>
1365 return std::numeric_limits<Int>::digits10;
1378template <
typename Char>
1385template <
typename Char>
1387template <
typename Char>
1391 return {result.grouping, Char(result.thousands_sep)};
1399template <
typename Char>
1401template <
typename Char>
1404 return Char(decimal_point_impl<char>(loc));
1409 return decimal_point_impl<wchar_t>(loc);
1413template <
typename Char>
1414auto equal2(
const Char* lhs,
const char* rhs) ->
bool
1416 return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1418inline auto equal2(
const char* lhs,
const char* rhs) ->
bool
1420 return memcmp(lhs, rhs, 2) == 0;
1424template <
typename Char>
1429 memcpy(dst, src, 2);
1432 *dst++ =
static_cast<Char
>(*src++);
1433 *dst =
static_cast<Char
>(*src);
1436template <
typename Iterator>
1446template <
typename Char,
typename UInt>
1453 while (
value >= 100)
1464 *--
out =
static_cast<Char
>(
'0' +
value);
1472template <
typename Char,
typename UInt,
typename Iterator, FMT_ENABLE_IF(!std::is_po
inter<remove_cvref_t<Iterator>>::value)>
1477 Char
buffer[digits10<UInt>() + 1];
1479 return {
out, detail::copy_str_noinline<Char>(
buffer, end,
out)};
1482template <
unsigned BASE_BITS,
typename Char,
typename UInt>
1489 const char*
digits = upper ?
"0123456789ABCDEF" :
"0123456789abcdef";
1490 unsigned digit =
static_cast<unsigned>(
value & ((1 << BASE_BITS) - 1));
1491 *--
buffer =
static_cast<Char
>(BASE_BITS < 4 ? static_cast<char>(
'0' + digit)
1493 }
while ((
value >>= BASE_BITS) != 0);
1497template <
unsigned BASE_BITS,
typename Char,
typename It,
typename UInt>
1503 format_uint<BASE_BITS>(
ptr,
value, num_digits, upper);
1507 char buffer[num_bits<UInt>() / BASE_BITS + 1];
1508 format_uint<BASE_BITS>(
buffer,
value, num_digits, upper);
1509 return detail::copy_str_noinline<Char>(
buffer,
buffer + num_digits,
out);
1522 return {&buffer_[0], size()};
1526 return buffer_.size() - 1;
1534 return {&buffer_[0], size()};
1542 template <
typename T,
typename Enable =
void>
1549 static const int exponent_bits = 8;
1550 static const int kappa = 1;
1551 static const int big_divisor = 100;
1552 static const int small_divisor = 10;
1553 static const int min_k = -31;
1554 static const int max_k = 46;
1555 static const int shorter_interval_tie_lower_threshold = -35;
1556 static const int shorter_interval_tie_upper_threshold = -35;
1563 static const int exponent_bits = 11;
1564 static const int kappa = 2;
1565 static const int big_divisor = 1000;
1566 static const int small_divisor = 100;
1567 static const int min_k = -292;
1568 static const int max_k = 326;
1569 static const int shorter_interval_tie_lower_threshold = -77;
1570 static const int shorter_interval_tie_upper_threshold = -77;
1574 template <
typename T>
1578 static const int exponent_bits = 15;
1582 template <
typename T>
1588 template <
typename T>
1596 template <
typename T>
1601template <
typename Float>
1605 return std::numeric_limits<Float>::digits != 64;
1610template <
typename Float>
1614 return is_float128<Float>() ? 112
1615 : (std::numeric_limits<Float>::digits -
1616 (has_implicit_bit<Float>() ? 1 : 0));
1619template <
typename Float>
1625 << num_significand_bits<Float>();
1627template <
typename Float>
1631 return is_float128<Float>() ? 16383
1632 : std::numeric_limits<Float>::max_exponent - 1;
1636template <
typename Char,
typename It>
1642 *it++ =
static_cast<Char
>(
'-');
1647 *it++ =
static_cast<Char
>(
'+');
1653 *it++ =
static_cast<Char
>(top[0]);
1654 *it++ =
static_cast<Char
>(top[1]);
1658 *it++ =
static_cast<Char
>(d[0]);
1659 *it++ =
static_cast<Char
>(d[1]);
1664template <
typename F>
1671 static_cast<int>(
sizeof(F) * num_bits<unsigned char>());
1678 : f(f_val), e(e_val)
1683 template <
typename Float>
1690 template <
typename Float, FMT_ENABLE_IF(!is_
double_
double<Float>::value)>
1693 static_assert(std::numeric_limits<Float>::digits <= 113,
"unsupported FP");
1696 const auto num_float_significand_bits =
1697 detail::num_significand_bits<Float>();
1698 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1699 const auto significand_mask = implicit_bit - 1;
1700 auto u = bit_cast<carrier_uint>(n);
1701 f =
static_cast<F
>(
u & significand_mask);
1702 auto biased_e =
static_cast<int>((
u & exponent_mask<Float>()) >>
1703 num_float_significand_bits);
1706 auto is_predecessor_closer = f == 0 && biased_e > 1;
1709 else if (has_implicit_bit<Float>())
1710 f +=
static_cast<F
>(implicit_bit);
1711 e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1712 if (!has_implicit_bit<Float>())
1714 return is_predecessor_closer;
1717 template <
typename Float, FMT_ENABLE_IF(is_
double_
double<Float>::value)>
1720 static_assert(std::numeric_limits<double>::is_iec559,
"unsupported FP");
1721 return assign(
static_cast<double>(n));
1728template <
int SHIFT = 0,
typename F>
1732 const auto implicit_bit = F(1) << num_significand_bits<double>();
1733 const auto shifted_implicit_bit = implicit_bit << SHIFT;
1734 while ((
value.f & shifted_implicit_bit) == 0)
1741 num_significand_bits<double>() - SHIFT - 1;
1751 auto product =
static_cast<__uint128_t
>(lhs) * rhs;
1752 auto f =
static_cast<uint64_t
>(product >> 64);
1753 return (
static_cast<uint64_t
>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1756 uint64_t mask = (1ULL << 32) - 1;
1757 uint64_t
a = lhs >> 32,
b = lhs & mask;
1758 uint64_t c = rhs >> 32, d = rhs & mask;
1759 uint64_t ac =
a * c, bc =
b * c, ad =
a * d, bd =
b * d;
1761 uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1762 return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1768 return {
multiply(x.f, y.f), x.e + y.e + 64};
1771template <
typename T =
void>
1776 static constexpr uint64_t pow10_significands[87] = {
1866#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1867#pragma GCC diagnostic push
1868#pragma GCC diagnostic ignored "-Wnarrowing"
1872 static constexpr int16_t pow10_exponents[87] = {
1873 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
1874 -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
1875 -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
1876 -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
1877 -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
1878 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
1879 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
1880 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
1881#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1882#pragma GCC diagnostic pop
1885 static constexpr uint64_t power_of_10_64[20] = {
1887 10000000000000000000ULL};
1890#if FMT_CPLUSPLUS < 201703L
1891template <
typename T>
1893template <
typename T>
1895template <
typename T>
1907 int& pow10_exponent)
1909 const int shift = 32;
1911 const int64_t significand = 0x4d104d427de7fbcc;
1912 int index =
static_cast<int>(
1913 ((min_exponent + fp::num_significand_bits - 1) * (significand >> shift) +
1914 ((int64_t(1) << shift) - 1))
1918 const int first_dec_exp = -348;
1920 const int dec_exp_step = 8;
1921 index = (
index - first_dec_exp - 1) / dec_exp_step + 1;
1922 pow10_exponent = first_dec_exp +
index * dec_exp_step;
1930#define FMT_SNPRINTF snprintf
1932FMT_API auto fmt_snprintf(
char* buf,
size_t size,
const char*
fmt, ...) -> int;
1933#define FMT_SNPRINTF fmt_snprintf
1937template <
typename T>
1941 FMT_ASSERT(buf.capacity() > buf.size(),
"empty buffer");
1943 static_assert(!std::is_same<T, float>::value,
"");
1947 char* format_ptr =
format;
1948 *format_ptr++ =
'%';
1949 if (specs.showpoint)
1950 *format_ptr++ =
'#';
1953 *format_ptr++ =
'.';
1954 *format_ptr++ =
'*';
1956 if (std::is_same<T, long double>())
1957 *format_ptr++ =
'L';
1958 *format_ptr++ = specs.upper ?
'A' :
'a';
1962 auto offset = buf.size();
1965 auto begin = buf.data() +
offset;
1966 auto capacity = buf.capacity() -
offset;
1967 abort_fuzzing_if(precision > 100000);
1970 int (*snprintf_ptr)(
char*, size_t,
const char*, ...) =
FMT_SNPRINTF;
1971 int result = precision >= 0
1972 ? snprintf_ptr(begin, capacity,
format, precision,
value)
1977 buf.try_reserve(buf.capacity() + 1);
1982 if (size < capacity)
1984 buf.try_resize(size +
offset);
1987 buf.try_reserve(size +
offset + 1);
1991template <
typename T>
1997template <
typename T>
2003template <
typename OutputIt,
typename Char>
2006 auto fill_size =
fill.size();
2010 for (
size_t i = 0;
i < n; ++
i)
2011 it = copy_str<Char>(
data,
data + fill_size, it);
2018template <align::type align = align::left,
typename OutputIt,
typename Char,
typename F>
2025 static_assert(
align == align::left ||
align == align::right,
"");
2027 size_t padding = spec_width > width ? spec_width - width : 0;
2030 auto* shifts =
align == align::left ?
"\x1f\x1f\x00\x01" :
"\x00\x1f\x00\x01";
2031 size_t left_padding = padding >> shifts[specs.align];
2032 size_t right_padding = padding - left_padding;
2033 auto it = reserve(
out, size + padding * specs.fill.size());
2034 if (left_padding != 0)
2035 it =
fill(it, left_padding, specs.fill);
2037 if (right_padding != 0)
2038 it =
fill(it, right_padding, specs.fill);
2039 return base_iterator(
out, it);
2042template <align::type align = align::left,
typename OutputIt,
typename Char,
typename F>
2045 return write_padded<align>(
out, specs, size, size, f);
2048template <align::type align = align::left,
typename Char,
typename OutputIt>
2052 return write_padded<align>(
2053 out, specs,
bytes.size(), [
bytes](reserve_iterator<OutputIt> it) {
2054 const char* data = bytes.data();
2055 return copy_str<Char>(data, data + bytes.size(), it);
2059template <
typename Char,
typename OutputIt,
typename UIntPtr>
2062 int num_digits = count_digits<4>(
value);
2064 auto write = [=](reserve_iterator<OutputIt> it) {
2065 *it++ =
static_cast<Char
>(
'0');
2066 *it++ =
static_cast<Char
>(
'x');
2067 return format_uint<4, Char>(it,
value, num_digits);
2069 return specs ? write_padded<align::right>(
out, *specs, size,
write)
2078 return cp < 0x20 || cp == 0x7f || cp ==
'"' || cp ==
'\\' ||
2082template <
typename Char>
2090template <
typename Char>
2093 std::make_unsigned<Char>,
2096template <
typename Char>
2100 for (; begin != end; ++begin)
2106 return {begin, begin + 1, cp};
2108 return {begin,
nullptr, 0};
2115 return find_escape<char>(begin, end);
2121 result = {sv.
begin(), sv.
end(), cp};
2129#define FMT_STRING_IMPL(s, base, explicit) \
2133 struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base \
2135 using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t<decltype(s[0])>; \
2136 FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
2137 operator fmt::basic_string_view<char_type>() const \
2139 return fmt::detail_exported::compile_string_to_view<char_type>(s); \
2142 return FMT_COMPILE_STRING(); \
2155#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
2157template <
size_t w
idth,
typename Char,
typename OutputIt>
2160 *
out++ =
static_cast<Char
>(
'\\');
2161 *
out++ =
static_cast<Char
>(prefix);
2163 fill_n(buf, width,
static_cast<Char
>(
'0'));
2164 format_uint<4>(buf, cp, width);
2165 return copy_str<Char>(buf, buf + width,
out);
2168template <
typename OutputIt,
typename Char>
2172 auto c =
static_cast<Char
>(escape.cp);
2176 *
out++ =
static_cast<Char
>(
'\\');
2177 c =
static_cast<Char
>(
'n');
2180 *
out++ =
static_cast<Char
>(
'\\');
2181 c =
static_cast<Char
>(
'r');
2184 *
out++ =
static_cast<Char
>(
'\\');
2185 c =
static_cast<Char
>(
't');
2192 *
out++ =
static_cast<Char
>(
'\\');
2197 if (escape.cp < 0x100)
2199 return write_codepoint<2, Char>(
out,
'x', escape.cp);
2201 if (escape.cp < 0x10000)
2203 return write_codepoint<4, Char>(
out,
'u', escape.cp);
2205 if (escape.cp < 0x110000)
2207 return write_codepoint<8, Char>(
out,
'U', escape.cp);
2211 escape.begin,
to_unsigned(escape.end - escape.begin)))
2213 out = write_codepoint<2, Char>(
out,
'x',
2214 static_cast<uint32_t
>(escape_char) & 0xFF);
2222template <
typename Char,
typename OutputIt>
2226 *
out++ =
static_cast<Char
>(
'"');
2227 auto begin = str.begin(), end = str.end();
2231 out = copy_str<Char>(begin, escape.begin,
out);
2235 out = write_escaped_cp<OutputIt, Char>(
out, escape);
2236 }
while (begin != end);
2237 *
out++ =
static_cast<Char
>(
'"');
2241template <
typename Char,
typename OutputIt>
2244 *
out++ =
static_cast<Char
>(
'\'');
2245 if ((
needs_escape(
static_cast<uint32_t
>(v)) && v !=
static_cast<Char
>(
'"')) ||
2246 v ==
static_cast<Char
>(
'\''))
2255 *
out++ =
static_cast<Char
>(
'\'');
2259template <
typename Char,
typename OutputIt>
2264 return write_padded(
out, specs, 1, [=](reserve_iterator<OutputIt> it) {
2271template <
typename Char,
typename OutputIt>
2281template <
typename Char>
2288 : size((prefix >> 24) +
to_unsigned(num_digits)), padding(0)
2290 if (specs.
align == align::numeric)
2295 padding = width - size;
2311template <
typename OutputIt,
typename Char,
typename W>
2317 auto it = reserve(
out,
to_unsigned(num_digits) + (prefix >> 24));
2320 for (
unsigned p = prefix & 0xffffff;
p != 0;
p >>= 8)
2321 *it++ =
static_cast<Char
>(
p & 0xff);
2323 return base_iterator(
out, write_digits(it));
2326 return write_padded<align::right>(
2327 out, specs,
data.size, [=](reserve_iterator<OutputIt> it) {
2328 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2329 *it++ = static_cast<Char>(p & 0xff);
2330 it = detail::fill_n(it, data.padding, static_cast<Char>(
'0'));
2331 return write_digits(it);
2335template <
typename Char>
2355 return max_value<int>();
2358 if (*state.
group <= 0 || *state.
group == max_value<char>())
2359 return max_value<int>();
2368 sep_ = thousands_sep<Char>(loc);
2385 auto state = initial_state();
2386 while (num_digits > next(state))
2392 template <
typename Out,
typename C>
2395 auto num_digits =
static_cast<int>(
digits.size());
2397 separators.push_back(0);
2398 auto state = initial_state();
2399 while (
int i = next(state))
2401 if (
i >= num_digits)
2403 separators.push_back(
i);
2405 for (
int i = 0, sep_index =
static_cast<int>(separators.size() - 1);
2406 i < num_digits; ++
i)
2408 if (num_digits -
i == separators[sep_index])
2410 *
out++ = separator();
2419template <
typename OutputIt,
typename UInt,
typename Char>
2422 static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>
::value,
"");
2426 unsigned size =
to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
2427 grouping.count_separators(num_digits));
2428 return write_padded<align::right>(
2429 out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
2432 char sign =
static_cast<char>(prefix);
2433 *it++ =
static_cast<Char
>(
sign);
2439template <
typename OutputIt,
typename UInt,
typename Char>
2451 prefix += (1u + (
value > 0xff ? 1 : 0)) << 24;
2454template <
typename UInt>
2461template <
typename T>
2469 prefix = 0x01000000 |
'-';
2470 abs_value = 0 - abs_value;
2474 constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u |
'+',
2476 prefix = prefixes[
sign];
2478 return {abs_value, prefix};
2481template <
typename Char,
typename OutputIt,
typename T>
2484 static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>
::value,
"");
2486 auto prefix =
arg.prefix;
2493 prefix, specs, loc))
2499 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2500 return format_decimal<Char>(it, abs_value, num_digits).end;
2507 prefix_append(prefix,
unsigned(upper ?
'X' :
'x') << 8 |
'0');
2508 int num_digits = count_digits<4>(abs_value);
2510 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2511 return format_uint<4, Char>(it, abs_value, num_digits, upper);
2518 prefix_append(prefix,
unsigned(upper ?
'B' :
'b') << 8 |
'0');
2519 int num_digits = count_digits<1>(abs_value);
2521 [=](reserve_iterator<OutputIt> it) {
2522 return format_uint<1, Char>(it, abs_value, num_digits);
2526 int num_digits = count_digits<3>(abs_value);
2529 if (specs.
alt && specs.
precision <= num_digits && abs_value != 0)
2532 [=](reserve_iterator<OutputIt> it) {
2533 return format_uint<3, Char>(it, abs_value, num_digits);
2537 return write_char(
out,
static_cast<Char
>(abs_value), specs);
2543template <
typename Char,
typename OutputIt,
typename T>
2549template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(is_
integral<T>::value && !std::is_same<T,
bool>::value && std::is_same<OutputIt, buffer_appender<Char>>::value)>
2556template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(is_
integral<T>::value && !std::is_same<T,
bool>::value && !std::is_same<OutputIt, buffer_appender<Char>>::value)>
2578 template <
typename T>
2609 it.
count_ +=
static_cast<size_t>(n);
2619template <
typename Char,
typename OutputIt>
2622 auto data =
s.data();
2623 auto size =
s.size();
2628 if (specs.
width != 0)
2636 [=](reserve_iterator<OutputIt> it) {
2639 return copy_str<Char>(
data,
data + size, it);
2642template <
typename Char,
typename OutputIt>
2652template <
typename Char,
typename OutputIt>
2658 : write_ptr<Char>(
out, bit_cast<uintptr_t>(
s), &specs);
2661template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(is_
integral<T>::value && !std::is_same<T,
bool>::value && !std::is_same<T, Char>::value)>
2668 abs_value = ~abs_value + 1;
2670 auto size = (negative ? 1 : 0) +
static_cast<size_t>(num_digits);
2671 auto it = reserve(
out, size);
2672 if (
auto ptr = to_pointer<Char>(it, size))
2675 *
ptr++ =
static_cast<Char
>(
'-');
2676 format_decimal<Char>(
ptr, abs_value, num_digits);
2680 *it++ =
static_cast<Char
>(
'-');
2681 it = format_decimal<Char>(it, abs_value, num_digits).end;
2682 return base_iterator(
out, it);
2685template <
typename Char,
typename OutputIt>
2689 isnan ? (fspecs.upper ?
"NAN" :
"nan") : (fspecs.upper ?
"INF" :
"inf");
2690 constexpr size_t str_size = 3;
2691 auto sign = fspecs.sign;
2692 auto size = str_size + (
sign ? 1 : 0);
2694 const bool is_zero_fill =
2695 specs.
fill.size() == 1 && *specs.
fill.data() ==
static_cast<Char
>(
'0');
2697 specs.
fill[0] =
static_cast<Char
>(
' ');
2698 return write_padded(
out, specs, size, [=](reserve_iterator<OutputIt> it) {
2700 *it++ = detail::sign<Char>(
sign);
2701 return copy_str<Char>(str, str + str_size, it);
2715 return f.significand_size;
2717template <
typename T>
2723template <
typename Char,
typename OutputIt>
2726 return copy_str<Char>(significand, significand + significand_size,
out);
2728template <
typename Char,
typename OutputIt,
typename UInt>
2731 return format_decimal<Char>(
out, significand, significand_size).end;
2733template <
typename Char,
typename OutputIt,
typename T,
typename Grouping>
2736 if (!grouping.separator())
2738 out = write_significand<Char>(
out, significand, significand_size);
2742 write_significand<char>(
appender(
buffer), significand, significand_size);
2747template <
typename Char,
typename UInt, FMT_ENABLE_IF(std::is_
integral<UInt>::value)>
2752 out += significand_size + 1;
2754 int floating_size = significand_size - integral_size;
2755 for (
int i = floating_size / 2;
i > 0; --
i)
2761 if (floating_size % 2 != 0)
2763 *--
out =
static_cast<Char
>(
'0' + significand % 10);
2771template <
typename OutputIt,
typename UInt,
typename Char, FMT_ENABLE_IF(!std::is_po
inter<remove_cvref_t<OutputIt>>::value)>
2775 Char
buffer[digits10<UInt>() + 2];
2778 return detail::copy_str_noinline<Char>(
buffer, end,
out);
2781template <
typename OutputIt,
typename Char>
2784 out = detail::copy_str_noinline<Char>(significand,
2785 significand + integral_size,
out);
2789 return detail::copy_str_noinline<Char>(significand + integral_size,
2790 significand + significand_size,
out);
2793template <
typename OutputIt,
typename Char,
typename T,
typename Grouping>
2796 if (!grouping.separator())
2806 return detail::copy_str_noinline<Char>(
buffer.
data() + integral_size,
2810template <
typename OutputIt,
typename DecimalFP,
typename Char,
typename Grouping = digit_grouping<Char>>
2814 auto significand = f.significand;
2816 const Char zero =
static_cast<Char
>(
'0');
2817 auto sign = fspecs.sign;
2819 using iterator = reserve_iterator<OutputIt>;
2822 fspecs.locale ? detail::decimal_point<Char>(loc) :
static_cast<Char
>(
'.');
2824 int output_exp = f.exponent + significand_size - 1;
2825 auto use_exp_format = [=]() {
2834 output_exp >= (fspecs.precision > 0 ? fspecs.precision :
exp_upper);
2836 if (use_exp_format())
2839 if (fspecs.showpoint)
2841 num_zeros = fspecs.precision - significand_size;
2846 else if (significand_size == 1)
2850 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2852 if (abs_output_exp >= 100)
2853 exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2856 char exp_char = fspecs.upper ?
'E' :
'e';
2857 auto write = [=](iterator it) {
2859 *it++ = detail::sign<Char>(
sign);
2865 *it++ =
static_cast<Char
>(exp_char);
2866 return write_exponent<Char>(output_exp, it);
2868 return specs.
width > 0 ? write_padded<align::right>(
out, specs, size,
write)
2872 int exp = f.exponent + significand_size;
2873 if (f.exponent >= 0)
2877 int num_zeros = fspecs.precision -
exp;
2878 abort_fuzzing_if(num_zeros > 5000);
2879 if (fspecs.showpoint)
2887 auto grouping = Grouping(loc, fspecs.locale);
2889 return write_padded<align::right>(
out, specs, size, [&](iterator it) {
2891 *it++ = detail::sign<Char>(
sign);
2892 it = write_significand<Char>(it, significand, significand_size,
2893 f.exponent, grouping);
2894 if (!fspecs.showpoint)
2903 int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
2904 size += 1 +
to_unsigned(num_zeros > 0 ? num_zeros : 0);
2905 auto grouping = Grouping(loc, fspecs.locale);
2906 size +=
to_unsigned(grouping.count_separators(significand_size));
2907 return write_padded<align::right>(
out, specs, size, [&](iterator it) {
2909 *it++ = detail::sign<Char>(
sign);
2916 int num_zeros = -
exp;
2917 if (significand_size == 0 && fspecs.precision >= 0 &&
2918 fspecs.precision < num_zeros)
2920 num_zeros = fspecs.precision;
2922 bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
2923 size += 1 + (pointy ? 1 : 0) +
to_unsigned(num_zeros);
2924 return write_padded<align::right>(
out, specs, size, [&](iterator it) {
2926 *it++ = detail::sign<Char>(
sign);
2932 return write_significand<Char>(it, significand, significand_size);
2936template <
typename Char>
2954 template <
typename Out,
typename C>
2961template <
typename OutputIt,
typename DecimalFP,
typename Char>
2977template <
typename T>
2983template <
typename T,
typename Enable =
void>
2988template <
typename T>
2994template <
typename T, FMT_ENABLE_IF(std::is_
floating_po
int<T>::value&& has_isfinite<T>::value)>
2997 constexpr T inf = T(std::numeric_limits<double>::infinity());
3000 return std::isfinite(
value);
3002template <
typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
3005 T inf = T(std::numeric_limits<double>::infinity());
3010template <
typename T, FMT_ENABLE_IF(is_
floating_po
int<T>::value)>
3015#ifdef __cpp_if_constexpr
3016 if constexpr (std::numeric_limits<double>::is_iec559)
3018 auto bits = detail::bit_cast<uint64_t>(
static_cast<double>(
value));
3019 return (bits >> (num_bits<uint64_t>() - 1)) != 0;
3023 return std::signbit(
static_cast<double>(
value));
3045 if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
3048 if (remainder >= error &&
3049 remainder - error >= divisor - (remainder - error))
3077 buf[size++] = digit;
3078 if (!integral && error >= remainder)
3080 if (size < precision)
3087 if (error >= divisor || error >= divisor - error)
3098 for (
int i = size - 1;
i > 0 && buf[
i] >
'9'; --
i)
3119 if (exp10 > 0 && precision > max_value<int>() - exp10)
3134 auto integral =
static_cast<uint32_t
>(
value.f >> -one.e);
3138 uint64_t fractional =
value.f & (one.f - 1);
3146 if (handler.precision <= 0)
3148 if (handler.precision < 0)
3163 auto divmod_integral = [&](uint32_t divisor) {
3164 digit = integral / divisor;
3165 integral %= divisor;
3172 divmod_integral(1000000000);
3175 divmod_integral(100000000);
3178 divmod_integral(10000000);
3181 divmod_integral(1000000);
3184 divmod_integral(100000);
3187 divmod_integral(10000);
3190 divmod_integral(1000);
3193 divmod_integral(100);
3196 divmod_integral(10);
3203 FMT_ASSERT(
false,
"invalid number of digits");
3206 auto remainder = (
static_cast<uint64_t
>(integral) << -one.e) + fractional;
3207 auto result = handler.on_digit(
static_cast<char>(
'0' + digit),
3209 remainder, error,
true);
3218 char digit =
static_cast<char>(
'0' + (fractional >> -one.e));
3219 fractional &= one.f - 1;
3221 auto result = handler.on_digit(digit, one.f, fractional, error,
false);
3236 bigits_capacity = 32
3250 static constexpr const int bigit_bits = num_bits<bigit>();
3258 borrow =
static_cast<bigit>(result >> (bigit_bits * 2 - 1));
3263 int num_bigits =
static_cast<int>(bigits_.size()) - 1;
3264 while (num_bigits > 0 && (*
this)[num_bigits] == 0)
3275 int i = other.
exp_ - exp_;
3276 for (
size_t j = 0, n = other.
bigits_.size(); j != n; ++
i, ++j)
3277 subtract_bigits(
i, other.
bigits_[j], borrow);
3279 subtract_bigits(
i, 0, borrow);
3280 remove_leading_zeros();
3287 for (
size_t i = 0, n = bigits_.size();
i < n; ++
i)
3290 bigits_[
i] =
static_cast<bigit>(result);
3291 carry =
static_cast<bigit>(result >> bigit_bits);
3294 bigits_.push_back(carry);
3297 template <
typename UInt, FMT_ENABLE_IF(std::is_same<UInt, u
int64_t>::value || std::is_same<UInt, u
int128_t>::value)>
3302 const int shift = num_bits<half_uint>() - bigit_bits;
3303 const UInt lower =
static_cast<half_uint
>(
value);
3304 const UInt upper =
value >> num_bits<half_uint>();
3306 for (
size_t i = 0, n = bigits_.size();
i < n; ++
i)
3308 UInt result = lower * bigits_[
i] +
static_cast<bigit>(carry);
3309 carry = (upper * bigits_[
i] << shift) + (result >> bigit_bits) +
3310 (carry >> bigit_bits);
3311 bigits_[
i] =
static_cast<bigit>(result);
3315 bigits_.push_back(
static_cast<bigit>(carry));
3316 carry >>= bigit_bits;
3320 template <
typename UInt, FMT_ENABLE_IF(std::is_same<UInt, u
int64_t>::value || std::is_same<UInt, u
int128_t>::value)>
3323 size_t num_bigits = 0;
3326 bigits_[num_bigits++] =
static_cast<bigit>(n);
3329 bigits_.
resize(num_bigits);
3348 auto size = other.
bigits_.size();
3351 std::copy(
data,
data + size, make_checked(bigits_.data(), size));
3355 template <
typename Int>
3364 return static_cast<int>(bigits_.size()) + exp_;
3370 exp_ += shift / bigit_bits;
3371 shift %= bigit_bits;
3375 for (
size_t i = 0, n = bigits_.size();
i < n; ++
i)
3377 bigit c = bigits_[
i] >> (bigit_bits - shift);
3378 bigits_[
i] = (bigits_[
i] << shift) + carry;
3382 bigits_.push_back(carry);
3386 template <
typename Int>
3397 if (num_lhs_bigits != num_rhs_bigits)
3398 return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
3399 int i =
static_cast<int>(lhs.
bigits_.size()) - 1;
3400 int j =
static_cast<int>(rhs.
bigits_.size()) - 1;
3404 for (;
i >= end; --
i, --j)
3406 bigit lhs_bigit = lhs[
i], rhs_bigit = rhs[j];
3407 if (lhs_bigit != rhs_bigit)
3408 return lhs_bigit > rhs_bigit ? 1 : -1;
3411 return i > j ? 1 : -1;
3418 auto minimum = [](
int a,
int b) {
return a <
b ?
a :
b; };
3419 auto maximum = [](
int a,
int b) {
return a >
b ?
a :
b; };
3422 if (max_lhs_bigits + 1 < num_rhs_bigits)
3424 if (max_lhs_bigits > num_rhs_bigits)
3430 int min_exp = minimum(minimum(lhs1.
exp_, lhs2.
exp_), rhs.
exp_);
3431 for (
int i = num_rhs_bigits - 1;
i >= min_exp; --
i)
3434 static_cast<double_bigit>(get_bigit(lhs1,
i)) + get_bigit(lhs2,
i);
3435 bigit rhs_bigit = get_bigit(rhs,
i);
3436 if (sum > rhs_bigit + borrow)
3438 borrow = rhs_bigit + borrow - sum;
3441 borrow <<= bigit_bits;
3443 return borrow != 0 ? -1 : 0;
3454 while (
exp >= bitmask)
3461 while (bitmask != 0)
3464 if ((
exp & bitmask) != 0)
3473 int num_bigits =
static_cast<int>(bigits_.size());
3474 int num_result_bigits = 2 * num_bigits;
3477 auto sum = uint128_t();
3478 for (
int bigit_index = 0; bigit_index < num_bigits; ++bigit_index)
3482 for (
int i = 0, j = bigit_index; j >= 0; ++
i, --j)
3487 (*this)[bigit_index] =
static_cast<bigit>(sum);
3488 sum >>= num_bits<bigit>();
3491 for (
int bigit_index = num_bigits; bigit_index < num_result_bigits;
3494 for (
int j = num_bigits - 1,
i = bigit_index - j;
i < num_bigits;)
3496 (*this)[bigit_index] =
static_cast<bigit>(sum);
3497 sum >>= num_bits<bigit>();
3499 remove_leading_zeros();
3507 int exp_difference = exp_ - other.
exp_;
3508 if (exp_difference <= 0)
3510 int num_bigits =
static_cast<int>(bigits_.size());
3512 for (
int i = num_bigits - 1, j =
i + exp_difference;
i >= 0; --
i, --j)
3513 bigits_[j] = bigits_[
i];
3514 std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
3515 exp_ -= exp_difference;
3523 if (compare(*
this, divisor) < 0)
3525 FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0,
"");
3530 subtract_aligned(divisor);
3532 }
while (compare(*
this, divisor) >= 0);
3564 int shift = is_predecessor_closer ? 2 : 1;
3567 numerator =
value.f;
3568 numerator <<=
value.e + shift;
3571 if (is_predecessor_closer)
3574 upper_store <<=
value.e + 1;
3575 upper = &upper_store;
3578 denominator <<= shift;
3584 if (is_predecessor_closer)
3586 upper_store.
assign(numerator);
3588 upper = &upper_store;
3590 numerator *=
value.f;
3591 numerator <<= shift;
3593 denominator <<= shift -
value.e;
3597 numerator =
value.f;
3598 numerator <<= shift;
3600 denominator <<= shift -
value.e;
3602 if (is_predecessor_closer)
3604 upper_store = 1ULL << 1;
3605 upper = &upper_store;
3608 int even =
static_cast<int>((
value.f & 1) == 0);
3613 if (add_compare(numerator, *upper, denominator) + even <= 0)
3620 if (upper != &lower)
3636 bool low = compare(numerator, lower) - even < 0;
3638 bool high = add_compare(numerator, *upper, denominator) + even > 0;
3639 data[num_digits++] =
static_cast<char>(
'0' + digit);
3644 ++
data[num_digits - 1];
3648 int result = add_compare(numerator, numerator, denominator);
3650 if (result > 0 || (result == 0 && (digit % 2) != 0))
3651 ++
data[num_digits - 1];
3654 exp10 -= num_digits - 1;
3659 if (upper != &lower)
3664 exp10 -= num_digits - 1;
3665 if (num_digits == 0)
3668 auto digit = add_compare(numerator, numerator, denominator) > 0 ?
'1' :
'0';
3673 for (
int i = 0;
i < num_digits - 1; ++
i)
3676 buf[
i] =
static_cast<char>(
'0' + digit);
3680 auto result = add_compare(numerator, numerator, denominator);
3681 if (result > 0 || (result == 0 && (digit % 2) != 0))
3685 const auto overflow =
'0' + 10;
3686 buf[num_digits - 1] = overflow;
3688 for (
int i = num_digits - 1;
i > 0 && buf[
i] == overflow; --
i)
3693 if (buf[0] == overflow)
3702 buf[num_digits - 1] =
static_cast<char>(
'0' + digit);
3705template <
typename Float>
3709 static_assert(!std::is_same<Float, float>::value,
"");
3716 if (precision <= 0 || !
fixed)
3722 fill_n(buf.data(), precision,
'0');
3727 bool use_dragon =
true;
3728 unsigned dragon_flags = 0;
3729 if (!is_fast_float<Float>())
3731 const auto inv_log2_10 = 0.3010299956639812;
3738 exp =
static_cast<int>(
3739 std::ceil((f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10));
3749 return dec.exponent;
3753 return dec.exponent;
3759 const int min_exp = -60;
3760 int cached_exp10 = 0;
3763 min_exp - (normalized.e + fp::num_significand_bits), cached_exp10);
3764 normalized = normalized * cached_pow;
3775 exp += handler.size - cached_exp10 - 1;
3776 precision = handler.precision;
3782 bool is_predecessor_closer = specs.binary32
3783 ? f.assign(
static_cast<float>(
value))
3784 : f.assign(converted_value);
3785 if (is_predecessor_closer)
3791 const int max_double_digits = 767;
3792 if (precision > max_double_digits)
3793 precision = max_double_digits;
3796 if (!
fixed && !specs.showpoint)
3799 auto num_digits = buf.size();
3800 while (num_digits > 0 && buf[num_digits - 1] ==
'0')
3805 buf.try_resize(num_digits);
3810template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(is_
floating_po
int<T>::value)>
3818 if (detail::signbit(
value))
3820 fspecs.
sign = sign::minus;
3823 else if (fspecs.
sign == sign::minus)
3825 fspecs.
sign = sign::none;
3828 if (!detail::isfinite(
value))
3831 if (specs.
align == align::numeric && fspecs.
sign)
3834 *it++ = detail::sign<Char>(fspecs.
sign);
3836 fspecs.
sign = sign::none;
3837 if (specs.
width != 0)
3855 if (precision == max_value<int>())
3872template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(is_fast_
float<T>::value)>
3881 if (detail::signbit(
value))
3883 fspecs.
sign = sign::minus;
3890 uint mask = exponent_mask<floaty>();
3891 if ((bit_cast<uint>(
value) & mask) == mask)
3898template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(is_
floating_po
int<T>::value && !is_fast_
float<T>::value)>
3904template <
typename Char,
typename OutputIt>
3911template <
typename Char,
typename OutputIt>
3915 auto it = reserve(
out,
value.size());
3916 it = copy_str_noinline<Char>(
value.begin(),
value.end(), it);
3917 return base_iterator(
out, it);
3920template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(is_
string<T>::value)>
3932 std::is_enum<T>::value && !std::is_same<T, Char>::value &&
3941template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(std::is_same<T,
bool>::value)>
3950template <
typename Char,
typename OutputIt>
3953 auto it = reserve(
out, 1);
3955 return base_iterator(
out, it);
3958template <
typename Char,
typename OutputIt>
3973template <
typename Char,
typename OutputIt,
typename T, FMT_ENABLE_IF(std::is_same<T,
void>::value)>
3978 return write_ptr<Char>(
out, bit_cast<uintptr_t>(
value), &specs);
3982template <
typename Char,
typename OutputIt,
typename T,
typename Context = basic_format_context<OutputIt, Char>>
3985 !is_floating_point<T>::value && !std::is_same<T, Char>::value &&
3986 !std::is_same<
const T&,
3993template <
typename Char,
typename OutputIt,
typename T,
typename Context = basic_format_context<OutputIt, Char>>
3998 using formatter_type =
4000 typename Context::template formatter_type<T>,
4002 auto ctx = Context(
out, {}, {});
4003 return formatter_type().format(
value, ctx);
4008template <
typename Char>
4018 template <
typename T>
4027 h.format(parse_ctx, format_ctx);
4028 return format_ctx.out();
4032template <
typename Char>
4042 template <
typename T>
4055template <
typename Char>
4064 h.format(parse_ctx, ctx);
4066 template <
typename T>
4072template <
typename T>
4075 !std::is_same<T, char>::value &&
4076 !std::is_same<T, wchar_t>::value>;
4078template <
typename ErrorHandler>
4087 template <
typename T, FMT_ENABLE_IF(is_
integer<T>::value)>
4091 handler_.on_error(
"negative width");
4092 return static_cast<unsigned long long>(
value);
4095 template <
typename T, FMT_ENABLE_IF(!is_
integer<T>::value)>
4098 handler_.on_error(
"width is not integer");
4106template <
typename ErrorHandler>
4115 template <
typename T, FMT_ENABLE_IF(is_
integer<T>::value)>
4119 handler_.on_error(
"negative precision");
4120 return static_cast<unsigned long long>(
value);
4123 template <
typename T, FMT_ENABLE_IF(!is_
integer<T>::value)>
4126 handler_.on_error(
"precision is not integer");
4134template <
template <
typename>
class Handler,
typename FormatArg,
typename ErrorHandler>
4139 eh.on_error(
"number is too big");
4140 return static_cast<int>(
value);
4143template <
typename Context,
typename ID>
4145 typename Context::format_arg
4147 auto arg = ctx.arg(
id);
4149 ctx.on_error(
"argument not found");
4154template <
typename Char>
4166 return detail::get_arg(context_, parse_context_.
next_arg_id());
4172 return detail::get_arg(context_, arg_id);
4178 return detail::get_arg(context_, arg_id);
4185 :
specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx)
4189 template <
typename Id>
4192 this->specs_.width = get_dynamic_spec<width_checker>(
4196 template <
typename Id>
4199 this->specs_.precision = get_dynamic_spec<precision_checker>(
4209template <
template <
typename>
class Handler,
typename Context>
4219 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
index),
4220 ctx.error_handler());
4223 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
name),
4224 ctx.error_handler());
4229#if FMT_USE_USER_DEFINED_LITERALS
4230template <
typename Char>
4235 template <
typename... T>
4236 auto operator()(T&&... args)
const -> std::basic_string<Char>
4242#if FMT_USE_NONTYPE_TEMPLATE_ARGS
4243template <
typename T,
typename Char,
size_t N, fmt::detail_exported::fixed_
string<Char, N> Str>
4244struct statically_named_arg :
view
4246 static constexpr auto name = Str.data;
4249 statically_named_arg(
const T& v)
4255template <
typename T,
typename Char,
size_t N, fmt::detail_exported::fixed_
string<Char, N> Str>
4256struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type
4260template <
typename T,
typename Char,
size_t N, fmt::detail_exported::fixed_
string<Char, N> Str>
4266template <
typename Char,
size_t N, fmt::detail_exported::fixed_
string<Char, N> Str>
4269 template <
typename T>
4270 auto operator=(T&&
value)
const
4272 return statically_named_arg<T, Char, N, Str>(std::forward<T>(
value));
4276template <
typename Char>
4281 template <
typename T>
4284 return {str, std::forward<T>(
value)};
4290template <
typename Locale,
typename Char>
4292 -> std::basic_string<Char>
4295 detail::vformat_to(
buffer, format_str, args, detail::locale_ref(loc));
4325template <
typename... T>
4327 -> std::system_error
4362 buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3
4364 mutable char buffer_[buffer_size];
4367 template <
typename UInt>
4370 auto n =
static_cast<detail::uint32_or_64_or_128_t<UInt>
>(
value);
4371 return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
4374 template <
typename Int>
4377 auto abs_value =
static_cast<detail::uint32_or_64_or_128_t<Int>
>(
value);
4378 bool negative =
value < 0;
4380 abs_value = 0 - abs_value;
4381 auto begin = format_unsigned(abs_value);
4389 : str_(format_signed(
value))
4393 : str_(format_signed(
value))
4397 : str_(format_signed(
value))
4401 : str_(format_unsigned(
value))
4405 : str_(format_unsigned(
value))
4409 : str_(format_unsigned(
value))
4416 return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
4434 buffer_[buffer_size - 1] =
'\0';
4445 return std::string(str_, size());
4449template <
typename T,
typename Char>
4450template <
typename FormatContext>
4454 const ->
decltype(ctx.out())
4456 if (specs_.width_ref.kind != detail::arg_id_kind::none ||
4457 specs_.precision_ref.kind != detail::arg_id_kind::none)
4459 auto specs = specs_;
4460 detail::handle_dynamic_spec<detail::width_checker>(specs.
width,
4461 specs.width_ref, ctx);
4462 detail::handle_dynamic_spec<detail::precision_checker>(
4463 specs.
precision, specs.precision_ref, ctx);
4464 return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
4466 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
4469template <
typename Char>
4472 template <
typename FormatContext>
4473 auto format(
void* val, FormatContext& ctx)
const ->
decltype(ctx.out())
4479template <
typename Char,
size_t N>
4482 template <
typename FormatContext>
4484 ->
decltype(ctx.out())
4502template <
typename Char =
char>
4522 template <
typename Context>
4525 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4526 specs_.width_ref, ctx);
4527 detail::handle_dynamic_spec<detail::precision_checker>(
4528 specs_.precision, specs_.precision_ref, ctx);
4532 template <
typename ParseContext>
4535 format_str_ = ctx.begin();
4537 detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
4538 return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
4541 template <
typename T,
typename FormatContext>
4542 auto format(
const T& val, FormatContext& ctx) ->
decltype(ctx.out())
4545 detail::specs_checker<null_handler> checker(
4546 null_handler(), detail::mapped_type_constant<T, FormatContext>::value);
4547 checker.on_align(specs_.align);
4548 if (specs_.sign != sign::none)
4549 checker.on_sign(specs_.sign);
4552 if (specs_.precision >= 0)
4553 checker.end_precision();
4554 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
4567template <
typename T>
4570 static_assert(std::is_pointer<T>::value,
"");
4571 return detail::bit_cast<const void*>(
p);
4573template <
typename T>
4574auto ptr(
const std::unique_ptr<T>&
p) ->
const void*
4578template <
typename T>
4579auto ptr(
const std::shared_ptr<T>&
p) ->
const void*
4594template <
typename Enum>
4602 template <
typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
4629 template <
typename ParseContext>
4632 using handler_type = detail::dynamic_specs_handler<ParseContext>;
4633 detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
4634 detail::type::string_type);
4636 detail::check_string_type_spec(specs_.type, ctx.error_handler());
4640 template <
typename FormatContext>
4643 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4644 specs_.width_ref, ctx);
4645 detail::handle_dynamic_spec<detail::precision_checker>(
4646 specs_.precision, specs_.precision_ref, ctx);
4647 return detail::write_bytes(ctx.out(),
b.data_, specs_);
4652template <
typename T>
4669template <
typename T>
4675template <
typename T>
4682 template <
typename ParseContext>
4685 using handler_type = detail::dynamic_specs_handler<ParseContext>;
4686 detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
4687 detail::type::int_type);
4689 detail::check_string_type_spec(specs_.type, ctx.error_handler());
4693 template <
typename FormatContext>
4695 ->
decltype(ctx.out())
4697 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4698 specs_.width_ref, ctx);
4699 detail::handle_dynamic_spec<detail::precision_checker>(
4700 specs_.precision, specs_.precision_ref, ctx);
4701 return detail::write_int_localized(
4702 ctx.out(),
static_cast<detail::uint64_or_128_t<T>
>(t.value), 0, specs_,
4703 detail::digit_grouping<char>({
"\3",
','}));
4707template <
typename It,
typename Sentinel,
typename Char =
char>
4715 : begin(
b), end(e), sep(
s)
4720template <
typename It,
typename Sentinel,
typename Char>
4725#ifdef __cpp_lib_ranges
4726 std::iter_value_t<It>;
4728 typename std::iterator_traits<It>::value_type;
4733 template <
typename T, FMT_ENABLE_IF(has_formatter<T, context>::value)>
4738 template <
typename T, FMT_ENABLE_IF(!has_formatter<T, context>::value)>
4747 std::declval<const value_type&>()))>,
4749 detail::fallback_formatter<value_type, Char>>;
4754 template <
typename ParseContext>
4757 return value_formatter_.parse(ctx);
4760 template <
typename FormatContext>
4762 FormatContext& ctx)
const ->
decltype(ctx.out())
4764 auto it =
value.begin;
4765 auto out = ctx.out();
4766 if (it !=
value.end)
4768 out = value_formatter_.format(
map(*it), ctx);
4770 while (it !=
value.end)
4773 ctx.advance_to(
out);
4774 out = value_formatter_.format(
map(*it), ctx);
4786template <
typename It,
typename Sentinel>
4789 return {begin, end, sep};
4808template <
typename Range>
4812 return join(std::begin(range), std::end(range), sep);
4826template <
typename T, FMT_ENABLE_IF(!std::is_
integral<T>::value)>
4829 auto result = std::string();
4830 detail::write<char>(std::back_inserter(result),
value);
4834template <
typename T, FMT_ENABLE_IF(std::is_
integral<T>::value)>
4839 constexpr int max_size = detail::digits10<T>() + 2;
4840 char buffer[max_size > 5 ?
static_cast<unsigned>(max_size) : 5];
4842 return std::string(begin, detail::write<char>(begin,
value));
4845template <
typename Char,
size_t SIZE>
4847 -> std::basic_string<Char>
4849 auto size = buf.size();
4851 return std::basic_string<Char>(buf.data(), size);
4856template <
typename Char>
4862 using detail::arg_formatter;
4863 using detail::buffer_appender;
4864 using detail::custom_formatter;
4865 using detail::default_arg_formatter;
4866 using detail::get_arg;
4867 using detail::locale_ref;
4868 using detail::parse_format_specs;
4869 using detail::specs_checker;
4870 using detail::specs_handler;
4871 using detail::to_unsigned;
4877 auto arg = args.get(0);
4890 : parse_context(str), context(p_out, p_args, p_loc)
4894 void on_text(
const Char* begin,
const Char* end)
4910 int arg_id = context.
arg_id(
id);
4912 on_error(
"argument not found");
4916 FMT_INLINE void on_replacement_field(
int id,
const Char*)
4925 auto on_format_specs(
int id,
const Char* begin,
const Char* end)
4932 (begin - &*parse_context.
begin()));
4934 return parse_context.
begin();
4940 if (begin == end || *begin !=
'}')
4941 on_error(
"missing '}' in format string");
4947 detail::parse_format_string<false>(
fmt, format_handler(
out,
fmt, args, loc));
4950#ifndef FMT_HEADER_ONLY
4961#if FMT_USE_USER_DEFINED_LITERALS
4974#if FMT_USE_NONTYPE_TEMPLATE_ARGS
4975 template <detail_exported::fixed_
string Str>
4976 constexpr auto operator""_a()
4979 return detail::udl_arg<
char_t,
sizeof(Str.data) /
sizeof(
char_t), Str>();
4982 constexpr auto operator"" _a(
const char*
s,
size_t) -> detail::udl_arg<char>
4990template <
typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4994 return detail::vformat(loc,
fmt, args);
4997template <
typename Locale,
typename... T,
FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
5004template <
typename OutputIt,
typename Locale, FMT_ENABLE_IF(detail::is_output_iterator<OutputIt,
char>::value&& detail::is_locale<Locale>::value)>
5007 using detail::get_buffer;
5008 auto&& buf = get_buffer<char>(
out);
5009 detail::vformat_to(buf,
fmt, args, detail::locale_ref(loc));
5010 return detail::get_iterator(buf);
5013template <
typename OutputIt,
typename Locale,
typename... T,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&& detail::is_locale<Locale>::value)>
5022#ifdef FMT_HEADER_ONLY
5023#define FMT_FUNC inline
bool isfinite(T)
Definition chrono.h:1878
FMT_CONSTEXPR auto locale() -> detail::locale_ref
Definition core.h:2407
FMT_CONSTEXPR auto out() -> iterator
Definition core.h:2395
FMT_CONSTEXPR auto arg_id(basic_string_view< char_type > name) -> int
Definition core.h:2376
void on_error(const char *message)
Definition core.h:2389
FMT_CONSTEXPR auto error_handler() -> detail::error_handler
Definition core.h:2385
auto args() const -> const basic_format_args< basic_format_context > &
Definition core.h:2380
void advance_to(iterator it)
Definition core.h:2401
FMT_CONSTEXPR void check_arg_id(int id)
Definition core.h:830
FMT_CONSTEXPR auto next_arg_id() -> int
Definition core.h:814
FMT_CONSTEXPR void advance_to(iterator it)
Definition core.h:805
constexpr auto begin() const noexcept -> iterator
Definition core.h:791
Allocator alloc_
Definition format.h:960
const T & const_reference
Definition format.h:975
FMT_CONSTEXPR20 void resize(size_t count)
Definition format.h:1049
FMT_CONSTEXPR20 ~basic_memory_buffer()
Definition format.h:985
auto operator=(basic_memory_buffer &&other) noexcept -> basic_memory_buffer &
Definition format.h:1031
void reserve(size_t new_capacity)
Definition format.h:1055
auto get_allocator() const -> Allocator
Definition format.h:1040
T store_[SIZE]
Definition format.h:957
FMT_CONSTEXPR20 void grow(size_t size) override
Definition format.h:1070
void append(const ContiguousRange &range)
Definition format.h:1063
FMT_CONSTEXPR20 void move(basic_memory_buffer &other)
Definition format.h:992
FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer &&other) noexcept
Definition format.h:1021
T value_type
Definition format.h:974
constexpr auto end() const noexcept -> iterator
Definition core.h:550
constexpr auto data() const noexcept -> const Char *
Definition core.h:535
constexpr auto begin() const noexcept -> iterator
Definition core.h:546
FMT_CONSTEXPR20 bigit & operator[](int index)
Definition format.h:3245
FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit &borrow)
Definition format.h:3254
friend FMT_CONSTEXPR20 int compare(const bigint &lhs, const bigint &rhs)
Definition format.h:3394
basic_memory_buffer< bigit, bigits_capacity > bigits_
Definition format.h:3238
FMT_CONSTEXPR20 void assign_pow10(int exp)
Definition format.h:3447
uint64_t double_bigit
Definition format.h:3233
FMT_CONSTEXPR20 bigint()
Definition format.h:3334
bigint(const bigint &)=delete
FMT_CONSTEXPR20 void assign(const bigint &other)
Definition format.h:3346
int exp_
Definition format.h:3239
FMT_CONSTEXPR20 void assign(UInt n)
Definition format.h:3321
FMT_CONSTEXPR20 void square()
Definition format.h:3471
friend FMT_CONSTEXPR20 int add_compare(const bigint &lhs1, const bigint &lhs2, const bigint &rhs)
Definition format.h:3416
FMT_NOINLINE FMT_CONSTEXPR20 bigint & operator<<=(int shift)
Definition format.h:3367
FMT_CONSTEXPR20 void multiply(uint32_t value)
Definition format.h:3283
FMT_CONSTEXPR20 int divmod_assign(const bigint &divisor)
Definition format.h:3520
FMT_CONSTEXPR20 void subtract_aligned(const bigint &other)
Definition format.h:3270
FMT_CONSTEXPR20 void multiply(UInt value)
Definition format.h:3298
bigint(uint64_t n)
Definition format.h:3338
FMT_CONSTEXPR20 bigint & operator*=(Int value)
Definition format.h:3387
FMT_CONSTEXPR20 int num_bigits() const
Definition format.h:3362
FMT_CONSTEXPR20 void remove_leading_zeros()
Definition format.h:3261
void operator=(const bigint &)=delete
FMT_CONSTEXPR20 bigit operator[](int index) const
Definition format.h:3241
FMT_CONSTEXPR20 void align(const bigint &other)
Definition format.h:3505
uint32_t bigit
Definition format.h:3232
FMT_CONSTEXPR20 void operator=(Int n)
Definition format.h:3356
void append(const U *begin, const U *end)
auto end() noexcept -> T *
Definition core.h:1075
FMT_CONSTEXPR20 void push_back(const T &value)
Definition core.h:1137
FMT_CONSTEXPR auto data() noexcept -> T *
Definition core.h:1102
FMT_CONSTEXPR20 void try_resize(size_t count)
Definition core.h:1121
constexpr auto size() const noexcept -> size_t
Definition core.h:1090
string_view data_
Definition format.h:4612
bytes(string_view data)
Definition format.h:4616
std::ptrdiff_t difference_type
Definition format.h:2571
void pointer
Definition format.h:2572
FMT_CONSTEXPR value_type operator*() const
Definition format.h:2613
FMT_CONSTEXPR size_t count() const
Definition format.h:2589
FMT_CONSTEXPR friend counting_iterator operator+(counting_iterator it, difference_type n)
Definition format.h:2606
std::output_iterator_tag iterator_category
Definition format.h:2570
size_t count_
Definition format.h:2567
FMT_CONSTEXPR counting_iterator & operator++()
Definition format.h:2594
FMT_UNCHECKED_ITERATOR(counting_iterator)
void reference
Definition format.h:2573
FMT_CONSTEXPR counting_iterator operator++(int)
Definition format.h:2599
FMT_CONSTEXPR counting_iterator()
Definition format.h:2584
uint64_t lo_
Definition format.h:354
FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback &
Definition format.h:447
constexpr uint64_t low() const noexcept
Definition format.h:372
friend uint128_fallback umul128(uint64_t x, uint64_t y) noexcept
Definition format-inl.h:166
constexpr uint128_fallback(uint64_t hi, uint64_t lo)
Definition format.h:359
FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback
Definition format.h:431
friend constexpr auto operator==(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition format.h:383
friend auto operator-(const uint128_fallback &lhs, uint64_t rhs) -> uint128_fallback
Definition format.h:426
uint64_t hi_
Definition format.h:354
friend constexpr auto operator|(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition format.h:398
friend auto operator*(const uint128_fallback &lhs, uint32_t rhs) -> uint128_fallback
Definition format.h:417
FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback
Definition format.h:439
FMT_CONSTEXPR20 uint128_fallback & operator+=(uint64_t n) noexcept
Definition format.h:460
friend constexpr auto operator!=(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition format.h:388
friend auto operator+(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition format.h:410
friend constexpr auto operator>(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition format.h:393
constexpr uint128_fallback(uint64_t value=0)
Definition format.h:363
FMT_CONSTEXPR void operator+=(uint128_fallback n)
Definition format.h:451
friend constexpr auto operator&(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition format.h:404
constexpr uint64_t high() const noexcept
Definition format.h:368
thousands_sep_result< Char > sep_
Definition format.h:2339
Out apply(Out out, basic_string_view< C > digits) const
Definition format.h:2393
digit_grouping(thousands_sep_result< Char > sep)
Definition format.h:2372
int next(next_state &state) const
Definition format.h:2352
next_state initial_state() const
Definition format.h:2346
digit_grouping(locale_ref loc, bool localized=true)
Definition format.h:2365
int count_separators(int num_digits) const
Definition format.h:2382
Char separator() const
Definition format.h:2377
constexpr fallback_digit_grouping(locale_ref, bool)
Definition format.h:2940
constexpr Char separator() const
Definition format.h:2944
constexpr int count_separators(int) const
Definition format.h:2949
constexpr Out apply(Out out, basic_string_view< C >) const
Definition format.h:2955
ErrorHandler & handler_
Definition format.h:4131
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition format.h:4124
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
Definition format.h:4110
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition format.h:4116
buffer_context< Char > & context_
Definition format.h:4159
basic_format_parse_context< Char > & parse_context_
Definition format.h:4158
FMT_CONSTEXPR auto get_arg(basic_string_view< Char > arg_id) -> format_arg
Definition format.h:4175
basic_format_arg< buffer_context< Char > > format_arg
Definition format.h:4162
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition format.h:4190
void on_error(const char *message)
Definition format.h:4203
FMT_CONSTEXPR specs_handler(basic_format_specs< Char > &specs, basic_format_parse_context< Char > &parse_ctx, buffer_context< Char > &ctx)
Definition format.h:4182
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition format.h:4197
FMT_CONSTEXPR auto get_arg(int arg_id) -> format_arg
Definition format.h:4169
FMT_CONSTEXPR auto get_arg(auto_id) -> format_arg
Definition format.h:4164
auto str() const -> std::wstring
Definition format.h:1532
auto size() const -> size_t
Definition format.h:1524
auto c_str() const -> const wchar_t *
Definition format.h:1528
basic_memory_buffer< wchar_t > buffer_
Definition format.h:1516
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition format.h:4096
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition format.h:4088
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
Definition format.h:4082
ErrorHandler & handler_
Definition format.h:4103
auto format_to(OutputIt out, const text_style &ts, const S &format_str, Args &&... args) -> typename std::enable_if< enable, OutputIt >::type
Definition color.h:677
void vformat_to(buffer< Char > &buf, const text_style &ts, basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char > > > args)
Definition color.h:545
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
Definition color.h:646
std::basic_string< Char > vformat(const text_style &ts, const S &format_str, basic_format_args< buffer_context< type_identity_t< Char > > > args)
Definition color.h:625
typename std::enable_if< B, T >::type enable_if_t
Definition core.h:302
constexpr FMT_INLINE auto const_check(T value) -> T
Definition core.h:390
#define FMT_ASSERT(condition, message)
Definition core.h:403
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
Definition core.h:2133
FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler) -> const Char *
Definition core.h:3324
std::integral_constant< bool, B > bool_constant
Definition core.h:306
#define FMT_USE_LONG_DOUBLE
Definition core.h:192
basic_string_view< char > string_view
Definition core.h:604
FMT_CONSTEXPR auto code_point_length_impl(char c) -> int
Definition core.h:3011
align::type align_t
Definition core.h:2687
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition core.h:2506
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> bool
Definition core.h:3574
#define FMT_FALLTHROUGH
Definition core.h:174
#define FMT_NODISCARD
Definition core.h:181
typename std::remove_reference< T >::type remove_reference_t
Definition core.h:308
uint128_opt
Definition core.h:443
typename detail::char_t_impl< S >::type char_t
Definition core.h:759
#define FMT_END_DETAIL_NAMESPACE
Definition core.h:231
#define FMT_USE_FLOAT
Definition core.h:186
FMT_CONSTEXPR void check_string_type_spec(presentation_type type, ErrorHandler &&eh={})
Definition core.h:3668
constexpr auto count() -> size_t
Definition core.h:1538
basic_format_string< char, type_identity_t< Args >... > format_string
Definition core.h:4059
#define FMT_CLASS_API
Definition core.h:242
int128_opt
Definition core.h:440
#define FMT_CONSTEXPR
Definition core.h:106
FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type, ErrorHandler &&eh)
Definition core.h:3677
type
Definition core.h:681
#define FMT_BEGIN_NAMESPACE
Definition core.h:214
#define FMT_BEGIN_DETAIL_NAMESPACE
Definition core.h:228
#define FMT_API
Definition core.h:250
FMT_BEGIN_DETAIL_NAMESPACE FMT_CONSTEXPR void ignore_unused(const T &...)
Definition core.h:373
constexpr FMT_INLINE auto is_constant_evaluated(bool default_value=false) noexcept -> bool
Definition core.h:377
#define FMT_BUFFER_CONTEXT(Char)
Definition core.h:2419
constexpr auto is_utf8() -> bool
Definition core.h:465
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T > > > buffer_appender
Definition core.h:1398
FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type, ErrorHandler &&eh={}) -> bool
Definition core.h:3656
#define FMT_ENABLE_IF(...)
Definition core.h:364
#define FMT_CONSTEXPR_CHAR_TRAITS
Definition core.h:130
#define FMT_INLINE
Definition core.h:199
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition core.h:455
FMT_NORETURN FMT_API void throw_format_error(const char *message)
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition core.h:630
#define FMT_MSC_WARNING(...)
Definition core.h:57
typename type_identity< T >::type type_identity_t
Definition core.h:319
typename std::conditional< B, T, F >::type conditional_t
Definition core.h:304
#define FMT_CONSTEXPR20
Definition core.h:114
auto get_container(std::back_insert_iterator< Container > it) -> Container &
Definition core.h:990
sign::type sign_t
Definition core.h:2698
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition core.h:312
type_constant< decltype(arg_mapper< Context >().map(std::declval< const T & >())), typename Context::char_type > mapped_type_constant
Definition core.h:1998
#define FMT_USE_DOUBLE
Definition core.h:189
typename std::underlying_type< T >::type underlying_t
Definition core.h:321
#define FMT_END_NAMESPACE
Definition core.h:219
#define FMT_MODULE_EXPORT_END
Definition core.h:227
FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> float_specs
Definition core.h:3610
#define offset(member)
Definition css_properties.cpp:5
#define out
Definition encodings.cpp:5
constexpr auto compile_string_to_view(const Char(&s)[N]) -> basic_string_view< Char >
Definition format.h:1147
FMT_CONSTEXPR20 auto bit_cast(const From &from) -> To
Definition format.h:322
decltype(std::end(std::declval< T & >())) sentinel_t
Definition format.h:556
FMT_INLINE void assume(bool condition)
Definition format.h:544
constexpr auto num_bits() -> int
Definition format.h:504
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition chrono.h:481
auto is_big_endian() -> bool
Definition format.h:334
auto compute_width(basic_string_view< Char > s) -> size_t
Definition format.h:785
constexpr auto num_bits< uint128_t >() -> int
Definition format.h:515
auto base_iterator(std::back_insert_iterator< Container > &it, checked_ptr< typename Container::value_type >) -> std::back_insert_iterator< Container >
Definition format.h:640
std::is_same< T, float128 > is_float128
Definition format.h:873
constexpr auto max_value() -> T
Definition format.h:499
void float128
Definition format.h:870
decltype(std::begin(std::declval< T & >())) iterator_t
Definition format.h:554
FMT_FUNC void print(std::FILE *f, string_view text)
Definition format-inl.h:1620
constexpr uint32_t invalid_code_point
Definition format.h:742
constexpr auto to_pointer(OutputIt, size_t) -> T *
Definition format.h:624
bool_constant< std::is_floating_point< T >::value||is_float128< T >::value > is_floating_point
Definition format.h:877
remove_reference_t< decltype(reserve(std::declval< OutputIt & >(), 0))> reserve_iterator
Definition format.h:621
auto reserve(std::back_insert_iterator< Container > it, size_t n) -> checked_ptr< typename Container::value_type >
Definition format.h:596
constexpr auto num_bits< int128_opt >() -> int
Definition format.h:510
conditional_t< FMT_USE_INT128, uint128_opt, uint128_fallback > uint128_t
Definition format.h:488
FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T &value) -> OutputIt
Definition format.h:656
constexpr auto make_checked(T *p, size_t) -> T *
Definition format.h:583
FMT_CONSTEXPR auto utf8_decode(const char *s, uint32_t *c, int *e) -> const char *
Definition format.h:705
FMT_CONSTEXPR void abort_fuzzing_if(bool condition)
Definition format.h:258
auto code_point_index(basic_string_view< Char > s, size_t n) -> size_t
Definition format.h:834
auto get_data(std::basic_string< Char > &s) -> Char *
Definition format.h:560
FMT_CONSTEXPR void for_each_codepoint(string_view s, F f)
Definition format.h:747
uint128_t uintptr_t
Definition format.h:493
T * checked_ptr
Definition format.h:581
FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition format.h:683
char8_type
Definition format.h:678
result
Definition format.h:3059
@ done
Definition format.h:3061
@ error
Definition format.h:3062
@ more
Definition format.h:3060
FMT_API auto to_decimal(T x) noexcept -> decimal_fp< T >
constexpr auto format_as(Enum e) noexcept -> underlying_t< Enum >
Definition format.h:4603
Definition bin_to_hex.h:111
FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int
Definition core.h:1763
arg_id_kind kind
Definition core.h:2830
static constexpr uint64_t pow10_significands[87]
Definition format.h:1776
static constexpr uint64_t power_of_10_64[20]
Definition format.h:1885
static constexpr int16_t pow10_exponents[87]
Definition format.h:1872
int e
Definition format.h:1668
FMT_CONSTEXPR auto assign(Float n) -> bool
Definition format.h:1691
constexpr basic_fp()
Definition format.h:1673
F f
Definition format.h:1667
FMT_CONSTEXPR basic_fp(Float n)
Definition format.h:1684
constexpr basic_fp(uint64_t f_val, int e_val)
Definition format.h:1677
int significand_size
Definition format.h:2709
int exponent
Definition format.h:2710
const char * significand
Definition format.h:2708
FMT_CONSTEXPR void operator=(const T &)
Definition format.h:2579
static constexpr CharT value[sizeof...(C)]
Definition format.h:270
int pos
Definition format.h:2344
std::string::const_iterator group
Definition format.h:2343
int exponent
Definition format.h:1593
typename float_info< T >::carrier_uint significand_type
Definition format.h:1591
significand_type significand
Definition format.h:1592
detail::uint128_t carrier_uint
Definition format.h:1585
detail::uint128_t carrier_uint
Definition format.h:1577
uint64_t carrier_uint
Definition format.h:1562
uint32_t carrier_uint
Definition format.h:1548
FMT_NORETURN void on_error(const char *message)
Definition core.h:750
const Char * end
Definition format.h:2086
uint32_t cp
Definition format.h:2087
const Char * begin
Definition format.h:2085
float_format format
Definition core.h:3601
int precision
Definition core.h:3600
sign_t sign
Definition core.h:3602
bool binary32
Definition core.h:3605
bool fixed
Definition format.h:3072
FMT_CONSTEXPR digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, uint64_t error, bool integral)
Definition format.h:3074
int exp10
Definition format.h:3071
int size
Definition format.h:3069
int precision
Definition format.h:3070
char * buf
Definition format.h:3068
T value
Definition format.h:4655
It begin
Definition format.h:4710
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition format.h:4714
Sentinel end
Definition format.h:4711
basic_string_view< Char > sep
Definition format.h:4712
std::string grouping
Definition format.h:1381
Char thousands_sep
Definition format.h:1382
UInt abs_value
Definition format.h:2457
unsigned prefix
Definition format.h:2458
FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, const basic_format_specs< Char > &specs)
Definition format.h:2287
size_t padding
Definition format.h:2285
size_t size
Definition format.h:2284
b
Definition tag_strings.h:61
s
Definition tag_strings.h:47
a
Definition tag_strings.h:43
u
Definition tag_strings.h:62
i
Definition tag_strings.h:60
annotation dir
Definition tag_strings.h:132
map
Definition tag_strings.h:86
p
Definition tag_strings.h:29
annotation table
Definition tag_strings.h:100
int index
Definition core.h:2841
basic_string_view< Char > name
Definition core.h:2842