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)];
298 struct fallback_uintptr {
299 unsigned char value[
sizeof(
void*)];
301 fallback_uintptr() =
default;
302 explicit fallback_uintptr(
const void* p) {
303 *
this =
bit_cast<fallback_uintptr>(p);
305 for (
size_t i = 0, j =
sizeof(
void*) - 1;
i < j; ++
i, --j)
322 template <
typename T> constexpr T
max_value() {
323 return (std::numeric_limits<T>::max)();
325 template <
typename T> constexpr
int num_bits() {
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; }
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>
403 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
405 std::back_insert_iterator<Container>& it,
410 template <
typename Iterator>
423 using difference_type = std::ptrdiff_t;
424 using pointer =
void;
429 template <
typename T>
void operator=(
const T&) {}
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;
466 using difference_type =
void;
467 using pointer =
void;
469 using _Unchecked_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;
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>
550 return n < size ? n : size;
556 size_t num_code_points = 0;
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,
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) {
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,
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_);
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_);
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);
721 Allocator get_allocator()
const {
return alloc_; }
727 void resize(
size_t count) { this->try_resize(count); }
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>
770 class FMT_API format_error :
public std::runtime_error {
772 explicit format_error(
const char* message) : std::runtime_error(message) {}
773 explicit format_error(
const std::string& message)
774 : std::runtime_error(message) {}
775 format_error(
const format_error&) =
default;
776 format_error& operator=(
const format_error&) =
default;
777 format_error(format_error&&) =
default;
778 format_error& operator=(format_error&&) =
default;
784 template <
typename T>
786 std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
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[];
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[];
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);
992 return std::numeric_limits<Int>::digits10;
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>
1114 inline It
format_uint(It out, UInt value,
int num_digits,
bool upper =
false) {
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);
1129 size_t size()
const {
return buffer_.size() - 1; }
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) {
1147 FMT_THROW(format_error(
"invalid fill"));
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(
' ');
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();
1417 handler.on_error(
"invalid format specifier for char");
1421 template <
typename Char,
typename Handler>
1423 if (spec == 0 || spec ==
's')
1425 else if (spec ==
'p')
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;
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);
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';
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); });
1714 FMT_THROW(format_error(
"invalid type specifier"));
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)) {
1910 if (!std::isfinite(value))
1929 if (precision == max_value<int>())
1930 FMT_THROW(format_error(
"number is too big"));
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,
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) {
2070 FMT_THROW(format_error(
"string pointer is null"));
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,
"");
2163 auto&& it =
reserve(value.size());
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);
2229 FMT_THROW(format_error(
"string pointer is null"));
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 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>
2350 !std::is_same<T, char>::value &&
2351 !std::is_same<T, wchar_t>::value>;
2357 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2359 if (
is_negative(value)) handler_.on_error(
"negative width");
2360 return static_cast<unsigned long long>(value);
2363 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2365 handler_.on_error(
"width is not integer");
2377 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2379 if (
is_negative(value)) handler_.on_error(
"negative precision");
2380 return static_cast<unsigned long long>(value);
2383 template <typename T, FMT_ENABLE_IF(!is_integer<T>::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')));
2715 handler.on_dynamic_precision(
id);
2725 template <
typename Char>
2727 if (
const_check(
sizeof(Char) != 1) || (*begin & 0x80) == 0)
return begin + 1;
2730 }
while (begin != end && (*begin & 0xc0) == 0x80);
2735 template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
2740 template <typename Char, FMT_ENABLE_IF(std::is_enum<Char>::value)>
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;
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;
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 ==
'}') {
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");
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(
"") {
3326 enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
3327 mutable char buffer_[buffer_size];
3330 template <
typename UInt>
char* format_unsigned(UInt value) {
3335 template <
typename Int>
char* format_signed(Int value) {
3337 bool negative = value < 0;
3338 if (negative) abs_value = 0 - abs_value;
3339 auto begin = format_unsigned(abs_value);
3340 if (negative) *--begin =
'-';
3345 explicit format_int(
int value) : str_(format_signed(value)) {}
3346 explicit format_int(
long value) : str_(format_signed(value)) {}
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)) {}
3350 explicit format_int(
unsigned long long value)
3351 : str_(format_unsigned(value)) {}
3354 size_t size()
const {
3362 const char*
data()
const {
return str_; }
3368 const char* c_str()
const {
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>
3392 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
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()) {
3541 checker.on_align(specs_.
align);
3542 switch (specs_.
sign) {
3555 if (specs_.
alt) checker.on_hash();
3556 if (specs_.
precision >= 0) checker.end_precision();
3560 detail::make_arg<FormatContext>(val));
3565 template <
typename Context>
void handle_specs(Context& ctx) {
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);
3573 const Char* format_str_;
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>
3633 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3642 template <
typename FormatContext>
3643 auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
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);
3736 template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
3739 detail::write<char>(std::back_inserter(result), value);
3743 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
3747 constexpr
int max_size = detail::digits10<T>() + 2;
3748 char buffer[max_size > 5 ?
static_cast<unsigned>(max_size) : 5];
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>
3775 #ifndef FMT_HEADER_ONLY 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...);
3837 template <typename Char, enable_if_t<(!std::is_same<Char, char>::value),
int>>
3846 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
3851 buffer.push_back(L
'\0');
3852 if (std::fputws(buffer.data(), f) == -1)
3856 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
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 {
3888 return {str, std::forward<T>(value)};
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 3948 # include "format-inl.h" 3953 #endif // FMT_FORMAT_H_
OutputIt write_ptr(OutputIt out, UIntPtr value, const basic_format_specs< Char > *specs)
constexpr auto num_bits< int128_t >() -> int
constexpr auto max_value() -> T
FMT_CONSTEXPR width_adapter(SpecHandler &h)
FMT_CONSTEXPR void on_error()
FMT_CONSTEXPR const Char * next_code_point(const Char *begin, const Char *end)
static const char hex_digits[]
FMT_CONSTEXPR specs_setter(const specs_setter &other)
#define FMT_ENABLE_IF(...)
auto make_checked(T *p, size_t) -> T *
FMT_CONSTEXPR void operator()()
bool equal2(const Char *lhs, const char *rhs)
constexpr bool is_arithmetic_type(type t)
bool_constant< std::numeric_limits< T >::is_iec559 &&sizeof(T)<=sizeof(double)> is_fast_float
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
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])
void append(const U *begin, const U *end)
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_CONSTEXPR void operator()(int id)
numeric_specs_checker< Handler > checker_
dynamic_format_specs< char_type > & specs_
std::string grouping(locale_ref loc)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler &&handler)
FMT_FUNC void format_error_code(detail::buffer< char > &out, int error_code, string_view message) FMT_NOEXCEPT
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)
constexpr auto begin() const FMT_NOEXCEPT -> iterator
ErrorHandler & error_handler_
span_CONFIG_SIZE_TYPE size_t
FMT_INLINE uint16_t bsr2log10(int bsr)
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
FMT_CONSTEXPR void on_bin()
const wchar_t * c_str() const
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()
void init(const M_string &remappings)
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)
constexpr auto num_bits() -> int
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)
auto make_args_checked(const S &format_str, const remove_reference_t< Args > &... args) -> format_arg_store< buffer_context< Char >, remove_reference_t< Args >... >
int_writer(OutputIt output, locale_ref loc, Int value, const basic_format_specs< Char > &s)
FMT_CONSTEXPR void require_numeric_argument()
counting_iterator copy_str(InputIt begin, InputIt end, counting_iterator it)
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)
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)
constexpr dragonbox::float_info< T >::carrier_uint exponent_mask()
ParseContext & parse_context_
FMT_CONSTEXPR void operator()(int id)
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)
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)
FMT_CONSTEXPR void on_dec()
template int format_float< double >(double value, int precision, float_specs specs, buffer< char > &buf)
constexpr auto size() const -> size_t
auto code_point_index(basic_string_view< Char > s, size_t n) -> size_t
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
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)
FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result< Char >
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()
auto get_data(std::basic_string< Char > &s) -> Char *
Char decimal_point(locale_ref loc)
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
FMT_CONSTEXPR void on_hex()
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
auto base_iterator(std::back_insert_iterator< Container > &it, checked_ptr< typename Container::value_type >) -> std::back_insert_iterator< Container >
FMT_CONSTEXPR int get_dynamic_spec(FormatArg arg, ErrorHandler eh)
constexpr auto data() const -> const char *
constexpr Char to_integral(Char value)
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
static const digit_pair digits[]
void on_error(const char *message)
FMT_CONSTEXPR arg_ref & operator=(int idx)
integral_constant< bool, false > false_type
void push_back(const T &value)
constexpr bool is_integral_type(type t)
#define FMT_EXTERN_TEMPLATE_API
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
FMT_CONSTEXPR auto next_arg_id() -> int
FMT_NORETURN FMT_API void on_error(const char *message)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR arg_ref_type make_arg_ref(int arg_id)
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)
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T > >> buffer_appender
string_view get_prefix() const
basic_string_view< wchar_t > wstring_view
std::wstring_view wstring_view
FMT_CONSTEXPR void on_hash()
OutputIt write_float(OutputIt out, const DecimalFP &fp, const basic_format_specs< Char > &specs, float_specs fspecs, Char decimal_point)
static const uint32_t zero_or_powers_of_10_32[]
const Char * data() const
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char >>> args)
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)
format_arg_store< Context, Args... > make_format_args(const Args &... args)
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh)
typename std::remove_reference< T >::type remove_reference_t
constexpr auto begin() const -> iterator
integral_constant< bool, true > true_type
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
FMT_CONSTEXPR void on_int()
FMT_CONSTEXPR specs_handler(basic_format_specs< char_type > &specs, ParseContext &parse_ctx, Context &ctx)
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
bool find< false, char >(const char *first, const char *last, char value, const char *&out)
void reset_color(FILE *stream) FMT_NOEXCEPT
typename float_info< T >::carrier_uint significand_type
auto to_uintptr(const void *p) -> fallback_uintptr
FMT_CONSTEXPR void end_precision()
significand_type significand
FMT_CONSTEXPR specs_setter(basic_format_specs< Char > &specs)
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&... args)
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
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)
FMT_CONSTEXPR const Char & operator[](size_t index) const
auto reserve(std::back_insert_iterator< Container > it, size_t n) -> checked_ptr< typename Container::value_type >
const T & move(const T &v)
FMT_CONSTEXPR int_type_checker(ErrorHandler eh)
ring_iterator< RS, C > operator+(ring_iterator< RS, C > it, int i) nsrs_noexcept
FMT_CONSTEXPR void on_minus()
constexpr auto num_bits< fallback_uintptr >() -> int
FMT_CONSTEXPR specs_checker(const Handler &handler, detail::type arg_type)
FMT_CONSTEXPR void end_precision()
FMT_INLINE void assume(bool condition)
const T & first(const T &value, const Tail &...)
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)
remove_cvref_t< decltype(*detail::range_begin(std::declval< Range >()))> value_type
void swap(llvm_vecsmall::SmallVectorImpl< T > &LHS, llvm_vecsmall::SmallVectorImpl< T > &RHS)
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
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)
auto bit_cast(const Source &source) -> Dest
FMT_NORETURN void on_error()
FMT_CONSTEXPR bool is_name_start(Char c)
typename type_identity< T >::type type_identity_t
constexpr auto num_bits< uint128_t >() -> int
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)
constexpr auto to_pointer(OutputIt, size_t) -> T *
FMT_CONSTEXPR void on_zero()
FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
OutputIt write_padded(OutputIt out, const basic_format_specs< Char > &specs, size_t size, size_t width, F &&f)
static const uint64_t zero_or_powers_of_10_64[]
constexpr auto end() const -> iterator
static FMT_CONSTEXPR fill_t< Char > make()
FMT_FUNC void report_error(format_func func, int error_code, const char *message) FMT_NOEXCEPT
typename std::enable_if< B, T >::type enable_if_t
FMT_CONSTEXPR void check_precision()
void resize(size_t count)
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
span_constexpr std::size_t size(span< T, Extent > const &spn)
#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)
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)
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
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)
FMT_CONSTEXPR auto out() -> iterator
OutputIt write_bytes(OutputIt out, string_view bytes, const basic_format_specs< Char > &specs)
FMT_CONSTEXPR void on_width(int width)
FMT_CONSTEXPR bool is_supported_floating_point(T)
static const char right_padding_shifts[5]
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_CONSTEXPR void on_num()
FMT_FUNC std::string grouping_impl(locale_ref loc)
FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id)
void grow(size_t size) final FMT_OVERRIDE
FMT_CONSTEXPR void handle_char_specs(const basic_format_specs< Char > *specs, Handler &&handler)
auto is_big_endian() -> bool
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR bool is_negative(T value)
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)
QCXXHighlighter::QCXXHighlighter(QTextDocument *document) m_highlightRul append))({ QRegularExpression(R"(#[a-zA-Z_]+)"), "Preprocessor" })
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
FMT_FUNC Char decimal_point_impl(locale_ref loc)
int count_digits(uint64_t n)
static const char left_padding_shifts[5]
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)
static const char signs[]