47 # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) 49 # define FMT_CLANG_VERSION 0 52 #ifdef __INTEL_COMPILER 53 # define FMT_ICC_VERSION __INTEL_COMPILER 55 # define FMT_ICC_VERSION __ICL 57 # define FMT_ICC_VERSION 0 61 # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__) 63 # define FMT_CUDA_VERSION 0 67 # define FMT_HAS_BUILTIN(x) __has_builtin(x) 69 # define FMT_HAS_BUILTIN(x) 0 72 #if FMT_HAS_CPP_ATTRIBUTE(fallthrough) && \ 73 (__cplusplus >= 201703 || FMT_GCC_VERSION != 0) 74 # define FMT_FALLTHROUGH [[fallthrough]] 76 # define FMT_FALLTHROUGH 84 template <
typename Exception>
inline void do_throw(
const Exception& x) {
87 volatile bool b =
true;
92 # define FMT_THROW(x) internal::do_throw(x) 94 # define FMT_THROW(x) throw x 97 # define FMT_THROW(x) \ 99 static_cast<void>(sizeof(x)); \ 100 FMT_ASSERT(false, ""); \ 105 #ifndef FMT_USE_USER_DEFINED_LITERALS 107 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ 108 FMT_MSC_VER >= 1900) && \ 109 (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || FMT_ICC_VERSION >= 1500 || \ 110 FMT_CUDA_VERSION >= 700) 111 # define FMT_USE_USER_DEFINED_LITERALS 1 113 # define FMT_USE_USER_DEFINED_LITERALS 0 117 #ifndef FMT_USE_UDL_TEMPLATE 120 # if FMT_USE_USER_DEFINED_LITERALS && FMT_ICC_VERSION == 0 && \ 121 FMT_CUDA_VERSION == 0 && \ 122 ((FMT_GCC_VERSION >= 600 && FMT_GCC_VERSION <= 900 && \ 123 __cplusplus >= 201402L) || \ 124 FMT_CLANG_VERSION >= 304) 125 # define FMT_USE_UDL_TEMPLATE 1 127 # define FMT_USE_UDL_TEMPLATE 0 133 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER 134 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) 136 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER 137 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) 143 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED) 150 # pragma intrinsic(_BitScanReverse) 152 inline uint32_t clz(uint32_t x) {
154 _BitScanReverse(&r, x);
160 # pragma warning(suppress : 6102) 163 # define FMT_BUILTIN_CLZ(n) internal::clz(n) 165 # if defined(_WIN64) && !defined(__clang__) 166 # pragma intrinsic(_BitScanReverse64) 169 inline uint32_t clzll(uint64_t x) {
172 _BitScanReverse64(&r, x);
175 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
return 63 - (r + 32);
178 _BitScanReverse(&r, static_cast<uint32_t>(x));
185 # pragma warning(suppress : 6102) 188 # define FMT_BUILTIN_CLZLL(n) internal::clzll(n) 194 #ifndef FMT_NUMERIC_ALIGN 195 # define FMT_NUMERIC_ALIGN 1 199 #ifndef FMT_DEPRECATED_PERCENT 200 # define FMT_DEPRECATED_PERCENT 0 213 template <
typename Dest,
typename Source>
215 static_assert(
sizeof(Dest) ==
sizeof(Source),
"size mismatch");
217 std::memcpy(&dest, &source,
sizeof(dest));
224 char data[
sizeof(u)];
226 return bit_cast<bytes>(u).data[0] == 0;
237 for (
size_t i = 0, j =
sizeof(
void*) - 1; i < j; ++i, --j)
255 return (std::numeric_limits<T>::max)();
258 return std::numeric_limits<T>::digits;
261 return static_cast<int>(
sizeof(
void*) *
262 std::numeric_limits<unsigned char>::digits);
266 template <
typename T>
272 template <
typename It,
typename Enable =
void>
276 using type = std::random_access_iterator_tag;
279 template <
typename It>
281 using type =
typename It::iterator_category;
291 template <
typename U>
292 static decltype(*(std::declval<U>())) test(std::input_iterator_tag);
293 template <typename U> static
char& test(std::output_iterator_tag);
294 template <typename U> static const
char& test(...);
299 static const bool value = !std::is_const<remove_reference_t<type>>
::value;
303 template <
typename Char>
inline Char*
get_data(std::basic_string<Char>& s) {
306 template <
typename Container>
307 inline typename Container::value_type*
get_data(Container& c) {
313 template <
typename T>
using checked_ptr = stdext::checked_array_iterator<T*>;
319 template <
typename T>
inline T*
make_checked(T* p, std::size_t) {
return p; }
322 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
324 std::back_insert_iterator<Container>& it, std::size_t n) {
326 std::size_t size = c.size();
331 template <
typename Iterator>
332 inline Iterator&
reserve(Iterator& it, std::size_t) {
355 std::size_t
count()
const {
return count_; }
378 : out_(out), limit_(limit), count_(0) {}
388 OutputIt
base()
const {
return out_; }
389 std::size_t
count()
const {
return count_; }
394 template <
typename OutputIt,
395 typename Enable =
typename std::is_void<
396 typename std::iterator_traits<OutputIt>::value_type>
::type>
399 template <
typename OutputIt>
402 using traits = std::iterator_traits<OutputIt>;
413 if (this->count_++ < this->limit_) ++this->out_;
424 return this->count_ < this->limit_ ? *this->out_ : blackhole_;
428 template <
typename OutputIt>
432 using value_type =
typename OutputIt::container_type::value_type;
438 if (this->count_++ < this->limit_) this->out_ = val;
448 template <
typename OutputIt,
typename T =
typename OutputIt::value_type>
459 OutputIt
begin()
const {
return it_; }
460 sentinel
end()
const {
return {}; }
463 template <
typename Char>
471 size_t num_code_points = 0;
472 for (
size_t i = 0, size = s.
size(); i != size; ++i) {
473 if ((data[i] & 0xc0) != 0x80) ++num_code_points;
475 return num_code_points;
478 template <
typename Char>
480 size_t size = s.
size();
481 return n < size ? n : size;
487 size_t num_code_points = 0;
488 for (
size_t i = 0, size = s.
size(); i != size; ++i) {
489 if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) {
498 template <
typename InputIt,
typename OutChar>
500 std::is_same<typename std::iterator_traits<InputIt>::value_type,
502 std::is_same<OutChar, char8_t>::value>;
504 template <
typename OutChar,
typename InputIt,
typename OutputIt,
506 OutputIt
copy_str(InputIt begin, InputIt end, OutputIt it) {
510 template <
typename OutChar,
typename InputIt,
typename OutputIt,
512 OutputIt
copy_str(InputIt begin, InputIt end, OutputIt it) {
513 return std::transform(begin, end, it,
to_char8_t);
516 #ifndef FMT_USE_GRISU 517 # define FMT_USE_GRISU 1 521 return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559 &&
522 sizeof(T) <=
sizeof(
double);
525 template <
typename T>
526 template <
typename U>
528 std::size_t new_size = size_ +
to_unsigned(end - begin);
530 std::uninitialized_copy(begin, end,
make_checked(ptr_, capacity_) + size_);
536 template <
typename T>
538 std::back_insert_iterator<internal::buffer<T>>, T> {
540 using iterator = std::back_insert_iterator<internal::buffer<T>>;
556 #if FMT_USE_USER_DEFINED_LITERALS 557 inline namespace literals {
558 inline u8string_view operator"" _u(
const char* s, std::size_t n) {
598 typename Allocator = std::allocator<T>>
605 T* data = this->data();
606 if (data != store_) Allocator::deallocate(data, this->capacity());
618 this->
set(store_, SIZE);
625 Allocator &this_alloc = *
this, &other_alloc = other;
626 this_alloc = std::move(other_alloc);
627 T* data = other.
data();
628 std::size_t size = other.
size(), capacity = other.
capacity();
629 if (data == other.
store_) {
630 this->
set(store_, capacity);
631 std::uninitialized_copy(other.
store_, other.
store_ + size,
634 this->
set(data, capacity);
667 template <
typename T, std::
size_t SIZE,
typename Allocator>
669 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 670 if (size > 1000)
throw std::runtime_error(
"fuzz mode - won't grow that much");
672 std::size_t old_capacity = this->capacity();
673 std::size_t new_capacity = old_capacity + old_capacity / 2;
674 if (size > new_capacity) new_capacity = size;
675 T* old_data = this->data();
676 T* new_data = std::allocator_traits<Allocator>::allocate(*
this, new_capacity);
678 std::uninitialized_copy(old_data, old_data + this->size(),
680 this->
set(new_data, new_capacity);
684 if (old_data != store_) Allocator::deallocate(old_data, old_capacity);
693 explicit format_error(
const char* message) : std::runtime_error(message) {}
695 : std::runtime_error(message) {}
707 template <typename T, FMT_ENABLE_IF(std::numeric_limits<T>::is_signed)>
711 template <typename T, FMT_ENABLE_IF(!std::numeric_limits<T>::is_signed)>
718 template <
typename T>
720 std::numeric_limits<T>::digits <= 32, uint32_t,
725 static const uint64_t powers_of_10_64[];
726 static const uint32_t zero_or_powers_of_10_32[];
727 static const uint64_t zero_or_powers_of_10_64[];
728 static const uint64_t pow10_significands[];
729 static const int16_t pow10_exponents[];
730 static const char digits[];
731 static const char hex_digits[];
732 static const char foreground_color[];
733 static const char background_color[];
735 static const wchar_t wreset_color[5];
736 static const char signs[];
744 #ifdef FMT_BUILTIN_CLZLL 750 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
761 if (n < 10)
return count;
762 if (n < 100)
return count + 1;
763 if (n < 1000)
return count + 2;
764 if (n < 10000)
return count + 3;
778 if (n < 10)
return count;
779 if (n < 100)
return count + 1;
780 if (n < 1000)
return count + 2;
781 if (n < 10000)
return count + 3;
789 template <
unsigned BITS,
typename UInt>
inline int count_digits(UInt n) {
793 }
while ((n >>= BITS) != 0);
799 #if FMT_GCC_VERSION || FMT_CLANG_VERSION 800 # define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) 802 # define FMT_ALWAYS_INLINE 805 #ifdef FMT_BUILTIN_CLZ 808 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
815 return grouping_impl<char>(loc);
818 return grouping_impl<wchar_t>(loc);
823 return Char(thousands_sep_impl<char>(loc));
826 return thousands_sep_impl<wchar_t>(loc);
831 return Char(decimal_point_impl<char>(loc));
834 return decimal_point_impl<wchar_t>(loc);
840 template <
typename UInt,
typename Char,
typename F>
842 F add_thousands_sep) {
843 FMT_ASSERT(num_digits >= 0,
"invalid digit count");
844 buffer += num_digits;
846 while (value >= 100) {
850 auto index =
static_cast<unsigned>((value % 100) * 2);
853 add_thousands_sep(buffer);
855 add_thousands_sep(buffer);
858 *--buffer =
static_cast<Char
>(
'0' + value);
861 auto index =
static_cast<unsigned>(value * 2);
863 add_thousands_sep(buffer);
868 template <
typename Int> constexpr
int digits10() noexcept {
874 template <
typename Char,
typename UInt,
typename Iterator,
typename F>
876 F add_thousands_sep) {
877 FMT_ASSERT(num_digits >= 0,
"invalid digit count");
879 enum { max_size = digits10<UInt>() + 1 };
880 Char
buffer[2 * max_size];
881 auto end =
format_decimal(buffer, value, num_digits, add_thousands_sep);
882 return internal::copy_str<Char>(buffer, end, out);
885 template <
typename Char,
typename It,
typename UInt>
887 return format_decimal<Char>(out, value, num_digits, [](Char*) {});
890 template <
unsigned BASE_BITS,
typename Char,
typename UInt>
892 bool upper =
false) {
893 buffer += num_digits;
897 unsigned digit = (value & ((1 << BASE_BITS) - 1));
898 *--buffer =
static_cast<Char
>(BASE_BITS < 4 ? static_cast<char>(
'0' + digit)
900 }
while ((value >>= BASE_BITS) != 0);
904 template <
unsigned BASE_BITS,
typename Char>
907 auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
908 int start = (num_digits + char_digits - 1) / char_digits - 1;
909 if (
int start_digits = num_digits % char_digits) {
910 unsigned value = n.
value[start--];
911 buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
913 for (; start >= 0; --start) {
914 unsigned value = n.
value[start];
915 buffer += char_digits;
917 for (
int i = 0; i < char_digits; ++i) {
918 unsigned digit = (value & ((1 << BASE_BITS) - 1));
926 template <
unsigned BASE_BITS,
typename Char,
typename It,
typename UInt>
927 inline It
format_uint(It out, UInt value,
int num_digits,
bool upper =
false) {
929 char buffer[num_bits<UInt>() / BASE_BITS + 1];
930 format_uint<BASE_BITS>(
buffer, value, num_digits, upper);
931 return internal::copy_str<Char>(buffer, buffer + num_digits, out);
935 # define FMT_USE_WINDOWS_H 0 936 #elif !defined(FMT_USE_WINDOWS_H) 937 # define FMT_USE_WINDOWS_H 1 942 #if FMT_USE_WINDOWS_H 945 class utf8_to_utf16 {
952 size_t size()
const {
return buffer_.
size() - 1; }
953 const wchar_t* c_str()
const {
return &buffer_[0]; }
954 std::wstring str()
const {
return std::wstring(&buffer_[0], size()); }
959 class utf16_to_utf8 {
967 size_t size()
const {
return buffer_.
size() - 1; }
968 const char* c_str()
const {
return &buffer_[0]; }
969 std::string str()
const {
return std::string(&buffer_[0], size()); }
981 template <
typename T =
void>
struct null {};
1031 fill(
internal::fill_t<Char>::make()) {}
1060 FMT_ASSERT(-10000 < exp && exp < 10000,
"exponent out of range");
1062 *it++ =
static_cast<Char
>(
'-');
1065 *it++ =
static_cast<Char
>(
'+');
1069 if (exp >= 1000) *it++ =
static_cast<Char
>(top[0]);
1070 *it++ =
static_cast<Char
>(top[1]);
1074 *it++ =
static_cast<Char
>(d[0]);
1075 *it++ =
static_cast<Char
>(d[1]);
1091 int full_exp = num_digits_ + exp_;
1094 *it++ =
static_cast<Char
>(*digits_);
1095 int num_zeros = specs_.
precision - num_digits_;
1097 if (num_digits_ > 1 || trailing_zeros) *it++ = decimal_point_;
1098 it = copy_str<Char>(digits_ + 1, digits_ + num_digits_, it);
1100 it = std::fill_n(it, num_zeros, static_cast<Char>(
'0'));
1101 *it++ =
static_cast<Char
>(specs_.
upper ?
'E' :
'e');
1102 return write_exponent<Char>(full_exp - 1, it);
1104 if (num_digits_ <= full_exp) {
1106 it = copy_str<Char>(digits_, digits_ + num_digits_, it);
1107 it = std::fill_n(it, full_exp - num_digits_, static_cast<Char>(
'0'));
1109 *it++ = decimal_point_;
1110 int num_zeros = specs_.
precision - full_exp;
1111 if (num_zeros <= 0) {
1113 *it++ =
static_cast<Char
>(
'0');
1116 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 1117 if (num_zeros > 1000)
1118 throw std::runtime_error(
"fuzz mode - avoiding excessive cpu use");
1120 it = std::fill_n(it, num_zeros, static_cast<Char>(
'0'));
1122 }
else if (full_exp > 0) {
1124 it = copy_str<Char>(digits_, digits_ + full_exp, it);
1127 int num_digits = num_digits_;
1128 while (num_digits > full_exp && digits_[num_digits - 1] ==
'0')
1130 if (num_digits != full_exp) *it++ = decimal_point_;
1131 return copy_str<Char>(digits_ + full_exp, digits_ + num_digits, it);
1133 *it++ = decimal_point_;
1134 it = copy_str<Char>(digits_ + full_exp, digits_ + num_digits_, it);
1137 int num_zeros = specs_.
precision - num_digits_;
1138 it = std::fill_n(it, num_zeros, static_cast<Char>(
'0'));
1142 *it++ =
static_cast<Char
>(
'0');
1143 int num_zeros = -full_exp;
1146 int num_digits = num_digits_;
1148 while (num_digits > 0 && digits_[num_digits - 1] ==
'0') --num_digits;
1149 if (num_zeros != 0 || num_digits != 0) {
1150 *it++ = decimal_point_;
1151 it = std::fill_n(it, num_zeros, static_cast<Char>(
'0'));
1152 it = copy_str<Char>(digits_, digits_ + num_digits, it);
1162 num_digits_(num_digits),
1165 decimal_point_(decimal_point) {
1166 int full_exp = num_digits + exp - 1;
1169 !(full_exp >= -4 && full_exp < precision)) {
1173 size_ += specs.
sign ? 1 : 0;
1176 size_t size()
const {
return size_; }
1185 template <
typename T>
1189 template <
typename T>
1196 template <
typename Handler>
1222 template <
typename ErrorHandler = error_handler,
typename Char>
1227 switch (specs.
type) {
1252 #if FMT_DEPRECATED_PERCENT 1268 eh.on_error(
"invalid type specifier");
1274 template <
typename Char,
typename Handler>
1276 Handler&& handler) {
1277 if (!specs)
return handler.on_char();
1278 if (specs->
type && specs->
type !=
'c')
return handler.on_int();
1280 handler.on_error(
"invalid format specifier for char");
1284 template <
typename Char,
typename Handler>
1286 if (spec == 0 || spec ==
's')
1287 handler.on_string();
1288 else if (spec ==
'p')
1289 handler.on_pointer();
1291 handler.on_error(
"invalid type specifier");
1294 template <
typename Char,
typename ErrorHandler>
1296 if (spec != 0 && spec !=
's') eh.on_error(
"invalid type specifier");
1299 template <
typename Char,
typename ErrorHandler>
1301 if (spec != 0 && spec !=
'p') eh.on_error(
"invalid type specifier");
1315 ErrorHandler::on_error(
"invalid type specifier");
1319 template <
typename ErrorHandler>
1326 : ErrorHandler(eh), type_(type) {}
1334 template <
typename ErrorHandler>
1338 : ErrorHandler(eh) {}
1344 template <
typename Context>
1349 for (
int i = 0;; ++i) {
1355 for (
int i = 0, n = args.
max_size(); i < n; ++i) {
1364 static constexpr
size_t str_size = 3;
1366 size_t size()
const {
return str_size + (sign ? 1 : 0); }
1370 if (sign) *it++ =
static_cast<Char
>(
data::signs[sign]);
1371 it = copy_str<Char>(str, str + str_size, it);
1400 size_t size()
const {
return size_; }
1404 if (prefix.
size() != 0)
1405 it = copy_str<char_type>(prefix.
begin(), prefix.
end(), it);
1406 it = std::fill_n(it, padding, fill);
1414 template <
typename F>
1418 std::size_t padding = 0;
1421 if (unsiged_width > size) {
1422 padding = unsiged_width - size;
1423 size = unsiged_width;
1425 }
else if (specs.
precision > num_digits) {
1439 if (negative) abs_value = ~abs_value + 1;
1441 auto&& it =
reserve((negative ? 1 : 0) + static_cast<size_t>(num_digits));
1442 if (negative) *it++ =
static_cast<char_type>(
'-');
1443 it = format_decimal<char_type>(it, abs_value, num_digits);
1466 abs_value = 0 - abs_value;
1468 prefix[0] = specs.sign ==
sign::plus ?
'+' :
' ';
1478 it = internal::format_decimal<char_type>(it, abs_value, num_digits);
1484 writer.
write_int(num_digits, get_prefix(), specs,
1493 it = format_uint<4, char_type>(it,
self.abs_value, num_digits,
1494 self.specs.type !=
'x');
1500 prefix[prefix_size++] =
'0';
1501 prefix[prefix_size++] = specs.type;
1504 writer.
write_int(num_digits, get_prefix(), specs,
1513 it = format_uint<BITS, char_type>(it, abs_value, num_digits);
1519 prefix[prefix_size++] =
'0';
1520 prefix[prefix_size++] =
static_cast<char>(specs.type);
1522 int num_digits = count_digits<1>(abs_value);
1523 writer.
write_int(num_digits, get_prefix(), specs,
1528 int num_digits = count_digits<3>(abs_value);
1529 if (specs.alt && specs.precision <= num_digits && abs_value != 0) {
1532 prefix[prefix_size++] =
'0';
1534 writer.
write_int(num_digits, get_prefix(), specs,
1538 enum { sep_size = 1 };
1550 int digit_index = 0;
1551 std::string::const_iterator group = groups.cbegin();
1552 it = format_decimal<char_type>(
1553 it, abs_value, size,
1555 if (*group <= 0 || ++digit_index % *group != 0 ||
1556 *group == max_value<char>())
1558 if (group + 1 != groups.cend()) {
1563 std::uninitialized_copy(s.data(), s.data() + s.size(),
1570 std::string groups = grouping<char_type>(writer.
locale_);
1571 if (groups.empty())
return on_dec();
1572 auto sep = thousands_sep<char_type>(writer.
locale_);
1573 if (!sep)
return on_dec();
1575 int size = num_digits;
1576 std::string::const_iterator group = groups.cbegin();
1577 while (group != groups.cend() && num_digits > *group && *group > 0 &&
1578 *group != max_value<char>()) {
1580 num_digits -= *group;
1583 if (group == groups.cend())
1584 size += sep_size * ((num_digits - 1) / groups.back());
1585 writer.
write_int(size, get_prefix(), specs,
1598 size_t size()
const {
return size_; }
1604 it = copy_str<char_type>(s, s + size_, it);
1618 it = format_uint<4, char_type>(it, value, num_digits);
1624 : out_(out.begin()), locale_(loc) {}
1634 size_t size = f.size();
1635 size_t num_code_points = width != 0 ? f.width() : size;
1636 if (width <= num_code_points)
return f(
reserve(size));
1637 auto&& it =
reserve(width + (size - num_code_points));
1639 std::size_t padding = width - num_code_points;
1641 it = std::fill_n(it, padding, fill);
1644 std::size_t left_padding = padding / 2;
1645 it = std::fill_n(it, left_padding, fill);
1647 it = std::fill_n(it, padding - left_padding, fill);
1650 it = std::fill_n(it, padding, fill);
1654 void write(
int value) { write_decimal(value); }
1655 void write(
long value) { write_decimal(value); }
1656 void write(
long long value) { write_decimal(value); }
1658 void write(
unsigned value) { write_decimal(value); }
1659 void write(
unsigned long value) { write_decimal(value); }
1660 void write(
unsigned long long value) { write_decimal(value); }
1667 template <
typename T,
typename Spec>
1672 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
1676 if (std::signbit(value)) {
1684 auto str = std::isinf(value) ? (fspecs.
upper ?
"INF" :
"inf")
1685 : (fspecs.
upper ?
"NAN" :
"nan");
1720 : static_cast<char_type>(
'.');
1722 static_cast<int>(buffer.
size()),
1723 exp, fspecs, point));
1731 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char_type>::value)>
1739 it = copy_str<char_type>(value.
begin(), value.
end(), it);
1742 static_assert(std::is_same<char_type, wchar_t>::value,
"");
1747 template <
typename Char>
1752 template <
typename Char>
1755 std::size_t size = s.
size();
1758 write(data, size, specs);
1761 template <
typename UIntPtr>
1768 write_padded(specs_copy, pw);
1778 template <
typename Range,
typename ErrorHandler =
internal::error_handler>
1796 template <
typename It>
void operator()(It&& it)
const { *it++ = value; }
1803 writer_.
write(value);
1818 specs_ ? writer_.
write(sv, *specs_) : writer_.
write(sv);
1825 auto length = std::char_traits<char_type>::length(value);
1827 specs_ ? writer_.
write(sv, *specs_) : writer_.
write(sv);
1833 : writer_(r, loc), specs_(s) {}
1840 template <typename T, FMT_ENABLE_IF(is_integral<T>::value)>
1845 writer_.
write(value);
1851 specs_, char_spec_handler(*
this, static_cast<char_type>(value)));
1856 if (specs_ && specs_->
type)
return (*
this)(value ? 1 : 0);
1861 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
1872 : formatter(f), value(val) {}
1888 : formatter(f), value(val) {}
1895 if (!specs_)
return write(value), out();
1897 cstring_spec_handler(*
this, value));
1904 writer_.
write(value, *specs_);
1906 writer_.
write(value);
1914 write_pointer(value);
1920 return (
'a' <= c && c <=
'z') || (
'A' <= c && c <=
'Z') ||
'_' == c;
1925 template <
typename Char,
typename ErrorHandler>
1927 ErrorHandler&& eh) {
1928 FMT_ASSERT(begin != end &&
'0' <= *begin && *begin <=
'9',
"");
1929 if (*begin ==
'0') {
1935 constexpr
unsigned max_int = max_value<int>();
1936 unsigned big = max_int / 10;
1940 value = max_int + 1;
1943 value = value * 10 + unsigned(*begin -
'0');
1945 }
while (begin != end &&
'0' <= *begin && *begin <=
'9');
1946 if (value > max_int) eh.on_error(
"number is too big");
1947 return static_cast<int>(value);
1960 : parse_ctx_(parse_ctx), ctx_(ctx) {}
1963 h.
format(parse_ctx_, ctx_);
1970 template <
typename T>
1973 !std::is_same<T, char>::value &&
1974 !std::is_same<T, wchar_t>::value>;
1980 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
1982 if (
is_negative(value)) handler_.on_error(
"negative width");
1983 return static_cast<unsigned long long>(value);
1986 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
1988 handler_.on_error(
"width is not integer");
2000 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2002 if (
is_negative(value)) handler_.on_error(
"negative precision");
2003 return static_cast<unsigned long long>(value);
2006 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2008 handler_.on_error(
"precision is not integer");
2023 : specs_(other.specs_) {}
2034 specs_.
fill[0] = Char(
'0');
2044 specs_.
type =
static_cast<char>(
type);
2054 : error_handler_(eh), arg_type_(arg_type) {}
2058 error_handler_.on_error(
"format specifier requires numeric argument");
2062 require_numeric_argument();
2065 error_handler_.on_error(
"format specifier requires signed argument");
2071 error_handler_.on_error(
"precision not allowed for this argument type");
2084 : Handler(handler), checker_(*this, arg_type) {}
2087 : Handler(other), checker_(*this, other.arg_type_) {}
2090 if (align ==
align::numeric) checker_.require_numeric_argument();
2091 Handler::on_align(align);
2095 checker_.check_sign();
2100 checker_.check_sign();
2101 Handler::on_minus();
2105 checker_.check_sign();
2106 Handler::on_space();
2110 checker_.require_numeric_argument();
2115 checker_.require_numeric_argument();
2125 template <
template <
typename>
class Handler,
typename FormatArg,
2126 typename ErrorHandler>
2128 unsigned long long value =
visit_format_arg(Handler<ErrorHandler>(eh), arg);
2129 if (value >
to_unsigned(max_value<int>())) eh.on_error(
"number is too big");
2130 return static_cast<int>(value);
2135 template <
typename Context>
2137 auto arg = ctx.arg(
id);
2138 if (!
arg) ctx.on_error(
"argument index out of range");
2143 template <
typename ParseContext,
typename Context>
2149 ParseContext& parse_ctx, Context& ctx)
2151 parse_context_(parse_ctx),
2155 this->specs_.
width = get_dynamic_spec<width_checker>(
2156 get_arg(arg_id), context_.error_handler());
2160 this->specs_.
precision = get_dynamic_spec<precision_checker>(
2161 get_arg(arg_id), context_.error_handler());
2164 void on_error(
const char* message) { context_.on_error(message); }
2175 parse_context_.check_arg_id(arg_id);
2180 parse_context_.check_arg_id(arg_id);
2181 return context_.arg(arg_id);
2217 template <
typename Char>
2225 template <
typename ParseContext>
2227 :
public specs_setter<typename ParseContext::char_type> {
2237 specs_(other.specs_),
2238 context_(other.context_) {}
2241 specs_.width_ref = make_arg_ref(arg_id);
2245 specs_.precision_ref = make_arg_ref(arg_id);
2249 context_.on_error(message);
2256 context_.check_arg_id(arg_id);
2265 context_.check_arg_id(arg_id);
2267 context_.begin(),
to_unsigned(context_.end() - context_.begin()));
2275 template <
typename Char,
typename IDHandler>
2277 IDHandler&& handler) {
2280 if (c ==
'}' || c ==
':') {
2284 if (c >=
'0' && c <=
'9') {
2286 if (begin == end || (*begin !=
'}' && *begin !=
':'))
2287 handler.on_error(
"invalid format string");
2293 handler.on_error(
"invalid format string");
2299 }
while (it != end && (
is_name_start(c = *it) || (
'0' <= c && c <=
'9')));
2311 handler.on_dynamic_width(
id);
2315 handler.on_error(message);
2328 handler.on_dynamic_precision(
id);
2332 handler.on_error(message);
2339 template <
typename Char,
typename Handler>
2341 Handler&& handler) {
2345 if (begin + 1 != end) ++i;
2347 switch (static_cast<char>(begin[i])) {
2354 #if FMT_NUMERIC_ALIGN 2367 return handler.on_error(
"invalid fill character '{'"), begin;
2372 handler.on_align(
align);
2379 template <
typename Char,
typename Handler>
2381 Handler&& handler) {
2383 if (
'0' <= *begin && *begin <=
'9') {
2385 }
else if (*begin ==
'{') {
2389 if (begin == end || *begin !=
'}')
2390 return handler.on_error(
"invalid format string"), begin;
2396 template <
typename Char,
typename Handler>
2398 Handler&& handler) {
2400 auto c = begin != end ? *begin : Char();
2401 if (
'0' <= c && c <=
'9') {
2403 }
else if (c ==
'{') {
2409 if (begin == end || *begin++ !=
'}')
2410 return handler.on_error(
"invalid format string"), begin;
2412 return handler.on_error(
"missing precision specifier"), begin;
2414 handler.end_precision();
2420 template <
typename Char,
typename SpecHandler>
2422 SpecHandler&& handler) {
2423 if (begin == end || *begin ==
'}')
return begin;
2426 if (begin == end)
return begin;
2429 switch (static_cast<char>(*begin)) {
2443 if (begin == end)
return begin;
2445 if (*begin ==
'#') {
2447 if (++begin == end)
return begin;
2451 if (*begin ==
'0') {
2453 if (++begin == end)
return begin;
2457 if (begin == end)
return begin;
2460 if (*begin ==
'.') {
2465 if (begin != end && *begin !=
'}') handler.on_type(*begin++);
2470 template <
bool IS_CONSTEXPR,
typename T,
typename Ptr = const T*>
2472 for (out = first; out != last; ++out) {
2473 if (*out == value)
return true;
2481 out =
static_cast<const char*
>(
2483 return out !=
nullptr;
2490 handler.on_arg_id(
id);
2493 handler.on_error(message);
2498 template <
bool IS_CONSTEXPR,
typename Char,
typename Handler>
2500 Handler&& handler) {
2502 FMT_CONSTEXPR void operator()(
const Char* begin,
const Char* end) {
2503 if (begin == end)
return;
2505 const Char* p =
nullptr;
2506 if (!find<IS_CONSTEXPR>(begin, end,
'}', p))
2507 return handler_.on_text(begin, end);
2509 if (p == end || *p !=
'}')
2510 return handler_.on_error(
"unmatched '}' in format string");
2511 handler_.on_text(begin, p);
2517 auto begin = format_str.
data();
2518 auto end = begin + format_str.
size();
2519 while (begin != end) {
2522 const Char* p = begin;
2523 if (*begin !=
'{' && !find<IS_CONSTEXPR>(begin, end,
'{', p))
2524 return write(begin, end);
2527 if (p == end)
return handler.on_error(
"invalid format string");
2528 if (static_cast<char>(*p) ==
'}') {
2529 handler.on_arg_id();
2530 handler.on_replacement_field(p);
2531 }
else if (*p ==
'{') {
2532 handler.on_text(p, p + 1);
2535 Char c = p != end ? *p : Char();
2537 handler.on_replacement_field(p);
2538 }
else if (c ==
':') {
2539 p = handler.on_format_specs(p + 1, end);
2540 if (p == end || *p !=
'}')
2541 return handler.on_error(
"unknown format specifier");
2543 return handler.on_error(
"missing '}' in format string");
2550 template <
typename T,
typename ParseContext>
2552 ParseContext& ctx) {
2562 return f.parse(ctx);
2565 template <
typename Char,
typename ErrorHandler,
typename... Args>
2571 context_(format_str, eh),
2572 parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
2577 arg_id_ = context_.next_arg_id();
2582 context_.check_arg_id(
id);
2586 on_error(
"compile-time checks don't support named arguments");
2593 return arg_id_ < num_args ? parse_funcs_[arg_id_](context_) : begin;
2597 context_.on_error(message);
2602 enum { num_args =
sizeof...(Args) };
2605 if (arg_id_ >= num_args) context_.on_error(
"argument index out of range");
2616 template <
typename Char,
typename ErrorHandler,
typename... Args>
2618 ErrorHandler eh = ErrorHandler()) {
2620 parse_format_string<true>(s, checker);
2624 template <
typename... Args,
typename S,
2631 (void)invalid_format;
2634 template <
template <
typename>
class Handler,
typename Context>
2641 value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
index),
2642 ctx.error_handler());
2645 value = internal::get_dynamic_spec<Handler>(ctx.arg(ref.
val.
name),
2646 ctx.error_handler());
2652 template <
typename Range>
2655 using wwriter FMT_DEPRECATED_ALIAS =
2659 template <
typename Range>
2685 :
base(Range(ctx.out()), specs, ctx.locale()),
2687 parse_ctx_(parse_ctx) {}
2689 using base::operator();
2693 handle.
format(*parse_ctx_, ctx_);
2730 template <
typename... Args>
2732 : std::runtime_error(
"") {
2768 #if FMT_USE_WINDOWS_H 2804 template <
typename... Args>
2805 windows_error(
int error_code,
string_view message,
const Args&... args) {
2812 FMT_API void report_windows_error(
int error_code,
2823 mutable char buffer_[buffer_size];
2828 char*
ptr = buffer_ + (buffer_size - 1);
2829 while (value >= 100) {
2833 auto index =
static_cast<unsigned>((value % 100) * 2);
2839 *--ptr =
static_cast<char>(
'0' + value);
2842 auto index =
static_cast<unsigned>(value * 2);
2849 auto abs_value =
static_cast<unsigned long long>(value);
2850 bool negative = value < 0;
2851 if (negative) abs_value = 0 - abs_value;
2853 if (negative) *--str_ =
'-';
2873 const char*
data()
const {
return str_; }
2880 buffer_[buffer_size - 1] =
'\0';
2889 std::string
str()
const {
return std::string(str_, size()); }
2894 template <
typename T,
typename Char>
2902 template <
typename ParseContext>
2909 auto eh = ctx.error_handler();
2952 template <
typename FormatContext>
2953 auto format(
const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
2954 internal::handle_dynamic_spec<internal::width_checker>(
2955 specs_.
width, specs_.width_ref, ctx);
2956 internal::handle_dynamic_spec<internal::precision_checker>(
2957 specs_.
precision, specs_.precision_ref, ctx);
2962 internal::make_arg<FormatContext>(val));
2969 #define FMT_FORMAT_AS(Type, Base) \ 2970 template <typename Char> \ 2971 struct formatter<Type, Char> : formatter<Base, Char> { \ 2972 template <typename FormatContext> \ 2973 auto format(const Type& val, FormatContext& ctx) -> decltype(ctx.out()) { \ 2974 return formatter<Base, Char>::format(val, ctx); \ 2989 template <
typename Char>
2991 template <
typename FormatContext>
2992 auto format(
void* val, FormatContext& ctx) -> decltype(ctx.out()) {
2997 template <
typename Char,
size_t N>
2999 template <
typename FormatContext>
3000 auto format(
const Char* val, FormatContext& ctx) -> decltype(ctx.out()) {
3026 template <
typename ParseContext>
3027 auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3028 format_str_ = ctx.begin();
3034 template <
typename T,
typename FormatContext>
3035 auto format(
const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3041 switch (specs_.
sign) {
3059 internal::make_arg<FormatContext>(val));
3065 internal::handle_dynamic_spec<internal::width_checker>(
3066 specs_.
width, specs_.width_ref, ctx);
3067 internal::handle_dynamic_spec<internal::precision_checker>(
3068 specs_.
precision, specs_.precision_ref, ctx);
3075 template <
typename Range,
typename Char>
3084 template <
typename Char,
typename ErrorHandler>
3090 template <
typename ArgFormatter,
typename Char,
typename Context>
3092 using range =
typename ArgFormatter::range;
3097 : parse_context(str), context(r.begin(), format_args, loc) {}
3099 void on_text(
const Char* begin,
const Char* end) {
3101 auto out = context.out();
3103 it = std::copy_n(begin, size, it);
3104 context.advance_to(out);
3111 parse_context.check_arg_id(
id);
3130 specs_handler<parse_context_t, Context>(specs, parse_context, context),
3133 if (begin == end || *begin !=
'}') on_error(
"missing '}' in format string");
3146 template <
typename ArgFormatter,
typename Char,
typename Context>
3152 internal::parse_format_string<false>(format_str, h);
3159 template <
typename T>
inline const void*
ptr(
const T* p) {
return p; }
3160 template <
typename T>
inline const void*
ptr(
const std::unique_ptr<T>& p) {
3163 template <
typename T>
inline const void*
ptr(
const std::shared_ptr<T>& p) {
3175 template <
typename It,
typename Char>
3177 :
formatter<typename std::iterator_traits<It>::value_type, Char> {
3178 template <
typename FormatContext>
3180 -> decltype(ctx.out()) {
3182 auto it = value.begin;
3183 auto out = ctx.out();
3184 if (it != value.end) {
3186 while (it != value.end) {
3187 out =
std::copy(value.sep.begin(), value.sep.end(), out);
3188 ctx.advance_to(out);
3200 template <
typename It>
3202 return {begin, end, sep};
3205 template <
typename It>
3207 return {begin, end, sep};
3221 template <
typename Range>
3224 return join(std::begin(range), std::end(range), sep);
3227 template <
typename Range>
3230 return join(std::begin(range), std::end(range), sep);
3245 template <
typename T>
inline std::string
to_string(
const T& value) {
3246 return format(
"{}", value);
3252 template <
typename T>
inline std::wstring
to_wstring(
const T& value) {
3253 return format(L
"{}", value);
3256 template <
typename Char, std::
size_t SIZE>
3258 return std::basic_string<Char>(buf.
data(), buf.
size());
3261 template <
typename Char>
3266 return vformat_to<arg_formatter<range>>(buf,
to_string_view(format_str),
3270 template <
typename S,
typename Char =
char_t<S>,
3271 FMT_ENABLE_IF(
internal::is_
string<S>::value)>
3285 {make_format_args<context>(args...)});
3288 template <
typename OutputIt,
typename Char =
char>
3291 template <
typename OutputIt,
typename Char =
char>
3294 template <
typename S,
typename OutputIt,
typename... Args,
3301 return vformat_to<arg_formatter<range>>(range(out),
3316 template <
typename OutputIt,
typename S,
typename... Args,
3321 inline OutputIt
format_to(OutputIt out,
const S& format_str, Args&&... args) {
3325 {make_format_args<context>(args...)});
3335 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3339 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3342 template <
typename OutputIt,
typename Char,
typename... Args>
3345 return format_arg_store<format_to_n_context<OutputIt, Char>, Args...>(
3349 template <
typename OutputIt,
typename Char,
typename... Args,
3356 return {it.base(), it.count()};
3366 template <
typename OutputIt,
typename S,
typename... Args,
3370 const S& format_str,
3371 const Args&... args) {
3375 {make_format_args<context>(args...)});
3378 template <
typename Char>
3391 template <
typename... Args>
3396 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
3402 if (std::fputws(buffer.
data(), f) == -1)
3406 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
3408 vprint(stdout, format_str, args);
3411 #if FMT_USE_USER_DEFINED_LITERALS 3414 # if FMT_USE_UDL_TEMPLATE 3415 template <
typename Char, Char... CHARS>
class udl_formatter {
3417 template <
typename... Args>
3418 std::basic_string<Char> operator()(Args&&... args)
const {
3421 do_check_format_string<Char, error_handler, remove_cvref_t<Args>...>(
3423 (void)invalid_format;
3424 return format(s, std::forward<Args>(args)...);
3428 template <
typename Char>
struct udl_formatter {
3431 template <
typename... Args>
3432 std::basic_string<Char> operator()(Args&&... args)
const {
3433 return format(str, std::forward<Args>(args)...);
3436 # endif // FMT_USE_UDL_TEMPLATE 3438 template <
typename Char>
struct udl_arg {
3441 template <
typename T> named_arg<T, Char> operator=(T&& value)
const {
3442 return {str, std::forward<T>(value)};
3448 inline namespace literals {
3449 # if FMT_USE_UDL_TEMPLATE 3450 # pragma GCC diagnostic push 3451 # if FMT_CLANG_VERSION 3452 # pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template" 3454 template <
typename Char, Char... CHARS>
3455 FMT_CONSTEXPR internal::udl_formatter<Char, CHARS...>
operator""_format() {
3458 # pragma GCC diagnostic pop 3470 FMT_CONSTEXPR internal::udl_formatter<char>
operator"" _format(
const char* s,
3474 FMT_CONSTEXPR internal::udl_formatter<wchar_t>
operator"" _format(
3475 const wchar_t* s, std::size_t n) {
3478 # endif // FMT_USE_UDL_TEMPLATE 3490 FMT_CONSTEXPR internal::udl_arg<char>
operator"" _a(
const char* s,
3494 FMT_CONSTEXPR internal::udl_arg<wchar_t>
operator"" _a(
const wchar_t* s,
3499 #endif // FMT_USE_USER_DEFINED_LITERALS 3502 #define FMT_STRING_IMPL(s, ...) \ 3504 struct str : fmt::compile_string { \ 3505 using char_type = typename std::remove_cv<std::remove_pointer< \ 3506 typename std::decay<decltype(s)>::type>::type>::type; \ 3507 __VA_ARGS__ FMT_CONSTEXPR \ 3508 operator fmt::basic_string_view<char_type>() const { \ 3509 return {s, sizeof(s) / sizeof(char_type) - 1}; \ 3513 (void)static_cast<fmt::basic_string_view<typename str::char_type>>( \ 3528 #define FMT_STRING(s) FMT_STRING_IMPL(s, ) 3530 #if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS 3531 # define fmt(s) FMT_STRING_IMPL(s, [[deprecated]]) 3534 #ifdef FMT_HEADER_ONLY 3535 # define FMT_FUNC inline 3541 #endif // FMT_FORMAT_H_ FMT_CONSTEXPR void on_space()
constexpr int digits10< int128_t >() noexcept
#define FMT_BEGIN_NAMESPACE
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
void operator()(It &&it) const
void write(T value, format_specs specs={})
#define FMT_ASSERT(condition, message)
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
FMT_CONSTEXPR bool is_arithmetic_type(type t)
format_arg arg(int id) const
FMT_CONSTEXPR void end_precision()
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
FMT_CONSTEXPR void on_type(Char type)
std::size_t size() const FMT_NOEXCEPT
FMT_CONSTEXPR void on_fill(Char fill)
FMT_CONSTEXPR arg_ref_type make_arg_ref(int arg_id)
FMT_CONSTEXPR void on_width(int width)
FMT_CONSTEXPR void operator()()
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
void write(string_view value)
union internal::arg_ref::value val
typename internal::void_t_impl< Ts... >::type void_t
FMT_CONSTEXPR iterator end() const
FMT_CONSTEXPR void on_string()
FMT_CONSTEXPR const Char * parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler)
FMT_CONSTEXPR void on_hash()
It write_exponent(int exp, It it)
FMT_CONSTEXPR value(basic_string_view< Char > n)
Char * get_data(std::basic_string< Char > &s)
Char * format_decimal(Char *buffer, UInt value, int num_digits, F add_thousands_sep)
FMT_CONSTEXPR bool is_integral_type(type t)
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 void check_pointer_type_spec(Char spec, ErrorHandler &&eh)
FMT_CONSTEXPR void on_hex()
decltype(test< It >(typename iterator_category< It >::type{})) type
void operator()(It &&it) const
void format_arg(basic_format_parse_context< typename Range::value_type > &parse_ctx, Context &ctx, Id arg_id)
FMT_CONSTEXPR void on_error()
u8string_view(const char *s)
truncating_iterator & operator++()
FMT_CONSTEXPR void on_hash()
uint32_or_64_or_128_t< Int > unsigned_type
void write(unsigned long value)
decltype(std::begin(std::declval< T & >())) iterator_t
truncating_iterator & operator++()
FMT_CONSTEXPR void operator()()
FMT_CONSTEXPR specs_setter(basic_format_specs< Char > &specs)
truncating_iterator & operator=(value_type val)
static const uint32_t zero_or_powers_of_10_32[]
unsigned char value[sizeof(void *)]
void operator()(It &&it) const
FMT_CONSTEXPR Context::format_arg get_arg(Context &ctx, int id)
FMT_CONSTEXPR Char & operator[](size_t index)
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
void operator=(const T &)
char8_t to_char8_t(char c)
std::size_t count() const
FMT_CONSTEXPR specs_checker(const Handler &handler, internal::type arg_type)
FMT_CONSTEXPR void handle_char_specs(const basic_format_specs< Char > *specs, Handler &&handler)
std::iterator_traits< OutputIt > traits
fallback_uintptr uintptr_t
Allocator get_allocator() const
int format_float(T value, int precision, float_specs specs, buffer< char > &buf)
FMT_CONSTEXPR void operator()(int id)
FMT_CONSTEXPR arg_ref & operator=(int idx)
void init(const basic_format_args< Context > &args)
basic_memory_buffer & operator=(basic_memory_buffer &&other) FMT_NOEXCEPT
std::back_insert_iterator< internal::buffer< T > > iterator
const Char & const_reference
FMT_CONSTEXPR void check_sign()
FMT_CONSTEXPR void on_num()
FMT_CONSTEXPR width_adapter(SpecHandler &h)
constexpr bool use_grisu()
output_range(OutputIt it)
FMT_CONSTEXPR int get_dynamic_spec(FormatArg arg, ErrorHandler eh)
bool_constant< std::is_same< typename std::iterator_traits< InputIt >::value_type, char >::value &&std::is_same< OutChar, char8_t >::value > needs_conversion
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
ErrorHandler & error_handler_
std::random_access_iterator_tag type
#define FMT_CONSTEXPR_DECL
void write(unsigned value)
arg_join(It b, It e, basic_string_view< Char > s)
void append(const U *begin, const U *end)
basic_string_view< wchar_t > wstring_view
~basic_memory_buffer() FMT_OVERRIDE
void check_format_string(const S &)
auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n))
void write_decimal(Int value)
#define FMT_EXTERN_TEMPLATE_API
FMT_CONSTEXPR bool is_negative(T value)
FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler &&handler)
FMT_CONSTEXPR iterator begin() const FMT_NOEXCEPT
basic_memory_buffer(basic_memory_buffer &&other) FMT_NOEXCEPT
static const char signs[]
void write_pointer(UIntPtr value, const format_specs *specs)
FMT_CONSTEXPR int_type_checker(ErrorHandler eh)
FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler &&handler)
void vformat_to(basic_memory_buffer< Char > &buf, const text_style &ts, basic_string_view< Char > format_str, basic_format_args< buffer_context< Char >> args)
FMT_CONSTEXPR const Char * parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler)
void operator()(It &&it) const
FMT_CONSTEXPR const Char * parse_width(const Char *begin, const Char *end, Handler &&handler)
FMT_CONSTEXPR void on_error(const char *message)
buffer_range(internal::buffer< T > &buf)
constexpr int num_bits< fallback_uintptr >()
const std::string & groups
Char thousands_sep(locale_ref loc)
FMT_CONSTEXPR float_specs parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={})
truncating_iterator(OutputIt out, std::size_t limit)
FMT_CONSTEXPR void on_error(const char *message)
void operator()(It &&it) const
typename internal::char_t_impl< S >::type char_t
int count_digits(uint64_t n)
traits::value_type blackhole_
basic_string_view< Char > name
void handle_dynamic_spec(int &value, arg_ref< typename Context::char_type > ref, Context &ctx)
#define FMT_END_NAMESPACE
FMT_CONSTEXPR void on_int()
typename Range::iterator iterator
FMT_CONSTEXPR void on_minus()
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
FMT_CONSTEXPR size_t size() const
FMT_CONSTEXPR void on_space()
void operator()(It &&it) const
void write_padded(const format_specs &specs, F &&f)
static const uint64_t zero_or_powers_of_10_64[]
checked_ptr< typename Container::value_type > reserve(std::back_insert_iterator< Container > &it, std::size_t n)
void write(const Char *s, std::size_t size, const format_specs &specs)
basic_writer< Range > & writer
FMT_CONSTEXPR void on_pointer()
FMT_CONSTEXPR void on_plus()
FMT_CONSTEXPR format_arg get_arg(auto_id)
typename std::enable_if< B, T >::type enable_if_t
FMT_FUNC std::string grouping_impl(locale_ref loc)
FMT_CONSTEXPR specs_handler(basic_format_specs< char_type > &specs, ParseContext &parse_ctx, Context &ctx)
FMT_CONSTEXPR void on_oct()
truncating_iterator & operator++(int)
basic_memory_buffer(const Allocator &alloc=Allocator())
constexpr int digits10< uint128_t >() noexcept
typename ParseContext::char_type char_type
FMT_CONSTEXPR void end_precision()
FMT_CONSTEXPR bool is_name_start(Char c)
std::output_iterator_tag iterator_category
FMT_CONSTEXPR int parse_nonnegative_int(const Char *&begin, const Char *end, ErrorHandler &&eh)
FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs< char_type > &specs, ParseContext &ctx)
FMT_CONSTEXPR arg_ref(int index)
OutputIterator copy(const RangeT &range, OutputIterator out)
void move(basic_memory_buffer &other)
FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id)
format_arg_store< Context, Args... > make_format_args(const Args &... args)
FMT_CONSTEXPR void check_precision()
u8string_view(const char *s, size_t count) FMT_NOEXCEPT
#define FMT_ENABLE_IF(...)
int_writer(basic_writer< Range > &w, Int value, const Specs &s)
void write(unsigned long long value)
void operator()(It &&it) const
FMT_CONSTEXPR void on_error(const char *message)
FMT_CONSTEXPR void on_error(const char *message)
FMT_FUNC Char decimal_point_impl(locale_ref loc)
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it)
typename std::conditional< B, T, F >::type conditional_t
basic_format_specs< Char > & specs_
FMT_CONSTEXPR const Char * parse_precision(const Char *begin, const Char *end, Handler &&handler)
FMT_CONSTEXPR void on_align(align_t align)
counting_iterator operator++(int)
static FMT_CONSTEXPR fill_t< Char > make()
void write(wstring_view value)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR cstring_type_checker(ErrorHandler eh)
truncating_iterator(OutputIt out, std::size_t limit)
ParseContext & parse_context_
FMT_CONSTEXPR auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
FMT_FUNC int count_digits< 4 >(internal::fallback_uintptr n)
typename Context::format_arg format_arg
FMT_CONSTEXPR format_arg get_arg(int arg_id)
FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
FMT_CONSTEXPR void on_zero()
FMT_NORETURN void on_error()
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
std::integral_constant< bool, B > bool_constant
FMT_CONSTEXPR void on_bin()
FMT_CONSTEXPR const Char * data() const
Char * format_uint(Char *buffer, UInt value, int num_digits, bool upper=false)
truncating_iterator_base(OutputIt out, std::size_t limit)
Char decimal_point(locale_ref loc)
FMT_CONSTEXPR void on_align(align_t align)
void push_back(const T &value)
std::size_t capacity() const FMT_NOEXCEPT
truncating_iterator & operator*()
FMT_CONSTEXPR void on_minus()
FMT_CONSTEXPR specs_checker(const specs_checker &other)
FMT_CONSTEXPR format_arg get_arg(basic_string_view< char_type > arg_id)
typename OutputIt::container_type::value_type value_type
FMT_CONSTEXPR void require_numeric_argument()
FMT_CONSTEXPR void parse_format_string(basic_string_view< Char > format_str, Handler &&handler)
int snprintf_float(T value, int precision, float_specs specs, buffer< char > &buf)
value_type operator*() const
FMT_CONSTEXPR void advance_to(iterator it)
void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT
typename Range::value_type char_type
numeric_specs_checker< Handler > checker_
FMT_CONSTEXPR void operator()(int id)
FMT_CONSTEXPR void on_char()
FMT_CONSTEXPR iterator begin() const
void on_error(const char *message)
constexpr int digits10() noexcept
FMT_CONSTEXPR void on_dec()
FMT_CONSTEXPR bool do_check_format_string(basic_string_view< Char > s, ErrorHandler eh=ErrorHandler())
size_t code_point_index(basic_string_view< Char > s, size_t n)
FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view< char_type > arg_id)
FMT_CONSTEXPR specs_setter(const specs_setter &other)
FMT_FUNC Char thousands_sep_impl(locale_ref loc)
basic_string_view< char > string_view
void write(basic_string_view< Char > s, const format_specs &specs={})
bool find< false, char >(const char *first, const char *last, char value, const char *&out)
std::output_iterator_tag iterator_category
static const char hex_digits[]
fallback_uintptr to_uintptr(const void *p)
FMT_CONSTEXPR void on_zero()
std::back_insert_iterator< internal::buffer< T > > iterator
Dest bit_cast(const Source &source)
typename traits::value_type value_type
fallback_uintptr(const void *p)
void write_int(T value, const Spec &spec)
FMT_CONSTEXPR numeric_specs_checker(ErrorHandler &eh, internal::type arg_type)
std::size_t count() const
FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler &other)
FMT_CONSTEXPR const Char & operator[](size_t index) const
void operator()(It &&it) const
FMT_CONSTEXPR const Char * parse_align(const Char *begin, const Char *end, Handler &&handler)
std::ptrdiff_t difference_type
void write_int(int num_digits, string_view prefix, format_specs specs, F f)
T * make_checked(T *p, std::size_t)
basic_writer(Range out, locale_ref loc=locale_ref())
dynamic_format_specs< char_type > & specs_
std::string grouping(locale_ref loc)
float_writer(const char *digits, int num_digits, int exp, float_specs specs, Char decimal_point)
string_view get_prefix() const
basic_string_view< Char > sep
conditional_t< std::numeric_limits< T >::digits<=32, uint32_t, conditional_t< std::numeric_limits< T >::digits<=64, uint64_t, uint128_t > > uint32_or_64_or_128_t
Container & get_container(std::back_insert_iterator< Container > it)
FMT_CONSTEXPR precision_adapter(SpecHandler &h)
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
FMT_CONSTEXPR arg_ref(basic_string_view< Char > name)
FMT_CONSTEXPR void on_precision(int precision)
void write(std::basic_ostream< Char > &os, buffer< Char > &buf)
typename Context::char_type char_type
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< buffer_context< Char >> args)
void reset_color(FILE *stream) FMT_NOEXCEPT
internal::named_arg< T, Char > arg(const S &name, const T &arg)
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh)
std::string grouping< wchar_t >(locale_ref loc)
FMT_CONSTEXPR value(int id=0)
truncating_iterator operator++(int)
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
typename It::iterator_category type
size_t count_code_points(basic_string_view< Char > s)
counting_iterator & operator++()
static const char digits[]
system_error(int error_code, string_view message, const Args &... args)
FMT_CONSTEXPR void on_plus()
FMT_CONSTEXPR void operator()(int id)
FMT_CONSTEXPR void operator()()
basic_writer< buffer_range< char > > writer
void write(long long value)
void grow(std::size_t size) FMT_OVERRIDE
value_type & operator*() const