41 # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) 43 # define FMT_CLANG_VERSION 0 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 62 #if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION 63 # pragma GCC diagnostic push 67 # pragma GCC diagnostic ignored "-Wshadow" 71 # pragma GCC diagnostic ignored "-Wformat-nonliteral" 74 # if FMT_CLANG_VERSION 75 # pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template" 79 # define FMT_SECURE_SCL _SECURE_SCL 81 # define FMT_SECURE_SCL 0 89 # define FMT_HAS_BUILTIN(x) __has_builtin(x) 91 # define FMT_HAS_BUILTIN(x) 0 94 #ifdef __GNUC_LIBSTD__ 95 # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) 103 template <
typename Exception>
104 inline void do_throw(
const Exception &x) {
107 volatile bool b =
true;
113 # define FMT_THROW(x) fmt::internal::do_throw(x) 115 # define FMT_THROW(x) throw x 118 # define FMT_THROW(x) do { static_cast<void>(sizeof(x)); assert(false); } while(false); 122 #ifndef FMT_USE_USER_DEFINED_LITERALS 125 # if (FMT_HAS_FEATURE(cxx_user_literals) || \ 126 FMT_GCC_VERSION >= 407 || FMT_MSC_VER >= 1900) && \ 127 (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || \ 128 FMT_ICC_VERSION >= 1500 || FMT_CUDA_VERSION >= 700) 129 # define FMT_USE_USER_DEFINED_LITERALS 1 131 # define FMT_USE_USER_DEFINED_LITERALS 0 137 #if FMT_USE_USER_DEFINED_LITERALS && \ 138 FMT_ICC_VERSION == 0 && \ 139 FMT_CUDA_VERSION == 0 && \ 140 ((FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L) || \ 141 (defined(FMT_CLANG_VERSION) && FMT_CLANG_VERSION >= 304)) 142 # define FMT_UDL_TEMPLATE 1 144 # define FMT_UDL_TEMPLATE 0 147 #ifndef FMT_USE_EXTERN_TEMPLATES 148 # ifndef FMT_HEADER_ONLY 149 # define FMT_USE_EXTERN_TEMPLATES \ 150 ((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \ 151 (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11)) 153 # define FMT_USE_EXTERN_TEMPLATES 0 157 #if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_trailing_return) || \ 159 # define FMT_USE_TRAILING_RETURN 1 161 # define FMT_USE_TRAILING_RETURN 0 164 #ifndef FMT_USE_GRISU 165 # define FMT_USE_GRISU 0 172 # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) 173 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) 176 # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) 177 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) 184 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED) 191 # pragma intrinsic(_BitScanReverse) 193 inline uint32_t clz(uint32_t x) {
195 _BitScanReverse(&r, x);
201 # pragma warning(suppress: 6102) 204 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n) 206 # if defined(_WIN64) && !defined(__clang__) 207 # pragma intrinsic(_BitScanReverse64) 210 inline uint32_t clzll(uint64_t x) {
213 _BitScanReverse64(&r, x);
216 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
217 return 63 - (r + 32);
220 _BitScanReverse(&r, static_cast<uint32_t>(x));
227 # pragma warning(suppress: 6102) 230 # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n) 241 template <
typename Dest,
typename Source>
243 static_assert(
sizeof(Dest) ==
sizeof(Source),
"size mismatch");
245 std::memcpy(&dest, &source,
sizeof(dest));
250 template <
typename C>
254 template <
typename T, std::
size_t N>
256 template <
typename C>
258 template <
typename T, std::
size_t N>
262 template <
typename Result>
264 template <
typename T>
270 operator int()
const {
return 0; }
272 typedef std::numeric_limits<internal::dummy_int>
fputil;
281 template <
typename Allocator>
282 typename Allocator::value_type *
allocate(Allocator& alloc, std::size_t n) {
283 #if __cplusplus >= 201103L || FMT_MSC_VER >= 1700 286 return alloc.allocate(n);
292 template <
typename T>
303 class numeric_limits<
fmt::internal::dummy_int> :
304 public std::numeric_limits<int> {
307 template <
typename T>
309 using namespace fmt::internal;
313 return isinf(x) != 0;
314 return !
_finite(static_cast<double>(x));
318 template <
typename T>
320 using namespace fmt::internal;
322 return isnan(x) != 0;
323 return _isnan(static_cast<double>(x)) != 0;
329 template <
typename Range>
332 template <
typename OutputIt,
typename T =
typename OutputIt::value_type>
338 typedef void sentinel;
339 sentinel
end()
const;
346 OutputIt
begin()
const {
return it_; }
350 template <
typename Container>
352 public output_range<std::back_insert_iterator<Container>> {
368 :
std::runtime_error(message) {}
371 :
std::runtime_error(message) {}
377 template <
typename T>
378 struct checked {
typedef stdext::checked_array_iterator<T*>
type; };
381 template <
typename T>
382 inline stdext::checked_array_iterator<T*>
make_checked(T *p, std::size_t size) {
386 template <
typename T>
388 template <
typename T>
392 template <
typename T>
393 template <
typename U>
397 std::uninitialized_copy(begin, end,
405 #if !defined(__cpp_char8_t) 421 #if FMT_USE_USER_DEFINED_LITERALS 422 inline namespace literals {
423 inline u8string_view operator"" _u(
const char *s, std::size_t n) {
463 typename Allocator = std::allocator<T> >
471 if (data != store_) Allocator::deallocate(data, this->capacity());
483 this->
set(store_, SIZE);
490 Allocator &this_alloc = *
this, &other_alloc = other;
491 this_alloc = std::move(other_alloc);
493 std::size_t size = other.
size(), capacity = other.
capacity();
494 if (data == other.store_) {
495 this->
set(store_, capacity);
496 std::uninitialized_copy(other.store_, other.store_ + size,
499 this->
set(
data, capacity);
502 other.
set(other.store_, 0);
524 assert(
this != &other);
534 template <
typename T, std::
size_t SIZE,
typename Allocator>
536 std::size_t old_capacity = this->capacity();
537 std::size_t new_capacity = old_capacity + old_capacity / 2;
538 if (size > new_capacity)
540 T *old_data = this->
data();
541 T *new_data = internal::allocate<Allocator>(*
this, new_capacity);
543 std::uninitialized_copy(old_data, old_data + this->size(),
545 this->
set(new_data, new_capacity);
549 if (old_data != store_)
550 Allocator::deallocate(old_data, old_capacity);
558 template <
typename Char>
564 template <
typename T>
565 FMT_API static int format_float(
char *
buffer, std::size_t size,
571 template <
typename T>
572 FMT_API static int format_float(
wchar_t *
buffer, std::size_t size,
576 #if FMT_USE_EXTERN_TEMPLATES 578 char *
buffer, std::size_t size,
const char*
format,
int precision,
581 char *
buffer, std::size_t size,
const char*
format,
int precision,
585 wchar_t *
buffer, std::size_t size,
const wchar_t*
format,
int precision,
588 wchar_t *
buffer, std::size_t size,
const wchar_t*
format,
int precision,
592 template <
typename Container>
593 inline typename std::enable_if<
596 reserve(std::back_insert_iterator<Container> &it, std::size_t n) {
598 std::size_t size = c.size();
603 template <
typename Iterator>
604 inline Iterator &
reserve(Iterator &it, std::size_t) {
return it; }
606 template <
typename Char>
609 template <
typename Char>
614 template <
typename T>
618 mutable T blackhole_;
630 std::size_t
count()
const {
return count_; }
646 template <
typename OutputIt>
654 : out_(out), limit_(limit), count_(0) {}
663 OutputIt
base()
const {
return out_; }
664 std::size_t
count()
const {
return count_; }
669 template <
typename OutputIt,
typename Enable =
typename std::is_void<
670 typename std::iterator_traits<OutputIt>::value_type>
::type>
673 template <
typename OutputIt>
676 typedef std::iterator_traits<OutputIt> traits;
678 mutable typename traits::value_type blackhole_;
687 if (this->count_++ < this->limit_)
699 return this->count_ < this->limit_ ? *this->out_ : blackhole_;
703 template <
typename OutputIt>
707 typedef typename OutputIt::container_type::value_type
value_type;
713 if (this->count_++ < this->limit_)
725 template <
typename T>
730 template <
typename T>
736 template <
typename T>
740 typedef typename std::conditional<
741 std::numeric_limits<T>::digits <= 32, uint32_t, uint64_t>
::type main_type;
746 template <
typename T =
void>
748 static const uint32_t POWERS_OF_10_32[];
749 static const uint32_t ZERO_OR_POWERS_OF_10_32[];
750 static const uint64_t ZERO_OR_POWERS_OF_10_64[];
751 static const uint64_t POW10_SIGNIFICANDS[];
752 static const int16_t POW10_EXPONENTS[];
753 static const char DIGITS[];
754 static const char FOREGROUND_COLOR[];
755 static const char BACKGROUND_COLOR[];
756 static const char RESET_COLOR[];
757 static const wchar_t WRESET_COLOR[];
760 #if FMT_USE_EXTERN_TEMPLATES 766 #ifdef FMT_BUILTIN_CLZLL 772 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
773 return t - (n < data::ZERO_OR_POWERS_OF_10_64[t]) + 1;
783 if (n < 10)
return count;
784 if (n < 100)
return count + 1;
785 if (n < 1000)
return count + 2;
786 if (n < 10000)
return count + 3;
793 template <
typename Char>
801 template <
typename InputIt,
typename OutChar>
804 typename std::iterator_traits<InputIt>::value_type,
char>
::value &&
805 std::is_same<OutChar, char8_t>::value> {};
807 template <
typename OutChar,
typename InputIt,
typename OutputIt>
808 typename std::enable_if<
814 template <
typename OutChar,
typename InputIt,
typename OutputIt>
815 typename std::enable_if<
818 return std::transform(begin, end, it,
to_char8_t);
821 #if FMT_HAS_CPP_ATTRIBUTE(always_inline) 822 # define FMT_ALWAYS_INLINE __attribute__((always_inline)) 824 # define FMT_ALWAYS_INLINE 827 template <
typename Handler>
831 template <
typename Handler>
832 inline char *
lg(uint32_t n, Handler h) {
833 return n < 100 ? n < 10 ? h.template on<0>(n) : h.template on<1>(n)
835 ? n < 10000 ? n < 1000 ? h.template on<2>(n)
836 : h.template on<3>(n)
837 : n < 100000 ? h.template on<4>(n)
838 : h.template on<5>(n)
839 : n < 100000000 ? n < 10000000 ? h.template on<6>(n)
840 : h.template on<7>(n)
841 : n < 1000000000 ? h.template on<8>(n)
842 : h.template on<9>(n);
851 void write_pair(
unsigned N, uint32_t index) {
852 std::memcpy(buffer_ + N, data::DIGITS + index * 2, 2);
858 template <
unsigned N>
char *
on(uint32_t u) {
860 *buffer_ =
static_cast<char>(u) +
'0';
867 unsigned a = n / 5 * n * 53 / 16;
868 uint64_t t = ((1ULL << (32 + a)) /
869 data::ZERO_OR_POWERS_OF_10_32[n] + 1 - n / 9);
870 t = ((t * u) >> a) + n / 5 * 4;
871 write_pair(0, t >> 32);
872 for (
unsigned i = 2; i < N; i += 2) {
873 t = 100ULL *
static_cast<uint32_t
>(t);
874 write_pair(i, t >> 32);
877 buffer_[N] =
static_cast<char>(
878 (10ULL *
static_cast<uint32_t
>(t)) >> 32) +
'0';
881 return buffer_ += N + 1;
890 template <
unsigned N>
char *
on(uint32_t u) {
891 char *buf = decimal_formatter::on<N>(u);
897 #ifdef FMT_BUILTIN_CLZ 900 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
901 return t - (n < data::ZERO_OR_POWERS_OF_10_32[t]) + 1;
909 template <
typename Char>
916 template <
typename Char>
922 unsigned digit_index_;
928 : sep_(sep), digit_index_(0) {}
931 if (++digit_index_ % 3 != 0)
933 buffer -= sep_.
size();
934 std::uninitialized_copy(sep_.
data(), sep_.
data() + sep_.
size(),
941 template <
typename Char>
944 template <
typename Char>
946 return Char(thousands_sep_impl<char>(loc));
951 return thousands_sep_impl<wchar_t>(loc);
957 template <
typename UInt,
typename Char,
typename ThousandsSep>
960 FMT_ASSERT(num_digits >= 0,
"invalid digit count");
961 buffer += num_digits;
963 while (value >= 100) {
967 unsigned index =
static_cast<unsigned>((value % 100) * 2);
969 *--buffer =
static_cast<Char
>(data::DIGITS[index + 1]);
971 *--buffer =
static_cast<Char
>(data::DIGITS[index]);
975 *--buffer =
static_cast<Char
>(
'0' + value);
978 unsigned index =
static_cast<unsigned>(value * 2);
979 *--buffer =
static_cast<Char
>(data::DIGITS[index + 1]);
981 *--buffer =
static_cast<Char
>(data::DIGITS[index]);
985 template <
typename OutChar,
typename UInt,
typename Iterator,
986 typename ThousandsSep>
988 Iterator out, UInt
value,
int num_digits, ThousandsSep sep) {
989 FMT_ASSERT(num_digits >= 0,
"invalid digit count");
992 enum { max_size = std::numeric_limits<UInt>::digits10 + 1 };
993 FMT_ASSERT(ThousandsSep::size <= 1,
"invalid separator");
994 char_type buffer[max_size + max_size / 3];
996 return internal::copy_str<OutChar>(
buffer,
end, out);
999 template <
typename OutChar,
typename It,
typename UInt>
1001 return format_decimal<OutChar>(out, value, num_digits,
no_thousands_sep());
1004 template <
unsigned BASE_BITS,
typename Char,
typename UInt>
1006 bool upper =
false) {
1007 buffer += num_digits;
1010 const char *digits = upper ?
"0123456789ABCDEF" :
"0123456789abcdef";
1011 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1012 *--buffer =
static_cast<Char
>(BASE_BITS < 4 ? static_cast<char>(
'0' + digit)
1014 }
while ((value >>= BASE_BITS) != 0);
1018 template <
unsigned BASE_BITS,
typename Char,
typename It,
typename UInt>
1020 bool upper =
false) {
1023 char buffer[std::numeric_limits<UInt>::digits / BASE_BITS + 2];
1024 format_uint<BASE_BITS>(
buffer, value, num_digits, upper);
1025 return internal::copy_str<Char>(
buffer, buffer + num_digits, out);
1029 # define FMT_USE_WINDOWS_H 0 1030 #elif !defined(FMT_USE_WINDOWS_H) 1031 # define FMT_USE_WINDOWS_H 1 1036 #if FMT_USE_WINDOWS_H 1039 class utf8_to_utf16 {
1041 wmemory_buffer buffer_;
1046 size_t size()
const {
return buffer_.size() - 1; }
1047 const wchar_t *c_str()
const {
return &buffer_[0]; }
1048 std::wstring str()
const {
return std::wstring(&buffer_[0], size()); }
1053 class utf16_to_utf8 {
1055 memory_buffer buffer_;
1061 size_t size()
const {
return buffer_.size() - 1; }
1062 const char *c_str()
const {
return &buffer_[0]; }
1063 std::string str()
const {
return std::string(&buffer_[0], size()); }
1075 template <
typename T =
void>
1110 template <
typename Char>
1117 template <
typename Char,
typename ErrorHandler>
1119 if (next_arg_id_ >= 0)
1121 on_error(
"cannot switch from manual to automatic argument indexing");
1125 namespace internal {
1129 template <
typename Double>
1132 template <
typename Double>
1136 template <
typename Double>
1139 template <
typename Handler>
1162 template <
typename Handler>
1165 case 0:
case 'g':
case 'G':
1166 handler.on_general();
1183 template <
typename Char,
typename Handler>
1186 if (!specs)
return handler.on_char();
1187 if (specs->
type && specs->
type !=
'c')
return handler.on_int();
1188 if (specs->
align() == ALIGN_NUMERIC || specs->
flags != 0)
1189 handler.on_error(
"invalid format specifier for char");
1193 template <
typename Char,
typename Handler>
1195 if (spec == 0 || spec ==
's')
1196 handler.on_string();
1197 else if (spec ==
'p')
1198 handler.on_pointer();
1200 handler.on_error(
"invalid type specifier");
1203 template <
typename Char,
typename ErrorHandler>
1205 if (spec != 0 && spec !=
's')
1206 eh.on_error(
"invalid type specifier");
1209 template <
typename Char,
typename ErrorHandler>
1211 if (spec != 0 && spec !=
'p')
1212 eh.on_error(
"invalid type specifier");
1215 template <
typename ErrorHandler>
1227 ErrorHandler::on_error(
"invalid type specifier");
1231 template <
typename ErrorHandler>
1235 : ErrorHandler(eh) {}
1243 ErrorHandler::on_error(
"invalid type specifier");
1247 template <
typename ErrorHandler>
1254 : ErrorHandler(eh), type_(type) {}
1262 template <
typename ErrorHandler>
1266 : ErrorHandler(eh) {}
1272 template <
typename Context>
1277 if (args.is_packed()) {
1278 for (
unsigned i = 0;; ++i) {
1291 for (
unsigned i = 0; ; ++i) {
1292 switch (args.
args_[i].type_) {
1296 push_back(args.
args_[i].value_);
1304 template <
typename Range>
1308 typedef decltype(internal::declval<Range>().
begin()) iterator;
1313 writer_type writer_;
1314 format_specs *specs_;
1316 struct char_writer {
1319 size_t size()
const {
return 1; }
1320 size_t width()
const {
return 1; }
1322 template <
typename It>
1323 void operator()(It &&it)
const { *it++ = value; }
1326 void write_char(char_type value) {
1328 writer_.write_padded(*specs_, char_writer{value});
1330 writer_.write(value);
1333 void write_pointer(
const void *p) {
1334 format_specs specs = specs_ ? *specs_ :
format_specs();
1337 writer_.write_int(reinterpret_cast<uintptr_t>(p), specs);
1342 format_specs *
spec() {
return specs_; }
1343 iterator
out() {
return writer_.out(); }
1347 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
1353 auto length = std::char_traits<char_type>::length(value);
1355 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
1360 : writer_(r, loc), specs_(s) {}
1367 template <
typename T>
1368 typename std::enable_if<
1369 std::is_integral<T>::value || std::is_same<T, char_type>::value,
1373 if (std::is_same<T, bool>::value) {
1374 if (specs_ && specs_->type)
1375 return (*
this)(value ? 1 : 0);
1377 }
else if (std::is_same<T, char_type>::value) {
1381 specs_ ? writer_.write_int(value, *specs_) : writer_.write(value);
1386 template <
typename T>
1387 typename std::enable_if<std::is_floating_point<T>::value, iterator>
::type 1389 writer_.write_double(value, specs_ ? *specs_ :
format_specs());
1398 : formatter(f), value(val) {}
1401 if (formatter.specs_)
1402 formatter.writer_.write_int(value, *formatter.specs_);
1404 formatter.writer_.
write(value);
1414 : formatter(f), value(val) {}
1421 if (!specs_)
return write(value), out();
1431 writer_.write(value, *specs_);
1433 writer_.write(value);
1441 write_pointer(value);
1446 template <
typename Char>
1448 return (
'a' <= c && c <=
'z') || (
'A' <= c && c <=
'Z') ||
'_' == c;
1453 template <
typename Char,
typename ErrorHandler>
1455 const Char *&
begin,
const Char *
end, ErrorHandler &&eh) {
1456 assert(begin != end &&
'0' <= *begin && *begin <=
'9');
1457 if (*begin ==
'0') {
1463 unsigned max_int = (std::numeric_limits<int>::max)();
1464 unsigned big = max_int / 10;
1468 value = max_int + 1;
1471 value = value * 10 + unsigned(*begin -
'0');
1473 }
while (begin != end &&
'0' <= *begin && *begin <=
'9');
1474 if (value > max_int)
1475 eh.on_error(
"number is too big");
1479 template <
typename Char,
typename Context>
1492 template <
typename T>
1496 template <
typename T>
1499 value = std::is_integral<T>::value && !std::is_same<T, bool>::value &&
1500 !std::is_same<T, char>::value && !std::is_same<T, wchar_t>::value
1504 template <
typename ErrorHandler>
1509 template <
typename T>
1511 typename std::enable_if<
1514 handler_.on_error(
"negative width");
1515 return static_cast<unsigned long long>(value);
1518 template <
typename T>
1521 handler_.on_error(
"width is not integer");
1526 ErrorHandler &handler_;
1529 template <
typename ErrorHandler>
1534 template <
typename T>
1538 handler_.on_error(
"negative precision");
1539 return static_cast<unsigned long long>(value);
1542 template <
typename T>
1545 handler_.on_error(
"precision is not integer");
1550 ErrorHandler &handler_;
1554 template <
typename Char>
1576 specs_.precision =
static_cast<int>(precision);
1581 specs_.type =
static_cast<char>(
type);
1590 template <
typename Handler>
1594 : Handler(handler), arg_type_(arg_type) {}
1597 : Handler(other), arg_type_(other.arg_type_) {}
1600 if (align == ALIGN_NUMERIC)
1601 require_numeric_argument();
1602 Handler::on_align(align);
1612 Handler::on_minus();
1617 Handler::on_space();
1621 require_numeric_argument();
1626 require_numeric_argument();
1632 this->on_error(
"precision not allowed for this argument type");
1638 this->on_error(
"format specifier requires numeric argument");
1642 require_numeric_argument();
1645 this->on_error(
"format specifier requires signed argument");
1652 template <
template <
typename>
class Handler,
typename T,
1653 typename Context,
typename ErrorHandler>
1656 unsigned long long big_value =
1658 if (big_value >
to_unsigned((std::numeric_limits<int>::max)()))
1659 eh.on_error(
"number is too big");
1660 value =
static_cast<T
>(big_value);
1666 template <
typename Context>
1675 template <
typename Id>
1677 set_dynamic_spec<width_checker>(
1678 this->specs_.width_, get_arg(arg_id), context_.error_handler());
1681 template <
typename Id>
1683 set_dynamic_spec<precision_checker>(
1684 this->specs_.precision, get_arg(arg_id), context_.error_handler());
1688 context_.on_error(message);
1693 return context_.next_arg();
1696 template <
typename Id>
1698 context_.parse_context().check_arg_id(arg_id);
1699 return context_.get_arg(arg_id);
1706 template <
typename Char>
1732 template <
typename Char>
1740 template <
typename ParseContext>
1742 public specs_setter<typename ParseContext::char_type> {
1748 :
specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}
1752 specs_(other.specs_), context_(other.context_) {}
1754 template <
typename Id>
1756 specs_.width_ref = make_arg_ref(arg_id);
1759 template <
typename Id>
1761 specs_.precision_ref = make_arg_ref(arg_id);
1765 context_.on_error(message);
1771 template <
typename Id>
1773 context_.check_arg_id(arg_id);
1774 return arg_ref_type(arg_id);
1778 return arg_ref_type(context_.next_arg_id());
1782 ParseContext &context_;
1785 template <
typename Char,
typename IDHandler>
1787 const Char *
begin,
const Char *
end, IDHandler &&handler) {
1788 assert(begin != end);
1790 if (c ==
'}' || c ==
':')
1791 return handler(),
begin;
1792 if (c >=
'0' && c <=
'9') {
1794 if (begin == end || (*begin !=
'}' && *begin !=
':'))
1795 return handler.on_error(
"invalid format string"),
begin;
1800 return handler.on_error(
"invalid format string"),
begin;
1804 }
while (it != end && (
is_name_start(c = *it) || (
'0' <= c && c <=
'9')));
1810 template <
typename SpecHandler,
typename Char>
1817 handler.on_dynamic_width(
id);
1821 handler.on_error(message);
1828 template <
typename SpecHandler,
typename Char>
1834 handler.on_dynamic_precision(
id);
1837 handler.on_dynamic_precision(
id);
1846 template <
typename Char,
typename Handler>
1848 const Char *
begin,
const Char *
end, Handler &&handler) {
1852 if (begin + 1 != end) ++i;
1854 switch (static_cast<char>(begin[i])) {
1872 return handler.on_error(
"invalid fill character '{'"),
begin;
1876 handler.on_align(align);
1883 template <
typename Char,
typename Handler>
1885 const Char *
begin,
const Char *
end, Handler &&handler) {
1887 if (
'0' <= *begin && *begin <=
'9') {
1889 }
else if (*begin ==
'{') {
1893 if (begin == end || *begin !=
'}')
1894 return handler.on_error(
"invalid format string"),
begin;
1902 template <
typename Char,
typename SpecHandler>
1904 const Char *
begin,
const Char *
end, SpecHandler &&handler) {
1905 if (begin == end || *begin ==
'}')
1909 if (begin == end)
return begin;
1912 switch (static_cast<char>(*begin)) {
1926 if (begin == end)
return begin;
1928 if (*begin ==
'#') {
1930 if (++begin == end)
return begin;
1934 if (*begin ==
'0') {
1936 if (++begin == end)
return begin;
1940 if (begin == end)
return begin;
1943 if (*begin ==
'.') {
1945 auto c = begin != end ? *begin : 0;
1946 if (
'0' <= c && c <=
'9') {
1948 }
else if (c ==
'{') {
1954 if (begin == end || *begin++ !=
'}')
1955 return handler.on_error(
"invalid format string"),
begin;
1957 return handler.on_error(
"missing precision specifier"),
begin;
1959 handler.end_precision();
1963 if (begin != end && *begin !=
'}')
1964 handler.on_type(*begin++);
1969 template <
bool IS_CONSTEXPR,
typename T,
typename Ptr = const T*>
1971 for (out = first; out != last; ++out) {
1980 const char *first,
const char *last,
char value,
const char *&out) {
1985 template <
typename Handler,
typename Char>
1990 handler.on_arg_id(
id);
1993 handler.on_error(message);
1998 template <
bool IS_CONSTEXPR,
typename Char,
typename Handler>
2003 if (begin == end)
return;
2006 if (!find<IS_CONSTEXPR>(begin, end,
'}', p))
2007 return handler_.on_text(begin, end);
2009 if (p == end || *p !=
'}')
2010 return handler_.on_error(
"unmatched '}' in format string");
2011 handler_.on_text(begin, p);
2022 const Char *p =
begin;
2023 if (*
begin !=
'{' && !find<IS_CONSTEXPR>(
begin,
end,
'{', p))
2028 return handler.on_error(
"invalid format string");
2029 if (static_cast<char>(*p) ==
'}') {
2030 handler.on_arg_id();
2031 handler.on_replacement_field(p);
2032 }
else if (*p ==
'{') {
2033 handler.on_text(p, p + 1);
2036 Char c = p !=
end ? *p : Char();
2038 handler.on_replacement_field(p);
2039 }
else if (c ==
':') {
2040 p = handler.on_format_specs(p + 1,
end);
2041 if (p ==
end || *p !=
'}')
2042 return handler.on_error(
"unknown format specifier");
2044 return handler.on_error(
"missing '}' in format string");
2051 template <
typename T,
typename ParseContext>
2056 return f.
parse(ctx);
2059 template <
typename Char,
typename ErrorHandler,
typename... Args>
2064 : arg_id_((
std::numeric_limits<unsigned>::max)()), context_(format_str, eh),
2065 parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
2070 arg_id_ = context_.next_arg_id();
2075 context_.check_arg_id(
id);
2083 context_.advance_to(begin);
2084 return arg_id_ < NUM_ARGS ?
2085 parse_funcs_[arg_id_](context_) : begin;
2089 context_.on_error(message);
2094 enum { NUM_ARGS =
sizeof...(Args) };
2097 if (arg_id_ >= NUM_ARGS)
2098 context_.on_error(
"argument index out of range");
2102 typedef const Char *(*parse_func)(parse_context_type &);
2105 parse_context_type context_;
2106 parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
2109 template <
typename Char,
typename ErrorHandler,
typename... Args>
2113 parse_format_string<true>(s, checker);
2117 template <
typename... Args,
typename S>
2118 typename std::enable_if<is_compile_string<S>::value>
::type 2123 (void)invalid_format;
2129 template <
typename Context,
typename T>
2131 std::integral_constant<bool, get_type<Context, T>::value != custom_type> {};
2133 template <
template <
typename>
class Handler,
typename Spec,
typename Context>
2141 internal::set_dynamic_spec<Handler>(
2142 value, ctx.get_arg(ref.
index), ctx.error_handler());
2145 internal::set_dynamic_spec<Handler>(
2146 value, ctx.get_arg({ref.
name.value, ref.
name.size}),
2147 ctx.error_handler());
2154 template <
typename Range>
2157 typename internal::arg_formatter_base<Range>::iterator>,
2160 typedef typename Range::value_type
char_type;
2179 : base(Range(ctx.out()), spec, ctx.locale()), ctx_(ctx) {}
2183 : base(Range(ctx.out()), &spec), ctx_(ctx) {}
2185 using base::operator();
2226 template <
typename... Args>
2228 :
std::runtime_error(
"") {
2258 template <
typename Range>
2262 typedef decltype(internal::declval<Range>().
begin()) iterator;
2267 internal::locale_ref locale_;
2278 template <
typename F>
2279 void write_padded(
const align_spec &spec, F &&f) {
2280 unsigned width = spec.
width();
2281 size_t size = f.size();
2282 size_t num_code_points = width != 0 ? f.width() : size;
2283 if (width <= num_code_points)
2285 auto &&it =
reserve(width + (size - num_code_points));
2286 char_type fill =
static_cast<char_type
>(spec.
fill());
2287 std::size_t padding = width - num_code_points;
2289 it = std::fill_n(it, padding, fill);
2292 std::size_t left_padding = padding / 2;
2293 it = std::fill_n(it, left_padding, fill);
2295 it = std::fill_n(it, padding - left_padding, fill);
2298 it = std::fill_n(it, padding, fill);
2302 template <
typename F>
2303 struct padded_int_writer {
2307 std::size_t padding;
2310 size_t size()
const {
return size_; }
2311 size_t width()
const {
return size_; }
2313 template <
typename It>
2314 void operator()(It &&it)
const {
2315 if (prefix.
size() != 0)
2316 it = internal::copy_str<char_type>(prefix.
begin(), prefix.
end(), it);
2317 it = std::fill_n(it, padding, fill);
2325 template <
typename Spec,
typename F>
2326 void write_int(
int num_digits,
string_view prefix,
2327 const Spec &spec, F f) {
2329 char_type fill =
static_cast<char_type
>(spec.fill());
2330 std::size_t padding = 0;
2332 if (spec.width() > size) {
2333 padding = spec.width() - size;
2334 size = spec.width();
2336 }
else if (spec.precision > num_digits) {
2339 fill =
static_cast<char_type
>(
'0');
2344 write_padded(as, padded_int_writer<F>{size, prefix, fill, padding, f});
2348 template <
typename Int>
2349 void write_decimal(Int value) {
2351 main_type abs_value =
static_cast<main_type
>(value);
2354 abs_value = 0 - abs_value;
2356 auto &&it =
reserve((is_negative ? 1 : 0) + static_cast<size_t>(num_digits));
2358 *it++ =
static_cast<char_type
>(
'-');
2359 it = internal::format_decimal<char_type>(it, abs_value, num_digits);
2363 template <
typename Int,
typename Spec>
2369 unsigned_type abs_value;
2371 unsigned prefix_size;
2376 template <
unsigned BITS>
2378 unsigned_type n = abs_value;
2382 }
while ((n >>= BITS) != 0);
2387 :
writer(w), spec(s), abs_value(static_cast<unsigned_type>(value)),
2392 abs_value = 0 - abs_value;
2394 prefix[0] = spec.has(
PLUS_FLAG) ?
'+' :
' ';
2403 template <
typename It>
2405 it = internal::format_decimal<char_type>(it, abs_value, num_digits);
2411 writer.write_int(num_digits, get_prefix(), spec,
2419 template <
typename It>
2421 it = internal::format_uint<4, char_type>(
2422 it,
self.abs_value, num_digits,
self.spec.type !=
'x');
2428 prefix[prefix_size++] =
'0';
2429 prefix[prefix_size++] =
static_cast<char>(spec.type);
2431 int num_digits = count_digits<4>();
2432 writer.write_int(num_digits, get_prefix(), spec,
2441 template <
typename It>
2443 it = internal::format_uint<BITS, char_type>(it, abs_value, num_digits);
2449 prefix[prefix_size++] =
'0';
2450 prefix[prefix_size++] =
static_cast<char>(spec.type);
2452 int num_digits = count_digits<1>();
2453 writer.write_int(num_digits, get_prefix(), spec,
2458 int num_digits = count_digits<3>();
2460 spec.precision <= num_digits) {
2463 prefix[prefix_size++] =
'0';
2465 writer.write_int(num_digits, get_prefix(), spec,
2469 enum { SEP_SIZE = 1 };
2476 template <
typename It>
2479 it = internal::format_decimal<char_type>(
2486 char_type sep = internal::thousands_sep<char_type>(writer.locale_);
2487 int size = num_digits + SEP_SIZE * ((num_digits - 1) / 3);
2488 writer.write_int(size, get_prefix(), spec,
2498 template <
typename T,
typename Spec>
2499 void write_int(T value,
const Spec &spec) {
2501 int_writer<T, Spec>(*
this, value, spec));
2504 enum {INF_SIZE = 3};
2506 struct inf_or_nan_writer {
2510 size_t size()
const {
2511 return static_cast<std::size_t
>(INF_SIZE + (sign ? 1 : 0));
2513 size_t width()
const {
return size(); }
2515 template <
typename It>
2516 void operator()(It &&it)
const {
2518 *it++ =
static_cast<char_type
>(sign);
2519 it = internal::copy_str<char_type>(
2520 str, str +
static_cast<std::size_t
>(INF_SIZE), it);
2524 struct double_writer {
2529 size_t size()
const {
return buffer.
size() + (sign ? 1 : 0); }
2530 size_t width()
const {
return size(); }
2532 template <
typename It>
2533 void operator()(It &&it) {
2535 *it++ =
static_cast<char_type
>(sign);
2538 it = internal::copy_str<char_type>(buffer.
begin(), buffer.
end(), it);
2543 template <
typename T>
2544 void write_double(T value,
const format_specs &spec);
2546 template <
typename Char>
2551 size_t size()
const {
return size_; }
2552 size_t width()
const {
2556 template <
typename It>
2557 void operator()(It &&it)
const {
2558 it = internal::copy_str<char_type>(s, s + size_, it);
2562 template <
typename Char>
2569 : out_(out.
begin()), locale_(loc) {}
2571 iterator
out()
const {
return out_; }
2573 void write(
int value) { write_decimal(value); }
2574 void write(
long value) { write_decimal(value); }
2575 void write(
long long value) { write_decimal(value); }
2577 void write(
unsigned value) { write_decimal(value); }
2578 void write(
unsigned long value) { write_decimal(value); }
2579 void write(
unsigned long long value) { write_decimal(value); }
2586 template <
typename T,
typename FormatSpec,
typename... FormatSpecs>
2587 typename std::enable_if<std::is_integral<T>::value,
void>
::type 2588 write(T value, FormatSpec spec, FormatSpecs... specs) {
2589 format_specs s(spec, specs...);
2591 write_int(value, s);
2613 static_assert(std::is_same<char_type, wchar_t>::value,
"");
2624 it = internal::copy_str<char_type>(value.
begin(), value.
end(), it);
2627 static_assert(std::is_same<char_type, wchar_t>::value,
"");
2633 template <
typename Char>
2635 write_padded(spec, str_writer<Char>{s, size});
2638 template <
typename Char>
2642 std::size_t size = s.
size();
2645 write(data, size, spec);
2648 template <
typename T>
2649 typename std::enable_if<std::is_same<T, void>::value>
::type 2654 write_int(reinterpret_cast<uintptr_t>(p), specs);
2696 template <
typename Range>
2697 template <
typename T>
2706 if (std::signbit(value)) {
2713 struct write_inf_or_nan_t {
2717 void operator()(
const char *str)
const {
2718 writer.write_padded(spec, inf_or_nan_writer{sign, str});
2720 } write_inf_or_nan = {*
this, spec, sign};
2724 if (internal::fputil::isnotanumber(value))
2725 return write_inf_or_nan(handler.
upper ?
"NAN" :
"nan");
2726 if (internal::fputil::isinfinity(value))
2727 return write_inf_or_nan(handler.
upper ?
"INF" :
"inf");
2730 bool use_grisu =
FMT_USE_GRISU &&
sizeof(T) <=
sizeof(
double) &&
2731 spec.
type !=
'a' && spec.
type !=
'A' &&
2734 format_specs normalized_spec(spec);
2735 normalized_spec.
type = handler.
type;
2738 size_t n = buffer.
size();
2743 *it++ =
static_cast<char_type
>(sign);
2755 write_padded(as, double_writer{n, sign, buffer});
2763 #if FMT_USE_WINDOWS_H 2799 template <
typename... Args>
2800 windows_error(
int error_code,
string_view message,
const Args &... args) {
2807 FMT_API void report_windows_error(
int error_code,
2817 enum {BUFFER_SIZE = std::numeric_limits<unsigned long long>::digits10 + 3};
2818 mutable char buffer_[BUFFER_SIZE];
2823 char *
ptr = buffer_ + (BUFFER_SIZE - 1);
2824 while (value >= 100) {
2828 unsigned index =
static_cast<unsigned>((value % 100) * 2);
2830 *--ptr = internal::data::DIGITS[index + 1];
2831 *--ptr = internal::data::DIGITS[index];
2834 *--ptr =
static_cast<char>(
'0' + value);
2837 unsigned index =
static_cast<unsigned>(value * 2);
2838 *--ptr = internal::data::DIGITS[index + 1];
2839 *--ptr = internal::data::DIGITS[index];
2843 void format_signed(
long long value) {
2844 unsigned long long abs_value =
static_cast<unsigned long long>(value);
2845 bool negative = value < 0;
2847 abs_value = 0 - abs_value;
2870 const char *
data()
const {
return str_; }
2877 buffer_[BUFFER_SIZE - 1] =
'\0';
2886 std::string
str()
const {
return std::string(str_, size()); }
2893 template <
typename T>
2896 main_type abs_value =
static_cast<main_type
>(value);
2899 abs_value = 0 - abs_value;
2901 if (abs_value < 100) {
2902 if (abs_value < 10) {
2903 *buffer++ =
static_cast<char>(
'0' + abs_value);
2906 unsigned index =
static_cast<unsigned>(abs_value * 2);
2907 *buffer++ = internal::data::DIGITS[index];
2908 *buffer++ = internal::data::DIGITS[index + 1];
2912 internal::format_decimal<char>(
2914 buffer += num_digits;
2918 template <
typename T,
typename Char>
2921 typename
std::enable_if<internal::format_type<
2922 typename buffer_context<Char>::type, T>::value>
::type> {
2926 template <
typename ParseContext>
2932 handler(handler_type(specs_, ctx),
type);
2934 auto type_spec = specs_.type;
2935 auto eh = ctx.error_handler();
2977 template <
typename FormatContext>
2978 auto format(
const T &val, FormatContext &ctx) -> decltype(ctx.out()) {
2979 internal::handle_dynamic_spec<internal::width_checker>(
2980 specs_.width_, specs_.width_ref, ctx);
2981 internal::handle_dynamic_spec<internal::precision_checker>(
2982 specs_.precision, specs_.precision_ref, ctx);
2986 internal::make_arg<FormatContext>(val));
3003 template <
typename Char =
char>
3015 template <
typename ParseContext>
3016 auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
3022 template <
typename T,
typename FormatContext>
3023 auto format(
const T &val, FormatContext &ctx) -> decltype(ctx.out()) {
3028 if (specs_.flags == 0);
3035 if (specs_.precision != -1)
3040 internal::make_arg<FormatContext>(val));
3045 template <
typename Context>
3046 void handle_specs(Context &ctx) {
3047 internal::handle_dynamic_spec<internal::width_checker>(
3048 specs_.width_, specs_.width_ref, ctx);
3049 internal::handle_dynamic_spec<internal::precision_checker>(
3050 specs_.precision, specs_.precision_ref, ctx);
3056 template <
typename Range,
typename Char>
3060 map_.init(this->args());
3063 this->on_error(
"argument not found");
3067 template <
typename ArgFormatter,
typename Char,
typename Context>
3069 typedef typename ArgFormatter::range
range;
3074 : context(r.
begin(), str, format_args, loc) {}
3078 auto out = context.out();
3080 it = std::copy_n(begin, size, it);
3081 context.advance_to(out);
3086 context.parse_context().check_arg_id(
id);
3087 arg = context.get_arg(
id);
3090 arg = context.get_arg(
id);
3094 context.parse_context().advance_to(p);
3101 auto &parse_ctx = context.parse_context();
3102 parse_ctx.advance_to(begin);
3105 return parse_ctx.begin();
3109 handler(specs_handler<Context>(specs, context),
arg.type());
3111 if (begin == end || *begin !=
'}')
3112 on_error(
"missing '}' in format string");
3113 parse_ctx.advance_to(begin);
3123 template <
typename ArgFormatter,
typename Char,
typename Context>
3125 typename ArgFormatter::range out,
3130 internal::parse_format_string<false>(format_str, h);
3137 template <
typename T>
3138 inline const void *
ptr(
const T *p) {
return p; }
3140 template <
typename It,
typename Char>
3147 : begin(begin), end(end), sep(sep) {}
3150 template <
typename It,
typename Char>
3152 formatter<typename std::iterator_traits<It>::value_type, Char> {
3153 template <
typename FormatContext>
3155 -> decltype(ctx.out()) {
3157 auto it = value.begin;
3158 auto out = ctx.out();
3159 if (it != value.end) {
3161 while (it != value.end) {
3162 out =
std::copy(value.sep.begin(), value.sep.end(), out);
3163 ctx.advance_to(out);
3171 template <
typename It>
3176 template <
typename It>
3182 #if FMT_USE_TRAILING_RETURN && (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 405) 3183 template <
typename Range>
3189 template <
typename Range>
3208 template <
typename T>
3212 writer(buf).write(value);
3219 template <
typename T>
3227 template <
typename Char, std::
size_t SIZE>
3229 return std::basic_string<Char>(buf.
data(), buf.
size());
3232 template <
typename Char>
3237 return vformat_to<arg_formatter<range>>(
3241 template <
typename S,
typename Char = FMT_CHAR(S)>
3249 typename S,
typename... Args,
3254 const Args &... args) {
3262 namespace internal {
3269 template<
typename... Ts>
3272 template <
typename T,
typename Enable =
void>
3275 template <
typename T>
3278 template <
typename T>
3280 typedef typename T::iterator_category
type;
3284 template <
typename It>
3292 template <
typename U>
3293 static decltype(*(internal::declval<U>())) test(std::input_iterator_tag);
3294 template <
typename U>
3295 static char& test(std::output_iterator_tag);
3296 template <
typename U>
3297 static const char& test(...);
3302 static const bool value = !std::is_const<result>::value;
3306 template <
typename OutputIt,
typename Char =
char>
3310 template <
typename OutputIt,
typename Char =
char>
3317 template <
typename String,
typename OutputIt,
typename... Args>
3318 inline typename std::enable_if<internal::is_output_iterator<OutputIt>::value,
3323 return vformat_to<arg_formatter<range>>(range(out),
3338 template <
typename OutputIt,
typename S,
typename... Args>
3342 format_to(OutputIt out, const S &format_str, const Args &... args) {
3350 template <
typename OutputIt>
3358 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3362 template <
typename OutputIt,
typename Char =
typename OutputIt::value_type>
3368 template <
typename OutputIt,
typename Char,
typename ...Args>
3373 typename format_to_n_context<OutputIt, Char>::type, Args...>(args...);
3376 template <
typename OutputIt,
typename Char,
typename... Args>
3377 inline typename std::enable_if<
3383 auto it =
vformat_to(It(out, n), format_str, args);
3384 return {it.base(), it.count()};
3394 template <
typename OutputIt,
typename S,
typename... Args>
3397 internal::is_output_iterator<OutputIt>::value,
3400 const Args &... args) {
3404 typename format_to_n_context<OutputIt, Char>::type, Args...> as(args...);
3409 template <
typename Char>
3422 template <
typename... Args>
3424 const Args &... args) {
3429 #if FMT_USE_USER_DEFINED_LITERALS 3430 namespace internal {
3432 # if FMT_UDL_TEMPLATE 3433 template <
typename Char, Char... CHARS>
3434 class udl_formatter {
3436 template <
typename... Args>
3437 std::basic_string<Char> operator()(
const Args &... args)
const {
3442 (void)invalid_format;
3443 return format(s, args...);
3447 template <
typename Char>
3448 struct udl_formatter {
3451 template <
typename... Args>
3452 auto operator()(Args &&... args)
const 3453 -> decltype(
format(str, std::forward<Args>(args)...)) {
3454 return format(str, std::forward<Args>(args)...);
3457 # endif // FMT_UDL_TEMPLATE 3459 template <
typename Char>
3463 template <
typename T>
3464 named_arg<T, Char> operator=(T &&value)
const {
3465 return {str, std::forward<T>(value)};
3471 inline namespace literals {
3473 # if FMT_UDL_TEMPLATE 3474 template <
typename Char, Char... CHARS>
3475 FMT_CONSTEXPR internal::udl_formatter<Char, CHARS...>
operator""_format() {
3489 inline internal::udl_formatter<char>
3490 operator"" _format(
const char *s, std::size_t) {
return {s}; }
3491 inline internal::udl_formatter<wchar_t>
3492 operator"" _format(
const wchar_t *s, std::size_t) {
return {s}; }
3493 # endif // FMT_UDL_TEMPLATE 3505 inline internal::udl_arg<char>
3506 operator"" _a(
const char *s, std::size_t) {
return {s}; }
3507 inline internal::udl_arg<wchar_t>
3508 operator"" _a(
const wchar_t *s, std::size_t) {
return {s}; }
3510 #endif // FMT_USE_USER_DEFINED_LITERALS 3513 #define FMT_STRING(s) [] { \ 3514 typedef typename std::remove_cv<std::remove_pointer< \ 3515 typename std::decay<decltype(s)>::type>::type>::type ct; \ 3516 struct str : fmt::compile_string { \ 3517 typedef ct char_type; \ 3518 FMT_CONSTEXPR operator fmt::basic_string_view<ct>() const { \ 3519 return {s, sizeof(s) / sizeof(ct) - 1}; \ 3525 #if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS 3540 # define fmt(s) FMT_STRING(s) 3543 #ifdef FMT_HEADER_ONLY 3544 # define FMT_FUNC inline 3551 #if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION 3552 # pragma GCC diagnostic pop 3555 #endif // FMT_FORMAT_H_
void operator()(unsigned id)
dynamic_specs_handler(dynamic_format_specs< char_type > &specs, ParseContext &ctx)
std::enable_if< !is_integer< T >::value, unsigned long long >::type operator()(T)
void operator()(It &&it) const
u8string_view(const char *s, size_t count)
std::numeric_limits< internal::dummy_int > fputil
std::enable_if< !std::numeric_limits< T >::is_signed, bool >::type is_negative(T)
truncating_iterator & operator++()
truncating_iterator_base(OutputIt out, std::size_t limit)
void on_dynamic_width(Id arg_id)
traits::value_type value_type
void write(wchar_t value)
T * make_checked(T *p, std::size_t)
wchar_t thousands_sep(locale_ref loc)
void parse_format_string(basic_string_view< Char > format_str, Handler &&handler)
std::size_t capacity() const
width_checker(ErrorHandler &eh)
std::enable_if< std::is_integral< T >::value, void >::type write(T value, FormatSpec spec, FormatSpecs...specs)
void operator()(basic_string_view< Char > id)
unsigned parse_nonnegative_int(const Char *&begin, const Char *end, ErrorHandler &&eh)
std::size_t count() const
precision_checker(ErrorHandler &eh)
void handle_cstring_type_spec(Char spec, Handler &&handler)
Dest bit_cast(const Source &source)
void write(std::basic_ostream< Char > &os, basic_buffer< Char > &buf)
void operator()(Char *&buffer)
void write(unsigned value)
static bool isinfinity(T x)
void write(unsigned long long value)
std::output_iterator_tag iterator_category
Allocator::value_type * allocate(Allocator &alloc, std::size_t n)
char * lg(uint32_t n, Handler h)
void on_align(alignment align)
void operator()(basic_string_view< Char > id)
OutputIt::container_type::value_type value_type
truncating_iterator & operator++()
void write(long long value)
std::enable_if< sizeof(Double)!=sizeof(uint64_t), bool >::type grisu2_format(Double, buffer &, core_format_specs)
void write(unsigned long value)
const T & const_reference
char_specs_checker(char type, ErrorHandler eh)
#define FMT_CONSTEXPR_DECL
internal::named_arg< T, char > arg(string_view name, const T &arg)
specs_checker(const Handler &handler, internal::type arg_type)
void handle_float_type_spec(char spec, Handler &&handler)
void write(basic_string_view< Char > s, const format_specs &spec=format_specs())
void on_error(const char *message)
Container & get_container(std::back_insert_iterator< Container > it)
void report_system_error(int error_code, fmt::string_view message)
void operator()(unsigned id)
std::enable_if< is_integer< T >::value, unsigned long long >::type operator()(T value)
truncating_iterator & operator=(value_type val)
int_type_checker(ErrorHandler eh)
specs_setter(basic_format_specs< Char > &specs)
#define FMT_END_NAMESPACE
bool find< false, char >(const char *first, const char *last, char value, const char *&out)
const Char * parse_width(const Char *begin, const Char *end, Handler &&handler)
std::ptrdiff_t difference_type
const ParseContext::char_type * parse_format_specs(ParseContext &ctx)
truncating_iterator & operator*()
T::iterator_category type
Range::value_type char_type
std::random_access_iterator_tag type
std::size_t formatted_size(string_view format_str, const Args &...args)
truncating_iterator(OutputIt out, std::size_t limit)
Context::char_type char_type
static bool isnotanumber(T x)
basic_memory_buffer< wchar_t > wmemory_buffer
basic_string_view< wchar_t > wstring_view
int count_digits(uint64_t n)
float_spec_handler(char t)
void operator()(It &&it) const
arg_join< It, wchar_t > join(It begin, It end, wstring_view sep)
basic_memory_buffer< char > memory_buffer
internal::result_of< Visitor(int)>::type visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg)
const Char * pointer_from(null_terminating_iterator< Char > it)
std::output_iterator_tag iterator_category
truncating_iterator_base _Unchecked_type
bool find(Ptr first, Ptr last, T value, Ptr &out)
basic_buffer< char > buffer
std::enable_if< !is_integer< T >::value, unsigned long long >::type operator()(T)
back_insert_range(typename base::iterator it)
arg_join(It begin, It end, basic_string_view< Char > sep)
value_type & operator*() const
truncating_iterator & operator++(int)
void set_dynamic_spec(T &value, basic_format_arg< Context > arg, ErrorHandler eh)
std::size_t count() const
truncating_iterator operator++(int)
format_arg_store< Context, Args... > make_format_args(const Args &...args)
std::make_unsigned< Int >::type to_unsigned(Int value)
std::basic_string< typename char_t< S >::type > format(const S &format_str, const Args &...args)
float_type_checker(ErrorHandler eh)
void write(wstring_view value)
void write(string_view value)
basic_writer< back_insert_range< internal::buffer > > writer
ParseContext::char_type char_type
basic_format_specs< Char > & specs_
It format_uint(It out, UInt value, int num_digits, bool upper=false)
counting_iterator & operator++()
add_thousands_sep(basic_string_view< Char > sep)
size_t count_code_points(basic_string_view< char8_t > s)
Char thousands_sep_impl(locale_ref loc)
bool do_check_format_string(basic_string_view< Char > s, ErrorHandler eh=ErrorHandler())
basic_format_specs< char > format_specs
Allocator get_allocator() const
bool is_name_start(Char c)
void operator()(It &&it) const
cstring_type_checker(ErrorHandler eh)
counting_iterator _Unchecked_type
void on_error(const char *message)
arg_ref(basic_string_view< Char > nm)
void on_dynamic_precision(Id arg_id)
specs_checker(const specs_checker &other)
void sprintf_format(Double value, internal::buffer &buf, core_format_specs spec)
output_range(OutputIt it)
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
char8_t to_char8_t(char c)
void set(T *buf_data, std::size_t buf_capacity)
std::enable_if< internal::is_string< S >::value &&internal::is_output_iterator< OutputIt >::value, format_to_n_result< OutputIt > >::type format_to_n(OutputIt out, std::size_t n, const S &format_str, const Args &...args)
void operator()(basic_string_view< Char > id)
string_view_t & to_string_view(spdlog::level::level_enum l) noexcept
std::wstring to_wstring(const T &value)
const void * ptr(const T *p)
std::enable_if< internal::is_output_iterator< OutputIt >::value, format_to_n_result< OutputIt > >::type vformat_to_n(OutputIt out, std::size_t n, basic_string_view< Char > format_str, typename format_to_n_args< OutputIt, Char >::type args)
specs_handler(basic_format_specs< char_type > &specs, Context &ctx)
void check_string_type_spec(Char spec, ErrorHandler &&eh)
void handle_dynamic_spec(Spec &value, arg_ref< typename Context::char_type > ref, Context &ctx)
std::basic_string< Char > to_string(const basic_memory_buffer< Char, SIZE > &buf)
specs_setter(const specs_setter &other)
void on_align(alignment align)
Iterator & reserve(Iterator &it, std::size_t)
void on_precision(unsigned precision)
void on_dynamic_precision(Id arg_id)
string_value< Char > name
system_error(int error_code, string_view message, const Args &...args)
void operator()(It &&it) const
bool is_arithmetic(type t)
void on_error(const char *message)
void operator()(unsigned id)
void copy(const RangeT &range, OutputIterator out)
basic_string_view< Char > sep
std::enable_if< internal::is_string< S >::value &&internal::is_output_iterator< OutputIt >::value, OutputIt >::type format_to(OutputIt out, const S &format_str, const Args &...args)
#define FMT_ENABLE_IF_T(B, T)
counting_iterator operator++(int)
void write(const Char *s, std::size_t size, const align_spec &spec)
basic_writer< back_insert_range< internal::wbuffer > > wwriter
#define FMT_ASSERT(condition, message)
const Char * parse_align(const Char *begin, const Char *end, Handler &&handler)
const Char * data() const
#define FMT_BEGIN_NAMESPACE
std::enable_if< is_integer< T >::value, unsigned long long >::type operator()(T value)
void on_error(const char *message)
void handle_int_type_spec(char spec, Handler &&handler)
void on_dynamic_width(Id arg_id)
std::enable_if< internal::is_output_iterator< OutputIt >::value, OutputIt >::type vformat_to(OutputIt out, const String &format_str, typename format_args_t< OutputIt, typename char_t< String >::type >::type args)
void format_system_error(internal::buffer &out, int error_code, string_view message)
void handle_char_specs(const basic_format_specs< Char > *specs, Handler &&handler)
u8string_view(const char *s)
const Char * parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler)
void check_pointer_type_spec(Char spec, ErrorHandler &&eh)
std::enable_if<!is_compile_string< S >::value >::type check_format_string(const S &)
void on_error(const char *message)
precision_adapter(SpecHandler &h)
basic_memory_buffer(basic_memory_buffer &&other)
void on_width(unsigned width)
basic_string_view< char > string_view
width_adapter(SpecHandler &h)
basic_writer(Range out, internal::locale_ref loc=internal::locale_ref())
std::enable_if< needs_conversion< InputIt, OutChar >::value, OutputIt >::type copy_str(InputIt begin, InputIt end, OutputIt it)
void format_decimal(char *&buffer, T value)
basic_memory_buffer & operator=(basic_memory_buffer &&other)
truncating_iterator(OutputIt out, std::size_t limit)
std::enable_if< std::is_same< T, void >::value >::type write(const T *p)
arg_ref & operator=(unsigned idx)
format_arg_store< typename format_to_n_context< OutputIt, Char >::type, Args... > make_format_to_n_args(const Args &...args)
basic_memory_buffer(const Allocator &alloc=Allocator())
void write(long double value)
dynamic_specs_handler(const dynamic_specs_handler &other)
Container::value_type value_type
back_insert_range(Container &c)
basic_format_context< OutputIt, Char > type