46 #ifdef __INTEL_COMPILER 47 # define FMT_ICC_VERSION __INTEL_COMPILER 49 # define FMT_ICC_VERSION __ICL 51 # define FMT_ICC_VERSION 0 55 # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__) 57 # define FMT_CUDA_VERSION 0 61 # define FMT_HAS_BUILTIN(x) __has_builtin(x) 63 # define FMT_HAS_BUILTIN(x) 0 66 #if FMT_GCC_VERSION || FMT_CLANG_VERSION 67 # define FMT_NOINLINE __attribute__((noinline)) 72 #if __cplusplus == 201103L || __cplusplus == 201402L 73 # if defined(__INTEL_COMPILER) || defined(__PGI) 74 # define FMT_FALLTHROUGH 75 # elif defined(__clang__) 76 # define FMT_FALLTHROUGH [[clang::fallthrough]] 77 # elif FMT_GCC_VERSION >= 700 && \ 78 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) 79 # define FMT_FALLTHROUGH [[gnu::fallthrough]] 81 # define FMT_FALLTHROUGH 83 #elif FMT_HAS_CPP17_ATTRIBUTE(fallthrough) || \ 84 (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 85 # define FMT_FALLTHROUGH [[fallthrough]] 87 # define FMT_FALLTHROUGH 90 #ifndef FMT_MAYBE_UNUSED 91 # if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused) 92 # define FMT_MAYBE_UNUSED [[maybe_unused]] 94 # define FMT_MAYBE_UNUSED 100 # if FMT_MSC_VER || FMT_NVCC 103 template <
typename Exception>
inline void do_throw(
const Exception& x) {
106 volatile bool b =
true;
111 # define FMT_THROW(x) detail::do_throw(x) 113 # define FMT_THROW(x) throw x 116 # define FMT_THROW(x) \ 118 static_cast<void>(sizeof(x)); \ 119 FMT_ASSERT(false, ""); \ 126 # define FMT_CATCH(x) catch (x) 128 # define FMT_TRY if (true) 129 # define FMT_CATCH(x) if (false) 132 #ifndef FMT_USE_USER_DEFINED_LITERALS 134 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ 135 FMT_MSC_VER >= 1900) && \ 136 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 480) 137 # define FMT_USE_USER_DEFINED_LITERALS 1 139 # define FMT_USE_USER_DEFINED_LITERALS 0 143 #ifndef FMT_USE_UDL_TEMPLATE 146 # if FMT_USE_USER_DEFINED_LITERALS && \ 147 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 501) && \ 148 ((FMT_GCC_VERSION >= 604 && __cplusplus >= 201402L) || \ 149 FMT_CLANG_VERSION >= 304) && \ 150 !defined(__PGI) && !defined(__NVCC__) 151 # define FMT_USE_UDL_TEMPLATE 1 153 # define FMT_USE_UDL_TEMPLATE 0 157 #ifndef FMT_USE_FLOAT 158 # define FMT_USE_FLOAT 1 161 #ifndef FMT_USE_DOUBLE 162 # define FMT_USE_DOUBLE 1 165 #ifndef FMT_USE_LONG_DOUBLE 166 # define FMT_USE_LONG_DOUBLE 1 173 #if !defined(FMT_REDUCE_INT_INSTANTIATIONS) 174 # define FMT_REDUCE_INT_INSTANTIATIONS 0 179 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER 180 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) 182 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER 183 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) 185 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctz)) 186 # define FMT_BUILTIN_CTZ(n) __builtin_ctz(n) 188 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctzll)) 189 # define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n) 199 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && \ 200 !defined(FMT_BUILTIN_CTZLL) && !defined(_MANAGED) 205 # pragma intrinsic(_BitScanForward) 206 # pragma intrinsic(_BitScanReverse) 208 # if defined(_WIN64) && !defined(__clang__) 209 # pragma intrinsic(_BitScanForward64) 210 # pragma intrinsic(_BitScanReverse64) 213 inline int clz(uint32_t x) {
215 _BitScanReverse(&r, x);
221 return 31 ^
static_cast<int>(r);
223 # define FMT_BUILTIN_CLZ(n) detail::clz(n) 225 inline int clzll(uint64_t x) {
228 _BitScanReverse64(&r, x);
231 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
return 63 ^ (r + 32);
233 _BitScanReverse(&r, static_cast<uint32_t>(x));
237 return 63 ^
static_cast<int>(r);
239 # define FMT_BUILTIN_CLZLL(n) detail::clzll(n) 241 inline int ctz(uint32_t x) {
243 _BitScanForward(&r, x);
246 return static_cast<int>(r);
248 # define FMT_BUILTIN_CTZ(n) detail::ctz(n) 250 inline int ctzll(uint64_t x) {
255 _BitScanForward64(&r, x);
258 if (_BitScanForward(&r, static_cast<uint32_t>(x)))
return static_cast<int>(r);
260 _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
263 return static_cast<int>(r);
265 # define FMT_BUILTIN_CTZLL(n) detail::ctzll(n) 271 #ifndef FMT_DEPRECATED_NUMERIC_ALIGN 272 # define FMT_DEPRECATED_NUMERIC_ALIGN 0 281 template <
typename Dest,
typename Source>
283 static_assert(
sizeof(Dest) ==
sizeof(Source),
"size mismatch");
285 std::memcpy(&dest, &source,
sizeof(dest));
292 char data[
sizeof(u)];
305 for (
size_t i = 0, j =
sizeof(
void*) - 1; i < j; ++i, --j)
323 return (std::numeric_limits<T>::max)();
326 return std::numeric_limits<T>::digits;
332 return static_cast<int>(
sizeof(
void*) *
333 std::numeric_limits<unsigned char>::digits);
338 #if FMT_HAS_BUILTIN(__builtin_assume) 339 __builtin_assume(condition);
344 template <
typename T>
346 template <
typename T>
using sentinel_t = decltype(std::end(std::declval<T&>()));
349 template <
typename Char>
inline Char*
get_data(std::basic_string<Char>& s) {
352 template <
typename Container>
357 #if defined(_SECURE_SCL) && _SECURE_SCL 359 template <
typename T>
using checked_ptr = stdext::checked_array_iterator<T*>;
365 template <
typename T>
inline T*
make_checked(T* p,
size_t) {
return p; }
368 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
370 __attribute__((no_sanitize(
"undefined")))
373 reserve(std::back_insert_iterator<Container> it,
size_t n) {
375 size_t size = c.size();
380 template <
typename T>
387 template <
typename Iterator>
inline Iterator&
reserve(Iterator& it,
size_t) {
391 template <
typename T,
typename OutputIt>
397 auto size = buf.
size();
398 if (buf.
capacity() < size + n)
return nullptr;
400 return buf.
data() + size;
403 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
405 std::back_insert_iterator<Container>& it,
410 template <
typename Iterator>
434 size_t count()
const {
return count_; }
447 it.
count_ +=
static_cast<size_t>(n);
461 : out_(out), limit_(limit), count_(0) {}
472 OutputIt
base()
const {
return out_; }
473 size_t count()
const {
return count_; }
478 template <
typename OutputIt,
479 typename Enable =
typename std::is_void<
483 template <
typename OutputIt>
495 if (this->count_++ < this->limit_) ++this->out_;
506 return this->count_ < this->limit_ ? *this->out_ : blackhole_;
510 template <
typename OutputIt>
518 if (this->count_++ < this->limit_) *this->out_++ = val;
527 template <
typename Char>
535 size_t num_code_points = 0;
536 for (
size_t i = 0, size = s.
size(); i != size; ++i) {
537 if ((data[i] & 0xc0) != 0x80) ++num_code_points;
539 return num_code_points;
544 reinterpret_cast<const char*>(s.
data()), s.
size()));
547 template <
typename Char>
549 size_t size = s.
size();
550 return n < size ? n : size;
556 size_t num_code_points = 0;
557 for (
size_t i = 0, size = s.
size(); i != size; ++i) {
558 if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) {
565 template <
typename InputIt,
typename OutChar>
569 std::is_same<OutChar, char8_type>::value>;
571 template <
typename OutChar,
typename InputIt,
typename OutputIt,
573 OutputIt
copy_str(InputIt begin, InputIt end, OutputIt it) {
577 template <
typename OutChar,
typename InputIt,
typename OutputIt,
579 OutputIt
copy_str(InputIt begin, InputIt end, OutputIt it) {
580 return std::transform(begin, end, it,
581 [](
char c) {
return static_cast<char8_type>(c); });
584 template <
typename Char,
typename InputIt>
587 return it + (end - begin);
590 template <
typename T>
592 sizeof(T) <=
sizeof(
double)>;
594 #ifndef FMT_USE_FULL_CACHE_DRAGONBOX 595 # define FMT_USE_FULL_CACHE_DRAGONBOX 0 598 template <
typename T>
599 template <
typename U>
603 try_reserve(size_ +
count);
604 auto free_cap = capacity_ - size_;
609 }
while (begin != end);
612 template <
typename OutputIt,
typename T,
typename Traits>
614 out_ = std::copy_n(data_, this->limit(this->size()), out_);
653 typename Allocator = std::allocator<T>>
663 T* data = this->data();
664 if (data != store_) alloc_.deallocate(data, this->capacity());
676 this->
set(store_, SIZE);
683 alloc_ = std::move(other.
alloc_);
684 T* data = other.
data();
685 size_t size = other.
size(), capacity = other.
capacity();
686 if (data == other.
store_) {
687 this->
set(store_, capacity);
688 std::uninitialized_copy(other.
store_, other.
store_ + size,
691 this->
set(data, capacity);
730 void reserve(
size_t new_capacity) { this->try_reserve(new_capacity); }
734 template <
typename ContiguousRange>
735 void append(
const ContiguousRange& range) {
736 append(range.data(), range.data() + range.size());
740 template <
typename T,
size_t SIZE,
typename Allocator>
743 if (size > 5000)
throw std::runtime_error(
"fuzz mode - won't grow that much");
745 size_t old_capacity = this->capacity();
746 size_t new_capacity = old_capacity + old_capacity / 2;
747 if (size > new_capacity) new_capacity = size;
748 T* old_data = this->data();
750 std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
752 std::uninitialized_copy(old_data, old_data + this->size(),
754 this->
set(new_data, new_capacity);
758 if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
764 template <
typename T,
size_t SIZE,
typename Allocator>
772 explicit format_error(
const char* message) : std::runtime_error(message) {}
774 : std::runtime_error(message) {}
784 template <
typename T>
787 std::is_same<T, int128_t>::value>;
791 template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
795 template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
800 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
809 template <
typename T>
823 : internal_{
static_cast<uint128_t
>(low) |
824 (static_cast<uint128_t>(high) << 64)} {}
828 uint64_t high()
const FMT_NOEXCEPT {
return uint64_t(internal_ >> 64); }
829 uint64_t low()
const FMT_NOEXCEPT {
return uint64_t(internal_); }
846 # if defined(_MSC_VER) && defined(_M_X64) 847 unsigned char carry = _addcarry_u64(0, low_, n, &low_);
848 _addcarry_u64(carry, high_, 0, &high_);
851 uint64_t sum = low_ + n;
852 high_ += (sum < low_ ? 1 : 0);
868 static const uint64_t powers_of_10_64[];
869 static const uint32_t zero_or_powers_of_10_32_new[];
870 static const uint64_t zero_or_powers_of_10_64_new[];
871 static const uint64_t grisu_pow10_significands[];
872 static const int16_t grisu_pow10_exponents[];
875 static const uint64_t dragonbox_pow10_significands_64[];
878 static const uint64_t log10_2_significand = 0x4d104d427de7fbcc;
879 #if !FMT_USE_FULL_CACHE_DRAGONBOX 880 static const uint64_t powers_of_5_64[];
881 static const uint32_t dragonbox_pow10_recovery_errors[];
886 static const char hex_digits[];
887 static const char foreground_color[];
888 static const char background_color[];
890 static const wchar_t wreset_color[5];
891 static const char signs[];
892 static const char left_padding_shifts[5];
893 static const char right_padding_shifts[5];
896 static const uint32_t zero_or_powers_of_10_32[];
897 static const uint64_t zero_or_powers_of_10_64[];
903 static constexpr uint16_t
data[] = {
904 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
905 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
906 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
907 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
918 #ifdef FMT_BUILTIN_CLZLL 923 auto t =
bsr2log10(FMT_BUILTIN_CLZLL(n | 1) ^ 63);
934 if (n < 10)
return count;
935 if (n < 100)
return count + 1;
936 if (n < 1000)
return count + 2;
937 if (n < 10000)
return count + 3;
951 if (n < 10)
return count;
952 if (n < 100)
return count + 1;
953 if (n < 1000)
return count + 2;
954 if (n < 10000)
return count + 3;
962 template <
unsigned BITS,
typename UInt>
inline int count_digits(UInt n) {
966 }
while ((n >>= BITS) != 0);
972 #if FMT_GCC_VERSION || FMT_CLANG_VERSION 973 # define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) 975 # define FMT_ALWAYS_INLINE __forceinline 977 # define FMT_ALWAYS_INLINE inline 981 #if FMT_MSC_VER && !FMT_CLANG_VERSION 982 # define FMT_SAFEBUFFERS __declspec(safebuffers) 984 # define FMT_SAFEBUFFERS 987 #ifdef FMT_BUILTIN_CLZ 990 auto t =
bsr2log10(FMT_BUILTIN_CLZ(n | 1) ^ 31);
1019 return Char(decimal_point_impl<char>(loc));
1022 return decimal_point_impl<wchar_t>(loc);
1026 template <
typename Char>
bool equal2(
const Char* lhs,
const char* rhs) {
1027 return lhs[0] == rhs[0] && lhs[1] == rhs[1];
1029 inline bool equal2(
const char* lhs,
const char* rhs) {
1030 return memcmp(lhs, rhs, 2) == 0;
1034 template <
typename Char>
void copy2(Char* dst,
const char* src) {
1035 *dst++ =
static_cast<Char
>(*src++);
1036 *dst =
static_cast<Char
>(*src);
1048 template <
typename Char,
typename UInt>
1054 while (value >= 100) {
1063 *--out =
static_cast<Char
>(
'0' + value);
1071 template <
typename Char,
typename UInt,
typename Iterator,
1076 Char
buffer[digits10<UInt>() + 1];
1078 return {out, detail::copy_str<Char>(
buffer, end, out)};
1081 template <
unsigned BASE_BITS,
typename Char,
typename UInt>
1083 bool upper =
false) {
1084 buffer += num_digits;
1088 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1089 *--buffer =
static_cast<Char
>(BASE_BITS < 4 ? static_cast<char>(
'0' + digit)
1091 }
while ((value >>= BASE_BITS) != 0);
1095 template <
unsigned BASE_BITS,
typename Char>
1098 auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
1099 int start = (num_digits + char_digits - 1) / char_digits - 1;
1100 if (
int start_digits = num_digits % char_digits) {
1101 unsigned value = n.
value[start--];
1102 buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
1104 for (; start >= 0; --start) {
1105 unsigned value = n.
value[start];
1106 buffer += char_digits;
1108 for (
int i = 0; i < char_digits; ++i) {
1109 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1111 value >>= BASE_BITS;
1117 template <
unsigned BASE_BITS,
typename Char,
typename It,
typename UInt>
1118 inline It
format_uint(It out, UInt value,
int num_digits,
bool upper =
false) {
1120 format_uint<BASE_BITS>(
ptr, value, num_digits, upper);
1124 char buffer[num_bits<UInt>() / BASE_BITS + 1];
1125 format_uint<BASE_BITS>(
buffer, value, num_digits, upper);
1126 return detail::copy_str<Char>(buffer, buffer + num_digits, out);
1138 const wchar_t*
c_str()
const {
return &buffer_[0]; }
1139 std::wstring
str()
const {
return {&buffer_[0], size()}; }
1142 template <
typename T =
void>
struct null {};
1147 enum { max_size = 4 };
1148 Char data_[max_size] = {Char(
' '), Char(0), Char(0), Char(0)};
1149 unsigned char size_ = 1;
1153 auto size = s.
size();
1154 if (size > max_size) {
1158 for (
size_t i = 0; i < size; ++i) data_[i] = s[i];
1159 size_ =
static_cast<unsigned char>(size);
1162 size_t size()
const {
return size_; }
1163 const Char*
data()
const {
return data_; }
1167 return data_[
index];
1206 namespace dragonbox {
1213 static const int significand_bits = 23;
1214 static const int exponent_bits = 8;
1215 static const int min_exponent = -126;
1216 static const int max_exponent = 127;
1217 static const int exponent_bias = -127;
1218 static const int decimal_digits = 9;
1219 static const int kappa = 1;
1220 static const int big_divisor = 100;
1221 static const int small_divisor = 10;
1222 static const int min_k = -31;
1223 static const int max_k = 46;
1224 static const int cache_bits = 64;
1225 static const int divisibility_check_by_5_threshold = 39;
1226 static const int case_fc_pm_half_lower_threshold = -1;
1227 static const int case_fc_pm_half_upper_threshold = 6;
1228 static const int case_fc_lower_threshold = -2;
1229 static const int case_fc_upper_threshold = 6;
1230 static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
1231 static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1232 static const int shorter_interval_tie_lower_threshold = -35;
1233 static const int shorter_interval_tie_upper_threshold = -35;
1234 static const int max_trailing_zeros = 7;
1239 static const int significand_bits = 52;
1240 static const int exponent_bits = 11;
1241 static const int min_exponent = -1022;
1242 static const int max_exponent = 1023;
1243 static const int exponent_bias = -1023;
1244 static const int decimal_digits = 17;
1245 static const int kappa = 2;
1246 static const int big_divisor = 1000;
1247 static const int small_divisor = 100;
1248 static const int min_k = -292;
1249 static const int max_k = 326;
1250 static const int cache_bits = 128;
1251 static const int divisibility_check_by_5_threshold = 86;
1252 static const int case_fc_pm_half_lower_threshold = -2;
1253 static const int case_fc_pm_half_upper_threshold = 9;
1254 static const int case_fc_lower_threshold = -4;
1255 static const int case_fc_upper_threshold = 9;
1256 static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
1257 static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1258 static const int shorter_interval_tie_lower_threshold = -77;
1259 static const int shorter_interval_tie_upper_threshold = -77;
1260 static const int max_trailing_zeros = 16;
1272 template <
typename T>
1300 FMT_ASSERT(-10000 < exp && exp < 10000,
"exponent out of range");
1302 *it++ =
static_cast<Char
>(
'-');
1305 *it++ =
static_cast<Char
>(
'+');
1309 if (exp >= 1000) *it++ =
static_cast<Char
>(top[0]);
1310 *it++ =
static_cast<Char
>(top[1]);
1314 *it++ =
static_cast<Char
>(d[0]);
1315 *it++ =
static_cast<Char
>(d[1]);
1319 template <
typename T>
1323 template <
typename T>
1330 template <
typename Handler>
1348 #ifdef FMT_DEPRECATED_N_SPECIFIER 1362 template <
typename ErrorHandler = error_handler,
typename Char>
1367 switch (specs.
type) {
1398 #ifdef FMT_DEPRECATED_N_SPECIFIER 1405 eh.on_error(
"invalid type specifier");
1411 template <
typename Char,
typename Handler>
1413 Handler&& handler) {
1414 if (!specs)
return handler.on_char();
1415 if (specs->
type && specs->
type !=
'c')
return handler.on_int();
1417 handler.on_error(
"invalid format specifier for char");
1421 template <
typename Char,
typename Handler>
1423 if (spec == 0 || spec ==
's')
1424 handler.on_string();
1425 else if (spec ==
'p')
1426 handler.on_pointer();
1428 handler.on_error(
"invalid type specifier");
1431 template <
typename Char,
typename ErrorHandler>
1433 if (spec != 0 && spec !=
's') eh.on_error(
"invalid type specifier");
1436 template <
typename Char,
typename ErrorHandler>
1438 if (spec != 0 && spec !=
'p') eh.on_error(
"invalid type specifier");
1453 ErrorHandler::on_error(
"invalid type specifier");
1457 template <
typename ErrorHandler>
1464 : ErrorHandler(eh), type_(type) {}
1472 template <
typename ErrorHandler>
1476 : ErrorHandler(eh) {}
1482 template <
typename OutputIt,
typename Char>
1484 auto fill_size = fill.
size();
1485 if (fill_size == 1)
return std::fill_n(it, n, fill[0]);
1486 for (
size_t i = 0; i < n; ++i) it = std::copy_n(fill.
data(), fill_size, it);
1497 size_t width, F&& f) {
1500 size_t padding = spec_width > width ? spec_width - width : 0;
1503 size_t left_padding = padding >> shifts[specs.
align];
1504 auto it =
reserve(out, size + padding * specs.
fill.size());
1505 it =
fill(it, left_padding, specs.
fill);
1507 it =
fill(it, padding - left_padding, specs.
fill);
1516 return write_padded<align>(out, specs, size, size, f);
1519 template <
typename Char,
typename OutputIt>
1525 return copy_str<Char>(data, data + bytes.
size(), it);
1537 : size(prefix.size() +
to_unsigned(num_digits)), padding(0) {
1541 padding = width - size;
1544 }
else if (specs.
precision > num_digits) {
1554 template <
typename OutputIt,
typename Char,
typename F>
1559 return write_padded<align::right>(out, specs,
data.size, [=](iterator it) {
1560 if (prefix.
size() != 0)
1561 it = copy_str<Char>(prefix.begin(), prefix.end(), it);
1562 it = std::fill_n(it,
data.padding, static_cast<Char>(
'0'));
1567 template <
typename StrChar,
typename Char,
typename OutputIt>
1571 auto size = s.
size();
1574 auto width = specs.
width != 0
1578 return write_padded(out, specs, size, width, [=](iterator it) {
1579 return copy_str<Char>(
data, data + size, it);
1584 template <
typename OutputIt,
typename Char,
typename UInt>
struct int_writer {
1597 template <
typename Int>
1603 abs_value(static_cast<UInt>(value)),
1609 abs_value = 0 - abs_value;
1619 out, num_digits, get_prefix(), specs, [
this, num_digits](
iterator it) {
1620 return format_decimal<Char>(it, abs_value, num_digits).end;
1626 prefix[prefix_size++] =
'0';
1627 prefix[prefix_size++] = specs.
type;
1630 out =
write_int(out, num_digits, get_prefix(), specs,
1632 return format_uint<4, Char>(it, abs_value, num_digits,
1639 prefix[prefix_size++] =
'0';
1640 prefix[prefix_size++] =
static_cast<char>(specs.
type);
1642 int num_digits = count_digits<1>(abs_value);
1643 out =
write_int(out, num_digits, get_prefix(), specs,
1645 return format_uint<1, Char>(it, abs_value, num_digits);
1650 int num_digits = count_digits<3>(abs_value);
1651 if (specs.
alt && specs.
precision <= num_digits && abs_value != 0) {
1654 prefix[prefix_size++] =
'0';
1656 out =
write_int(out, num_digits, get_prefix(), specs,
1658 return format_uint<3, Char>(it, abs_value, num_digits);
1662 enum { sep_size = 1 };
1665 std::string groups = grouping<Char>(locale);
1666 if (groups.empty())
return on_dec();
1667 auto sep = thousands_sep<Char>(locale);
1668 if (!sep)
return on_dec();
1670 int size = num_digits, n = num_digits;
1671 std::string::const_iterator group = groups.cbegin();
1672 while (group != groups.cend() && n > *group && *group > 0 &&
1673 *group != max_value<char>()) {
1678 if (group == groups.cend()) size += sep_size * ((n - 1) / groups.back());
1682 size +=
static_cast<int>(prefix_size);
1687 int digit_index = 0;
1688 group = groups.cbegin();
1689 auto p = buffer.
data() + size - 1;
1690 for (
int i = num_digits - 1; i > 0; --i) {
1691 *p-- =
static_cast<Char
>(digits[i]);
1692 if (*group <= 0 || ++digit_index % *group != 0 ||
1693 *group == max_value<char>())
1695 if (group + 1 != groups.cend()) {
1703 *p-- =
static_cast<Char
>(*digits);
1704 if (prefix_size != 0) *p =
static_cast<Char
>(
'-');
1706 out = write_padded<align::right>(
1707 out, specs, usize, usize,
1708 [=](
iterator it) {
return copy_str<Char>(
data, data + size, it); });
1711 void on_chr() { *out++ =
static_cast<Char
>(abs_value); }
1718 template <
typename Char,
typename OutputIt>
1723 isinf ? (fspecs.
upper ?
"INF" :
"inf") : (fspecs.
upper ?
"NAN" :
"nan");
1724 constexpr
size_t str_size = 3;
1726 auto size = str_size + (
sign ? 1 : 0);
1728 return write_padded(out, specs, size, [=](iterator it) {
1730 return copy_str<Char>(str, str + str_size, it);
1744 template <
typename T>
1749 template <
typename Char,
typename OutputIt>
1751 int& significand_size) {
1752 return copy_str<Char>(significand, significand + significand_size, out);
1754 template <
typename Char,
typename OutputIt,
typename UInt>
1756 int significand_size) {
1757 return format_decimal<Char>(out, significand, significand_size).end;
1760 template <
typename Char,
typename UInt,
1763 int significand_size,
int integral_size,
1767 auto end =
format_decimal(out + 1, significand, significand_size).end;
1768 if (integral_size == 1)
1771 std::copy_n(out + 1, integral_size, out);
1776 template <
typename OutputIt,
typename UInt,
typename Char,
1779 int significand_size,
int integral_size,
1782 Char
buffer[digits10<UInt>() + 2];
1784 integral_size, decimal_point);
1785 return detail::copy_str<Char>(
buffer, end, out);
1788 template <
typename OutputIt,
typename Char>
1790 int significand_size,
int integral_size,
1792 out = detail::copy_str<Char>(significand, significand + integral_size, out);
1793 if (!decimal_point)
return out;
1795 return detail::copy_str<Char>(significand + integral_size,
1796 significand + significand_size, out);
1799 template <
typename OutputIt,
typename DecimalFP,
typename Char>
1803 auto significand = fp.significand;
1805 static const Char zero =
static_cast<Char
>(
'0');
1810 int output_exp = fp.exponent + significand_size - 1;
1811 auto use_exp_format = [=]() {
1816 const int exp_lower = -4, exp_upper = 16;
1817 return output_exp < exp_lower ||
1820 if (use_exp_format()) {
1823 num_zeros = (std::max)(fspecs.
precision - significand_size, 0);
1825 }
else if (significand_size == 1) {
1826 decimal_point = Char();
1828 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
1830 if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
1832 size +=
to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
1833 char exp_char = fspecs.
upper ?
'E' :
'e';
1834 auto write = [=](iterator it) {
1839 if (num_zeros > 0) it = std::fill_n(it, num_zeros, zero);
1840 *it++ =
static_cast<Char
>(exp_char);
1841 return write_exponent<Char>(output_exp, it);
1843 return specs.
width > 0 ? write_padded<align::right>(out, specs, size,
write)
1847 int exp = fp.exponent + significand_size;
1848 if (fp.exponent >= 0) {
1853 if (num_zeros > 5000)
1854 throw std::runtime_error(
"fuzz mode - avoiding excessive cpu use");
1858 if (num_zeros > 0) size +=
to_unsigned(num_zeros);
1860 return write_padded<align::right>(out, specs, size, [&](iterator it) {
1862 it = write_significand<Char>(it, significand, significand_size);
1863 it = std::fill_n(it, fp.exponent, zero);
1866 return num_zeros > 0 ? std::fill_n(it, num_zeros, zero) : it;
1868 }
else if (exp > 0) {
1871 size += 1 +
to_unsigned(num_zeros > 0 ? num_zeros : 0);
1872 return write_padded<align::right>(out, specs, size, [&](iterator it) {
1876 return num_zeros > 0 ? std::fill_n(it, num_zeros, zero) : it;
1880 int num_zeros = -
exp;
1881 if (significand_size == 0 && fspecs.
precision >= 0 &&
1886 return write_padded<align::right>(out, specs, size, [&](iterator it) {
1889 if (num_zeros == 0 && significand_size == 0 && !fspecs.
showpoint)
return it;
1891 it = std::fill_n(it, num_zeros, zero);
1892 return write_significand<Char>(it, significand, significand_size);
1896 template <
typename Char,
typename OutputIt,
typename T,
1903 if (std::signbit(value)) {
1929 if (precision == max_value<int>())
1939 fspecs.
locale ? decimal_point<Char>(loc) : static_cast<Char>(
'.');
1944 template <
typename Char,
typename OutputIt,
typename T,
1954 auto sign_bit =
bits & (uint(1) << (num_bits<uint>() - 1));
1955 if (sign_bit != 0) {
1961 uint mask = exponent_mask<floaty>();
1962 if ((
bits & mask) == mask)
1966 return write_float(out, dec, specs, fspecs, static_cast<Char>(
'.'));
1969 template <
typename Char,
typename OutputIt,
typename T,
1972 inline OutputIt
write(OutputIt out, T value) {
1976 template <
typename Char,
typename OutputIt>
1986 template <
typename Char,
typename OutputIt,
typename UIntPtr>
1992 auto write = [=](iterator it) {
1993 *it++ =
static_cast<Char
>(
'0');
1994 *it++ =
static_cast<Char
>(
'x');
1995 return format_uint<4, Char>(it, value, num_digits);
1997 return specs ? write_padded<align::right>(out, *specs, size,
write)
2005 template <
typename Char,
typename OutputIt>
2011 template <
typename Char,
typename OutputIt,
2015 it = copy_str<Char>(value.
begin(), value.
end(), it);
2019 template <
typename Char,
typename OutputIt>
2026 template <
typename Char>
2033 template <
typename Char,
typename OutputIt,
typename T,
2035 !std::is_same<T, bool>::value &&
2036 !std::is_same<T, Char>::value)>
2037 OutputIt
write(OutputIt out, T value) {
2041 if (negative) abs_value = ~abs_value + 1;
2043 auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2045 if (
auto ptr = to_pointer<Char>(it, size)) {
2046 if (negative) *
ptr++ =
static_cast<Char
>(
'-');
2047 format_decimal<Char>(
ptr, abs_value, num_digits);
2050 if (negative) *it++ =
static_cast<Char
>(
'-');
2051 it = format_decimal<Char>(it, abs_value, num_digits).end;
2055 template <
typename Char,
typename OutputIt>
2056 OutputIt
write(OutputIt out,
bool value) {
2057 return write<Char>(out,
string_view(value ?
"true" :
"false"));
2060 template <
typename Char,
typename OutputIt>
2061 OutputIt
write(OutputIt out, Char value) {
2067 template <
typename Char,
typename OutputIt>
2068 OutputIt
write(OutputIt out,
const Char* value) {
2072 auto length = std::char_traits<Char>::length(value);
2078 template <
typename Char,
typename OutputIt>
2079 OutputIt
write(OutputIt out,
const void* value) {
2080 return write_ptr<Char>(out,
to_uintptr(value),
nullptr);
2083 template <
typename Char,
typename OutputIt,
typename T>
2084 auto write(OutputIt out,
const T& value) ->
typename std::enable_if<
2089 using formatter_type =
2091 typename context_type::template formatter_type<T>,
2093 context_type ctx(out, {}, {});
2094 return formatter_type().format(value, ctx);
2107 return write<Char>(out, value);
2113 handle.
format(parse_ctx, format_ctx);
2114 return format_ctx.out();
2118 template <
typename OutputIt,
typename Char,
2152 template <typename Ch, FMT_ENABLE_IF(std::is_same<Ch, Char>::value)>
2154 out_ = detail::write<Char>(out_, value);
2159 it = copy_str<Char>(value.
begin(), value.
end(), it);
2162 static_assert(std::is_same<Char, wchar_t>::value,
"");
2167 template <
typename Ch>
2169 auto width = specs.
width != 0
2173 return copy_str<Char>(s, s + size, it);
2177 template <
typename Ch>
2183 out_ = write_ptr<char_type>(out_,
to_uintptr(p), specs_);
2191 : formatter(f), value(val) {}
2201 formatter.
write(value);
2210 : formatter(f), value(val) {}
2224 out_ = detail::write<Char>(out_, value);
2231 auto length = std::char_traits<char_type>::length(value);
2239 : out_(out), locale_(loc), specs_(s) {}
2246 template <typename T, FMT_ENABLE_IF(is_integral<T>::value)>
2251 out_ = detail::write<Char>(out_, value);
2257 char_spec_handler(*
this, static_cast<Char>(value)));
2262 if (specs_ && specs_->
type)
return (*
this)(value ? 1 : 0);
2267 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
2273 FMT_ASSERT(
false,
"unsupported float argument type");
2278 if (!specs_)
return write(value), out_;
2286 write(value, *specs_);
2295 write_pointer(value);
2301 template <
typename OutputIt,
typename Char>
2327 :
base(ctx.out(), specs, ctx.locale()),
2329 parse_ctx_(parse_ctx),
2332 using base::operator();
2337 handle.
format(*parse_ctx_, ctx_);
2343 return (
'a' <= c && c <=
'z') || (
'A' <= c && c <=
'Z') ||
'_' == c;
2348 template <
typename Char,
typename ErrorHandler>
2350 ErrorHandler&& eh) {
2351 FMT_ASSERT(begin != end &&
'0' <= *begin && *begin <=
'9',
"");
2354 constexpr
unsigned max_int = max_value<int>();
2355 unsigned big = max_int / 10;
2359 value = max_int + 1;
2362 value = value * 10 + unsigned(*begin -
'0');
2364 }
while (begin != end &&
'0' <= *begin && *begin <=
'9');
2365 if (value > max_int) eh.on_error(
"number is too big");
2366 return static_cast<int>(value);
2379 : parse_ctx_(parse_ctx), ctx_(ctx) {}
2382 h.
format(parse_ctx_, ctx_);
2388 template <
typename T>
2391 !std::is_same<T, char>::value &&
2392 !std::is_same<T, wchar_t>::value>;
2398 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2400 if (
is_negative(value)) handler_.on_error(
"negative width");
2401 return static_cast<unsigned long long>(value);
2404 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2406 handler_.on_error(
"width is not integer");
2418 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2420 if (
is_negative(value)) handler_.on_error(
"negative precision");
2421 return static_cast<unsigned long long>(value);
2424 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2426 handler_.on_error(
"precision is not integer");
2441 : specs_(other.specs_) {}
2454 specs_.
fill[0] = Char(
'0');
2464 specs_.
type =
static_cast<char>(
type);
2474 : error_handler_(eh), arg_type_(arg_type) {}
2478 error_handler_.on_error(
"format specifier requires numeric argument");
2482 require_numeric_argument();
2485 error_handler_.on_error(
"format specifier requires signed argument");
2491 error_handler_.on_error(
"precision not allowed for this argument type");
2513 : Handler(other), checker_(
error_handler(), other.arg_type_) {}
2517 Handler::on_align(align);
2527 Handler::on_minus();
2532 Handler::on_space();
2548 template <
template <
typename>
class Handler,
typename FormatArg,
2549 typename ErrorHandler>
2551 unsigned long long value =
visit_format_arg(Handler<ErrorHandler>(eh), arg);
2552 if (value >
to_unsigned(max_value<int>())) eh.on_error(
"number is too big");
2553 return static_cast<int>(value);
2558 template <
typename Context,
typename ID>
2560 auto arg = ctx.arg(
id);
2561 if (!
arg) ctx.on_error(
"argument not found");
2566 template <
typename ParseContext,
typename Context>
2572 ParseContext& parse_ctx, Context& ctx)
2574 parse_context_(parse_ctx),
2578 this->specs_.
width = get_dynamic_spec<width_checker>(
2579 get_arg(arg_id), context_.error_handler());
2583 this->specs_.
precision = get_dynamic_spec<precision_checker>(
2584 get_arg(arg_id), context_.error_handler());
2587 void on_error(
const char* message) { context_.on_error(message); }
2598 parse_context_.check_arg_id(arg_id);
2603 parse_context_.check_arg_id(arg_id);
2641 template <
typename Char>
2649 template <
typename ParseContext>
2651 :
public specs_setter<typename ParseContext::char_type> {
2661 specs_(other.specs_),
2662 context_(other.context_) {}
2665 specs_.width_ref = make_arg_ref(arg_id);
2669 specs_.precision_ref = make_arg_ref(arg_id);
2673 context_.on_error(message);
2680 context_.check_arg_id(arg_id);
2689 context_.check_arg_id(arg_id);
2691 context_.begin(),
to_unsigned(context_.end() - context_.begin()));
2699 template <
typename Char,
typename IDHandler>
2701 IDHandler&& handler) {
2704 if (c ==
'}' || c ==
':') {
2708 if (c >=
'0' && c <=
'9') {
2714 if (begin == end || (*begin !=
'}' && *begin !=
':'))
2715 handler.on_error(
"invalid format string");
2721 handler.on_error(
"invalid format string");
2727 }
while (it != end && (
is_name_start(c = *it) || (
'0' <= c && c <=
'9')));
2739 handler.on_dynamic_width(
id);
2743 handler.on_error(message);
2756 handler.on_dynamic_precision(
id);
2760 handler.on_error(message);
2766 template <
typename Char>
2769 constexpr
char lengths[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2770 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0};
2771 int len = lengths[
static_cast<unsigned char>(*begin) >> 3];
2780 return (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z');
2784 template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
2788 template <typename Char, FMT_ENABLE_IF(std::is_enum<Char>::value)>
2794 template <
typename Char,
typename Handler>
2796 Handler&& handler) {
2800 if (p >= end) p = begin;
2809 #if FMT_DEPRECATED_NUMERIC_ALIGN 2822 return handler.on_error(
"invalid fill character '{'"), begin;
2827 handler.on_align(
align);
2829 }
else if (p == begin) {
2837 template <
typename Char,
typename Handler>
2839 Handler&& handler) {
2841 if (
'0' <= *begin && *begin <=
'9') {
2843 }
else if (*begin ==
'{') {
2847 if (begin == end || *begin !=
'}')
2848 return handler.on_error(
"invalid format string"), begin;
2854 template <
typename Char,
typename Handler>
2856 Handler&& handler) {
2858 auto c = begin != end ? *begin : Char();
2859 if (
'0' <= c && c <=
'9') {
2861 }
else if (c ==
'{') {
2867 if (begin == end || *begin++ !=
'}')
2868 return handler.on_error(
"invalid format string"), begin;
2870 return handler.on_error(
"missing precision specifier"), begin;
2872 handler.end_precision();
2878 template <
typename Char,
typename SpecHandler>
2880 SpecHandler&& handler) {
2881 if (begin == end)
return begin;
2884 if (begin == end)
return begin;
2901 if (begin == end)
return begin;
2903 if (*begin ==
'#') {
2905 if (++begin == end)
return begin;
2909 if (*begin ==
'0') {
2911 if (++begin == end)
return begin;
2915 if (begin == end)
return begin;
2918 if (*begin ==
'.') {
2923 if (begin != end && *begin !=
'}') handler.on_type(*begin++);
2928 template <
bool IS_CONSTEXPR,
typename T,
typename Ptr = const T*>
2930 for (out = first; out != last; ++out) {
2931 if (*out == value)
return true;
2939 out =
static_cast<const char*
>(
2941 return out !=
nullptr;
2951 arg_id = handler.on_arg_id(
id);
2954 handler.on_error(message);
2958 template <
typename Char,
typename Handler>
2961 Handler&& handler) {
2963 if (begin == end)
return handler.on_error(
"invalid format string"), end;
2964 if (*begin ==
'}') {
2965 handler.on_replacement_field(handler.on_arg_id(), begin);
2966 }
else if (*begin ==
'{') {
2967 handler.on_text(begin, begin + 1);
2971 Char c = begin != end ? *begin : Char();
2973 handler.on_replacement_field(adapter.arg_id, begin);
2974 }
else if (c ==
':') {
2975 begin = handler.on_format_specs(adapter.arg_id, begin + 1, end);
2976 if (begin == end || *begin !=
'}')
2977 return handler.on_error(
"unknown format specifier"), end;
2979 return handler.on_error(
"missing '}' in format string"), end;
2985 template <
bool IS_CONSTEXPR,
typename Char,
typename Handler>
2988 auto begin = format_str.
data();
2989 auto end = begin + format_str.
size();
2990 if (end - begin < 32) {
2992 const Char* p = begin;
2996 handler.on_text(begin, p - 1);
2998 }
else if (c ==
'}') {
2999 if (p == end || *p !=
'}')
3000 return handler.on_error(
"unmatched '}' in format string");
3001 handler.on_text(begin, p);
3005 handler.on_text(begin, end);
3009 FMT_CONSTEXPR void operator()(
const Char* pbegin,
const Char* pend) {
3010 if (pbegin == pend)
return;
3012 const Char* p =
nullptr;
3013 if (!find<IS_CONSTEXPR>(pbegin, pend,
'}', p))
3014 return handler_.on_text(pbegin, pend);
3016 if (p == pend || *p !=
'}')
3017 return handler_.on_error(
"unmatched '}' in format string");
3018 handler_.on_text(pbegin, p);
3024 while (begin != end) {
3027 const Char* p = begin;
3028 if (*begin !=
'{' && !find<IS_CONSTEXPR>(begin + 1, end,
'{', p))
3029 return write(begin, end);
3035 template <
typename T,
typename ParseContext>
3037 ParseContext& ctx) {
3047 return f.parse(ctx);
3050 template <
typename OutputIt,
typename Char,
typename Context>
3057 : parse_context(str), context(out, format_args, loc) {}
3059 void on_text(
const Char* begin,
const Char* end) {
3061 auto out = context.out();
3062 auto&& it =
reserve(out, size);
3063 it = std::copy_n(begin, size, it);
3064 context.advance_to(out);
3070 int arg_id = context.arg_id(
id);
3071 if (arg_id < 0) on_error(
"argument not found");
3088 return parse_context.
begin();
3092 specs.
type =
static_cast<char>(*begin++);
3100 if (begin == end || *begin !=
'}')
3101 on_error(
"missing '}' in format string");
3113 template <
typename Char,
typename ErrorHandler = error_handler>
3123 ErrorHandler eh = {})
3124 :
base(format_str, eh), num_args_(num_args) {}
3127 int id = base::next_arg_id();
3128 if (
id >= num_args_) this->on_error(
"argument not found");
3133 base::check_arg_id(
id);
3134 if (
id >= num_args_) this->on_error(
"argument not found");
3136 using base::check_arg_id;
3139 template <
typename Char,
typename ErrorHandler,
typename... Args>
3144 : context_(format_str, num_args, eh),
3145 parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
3152 on_error(
"compile-time checks don't support named arguments");
3161 return id < num_args ? parse_funcs_[id](context_) : begin;
3165 context_.on_error(message);
3170 enum { num_args =
sizeof...(Args) };
3180 template <
typename Char,
size_t N>
3182 const Char (&s)[N]) {
3186 N - ((std::char_traits<Char>::to_int_type(s[N - 1]) == 0) ? 1 : 0)};
3190 template <
typename Char>
3193 return {s.data(), s.size()};
3196 #define FMT_STRING_IMPL(s, base) \ 3199 struct FMT_COMPILE_STRING : base { \ 3200 using char_type = fmt::remove_cvref_t<decltype(s[0])>; \ 3201 FMT_MAYBE_UNUSED FMT_CONSTEXPR \ 3202 operator fmt::basic_string_view<char_type>() const { \ 3203 return fmt::detail::compile_string_to_view<char_type>(s); \ 3206 return FMT_COMPILE_STRING(); \ 3219 #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string) 3221 template <
typename... Args,
typename S,
3228 (parse_format_string<true>(s, checker(s, {})),
true);
3229 (void)invalid_format;
3232 template <
template <
typename>
class Handler,
typename Context>
3239 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
index),
3240 ctx.error_handler());
3243 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
name),
3244 ctx.error_handler());
3258 template <
typename OutputIt,
typename Char>
3295 template <
typename... Args>
3297 : std::runtime_error(
"") {
3339 mutable char buffer_[buffer_size];
3349 bool negative = value < 0;
3350 if (negative) abs_value = 0 - abs_value;
3351 auto begin = format_unsigned(abs_value);
3352 if (negative) *--begin =
'-';
3359 explicit format_int(
long long value) : str_(format_signed(value)) {}
3360 explicit format_int(
unsigned value) : str_(format_unsigned(value)) {}
3361 explicit format_int(
unsigned long value) : str_(format_unsigned(value)) {}
3363 : str_(format_unsigned(value)) {}
3374 const char*
data()
const {
return str_; }
3381 buffer_[buffer_size - 1] =
'\0';
3390 std::string
str()
const {
return std::string(str_, size()); }
3395 template <
typename T,
typename Char>
3403 template <
typename ParseContext>
3410 auto eh = ctx.error_handler();
3439 FMT_ASSERT(
false,
"double support disabled");
3445 FMT_ASSERT(
false,
"long double support disabled");
3465 template <
typename FormatContext>
3466 auto format(
const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3467 detail::handle_dynamic_spec<detail::width_checker>(specs_.
width,
3468 specs_.width_ref, ctx);
3469 detail::handle_dynamic_spec<detail::precision_checker>(
3470 specs_.
precision, specs_.precision_ref, ctx);
3474 detail::make_arg<FormatContext>(val));
3481 #define FMT_FORMAT_AS(Type, Base) \ 3482 template <typename Char> \ 3483 struct formatter<Type, Char> : formatter<Base, Char> { \ 3484 template <typename FormatContext> \ 3485 auto format(Type const& val, FormatContext& ctx) -> decltype(ctx.out()) { \ 3486 return formatter<Base, Char>::format(val, ctx); \ 3501 template <
typename Char>
3503 template <
typename FormatContext>
3504 auto format(
void* val, FormatContext& ctx) -> decltype(ctx.out()) {
3509 template <
typename Char,
size_t N>
3511 template <
typename FormatContext>
3512 auto format(
const Char* val, FormatContext& ctx) -> decltype(ctx.out()) {
3540 template <
typename ParseContext>
3541 auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3542 format_str_ = ctx.begin();
3548 template <
typename T,
typename FormatContext>
3549 auto format(
const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3554 switch (specs_.
sign) {
3572 detail::make_arg<FormatContext>(val));
3578 detail::handle_dynamic_spec<detail::width_checker>(specs_.
width,
3579 specs_.width_ref, ctx);
3580 detail::handle_dynamic_spec<detail::precision_checker>(
3581 specs_.
precision, specs_.precision_ref, ctx);
3588 template <
typename Char,
typename ErrorHandler>
3603 template <
typename T>
inline const void*
ptr(
const T* p) {
return p; }
3604 template <
typename T>
inline const void*
ptr(
const std::unique_ptr<T>& p) {
3607 template <
typename T>
inline const void*
ptr(
const std::shared_ptr<T>& p) {
3625 template <
typename ParseContext>
3635 template <
typename FormatContext>
3637 detail::handle_dynamic_spec<detail::width_checker>(specs_.
width,
3639 detail::handle_dynamic_spec<detail::precision_checker>(
3645 template <
typename It,
typename Sentinel,
typename Char>
3652 : begin(b), end(e), sep(s) {}
3655 template <
typename It,
typename Sentinel,
typename Char>
3657 :
formatter<typename std::iterator_traits<It>::value_type, Char> {
3658 template <
typename FormatContext>
3660 -> decltype(ctx.out()) {
3662 auto it = value.begin;
3663 auto out = ctx.out();
3664 if (it != value.end) {
3666 while (it != value.end) {
3667 out =
std::copy(value.sep.begin(), value.sep.end(), out);
3668 ctx.advance_to(out);
3680 template <
typename It,
typename Sentinel>
3682 return {begin, end, sep};
3685 template <
typename It,
typename Sentinel>
3687 return {begin, end, sep};
3706 template <
typename Range>
3709 return join(std::begin(range), std::end(range), sep);
3712 template <
typename Range>
3715 return join(std::begin(range), std::end(range), sep);
3729 template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
3732 detail::write<char>(std::back_inserter(result), value);
3736 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
3740 constexpr
int max_size = detail::digits10<T>() + 2;
3741 char buffer[max_size > 5 ?
static_cast<unsigned>(max_size) : 5];
3742 char* begin = buffer;
3743 return std::string(begin, detail::write<char>(begin, value));
3749 template <
typename T>
inline std::wstring
to_wstring(
const T& value) {
3750 return format(L
"{}", value);
3753 template <
typename Char,
size_t SIZE>
3755 auto size = buf.
size();
3757 return std::basic_string<Char>(buf.
data(), size);
3760 template <
typename Char>
3766 auto out = buffer_appender<Char>(buf);
3768 auto arg = args.get(0);
3769 if (!
arg) error_handler().on_error(
"argument not found");
3774 format_handler<iterator, Char, buffer_context<Char>> h(out, format_str, args,
3776 parse_format_string<false>(format_str, h);
3779 #ifndef FMT_HEADER_ONLY 3792 float_specs specs, buffer<char>& buf);
3796 int snprintf_float(
float value,
int precision, float_specs specs,
3797 buffer<char>& buf) =
delete;
3808 template <
typename S,
typename Char =
char_t<S>,
3809 FMT_ENABLE_IF(detail::is_
string<S>::value)>
3825 template <
typename OutputIt,
typename Char =
char>
3828 template <
typename OutputIt,
typename Char =
char>
3831 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3834 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3835 using format_to_n_args FMT_DEPRECATED_ALIAS =
3838 template <
typename OutputIt,
typename Char,
typename... Args>
3841 return format_arg_store<buffer_context<Char>, Args...>(args...);
3844 template <typename Char, enable_if_t<(!std::is_same<Char, char>::value),
int>>
3853 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
3859 if (std::fputws(buffer.
data(), f) == -1)
3863 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
3865 vprint(stdout, format_str, args);
3868 #if FMT_USE_USER_DEFINED_LITERALS 3871 # if FMT_USE_UDL_TEMPLATE 3872 template <
typename Char, Char... CHARS>
class udl_formatter {
3874 template <
typename... Args>
3875 std::basic_string<Char> operator()(Args&&... args)
const {
3881 template <
typename Char>
struct udl_formatter {
3884 template <
typename... Args>
3885 std::basic_string<Char> operator()(Args&&... args)
const {
3886 return format(str, std::forward<Args>(args)...);
3889 # endif // FMT_USE_UDL_TEMPLATE 3891 template <
typename Char>
struct udl_arg {
3894 template <
typename T> named_arg<Char, T> operator=(T&& value)
const {
3895 return {str, std::forward<T>(value)};
3900 inline namespace literals {
3901 # if FMT_USE_UDL_TEMPLATE 3902 # pragma GCC diagnostic push 3903 # pragma GCC diagnostic ignored "-Wpedantic" 3904 # if FMT_CLANG_VERSION 3905 # pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template" 3907 template <
typename Char, Char... CHARS>
3908 FMT_CONSTEXPR detail::udl_formatter<Char, CHARS...>
operator""_format() {
3911 # pragma GCC diagnostic pop 3923 FMT_CONSTEXPR detail::udl_formatter<char>
operator"" _format(
const char* s,
3927 FMT_CONSTEXPR detail::udl_formatter<wchar_t>
operator"" _format(
3928 const wchar_t* s,
size_t n) {
3931 # endif // FMT_USE_UDL_TEMPLATE 3943 FMT_CONSTEXPR detail::udl_arg<char>
operator"" _a(
const char* s,
size_t) {
3946 FMT_CONSTEXPR detail::udl_arg<wchar_t>
operator"" _a(
const wchar_t* s,
size_t) {
3950 #endif // FMT_USE_USER_DEFINED_LITERALS 3953 #ifdef FMT_HEADER_ONLY 3954 # define FMT_FUNC inline 3960 #endif // FMT_FORMAT_H_
FMT_CONSTEXPR void on_space()
FMT_CONSTEXPR void on_plus()
FMT_CONSTEXPR format_arg get_arg(basic_string_view< char_type > arg_id)
truncating_iterator & operator*()
#define FMT_BEGIN_NAMESPACE
FMT_API decimal_fp< T > to_decimal(T x) FMT_NOEXCEPT
constexpr size_t size() const
Dest bit_cast(const Source &source)
uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
#define FMT_ASSERT(condition, message)
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
FMT_FUNC int count_digits< 4 >(detail::fallback_uintptr n)
FMT_CONSTEXPR width_adapter(SpecHandler &h)
FMT_CONSTEXPR void require_numeric_argument()
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
void set(T *buf_data, size_t buf_capacity) FMT_NOEXCEPT
Char thousands_sep(locale_ref loc)
auto make_args_checked(const S &format_str, const remove_reference_t< Args > &... args) -> format_arg_store< buffer_context< Char >, remove_reference_t< Args >... >
FMT_CONSTEXPR void on_width(int width)
int snprintf_float(T value, int precision, float_specs specs, buffer< char > &buf)
size_t code_point_index(basic_string_view< Char > s, size_t n)
FMT_CONSTEXPR const Char * parse_align(const Char *begin, const Char *end, Handler &&handler)
FMT_CONSTEXPR void on_oct()
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
unsigned char value[sizeof(void *)]
FMT_CONSTEXPR bool is_supported_floating_point(T)
dynamic_format_specs< char_type > & specs_
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
FMT_CONSTEXPR int code_point_length(const Char *begin)
FMT_INLINE uint16_t bsr2log10(int bsr)
fallback_uintptr uintptr_t
FMT_CONSTEXPR void on_minus()
FMT_CONSTEXPR int parse_nonnegative_int(const Char *&begin, const Char *end, ErrorHandler &&eh)
void format_arg(basic_format_parse_context< typename Context::char_type > &parse_ctx, Context &ctx, Id arg_id)
static const char left_padding_shifts[5]
FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler &&handler)
FMT_CONSTEXPR numeric_specs_checker(ErrorHandler &eh, detail::type arg_type)
value_type & operator*() const
template int snprintf_float< double >(double value, int precision, float_specs specs, buffer< char > &buf)
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)
It write_exponent(int exp, It it)
FMT_CONSTEXPR float_specs parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={})
constexpr int digits10< uint128_t >() FMT_NOEXCEPT
FMT_CONSTEXPR void on_precision(int precision)
typename ParseContext::char_type char_type
FMT_CONSTEXPR const Char * parse_width(const Char *begin, const Char *end, Handler &&handler)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
int count_digits(uint64_t n)
FMT_CONSTEXPR specs_setter(const specs_setter &other)
#define FMT_BUFFER_CONTEXT(Char)
FMT_CONSTEXPR specs_handler(basic_format_specs< char_type > &specs, ParseContext &parse_ctx, Context &ctx)
template FMT_API std::string grouping_impl< char >(locale_ref loc)
arg_join(It b, Sentinel e, basic_string_view< Char > s)
FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view< char_type > arg_id)
FMT_CONSTEXPR compile_parse_context(basic_string_view< Char > format_str, int num_args=max_value< int >(), ErrorHandler eh={})
typename Context::format_arg format_arg
FMT_FUNC Char decimal_point_impl(locale_ref loc)
std::ptrdiff_t difference_type
template FMT_API std::string grouping_impl< wchar_t >(locale_ref loc)
OutputIt write(OutputIt out, basic_string_view< StrChar > s, const basic_format_specs< Char > &specs)
FMT_CONSTEXPR void on_num()
void push_back(const T &value)
FMT_FUNC void report_error(format_func func, int error_code, string_view message) FMT_NOEXCEPT
static const digit_pair digits[]
Allocator get_allocator() const
typename type_identity< T >::type type_identity_t
FMT_CONSTEXPR const Char & operator[](size_t index) const
bool find< false, char >(const char *first, const char *last, char value, const char *&out)
FMT_CONSTEXPR int_type_checker(ErrorHandler eh)
FMT_CONSTEXPR void operator()(int id)
OutputIt write_bytes(OutputIt out, string_view bytes, const basic_format_specs< Char > &specs)
basic_memory_buffer & operator=(basic_memory_buffer &&other) FMT_NOEXCEPT
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
FMT_CONSTEXPR void check_arg_id(int)
counting_iterator & operator++()
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char >>> args)
uint128_wrapper & operator+=(uint64_t n) FMT_NOEXCEPT
constexpr bool is_integral_type(type t)
FMT_CONSTEXPR void on_error(const char *message)
FMT_CONSTEXPR const Char * parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler)
conditional_t< num_bits< T >()<=32 &&!FMT_REDUCE_INT_INSTANTIATIONS, uint32_t, conditional_t< num_bits< T >()<=64, uint64_t, uint128_t > > uint32_or_64_or_128_t
FMT_CONSTEXPR precision_adapter(SpecHandler &h)
Char * format_uint(Char *buffer, UInt value, int num_digits, bool upper=false)
FMT_CONSTEXPR arg_ref(basic_string_view< Char > name)
#define FMT_CONSTEXPR_DECL
FMT_CONSTEXPR void operator()()
FMT_CONSTEXPR format_arg get_arg(auto_id)
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
basic_string_view< wchar_t > wstring_view
template int format_float< double >(double value, int precision, float_specs specs, buffer< char > &buf)
typename float_info< T >::carrier_uint significand_type
OutputIt write_nonfinite(OutputIt out, bool isinf, const basic_format_specs< Char > &specs, const float_specs &fspecs)
size_t count_code_points(basic_string_view< Char > s)
FMT_CONSTEXPR const Char * parse_replacement_field(const Char *begin, const Char *end, Handler &&handler)
#define FMT_EXTERN_TEMPLATE_API
basic_memory_buffer(basic_memory_buffer &&other) FMT_NOEXCEPT
FMT_CONSTEXPR void operator()()
static const uint64_t zero_or_powers_of_10_64_new[]
FMT_CONSTEXPR void check_arg_id(int id)
constexpr bool is_ascii_letter(Char c)
FMT_CONSTEXPR arg_ref_type make_arg_ref(int arg_id)
FMT_CONSTEXPR int next_arg_id()
constexpr const Char * data() const
FMT_CONSTEXPR void end_precision()
template FMT_API char thousands_sep_impl< char >(locale_ref loc)
void grow(size_t size) final FMT_OVERRIDE
constexpr int num_bits< int128_t >()
FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
typename std::iterator_traits< OutputIt >::value_type value_type
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
void reserve(size_t new_capacity)
size_t capacity() const FMT_NOEXCEPT
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh)
FMT_CONSTEXPR void end_precision()
bool_constant< std::numeric_limits< T >::is_iec559 &&sizeof(T)<=sizeof(double)> is_fast_float
constexpr int digits10< int128_t >() FMT_NOEXCEPT
OutputIt write_padded(OutputIt out, const basic_format_specs< Char > &specs, size_t size, size_t width, F &&f)
#define FMT_END_NAMESPACE
void copy2(Char *dst, const char *src)
truncating_iterator & operator=(T val)
void resize(size_t count)
constexpr int digits10() FMT_NOEXCEPT
#define FMT_CLANG_VERSION
int get_significand_size(const big_decimal_fp &fp)
FMT_CONSTEXPR const Char * parse_precision(const Char *begin, const Char *end, Handler &&handler)
FMT_CONSTEXPR basic_string_view< Char > compile_string_to_view(const Char(&s)[N])
FMT_CONSTEXPR cstring_type_checker(ErrorHandler eh)
FMT_SAFEBUFFERS decimal_fp< T > to_decimal(T x) FMT_NOEXCEPT
FMT_CONSTEXPR void on_zero()
constexpr Char to_ascii(Char value)
FMT_CONSTEXPR void on_hex()
value_type operator*() const
OutputIterator copy(const RangeT &range, OutputIterator out)
typename std::enable_if< B, T >::type enable_if_t
FMT_CONSTEXPR specs_checker(const specs_checker &other)
basic_memory_buffer(const Allocator &alloc=Allocator())
truncating_iterator_base(OutputIt out, size_t limit)
std::string grouping< wchar_t >(locale_ref loc)
FMT_CONSTEXPR void on_bin()
bool_constant< std::is_same< typename std::iterator_traits< InputIt >::value_type, char >::value &&std::is_same< OutChar, char8_type >::value > needs_conversion
FMT_CONSTEXPR void handle_char_specs(const basic_format_specs< Char > *specs, Handler &&handler)
void(*)(detail::buffer< char > &, int, string_view) format_func
truncating_iterator(OutputIt out, size_t limit)
FMT_CONSTEXPR bool is_negative(T value)
T * make_checked(T *p, size_t)
FMT_CONSTEXPR arg_ref & operator=(int idx)
FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler &&eh)
significand_type significand
void move(basic_memory_buffer &other)
FMT_CONSTEXPR void operator()()
FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler &other)
truncating_iterator & operator++()
uint64_t low() const FMT_NOEXCEPT
FMT_CONSTEXPR void on_int()
format_arg_store< Context, Args... > make_format_args(const Args &... args)
std::back_insert_iterator< Container > base_iterator(std::back_insert_iterator< Container > &it, checked_ptr< typename Container::value_type >)
#define FMT_ENABLE_IF(...)
truncating_iterator(OutputIt out, size_t limit)
FMT_SUPPRESS_MSC_WARNING(4566) const expr unsigned char micro[]
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it)
FMT_CONSTEXPR void on_error(const char *message)
typename detail::char_t_impl< S >::type char_t
constexpr iterator begin() const
FMT_INLINE void assume(bool condition)
FMT_CONSTEXPR void on_hash()
counting_iterator operator++(int)
static const char hex_digits[]
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_t >::value > is_signed
const wchar_t * c_str() const
typename std::conditional< B, T, F >::type conditional_t
FMT_CONSTEXPR void on_string()
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
FMT_CONSTEXPR void on_fill(basic_string_view< Char > fill)
FMT_CONSTEXPR void on_align(align_t align)
int format_float(T value, int precision, float_specs specs, buffer< char > &buf)
truncating_iterator operator++(int)
FMT_FUNC std::string grouping_impl(locale_ref loc)
typename std::remove_reference< T >::type remove_reference_t
FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs< char_type > &specs, ParseContext &ctx)
static const char right_padding_shifts[5]
std::output_iterator_tag iterator_category
Char * get_data(std::basic_string< Char > &s)
format_decimal_result< Char * > format_decimal(Char *out, UInt value, int size)
template int format_float< long double >(long double value, int precision, float_specs specs, buffer< char > &buf)
void reset_color(FILE *stream) FMT_NOEXCEPT
size_t size() const FMT_NOEXCEPT
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR value(int id=0)
truncating_iterator_base< OutputIt >::value_type blackhole_
truncating_iterator & operator++()
basic_string_view< Char > name
FMT_CONSTEXPR void check_sign()
bool_constant< is_integral< T >::value &&!std::is_same< T, bool >::value &&!std::is_same< T, char >::value &&!std::is_same< T, wchar_t >::value > is_integer
FMT_CONSTEXPR_DECL FMT_INLINE void parse_format_string(basic_string_view< Char > format_str, Handler &&handler)
FMT_CONSTEXPR int get_dynamic_spec(FormatArg arg, ErrorHandler eh)
FMT_CONSTEXPR void on_error(const char *message)
ParseContext & parse_context_
std::integral_constant< bool, B > bool_constant
string_view get_prefix() const
FMT_CONSTEXPR void operator()(int id)
fallback_uintptr(const void *p)
write_int_data(int num_digits, string_view prefix, const basic_format_specs< Char > &specs)
void try_resize(size_t count)
void operator=(const T &)
FMT_CONSTEXPR void on_type(Char type)
FMT_CONSTEXPR void on_chr()
truncating_iterator & operator++(int)
FMT_CONSTEXPR specs_setter(basic_format_specs< Char > &specs)
FMT_CONSTEXPR void on_zero()
void handle_dynamic_spec(int &value, arg_ref< typename Context::char_type > ref, Context &ctx)
FMT_CONSTEXPR void on_hash()
decltype(std::end(std::declval< T & >())) sentinel_t
void try_reserve(size_t new_capacity)
typename Context::char_type char_type
constexpr bool is_arithmetic_type(type t)
FMT_CONSTEXPR const Char * parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler)
static const uint32_t zero_or_powers_of_10_32_new[]
const wchar_t & const_reference
FMT_CONSTEXPR bool is_name_start(Char c)
FMT_CONSTEXPR int next_arg_id()
remove_cvref_t< decltype(*std::declval< Range >().begin())> value_type
FMT_CONSTEXPR Char & operator[](size_t index)
FMT_CONSTEXPR void on_char()
FMT_CONSTEXPR void advance_to(iterator it)
ErrorHandler & error_handler_
FMT_FUNC Char thousands_sep_impl(locale_ref loc)
uint64_t high() const FMT_NOEXCEPT
OutputIt write_significand(OutputIt out, const char *significand, int &significand_size)
FMT_CONSTEXPR void on_error(const char *message)
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
const basic_format_specs< Char > & specs
void append(const ContiguousRange &range)
constexpr iterator end() const
typename truncating_iterator_base< OutputIt >::value_type value_type
remove_reference_t< decltype(reserve(std::declval< OutputIt & >(), 0))> iterator
const T & first(const T &value, const Tail &...)
checked_ptr< typename Container::value_type > reserve(std::back_insert_iterator< Container > it, size_t n)
FMT_CONSTEXPR_DECL FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id)
FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler &&handler)
std::output_iterator_tag iterator_category
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
FMT_CONSTEXPR format_arg get_arg(int arg_id)
fallback_uintptr to_uintptr(const void *p)
FMT_CONSTEXPR void on_error()
FMT_CONSTEXPR void on_space()
basic_string_view< char > string_view
constexpr int num_bits< fallback_uintptr >()
constexpr T * to_pointer(OutputIt, size_t)
FMT_NORETURN void on_error()
FMT_CONSTEXPR void on_dec()
constexpr T const_check(T value)
std::string grouping(locale_ref loc)
Container & get_container(std::back_insert_iterator< Container > it)
FMT_CONSTEXPR value(basic_string_view< Char > n)
FMT_CONSTEXPR Context::format_arg get_arg(Context &ctx, ID id)
bool equal2(const Char *lhs, const char *rhs)
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
FMT_CONSTEXPR void on_plus()
void on_error(const char *message)
constexpr int num_bits< uint128_t >()
static const char signs[]
const Char * data() const
FMT_CONSTEXPR void operator=(basic_string_view< Char > s)
FMT_CONSTEXPR void on_align(align_t align)
constexpr dragonbox::float_info< T >::carrier_uint exponent_mask()
FMT_CONSTEXPR arg_ref(int index)
numeric_specs_checker< Handler > checker_
constexpr iterator begin() const FMT_NOEXCEPT
friend counting_iterator operator+(counting_iterator it, difference_type n)
OutputIt write_int(OutputIt out, int num_digits, string_view prefix, const basic_format_specs< Char > &specs, F f)
Char decimal_point(locale_ref loc)
basic_string_view< Char > sep
FMT_CONSTEXPR void check_precision()
basic_format_specs< Char > & specs_
FMT_CONSTEXPR Handler & error_handler()
FMT_CONSTEXPR void on_minus()
template int snprintf_float< long double >(long double value, int precision, float_specs specs, buffer< char > &buf)
FMT_INLINE void check_format_string(const S &)
OutputIt write_char(OutputIt out, Char value, const basic_format_specs< Char > &specs)
FMT_FUNC void format_error_code(detail::buffer< char > &out, int error_code, string_view message) FMT_NOEXCEPT
void append(const U *begin, const U *end)
decltype(std::begin(std::declval< T & >())) iterator_t
FMT_CONSTEXPR void operator()(int id)
int_writer(OutputIt output, locale_ref loc, Int value, const basic_format_specs< Char > &s)
OutputIt write_float(OutputIt out, const DecimalFP &fp, const basic_format_specs< Char > &specs, float_specs fspecs, Char decimal_point)
FMT_CONSTEXPR specs_checker(const Handler &handler, detail::type arg_type)
template FMT_API wchar_t thousands_sep_impl< wchar_t >(locale_ref loc)
system_error(int error_code, string_view message, const Args &... args)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
union detail::arg_ref::value val
OutputIt write_ptr(OutputIt out, UIntPtr value, const basic_format_specs< Char > *specs)
FMT_CONSTEXPR void on_pointer()