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)
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>
353 inline typename Container::value_type*
get_data(Container&
c) {
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; }
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;
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) {}
465 using value_type =
typename std::iterator_traits<OutputIt>::value_type;
472 OutputIt
base()
const {
return out_; }
473 size_t count()
const {
return count_; }
478 template <
typename OutputIt,
479 typename Enable =
typename std::is_void<
480 typename std::iterator_traits<OutputIt>::value_type>
::type>
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>
567 std::is_same<typename std::iterator_traits<InputIt>::value_type,
571 template <
typename OutChar,
typename InputIt,
typename OutputIt,
573 OutputIt
copy_str(InputIt begin, InputIt end, OutputIt it) {
574 return std::copy(begin, end, 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,
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>>
664 if (data != store_) alloc_.deallocate(data, this->capacity());
676 this->
set(store_, SIZE);
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>
774 :
std::runtime_error(message) {}
784 template <
typename T>
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[];
870 static const uint64_t zero_or_powers_of_10_64[];
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[];
889 static const char reset_color[5];
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];
899 static constexpr uint16_t
data[] = {
900 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
901 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
902 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
903 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
914 #ifdef FMT_BUILTIN_CLZLL 919 auto t =
bsr2log10(FMT_BUILTIN_CLZLL(n | 1) ^ 63);
930 if (n < 10)
return count;
931 if (n < 100)
return count + 1;
932 if (n < 1000)
return count + 2;
933 if (n < 10000)
return count + 3;
947 if (n < 10)
return count;
948 if (n < 100)
return count + 1;
949 if (n < 1000)
return count + 2;
950 if (n < 10000)
return count + 3;
958 template <
unsigned BITS,
typename UInt>
inline int count_digits(UInt n) {
962 }
while ((n >>= BITS) != 0);
968 #if FMT_GCC_VERSION || FMT_CLANG_VERSION 969 # define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) 971 # define FMT_ALWAYS_INLINE __forceinline 973 # define FMT_ALWAYS_INLINE inline 977 #if FMT_MSC_VER && !FMT_CLANG_VERSION 978 # define FMT_SAFEBUFFERS __declspec(safebuffers) 980 # define FMT_SAFEBUFFERS 983 #ifdef FMT_BUILTIN_CLZ 986 auto t =
bsr2log10(FMT_BUILTIN_CLZ(n | 1) ^ 31);
1015 return Char(decimal_point_impl<char>(loc));
1018 return decimal_point_impl<wchar_t>(loc);
1022 template <
typename Char>
bool equal2(
const Char* lhs,
const char* rhs) {
1023 return lhs[0] == rhs[0] && lhs[1] == rhs[1];
1025 inline bool equal2(
const char* lhs,
const char* rhs) {
1026 return memcmp(lhs, rhs, 2) == 0;
1030 template <
typename Char>
void copy2(Char* dst,
const char* src) {
1031 *dst++ =
static_cast<Char
>(*src++);
1032 *dst =
static_cast<Char
>(*src);
1044 template <
typename Char,
typename UInt>
1050 while (value >= 100) {
1059 *--out =
static_cast<Char
>(
'0' + value);
1067 template <
typename Char,
typename UInt,
typename Iterator,
1072 Char
buffer[digits10<UInt>() + 1];
1074 return {out, detail::copy_str<Char>(
buffer, end, out)};
1077 template <
unsigned BASE_BITS,
typename Char,
typename UInt>
1079 bool upper =
false) {
1080 buffer += num_digits;
1084 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1085 *--buffer =
static_cast<Char
>(BASE_BITS < 4 ? static_cast<char>(
'0' +
digit)
1087 }
while ((value >>= BASE_BITS) != 0);
1091 template <
unsigned BASE_BITS,
typename Char>
1094 auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
1095 int start = (num_digits + char_digits - 1) / char_digits - 1;
1096 if (
int start_digits = num_digits % char_digits) {
1097 unsigned value = n.
value[start--];
1098 buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
1100 for (; start >= 0; --start) {
1101 unsigned value = n.
value[start];
1102 buffer += char_digits;
1104 for (
int i = 0; i < char_digits; ++i) {
1105 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1107 value >>= BASE_BITS;
1113 template <
unsigned BASE_BITS,
typename Char,
typename It,
typename UInt>
1116 char buffer[num_bits<UInt>() / BASE_BITS + 1];
1117 format_uint<BASE_BITS>(
buffer, value, num_digits,
upper);
1118 return detail::copy_str<Char>(buffer, buffer + num_digits, out);
1130 const wchar_t*
c_str()
const {
return &buffer_[0]; }
1131 std::wstring
str()
const {
return {&buffer_[0], size()}; }
1134 template <
typename T =
void>
struct null {};
1139 enum { max_size = 4 };
1140 Char data_[max_size];
1145 auto size = s.
size();
1146 if (size > max_size) {
1150 for (
size_t i = 0; i < size; ++i) data_[i] = s[i];
1151 size_ =
static_cast<unsigned char>(size);
1154 size_t size()
const {
return size_; }
1155 const Char*
data()
const {
return data_; }
1159 return data_[
index];
1164 fill[0] = Char(
' ');
1200 fill(
detail::fill_t<Char>::make()) {}
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()) {
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<type>();
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>
2022 it = std::copy(value.
begin(), value.
end(), it);
2026 template <
typename Char>
2033 template <
typename Char,
typename OutputIt,
typename T,
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,
2154 out_ = detail::write<Char>(out_, value);
2159 it = copy_str<Char>(value.
begin(), value.
end(), it);
2164 it = std::copy(value.
begin(), value.
end(), it);
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) {}
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);
2273 FMT_ASSERT(
false,
"unsupported float argument type");
2278 if (!specs_)
return write(value), out_;
2286 write(value, *specs_);
2295 write_pointer(value);
2301 return (
'a' <= c && c <=
'z') || (
'A' <= c && c <=
'Z') ||
'_' == c;
2306 template <
typename Char,
typename ErrorHandler>
2308 ErrorHandler&& eh) {
2309 FMT_ASSERT(begin != end &&
'0' <= *begin && *begin <=
'9',
"");
2312 constexpr
unsigned max_int = max_value<int>();
2313 unsigned big = max_int / 10;
2317 value = max_int + 1;
2320 value = value * 10 + unsigned(*begin -
'0');
2322 }
while (begin != end &&
'0' <= *begin && *begin <=
'9');
2323 if (value > max_int) eh.on_error(
"number is too big");
2324 return static_cast<int>(value);
2337 : parse_ctx_(parse_ctx), ctx_(ctx) {}
2340 h.
format(parse_ctx_, ctx_);
2347 template <
typename T>
2359 if (
is_negative(value)) handler_.on_error(
"negative width");
2360 return static_cast<unsigned long long>(value);
2365 handler_.on_error(
"width is not integer");
2379 if (
is_negative(value)) handler_.on_error(
"negative precision");
2380 return static_cast<unsigned long long>(value);
2385 handler_.on_error(
"precision is not integer");
2400 : specs_(other.specs_) {}
2413 specs_.
fill[0] = Char(
'0');
2423 specs_.
type =
static_cast<char>(
type);
2433 : error_handler_(eh), arg_type_(arg_type) {}
2437 error_handler_.on_error(
"format specifier requires numeric argument");
2441 require_numeric_argument();
2444 error_handler_.on_error(
"format specifier requires signed argument");
2450 error_handler_.on_error(
"precision not allowed for this argument type");
2472 : Handler(other), checker_(
error_handler(), other.arg_type_) {}
2476 Handler::on_align(align);
2486 Handler::on_minus();
2491 Handler::on_space();
2507 template <
template <
typename>
class Handler,
typename FormatArg,
2508 typename ErrorHandler>
2510 unsigned long long value =
visit_format_arg(Handler<ErrorHandler>(eh), arg);
2511 if (value >
to_unsigned(max_value<int>())) eh.on_error(
"number is too big");
2512 return static_cast<int>(value);
2517 template <
typename Context,
typename ID>
2519 auto arg = ctx.arg(
id);
2520 if (!
arg) ctx.on_error(
"argument not found");
2525 template <
typename ParseContext,
typename Context>
2531 ParseContext& parse_ctx, Context& ctx)
2533 parse_context_(parse_ctx),
2537 this->specs_.
width = get_dynamic_spec<width_checker>(
2538 get_arg(arg_id), context_.error_handler());
2542 this->specs_.
precision = get_dynamic_spec<precision_checker>(
2543 get_arg(arg_id), context_.error_handler());
2546 void on_error(
const char* message) { context_.on_error(message); }
2557 parse_context_.check_arg_id(arg_id);
2562 parse_context_.check_arg_id(arg_id);
2600 template <
typename Char>
2608 template <
typename ParseContext>
2610 :
public specs_setter<typename ParseContext::char_type> {
2620 specs_(other.specs_),
2621 context_(other.context_) {}
2624 specs_.width_ref = make_arg_ref(arg_id);
2628 specs_.precision_ref = make_arg_ref(arg_id);
2632 context_.on_error(message);
2639 context_.check_arg_id(arg_id);
2648 context_.check_arg_id(arg_id);
2650 context_.begin(),
to_unsigned(context_.end() - context_.begin()));
2658 template <
typename Char,
typename IDHandler>
2660 IDHandler&& handler) {
2663 if (c ==
'}' || c ==
':') {
2667 if (c >=
'0' && c <=
'9') {
2673 if (begin == end || (*begin !=
'}' && *begin !=
':'))
2674 handler.on_error(
"invalid format string");
2680 handler.on_error(
"invalid format string");
2686 }
while (it != end && (
is_name_start(c = *it) || (
'0' <= c && c <=
'9')));
2698 handler.on_dynamic_width(
id);
2702 handler.on_error(message);
2715 handler.on_dynamic_precision(
id);
2719 handler.on_error(message);
2725 template <
typename Char>
2727 if (
const_check(
sizeof(Char) != 1) || (*begin & 0x80) == 0)
return begin + 1;
2730 }
while (begin != end && (*begin & 0xc0) == 0x80);
2746 template <
typename Char,
typename Handler>
2748 Handler&& handler) {
2752 if (p == end) p = begin;
2761 #if FMT_DEPRECATED_NUMERIC_ALIGN 2774 return handler.on_error(
"invalid fill character '{'"), begin;
2779 handler.on_align(
align);
2781 }
else if (p == begin) {
2789 template <
typename Char,
typename Handler>
2791 Handler&& handler) {
2793 if (
'0' <= *begin && *begin <=
'9') {
2795 }
else if (*begin ==
'{') {
2799 if (begin == end || *begin !=
'}')
2800 return handler.on_error(
"invalid format string"), begin;
2806 template <
typename Char,
typename Handler>
2808 Handler&& handler) {
2810 auto c = begin != end ? *begin : Char();
2811 if (
'0' <=
c &&
c <=
'9') {
2813 }
else if (
c ==
'{') {
2819 if (begin == end || *begin++ !=
'}')
2820 return handler.on_error(
"invalid format string"), begin;
2822 return handler.on_error(
"missing precision specifier"), begin;
2824 handler.end_precision();
2830 template <
typename Char,
typename SpecHandler>
2832 SpecHandler&& handler) {
2833 if (begin == end || *begin ==
'}')
return begin;
2836 if (begin == end)
return begin;
2853 if (begin == end)
return begin;
2855 if (*begin ==
'#') {
2857 if (++begin == end)
return begin;
2861 if (*begin ==
'0') {
2863 if (++begin == end)
return begin;
2867 if (begin == end)
return begin;
2870 if (*begin ==
'.') {
2875 if (begin != end && *begin !=
'}') handler.on_type(*begin++);
2880 template <
bool IS_CONSTEXPR,
typename T,
typename Ptr = const T*>
2882 for (out = first; out != last; ++out) {
2883 if (*out == value)
return true;
2891 out =
static_cast<const char*
>(
2893 return out !=
nullptr;
2903 arg_id = handler.on_arg_id(
id);
2906 handler.on_error(message);
2910 template <
typename Char,
typename Handler>
2913 Handler&& handler) {
2915 if (begin == end)
return handler.on_error(
"invalid format string"), end;
2916 if (*begin ==
'}') {
2917 handler.on_replacement_field(handler.on_arg_id(), begin);
2918 }
else if (*begin ==
'{') {
2919 handler.on_text(begin, begin + 1);
2923 Char
c = begin != end ? *begin : Char();
2925 handler.on_replacement_field(adapter.arg_id, begin);
2926 }
else if (c ==
':') {
2927 begin = handler.on_format_specs(adapter.arg_id, begin + 1, end);
2928 if (begin == end || *begin !=
'}')
2929 return handler.on_error(
"unknown format specifier"), end;
2931 return handler.on_error(
"missing '}' in format string"), end;
2937 template <
bool IS_CONSTEXPR,
typename Char,
typename Handler>
2940 auto begin = format_str.
data();
2941 auto end = begin + format_str.
size();
2942 if (end - begin < 32) {
2944 const Char* p = begin;
2948 handler.on_text(begin, p - 1);
2950 }
else if (
c ==
'}') {
2951 if (p == end || *p !=
'}')
2952 return handler.on_error(
"unmatched '}' in format string");
2953 handler.on_text(begin, p);
2957 handler.on_text(begin, end);
2961 FMT_CONSTEXPR void operator()(
const Char* pbegin,
const Char* pend) {
2962 if (pbegin == pend)
return;
2964 const Char* p =
nullptr;
2965 if (!find<IS_CONSTEXPR>(pbegin, pend,
'}', p))
2966 return handler_.on_text(pbegin, pend);
2968 if (p == pend || *p !=
'}')
2969 return handler_.on_error(
"unmatched '}' in format string");
2970 handler_.on_text(pbegin, p);
2976 while (begin != end) {
2979 const Char* p = begin;
2980 if (*begin !=
'{' && !find<IS_CONSTEXPR>(begin + 1, end,
'{', p))
2981 return write(begin, end);
2987 template <
typename T,
typename ParseContext>
2989 ParseContext& ctx) {
2999 return f.parse(ctx);
3002 template <
typename ArgFormatter,
typename Char,
typename Context>
3010 : parse_context(str), context(out, format_args, loc) {}
3012 void on_text(
const Char* begin,
const Char* end) {
3014 auto out = context.out();
3015 auto&& it =
reserve(out, size);
3016 it = std::copy_n(begin, size, it);
3017 context.advance_to(out);
3023 int arg_id = context.arg_id(
id);
3024 if (arg_id < 0) on_error(
"argument not found");
3032 context.
out(), context.args(), context.locale()},
3047 if (begin == end || *begin !=
'}') on_error(
"missing '}' in format string");
3059 template <
typename Char,
typename ErrorHandler = error_handler>
3069 ErrorHandler eh = {})
3070 :
base(format_str, eh), num_args_(num_args) {}
3073 int id = base::next_arg_id();
3074 if (
id >= num_args_) this->on_error(
"argument not found");
3079 base::check_arg_id(
id);
3080 if (
id >= num_args_) this->on_error(
"argument not found");
3082 using base::check_arg_id;
3085 template <
typename Char,
typename ErrorHandler,
typename... Args>
3090 : context_(format_str, num_args, eh),
3091 parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
3098 on_error(
"compile-time checks don't support named arguments");
3107 return id < num_args ? parse_funcs_[id](context_) : begin;
3111 context_.on_error(message);
3116 enum { num_args =
sizeof...(Args) };
3126 template <
typename Char,
size_t N>
3128 const Char (&s)[N]) {
3132 N - ((std::char_traits<Char>::to_int_type(s[N - 1]) == 0) ? 1 : 0)};
3136 template <
typename Char>
3139 return {s.data(), s.size()};
3142 #define FMT_STRING_IMPL(s, base) \ 3145 struct FMT_COMPILE_STRING : base { \ 3146 using char_type = fmt::remove_cvref_t<decltype(s[0])>; \ 3147 FMT_MAYBE_UNUSED FMT_CONSTEXPR \ 3148 operator fmt::basic_string_view<char_type>() const { \ 3149 return fmt::detail::compile_string_to_view<char_type>(s); \ 3152 return FMT_COMPILE_STRING(); \ 3165 #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string) 3167 template <
typename... Args,
typename S,
3174 (parse_format_string<true>(s, checker(s, {})),
true);
3175 (
void)invalid_format;
3178 template <
template <
typename>
class Handler,
typename Context>
3185 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
index),
3186 ctx.error_handler());
3189 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
name),
3190 ctx.error_handler());
3204 template <
typename OutputIt,
typename Char>
3230 :
base(ctx.out(), specs, ctx.locale()),
3232 parse_ctx_(parse_ctx),
3235 using base::operator();
3240 handle.
format(*parse_ctx_, ctx_);
3246 template <
typename OutputIt,
typename Char>
3283 template <
typename... Args>
3285 :
std::runtime_error(
"") {
3327 mutable char buffer_[buffer_size];
3337 bool negative = value < 0;
3338 if (negative) abs_value = 0 - abs_value;
3339 auto begin = format_unsigned(abs_value);
3340 if (negative) *--begin =
'-';
3347 explicit format_int(
long long value) : str_(format_signed(value)) {}
3348 explicit format_int(
unsigned value) : str_(format_unsigned(value)) {}
3349 explicit format_int(
unsigned long value) : str_(format_unsigned(value)) {}
3351 : str_(format_unsigned(value)) {}
3362 const char*
data()
const {
return str_; }
3369 buffer_[buffer_size - 1] =
'\0';
3378 std::string
str()
const {
return std::string(str_, size()); }
3383 template <
typename T,
typename Char>
3391 template <
typename ParseContext>
3398 auto eh = ctx.error_handler();
3427 FMT_ASSERT(
false,
"double support disabled");
3433 FMT_ASSERT(
false,
"long double support disabled");
3453 template <
typename FormatContext>
3454 auto format(
const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3455 detail::handle_dynamic_spec<detail::width_checker>(specs_.
width,
3456 specs_.width_ref, ctx);
3457 detail::handle_dynamic_spec<detail::precision_checker>(
3458 specs_.
precision, specs_.precision_ref, ctx);
3462 detail::make_arg<FormatContext>(val));
3469 #define FMT_FORMAT_AS(Type, Base) \ 3470 template <typename Char> \ 3471 struct formatter<Type, Char> : formatter<Base, Char> { \ 3472 template <typename FormatContext> \ 3473 auto format(Type const& val, FormatContext& ctx) -> decltype(ctx.out()) { \ 3474 return formatter<Base, Char>::format(val, ctx); \ 3489 template <
typename Char>
3491 template <
typename FormatContext>
3492 auto format(
void* val, FormatContext& ctx) -> decltype(ctx.out()) {
3497 template <
typename Char,
size_t N>
3499 template <
typename FormatContext>
3500 auto format(
const Char* val, FormatContext& ctx) -> decltype(ctx.out()) {
3528 template <
typename ParseContext>
3529 auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3530 format_str_ = ctx.begin();
3536 template <
typename T,
typename FormatContext>
3537 auto format(
const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3542 switch (specs_.
sign) {
3560 detail::make_arg<FormatContext>(val));
3566 detail::handle_dynamic_spec<detail::width_checker>(specs_.
width,
3567 specs_.width_ref, ctx);
3568 detail::handle_dynamic_spec<detail::precision_checker>(
3569 specs_.
precision, specs_.precision_ref, ctx);
3576 template <
typename Char,
typename ErrorHandler>
3583 template <
typename ArgFormatter,
typename Char,
typename Context>
3591 using iterator =
typename ArgFormatter::iterator;
3597 detail::parse_format_string<false>(format_str, h);
3598 return h.context.out();
3610 template <
typename T>
inline const void*
ptr(
const T* p) {
return p; }
3611 template <
typename T>
inline const void*
ptr(
const std::unique_ptr<T>& p) {
3614 template <
typename T>
inline const void*
ptr(
const std::shared_ptr<T>& p) {
3632 template <
typename ParseContext>
3642 template <
typename FormatContext>
3644 detail::handle_dynamic_spec<detail::width_checker>(specs_.
width,
3646 detail::handle_dynamic_spec<detail::precision_checker>(
3652 template <
typename It,
typename Sentinel,
typename Char>
3659 : begin(b), end(e), sep(s) {}
3662 template <
typename It,
typename Sentinel,
typename Char>
3664 :
formatter<typename std::iterator_traits<It>::value_type, Char> {
3665 template <
typename FormatContext>
3667 -> decltype(ctx.out()) {
3669 auto it = value.begin;
3670 auto out = ctx.out();
3671 if (it != value.end) {
3673 while (it != value.end) {
3674 out = std::copy(value.sep.begin(), value.sep.end(), out);
3675 ctx.advance_to(out);
3687 template <
typename It,
typename Sentinel>
3689 return {begin, end, sep};
3692 template <
typename It,
typename Sentinel>
3694 return {begin, end, sep};
3713 template <
typename Range>
3716 return join(std::begin(range), std::end(range), sep);
3719 template <
typename Range>
3722 return join(std::begin(range), std::end(range), sep);
3739 detail::write<char>(std::back_inserter(result), value);
3747 constexpr
int max_size = detail::digits10<T>() + 2;
3748 char buffer[max_size > 5 ?
static_cast<unsigned>(max_size) : 5];
3749 char* begin = buffer;
3750 return std::string(begin, detail::write<char>(begin, value));
3756 template <
typename T>
inline std::wstring
to_wstring(
const T& value) {
3757 return format(L
"{}", value);
3760 template <
typename Char,
size_t SIZE>
3762 auto size = buf.
size();
3764 return std::basic_string<Char>(buf.
data(), size);
3767 template <
typename Char>
3772 return vformat_to<af>(buffer_appender<Char>(buf), format_str, args);
3775 #ifndef FMT_HEADER_ONLY 3786 float_specs specs, buffer<char>& buf);
3790 int snprintf_float(
float value,
int precision, float_specs specs,
3791 buffer<char>& buf) =
delete;
3802 template <
typename S,
typename Char =
char_t<S>,
3803 FMT_ENABLE_IF(detail::is_
string<S>::value)>
3805 detail::buffer<Char>& buf, const S& format_str,
3818 template <
typename OutputIt,
typename Char =
char>
3821 template <
typename OutputIt,
typename Char =
char>
3824 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3827 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3828 using format_to_n_args FMT_DEPRECATED_ALIAS =
3831 template <
typename OutputIt,
typename Char,
typename... Args>
3834 return format_arg_store<buffer_context<Char>, Args...>(args...);
3852 if (std::fputws(buffer.
data(), f) == -1)
3858 vprint(stdout, format_str, args);
3861 #if FMT_USE_USER_DEFINED_LITERALS 3864 # if FMT_USE_UDL_TEMPLATE 3865 template <
typename Char, Char... CHARS>
class udl_formatter {
3867 template <
typename... Args>
3868 std::basic_string<Char> operator()(Args&&... args)
const {
3874 template <
typename Char>
struct udl_formatter {
3877 template <
typename... Args>
3878 std::basic_string<Char> operator()(Args&&... args)
const {
3879 return format(str, std::forward<Args>(args)...);
3882 # endif // FMT_USE_UDL_TEMPLATE 3884 template <
typename Char>
struct udl_arg {
3887 template <
typename T> named_arg<Char, T> operator=(T&& value)
const {
3888 return {str, std::forward<T>(value)};
3893 inline namespace literals {
3894 # if FMT_USE_UDL_TEMPLATE 3895 # pragma GCC diagnostic push 3896 # pragma GCC diagnostic ignored "-Wpedantic" 3897 # if FMT_CLANG_VERSION 3898 # pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template" 3900 template <
typename Char, Char... CHARS>
3901 FMT_CONSTEXPR detail::udl_formatter<Char, CHARS...>
operator""_format() {
3904 # pragma GCC diagnostic pop 3916 FMT_CONSTEXPR detail::udl_formatter<char>
operator"" _format(
const char* s,
3920 FMT_CONSTEXPR detail::udl_formatter<wchar_t>
operator"" _format(
3921 const wchar_t* s,
size_t n) {
3924 # endif // FMT_USE_UDL_TEMPLATE 3936 FMT_CONSTEXPR detail::udl_arg<char>
operator"" _a(
const char* s,
size_t) {
3939 FMT_CONSTEXPR detail::udl_arg<wchar_t>
operator"" _a(
const wchar_t* s,
size_t) {
3943 #endif // FMT_USE_USER_DEFINED_LITERALS 3946 #ifdef FMT_HEADER_ONLY 3947 # define FMT_FUNC inline 3953 #endif // FMT_FORMAT_H_
OutputIt write_ptr(OutputIt out, UIntPtr value, const basic_format_specs< Char > *specs)
FMT_FUNC Char decimal_point_impl(locale_ref loc)
FMT_CONSTEXPR width_adapter(SpecHandler &h)
FMT_CONSTEXPR void on_error()
FMT_CONSTEXPR const Char * next_code_point(const Char *begin, const Char *end)
FMT_CONSTEXPR specs_setter(const specs_setter &other)
#define FMT_ENABLE_IF(...)
FMT_CONSTEXPR void operator()()
bool equal2(const Char *lhs, const char *rhs)
constexpr bool is_arithmetic_type(type t)
enum MQTTPropertyCodes value
constexpr const Char * data() const
bool_constant< std::numeric_limits< T >::is_iec559 &&sizeof(T)<=sizeof(double)> is_fast_float
arg_join(It b, Sentinel e, basic_string_view< Char > s)
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 basic_string_view< Char > compile_string_to_view(const Char(&s)[N])
typename detail::char_t_impl< S >::type char_t
FMT_CONSTEXPR arg_ref(int index)
FMT_CONSTEXPR const Char * parse_width(const Char *begin, const Char *end, Handler &&handler)
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
FMT_CONSTEXPR void operator()(int id)
uint128_wrapper & operator+=(uint64_t n) FMT_NOEXCEPT
numeric_specs_checker< Handler > checker_
truncating_iterator & operator++()
dynamic_format_specs< char_type > & specs_
std::string grouping(locale_ref loc)
void reserve(size_t new_capacity)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler &&handler)
auto make_args_checked(const S &format_str, const remove_reference_t< Args > &...args) -> format_arg_store< buffer_context< Char >, remove_reference_t< Args >... >
const wchar_t * c_str() const
Char thousands_sep(locale_ref loc)
FMT_CONSTEXPR void advance_to(iterator it)
void try_reserve(size_t new_capacity)
typename std::conditional< B, T, F >::type conditional_t
FMT_CONSTEXPR_DECL FMT_INLINE void parse_format_string(basic_string_view< Char > format_str, Handler &&handler)
ErrorHandler & error_handler_
static const char hex_digits[]
FMT_INLINE uint16_t bsr2log10(int bsr)
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
FMT_CONSTEXPR void on_bin()
FMT_FUNC void report_error(format_func func, int error_code, string_view message) FMT_NOEXCEPT
unsigned char value[sizeof(void *)]
FMT_CONSTEXPR void on_fill(basic_string_view< Char > fill)
FMT_CONSTEXPR void on_pointer()
FMT_CONSTEXPR cstring_type_checker(ErrorHandler eh)
FMT_CONSTEXPR void on_char()
FMT_CONSTEXPR void on_space()
FMT_CONSTEXPR void on_minus()
FMT_CONSTEXPR void operator()()
void try_resize(size_t count)
FMT_CONSTEXPR void operator()()
constexpr T const_check(T value)
decltype(std::begin(std::declval< T & >())) iterator_t
FMT_CONSTEXPR const Char * parse_align(const Char *begin, const Char *end, Handler &&handler)
template int snprintf_float< double >(double value, int precision, float_specs specs, buffer< char > &buf)
int_writer(OutputIt output, locale_ref loc, Int value, const basic_format_specs< Char > &s)
static int writer(lua_State *L, const void *b, size_t size, void *ud)
uint64_t low() const FMT_NOEXCEPT
static const uint32_t zero_or_powers_of_10_32[]
FMT_CONSTEXPR void require_numeric_argument()
size_t size() const FMT_NOEXCEPT
fallback_uintptr uintptr_t
constexpr int digits10< int128_t >() FMT_NOEXCEPT
FMT_CONSTEXPR void on_error(const char *message)
Allocator get_allocator() const
typename truncating_iterator_base< OutputIt >::value_type value_type
void append(const ContiguousRange &range)
decltype(std::end(std::declval< T & >())) sentinel_t
FMT_CONSTEXPR float_specs parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={})
#define FMT_CONSTEXPR_DECL
basic_string_view< Char > sep
FMT_CONSTEXPR void on_align(align_t align)
FMT_CONSTEXPR int parse_nonnegative_int(const Char *&begin, const Char *end, ErrorHandler &&eh)
basic_format_specs< Char > & specs_
FMT_CONSTEXPR void on_type(Char type)
FMT_SAFEBUFFERS decimal_fp< T > to_decimal(T x) FMT_NOEXCEPT
constexpr dragonbox::float_info< T >::carrier_uint exponent_mask()
OutputIt write(OutputIt out, basic_string_view< StrChar > s, const basic_format_specs< Char > &specs)
ParseContext & parse_context_
FMT_CONSTEXPR void operator()(int id)
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_t >::value > is_signed
FMT_CONSTEXPR format_arg get_arg(auto_id)
OutputIt write_nonfinite(OutputIt out, bool isinf, const basic_format_specs< Char > &specs, const float_specs &fspecs)
system_error(int error_code, string_view message, const Args &...args)
typename std::remove_cv< remove_reference_t< T >>::type remove_cvref_t
FMT_CONSTEXPR compile_parse_context(basic_string_view< Char > format_str, int num_args=max_value< int >(), ErrorHandler eh={})
FMT_CONSTEXPR const Char * parse_precision(const Char *begin, const Char *end, Handler &&handler)
int get_significand_size(const big_decimal_fp &fp)
truncating_iterator & operator++()
FMT_CONSTEXPR void on_dec()
constexpr T * to_pointer(OutputIt, size_t)
template int format_float< double >(double value, int precision, float_specs specs, buffer< char > &buf)
truncating_iterator(OutputIt out, size_t limit)
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
fallback_uintptr(const void *p)
template int snprintf_float< long double >(long double value, int precision, float_specs specs, buffer< char > &buf)
FMT_CONSTEXPR void on_error(const char *message)
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
FMT_CONSTEXPR void operator=(basic_string_view< Char > s)
#define FMT_END_NAMESPACE
FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler &other)
FMT_FUNC int count_digits< 4 >(detail::fallback_uintptr n)
std::back_insert_iterator< Container > base_iterator(std::back_insert_iterator< Container > &it, checked_ptr< typename Container::value_type >)
FMT_CONSTEXPR void on_string()
It write_exponent(int exp, It it)
typename Context::char_type char_type
basic_string_view< char > string_view
template FMT_API char thousands_sep_impl< char >(locale_ref loc)
void(*)(detail::buffer< char > &, int, string_view) format_func
FMT_CONSTEXPR void check_arg_id(int id)
decimal_fp< T > to_decimal(T x) FMT_NOEXCEPT
typename Context::format_arg format_arg
FMT_CONSTEXPR void on_zero()
Char decimal_point(locale_ref loc)
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
truncating_iterator operator++(int)
FMT_CONSTEXPR void on_hex()
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
FMT_CONSTEXPR const Char & operator[](size_t index) const
counting_iterator & operator++()
FMT_CONSTEXPR int get_dynamic_spec(FormatArg arg, ErrorHandler eh)
constexpr Char to_integral(Char value)
counting_iterator operator++(int)
buffer_appender< Char > vformat_to(buffer< Char > &buf, basic_string_view< Char > format_str, basic_format_args< FMT_BUFFER_CONTEXT(type_identity_t< Char >)> args)
FMT_CONSTEXPR_DECL FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
FMT_CONSTEXPR arg_ref(basic_string_view< Char > name)
constexpr int digits10() FMT_NOEXCEPT
void on_error(const char *message)
FMT_CONSTEXPR arg_ref & operator=(int idx)
void push_back(const T &value)
constexpr bool is_integral_type(type t)
#define FMT_EXTERN_TEMPLATE_API
static const char left_padding_shifts[5]
static const digit_pair digits[]
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space, std::size_t &required_space)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR arg_ref_type make_arg_ref(int arg_id)
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it)
const basic_format_specs< Char > & specs
template FMT_API std::string grouping_impl< char >(locale_ref loc)
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
void copy2(Char *dst, const char *src)
void handle_dynamic_spec(int &value, arg_ref< typename Context::char_type > ref, Context &ctx)
constexpr iterator begin() const FMT_NOEXCEPT
basic_string_view< wchar_t > wstring_view
FMT_CONSTEXPR void on_hash()
constexpr int num_bits< uint128_t >()
OutputIt write_float(OutputIt out, const DecimalFP &fp, const basic_format_specs< Char > &specs, float_specs fspecs, Char decimal_point)
value_type operator*() const
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char >>> args)
void operator=(const T &)
remove_reference_t< decltype(reserve(std::declval< OutputIt & >(), 0))> iterator
template int format_float< long double >(long double value, int precision, float_specs specs, buffer< char > &buf)
FMT_CONSTEXPR specs_checker(const specs_checker &other)
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh)
uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
typename std::remove_reference< T >::type remove_reference_t
truncating_iterator_base< OutputIt >::value_type blackhole_
static const uint64_t zero_or_powers_of_10_64[]
typename ParseContext::char_type char_type
basic_string_view< Char > name
FMT_CONSTEXPR const Char * parse_replacement_field(const Char *begin, const Char *end, Handler &&handler)
typename std::iterator_traits< OutputIt >::value_type value_type
static const char right_padding_shifts[5]
FMT_CONSTEXPR int next_arg_id()
std::ptrdiff_t difference_type
FMT_CONSTEXPR void on_int()
Char * get_data(std::basic_string< Char > &s)
FMT_CONSTEXPR specs_handler(basic_format_specs< char_type > &specs, ParseContext &parse_ctx, Context &ctx)
std::output_iterator_tag iterator_category
checked_ptr< typename Container::value_type > reserve(std::back_insert_iterator< Container > it, size_t n)
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
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
bool find< false, char >(const char *first, const char *last, char value, const char *&out)
typename float_info< T >::carrier_uint significand_type
FMT_CONSTEXPR void end_precision()
format_arg_store< Context, Args... > make_format_args(const Args &...args)
significand_type significand
FMT_CONSTEXPR specs_setter(basic_format_specs< Char > &specs)
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
void move(basic_memory_buffer &other)
constexpr size_t size() const
int format_float(T value, int precision, float_specs specs, buffer< char > &buf)
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
const T & move(const T &v)
friend counting_iterator operator+(counting_iterator it, difference_type n)
FMT_CONSTEXPR int_type_checker(ErrorHandler eh)
FMT_CONSTEXPR void on_minus()
value_type & operator*() const
FMT_CONSTEXPR specs_checker(const Handler &handler, detail::type arg_type)
truncating_iterator_base(OutputIt out, size_t limit)
FMT_CONSTEXPR void end_precision()
FMT_INLINE void assume(bool condition)
FMT_CONSTEXPR Context::format_arg get_arg(Context &ctx, ID id)
Container & get_container(std::back_insert_iterator< Container > it)
FMT_CONSTEXPR void on_oct()
template FMT_API wchar_t thousands_sep_impl< wchar_t >(locale_ref loc)
FMT_CONSTEXPR const Char * parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler)
Char * format_uint(Char *buffer, UInt value, int num_digits, bool upper=false)
template FMT_API std::string grouping_impl< wchar_t >(locale_ref loc)
FMT_CONSTEXPR void on_align(align_t align)
FMT_CONSTEXPR Handler & error_handler()
constexpr int digits10< uint128_t >() FMT_NOEXCEPT
FMT_NORETURN FMT_API void on_error(const char *message)
truncating_iterator & operator=(T val)
Dest bit_cast(const Source &source)
size_t count_code_points(basic_string_view< Char > s)
FMT_CONSTEXPR void on_error(const char *message)
FMT_INLINE void check_format_string(const S &)
int snprintf_float(T value, int precision, float_specs specs, buffer< char > &buf)
FMT_NORETURN void on_error()
void append(const U *begin, const U *end)
std::output_iterator_tag iterator_category
FMT_CONSTEXPR bool is_name_start(Char c)
constexpr iterator end() const
typename type_identity< T >::type type_identity_t
FMT_FUNC Char thousands_sep_impl(locale_ref loc)
FMT_CONSTEXPR precision_adapter(SpecHandler &h)
FMT_SUPPRESS_MSC_WARNING(4566) const expr unsigned char micro[]
FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view< char_type > arg_id)
FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler &&handler)
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 on_plus()
FMT_CONSTEXPR value(basic_string_view< Char > n)
FMT_CONSTEXPR void on_zero()
FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
constexpr iterator begin() const
OutputIt write_padded(OutputIt out, const basic_format_specs< Char > &specs, size_t size, size_t width, F &&f)
basic_memory_buffer(basic_memory_buffer &&other) FMT_NOEXCEPT
static FMT_CONSTEXPR fill_t< Char > make()
T * make_checked(T *p, size_t)
string_view get_prefix() const
typename std::enable_if< B, T >::type enable_if_t
FMT_CONSTEXPR void check_precision()
uint64_t high() const FMT_NOEXCEPT
void resize(size_t count)
truncating_iterator & operator++(int)
#define FMT_CLANG_VERSION
void clear(lua_State *L, int table_index)
FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs< char_type > &specs, ParseContext &ctx)
static const char signs[]
basic_memory_buffer(const Allocator &alloc=Allocator())
union detail::arg_ref::value val
OutputIt write_int(OutputIt out, int num_digits, string_view prefix, const basic_format_specs< Char > &specs, F f)
fallback_uintptr to_uintptr(const void *p)
format_decimal_result< Char * > format_decimal(Char *out, UInt value, int size)
#define FMT_ASSERT(condition, message)
FMT_CONSTEXPR format_arg get_arg(int arg_id)
FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler &&eh)
#define FMT_BEGIN_NAMESPACE
const wchar_t & const_reference
write_int_data(int num_digits, string_view prefix, const basic_format_specs< Char > &specs)
FMT_CONSTEXPR const Char * parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler)
FMT_CONSTEXPR void operator()(int id)
OutputIt write_significand(OutputIt out, const char *significand, int &significand_size)
OutputIt write_bytes(OutputIt out, string_view bytes, const basic_format_specs< Char > &specs)
FMT_CONSTEXPR void on_width(int width)
size_t code_point_index(basic_string_view< Char > s, size_t n)
FMT_CONSTEXPR bool is_supported_floating_point(T)
truncating_iterator(OutputIt out, size_t limit)
FMT_CONSTEXPR void on_precision(int precision)
FMT_CONSTEXPR void on_space()
FMT_CONSTEXPR void on_hash()
FMT_CONSTEXPR void check_arg_id(int)
FMT_FUNC void format_error_code(detail::buffer< char > &out, int error_code, string_view message) FMT_NOEXCEPT
FMT_CONSTEXPR void on_num()
FMT_FUNC std::string grouping_impl(locale_ref loc)
FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id)
truncating_iterator & operator*()
constexpr int num_bits< int128_t >()
void grow(size_t size) final FMT_OVERRIDE
FMT_CONSTEXPR void handle_char_specs(const basic_format_specs< Char > *specs, Handler &&handler)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR bool is_negative(T value)
const Char * data() const
OutputIt write_char(OutputIt out, Char value, const basic_format_specs< Char > &specs)
std::integral_constant< bool, B > bool_constant
FMT_CONSTEXPR void on_chr()
FMT_CONSTEXPR value(int id=0)
FMT_CONSTEXPR void on_error(const char *message)
constexpr int num_bits< fallback_uintptr >()
FMT_CONSTEXPR format_arg get_arg(basic_string_view< char_type > arg_id)
FMT_CONSTEXPR Char & operator[](size_t index)
void set(T *buf_data, size_t buf_capacity) FMT_NOEXCEPT
int count_digits(uint64_t n)
basic_memory_buffer & operator=(basic_memory_buffer &&other) FMT_NOEXCEPT
std::string grouping< wchar_t >(locale_ref loc)
FMT_CONSTEXPR void check_sign()
FMT_CONSTEXPR int next_arg_id()
size_t capacity() const FMT_NOEXCEPT
FMT_CONSTEXPR void on_plus()
FMT_CONSTEXPR numeric_specs_checker(ErrorHandler &eh, detail::type arg_type)
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)