44 # define FMT_SECURE_SCL _SECURE_SCL
46 # define FMT_SECURE_SCL 0
54 # define FMT_MSC_VER _MSC_VER
56 # define FMT_MSC_VER 0
59 #if FMT_MSC_VER && FMT_MSC_VER <= 1500
60 typedef unsigned __int32 uint32_t;
61 typedef unsigned __int64 uint64_t;
62 typedef __int64 intmax_t;
67 #if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
69 # define FMT_API __declspec(dllexport)
70 # elif defined(FMT_SHARED)
71 # define FMT_API __declspec(dllimport)
79 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
80 # define FMT_GCC_EXTENSION __extension__
81 # if FMT_GCC_VERSION >= 406
82 # pragma GCC diagnostic push
85 # pragma GCC diagnostic ignored "-Wlong-long"
88 # pragma GCC diagnostic ignored "-Wshadow"
91 # pragma GCC diagnostic ignored "-Wsign-conversion"
93 # if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__
94 # define FMT_HAS_GXX_CXX11 1
97 # define FMT_GCC_EXTENSION
100 #if defined(__INTEL_COMPILER)
101 # define FMT_ICC_VERSION __INTEL_COMPILER
103 # define FMT_ICC_VERSION __ICL
106 #if defined(__clang__) && !defined(FMT_ICC_VERSION)
107 # pragma clang diagnostic push
108 # pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
109 # pragma clang diagnostic ignored "-Wpadded"
112 #ifdef __GNUC_LIBSTD__
113 # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
117 # define FMT_HAS_FEATURE(x) __has_feature(x)
119 # define FMT_HAS_FEATURE(x) 0
123 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
125 # define FMT_HAS_BUILTIN(x) 0
128 #ifdef __has_cpp_attribute
129 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
131 # define FMT_HAS_CPP_ATTRIBUTE(x) 0
134 #ifndef FMT_USE_VARIADIC_TEMPLATES
138 # define FMT_USE_VARIADIC_TEMPLATES \
139 (FMT_HAS_FEATURE(cxx_variadic_templates) || \
140 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800)
143 #ifndef FMT_USE_RVALUE_REFERENCES
146 # if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
147 # define FMT_USE_RVALUE_REFERENCES 0
149 # define FMT_USE_RVALUE_REFERENCES \
150 (FMT_HAS_FEATURE(cxx_rvalue_references) || \
151 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600)
155 #if FMT_USE_RVALUE_REFERENCES
160 #if defined(__GNUC__) && !defined(__EXCEPTIONS)
161 # define FMT_EXCEPTIONS 0
163 #if FMT_MSC_VER && !_HAS_EXCEPTIONS
164 # define FMT_EXCEPTIONS 0
166 #ifndef FMT_EXCEPTIONS
167 # define FMT_EXCEPTIONS 1
172 # define FMT_THROW(x) throw x
174 # define FMT_THROW(x) assert(false)
179 #ifndef FMT_USE_NOEXCEPT
180 # define FMT_USE_NOEXCEPT 0
185 # if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
186 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
188 # define FMT_NOEXCEPT noexcept
190 # define FMT_NOEXCEPT throw()
193 # define FMT_NOEXCEPT
199 #ifndef FMT_USE_DELETED_FUNCTIONS
200 # define FMT_USE_DELETED_FUNCTIONS 0
203 #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \
204 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1800
205 # define FMT_DELETED_OR_UNDEFINED = delete
206 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
207 TypeName(const TypeName&) = delete; \
208 TypeName& operator=(const TypeName&) = delete
210 # define FMT_DELETED_OR_UNDEFINED
211 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
212 TypeName(const TypeName&); \
213 TypeName& operator=(const TypeName&)
216 #ifndef FMT_USE_USER_DEFINED_LITERALS
221 # define FMT_USE_USER_DEFINED_LITERALS \
222 FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
223 (FMT_HAS_FEATURE(cxx_user_literals) || \
224 (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900) && \
225 (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
229 # define FMT_ASSERT(condition, message) assert((condition) && message)
232 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
233 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
236 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
237 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
244 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL)
249 # pragma intrinsic(_BitScanReverse)
250 inline uint32_t clz(uint32_t x) {
252 _BitScanReverse(&r, x);
258 # pragma warning(suppress: 6102)
261 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
264 # pragma intrinsic(_BitScanReverse64)
267 inline uint32_t clzll(uint64_t x) {
270 _BitScanReverse64(&r, x);
273 if (_BitScanReverse(&r,
static_cast<uint32_t
>(x >> 32)))
274 return 63 - (r + 32);
277 _BitScanReverse(&r,
static_cast<uint32_t
>(x));
284 # pragma warning(suppress: 6102)
287 # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
296 operator int()
const {
return 0; }
311 template <
typename T>
322 class numeric_limits<
fmt::internal::DummyInt> :
323 public std::numeric_limits<int> {
326 template <
typename T>
332 sizeof(
isinf(x)) ==
sizeof(
int))) {
333 return isinf(x) != 0;
335 return !
_finite(
static_cast<double>(x));
339 template <
typename T>
343 sizeof(
isnan(x)) ==
sizeof(
int))) {
344 return isnan(x) != 0;
346 return _isnan(
static_cast<double>(x)) != 0;
354 if (x < 0)
return true;
355 if (!isnotanumber(x))
return false;
356 int dec = 0, sign = 0;
358 _ecvt_s(buffer,
sizeof(buffer), x, 0, &dec, &sign);
371 #if FMT_USE_RVALUE_REFERENCES
375 template <
typename Char>
381 template <
typename Char>
384 template <
typename CharType,
412 template <
typename Char>
429 : data_(s), size_(
std::char_traits<Char>::length(s)) {}
437 : data_(s.c_str()), size_(s.size()) {}
445 return std::basic_string<Char>(data_, size_);
449 const Char *
data()
const {
return data_; }
452 std::size_t
size()
const {
return size_; }
456 std::size_t size = size_ < other.
size_ ? size_ : other.
size_;
457 int result = std::char_traits<Char>::compare(data_, other.
data_, size);
459 result = size_ == other.
size_ ? 0 : (size_ < other.
size_ ? -1 : 1);
511 template <
typename Char>
528 const Char *
c_str()
const {
return data_; }
538 :
std::runtime_error(message.c_str()) {}
545 template <
typename T>
548 #define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
550 struct MakeUnsigned<T> { typedef U Type; }
560 template <
typename Int>
572 template <
typename T>
573 inline stdext::checked_array_iterator<T*>
make_ptr(T *ptr, std::size_t size) {
574 return stdext::checked_array_iterator<T*>(ptr, size);
577 template <
typename T>
578 inline T *
make_ptr(T *ptr, std::size_t) {
return ptr; }
587 template <
typename T>
597 Buffer(T *ptr = 0, std::size_t capacity = 0)
598 : ptr_(ptr), size_(0), capacity_(capacity) {}
606 virtual void grow(std::size_t size) = 0;
612 std::size_t
size()
const {
return size_; }
621 if (new_size > capacity_)
632 if (capacity > capacity_)
639 if (size_ == capacity_)
641 ptr_[size_++] =
value;
645 template <
typename U>
646 void append(
const U *begin,
const U *end);
649 const T &
operator[](std::size_t index)
const {
return ptr_[index]; }
652 template <
typename T>
653 template <
typename U>
656 if (new_size > capacity_)
658 std::uninitialized_copy(begin, end,
667 template <
typename T, std::
size_t SIZE,
typename Allocator = std::allocator<T> >
674 if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_);
678 void grow(std::size_t size);
682 : Allocator(alloc),
Buffer<T>(data_, SIZE) {}
685 #if FMT_USE_RVALUE_REFERENCES
689 Allocator &this_alloc = *
this, &other_alloc = other;
691 this->size_ = other.
size_;
695 std::uninitialized_copy(other.
data_, other.
data_ + this->size_,
698 this->ptr_ = other.
ptr_;
711 assert(
this != &other);
722 template <
typename T, std::
size_t SIZE,
typename Allocator>
724 std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
725 if (size > new_capacity)
727 T *new_ptr = this->allocate(new_capacity);
729 std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
731 std::size_t old_capacity = this->capacity_;
732 T *old_ptr = this->ptr_;
733 this->capacity_ = new_capacity;
734 this->ptr_ = new_ptr;
738 if (old_ptr != data_)
739 Allocator::deallocate(old_ptr, old_capacity);
743 template <
typename Char>
749 FMT_API void grow(std::size_t size);
752 template <
typename Char>
756 typedef stdext::checked_array_iterator<Char*>
CharPtr;
763 template <
typename Char>
776 template <
typename T>
777 FMT_API static int format_float(
char *buffer, std::size_t size,
778 const char *
format,
unsigned width,
int precision, T
value);
787 template <
typename T>
788 FMT_API static int format_float(
wchar_t *buffer, std::size_t size,
789 const wchar_t *
format,
unsigned width,
int precision, T
value);
793 template <
bool IsSigned>
795 template <
typename T>
801 template <
typename T>
807 template <
typename T>
813 template <
bool FitsIn32Bits>
819 template <
typename T>
831 template <
typename T =
void>
833 static const uint32_t POWERS_OF_10_32[];
834 static const uint64_t POWERS_OF_10_64[];
835 static const char DIGITS[];
838 #ifndef FMT_USE_EXTERN_TEMPLATES
841 # define FMT_USE_EXTERN_TEMPLATES (__clang__ && FMT_USE_VARIADIC_TEMPLATES)
844 #if FMT_USE_EXTERN_TEMPLATES
850 #ifdef FMT_BUILTIN_CLZLL
856 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
857 return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1;
867 if (n < 10)
return count;
868 if (n < 100)
return count + 1;
869 if (n < 1000)
return count + 2;
870 if (n < 10000)
return count + 3;
877 #ifdef FMT_BUILTIN_CLZ
880 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
881 return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
887 template <
typename Char>
902 template <
typename Char>
904 if (++digit_index_ % 3 != 0)
906 buffer -= sep_.
size();
907 std::uninitialized_copy(sep_.
data(), sep_.
data() + sep_.
size(),
915 template <
typename UInt,
typename Char,
typename ThousandsSep>
918 buffer += num_digits;
919 while (
value >= 100) {
923 unsigned index =
static_cast<unsigned>((
value % 100) * 2);
925 *--buffer = Data::DIGITS[index + 1];
927 *--buffer = Data::DIGITS[index];
931 *--buffer =
static_cast<char>(
'0' +
value);
934 unsigned index =
static_cast<unsigned>(
value * 2);
935 *--buffer = Data::DIGITS[index + 1];
936 *--buffer = Data::DIGITS[index];
939 template <
typename UInt,
typename Char>
945 # define FMT_USE_WINDOWS_H 0
946 #elif !defined(FMT_USE_WINDOWS_H)
947 # define FMT_USE_WINDOWS_H 1
952 #if FMT_USE_WINDOWS_H
962 size_t size()
const {
return buffer_.
size() - 1; }
963 const wchar_t *c_str()
const {
return &buffer_[0]; }
964 std::wstring str()
const {
return std::wstring(&buffer_[0], size()); }
977 size_t size()
const {
return buffer_.
size() - 1; }
978 const char *c_str()
const {
return &buffer_[0]; }
979 std::string str()
const {
return std::string(&buffer_[0], size()); }
993 template <
typename Char>
999 typedef void (*FormatFunc)(
1000 void *formatter,
const void *
arg,
void *format_str_ptr);
1025 INT, UINT, LONG_LONG,
ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
1038 template <
typename Char>
1041 template <
typename T =
void>
1046 template <
typename T,
typename Char>
1052 template <
typename T>
1061 template <
typename T>
1068 template<
typename T,
bool ENABLE_CONVERSION>
1073 template<
typename T,
bool ENABLE_CONVERSION>
1078 template<
typename T>
1086 template<
typename T>
1088 enum { enable_conversion =
sizeof(
convert(get<T>())) ==
sizeof(
Yes) };
1092 #define FMT_DISABLE_CONVERSION_TO_INT(Type) \
1094 struct ConvertToInt<Type> { enum { value = 0 }; }
1101 template<
bool B,
class T =
void>
1107 template<
bool B,
class T,
class F>
1110 template<
class T,
class F>
1127 template <
typename LConv>
1130 return lc->thousands_sep;
1136 template <
typename Formatter>
1139 typedef typename Formatter::Char
Char;
1147 template <
typename T>
1149 template <
typename T>
1156 #if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED)
1165 string.value = str.
data();
1166 string.size = str.
size();
1170 wstring.value = str.
data();
1171 wstring.size = str.
size();
1175 template <
typename T>
1177 void *formatter,
const void *
arg,
void *format_str_ptr) {
1178 format(*
static_cast<Formatter*
>(formatter),
1179 *
static_cast<const Char**
>(format_str_ptr),
1180 *
static_cast<const T*
>(
arg));
1186 #define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \
1187 MakeValue(Type value) { field = rhs; } \
1188 static uint64_t type(Type) { return Arg::TYPE; }
1190 #define FMT_MAKE_VALUE(Type, field, TYPE) \
1191 FMT_MAKE_VALUE_(Type, field, TYPE, value)
1202 if (
check(
sizeof(
long) ==
sizeof(
int)))
1203 int_value =
static_cast<int>(
value);
1205 long_long_value =
value;
1208 return sizeof(long) ==
sizeof(
int) ? Arg::INT : Arg::LONG_LONG;
1212 if (
check(
sizeof(
unsigned long) ==
sizeof(
unsigned)))
1213 uint_value =
static_cast<unsigned>(
value);
1215 ulong_long_value =
value;
1217 static uint64_t
type(
unsigned long) {
1218 return sizeof(
unsigned long) ==
sizeof(
unsigned) ?
1219 Arg::UINT : Arg::ULONG_LONG;
1231 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
1235 static uint64_t
type(
wchar_t) {
return Arg::CHAR; }
1238 #define FMT_MAKE_STR_VALUE(Type, TYPE) \
1239 MakeValue(Type value) { set_string(value); } \
1240 static uint64_t type(Type) { return Arg::TYPE; }
1250 #define FMT_MAKE_WSTR_VALUE(Type, TYPE) \
1251 MakeValue(typename WCharHelper<Type, Char>::Supported value) { \
1252 set_string(value); \
1254 static uint64_t type(Type) { return Arg::TYPE; }
1264 template <
typename T>
1268 custom.value = &
value;
1269 custom.format = &format_custom_arg<T>;
1272 template <
typename T>
1278 template <
typename T>
1285 template <
typename Char_>
1288 template <
typename Char_>
1292 template <
typename Formatter>
1299 template <
typename T>
1306 template <
typename Char>
1310 template <
typename T>
1321 template <typename Impl, typename Char>
1324 template <typename Char>
1345 unsigned shift = index * 4;
1346 uint64_t mask = 0xf;
1348 (types_ & (mask << shift)) >> shift);
1351 template <
typename Char>
1356 enum { MAX_PACKED_ARGS = 16 };
1361 : types_(types), values_(values) {}
1363 : types_(types), args_(args) {}
1369 bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE;
1370 if (index < MAX_PACKED_ARGS) {
1371 Arg::Type arg_type = type(index);
1373 if (arg_type != Arg::NONE)
1374 val = use_values ? values_[index] : args_[index];
1375 arg.type = arg_type;
1381 arg.type = Arg::NONE;
1384 for (
unsigned i = MAX_PACKED_ARGS; i <= index; ++i) {
1385 if (args_[i].type == Arg::NONE)
1388 return args_[index];
1392 #define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
1418 template <
typename Impl,
typename Result>
1462 template <
typename T>
1478 template <
typename T>
1519 case Arg::NAMED_ARG:
1526 case Arg::LONG_LONG:
1528 case Arg::ULONG_LONG:
1536 case Arg::LONG_DOUBLE:
1567 template <
char TYPE>
1572 bool flag(
unsigned)
const {
return false; }
1584 WidthSpec(
unsigned width,
wchar_t fill) : width_(width), fill_(fill) {}
1586 unsigned width()
const {
return width_; }
1587 wchar_t fill()
const {
return fill_; }
1595 :
WidthSpec(width, fill), align_(align) {}
1603 template <
char TYPE>
1607 bool flag(
unsigned)
const {
return false; }
1618 unsigned width = 0,
char type = 0,
wchar_t fill =
' ')
1619 :
AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
1621 bool flag(
unsigned f)
const {
return (flags_ & f) != 0; }
1623 char type()
const {
return type_; }
1627 template <
typename T,
typename SpecT = TypeSpec<0>,
typename Char =
char>
1634 : SpecT(spec), value_(val) {}
1640 template <
typename Char>
1646 template <
typename FillChar>
1652 const Char *
str()
const {
return str_; }
1658 IntFormatSpec<int, TypeSpec<'b'> >
bin(
int value);
1663 IntFormatSpec<int, TypeSpec<'o'> >
oct(
int value);
1669 IntFormatSpec<int, TypeSpec<'x'> >
hex(
int value);
1675 IntFormatSpec<int, TypeSpec<'X'> >
hexu(
int value);
1691 template <
char TYPE_CODE,
typename Char>
1692 IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char>
pad(
1693 int value,
unsigned width, Char fill =
' ');
1695 #define FMT_DEFINE_INT_FORMATTERS(TYPE) \
1696 inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
1697 return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
1700 inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
1701 return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
1704 inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \
1705 return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \
1708 inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \
1709 return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \
1712 template <char TYPE_CODE> \
1713 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \
1714 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \
1715 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \
1716 f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \
1723 template <char TYPE_CODE, typename Char> \
1724 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \
1725 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f, \
1726 unsigned width, Char fill) { \
1727 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \
1728 f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \
1731 inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \
1732 TYPE value, unsigned width) { \
1733 return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
1734 value, AlignTypeSpec<0>(width, ' ')); \
1737 template <typename Char> \
1738 inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \
1739 TYPE value, unsigned width, Char fill) { \
1740 return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \
1741 value, AlignTypeSpec<0>(width, fill)); \
1763 template <
typename Char>
1765 const Char *str,
unsigned width, Char fill =
' ') {
1770 const wchar_t *str,
unsigned width,
char fill =
' ') {
1776 template <
typename Char>
1781 typedef typename MapType::value_type
Pair;
1790 for (
typename MapType::const_iterator
it = map_.begin(), end = map_.end();
1792 if (
it->first == name)
1799 template <
typename Impl,
typename Char>
1810 writer_.
write_int(
reinterpret_cast<uintptr_t
>(p), spec_);
1818 const char *str_value =
value ?
"true" :
"false";
1830 : writer_(w), spec_(s) {}
1832 template <
typename T>
1835 template <
typename T>
1840 return visit_any_int(
value);
1854 CharPtr out = CharPtr();
1865 std::uninitialized_fill_n(out +
CHAR_SIZE,
1875 if (spec_.
type_ ==
'p')
1876 return write_pointer(
value);
1893 write_pointer(
value);
1903 FMT_API Arg do_get_arg(
unsigned arg_index,
const char *&error);
1910 next_arg_index_ = 0;
1915 if (next_arg_index_ >= 0)
1917 error =
"cannot switch from manual to automatic argument indexing";
1924 return check_no_auto_index(error) ? do_get_arg(arg_index, error) :
Arg();
1928 if (next_arg_index_ > 0) {
1929 error =
"cannot switch from automatic to manual argument indexing";
1932 next_arg_index_ = -1;
1936 template <
typename Char>
1961 template <
typename Impl,
typename Char>
1979 formatter_(formatter), format_(
fmt) {}
1988 template <
typename Char>
1989 class ArgFormatter :
public BasicArgFormatter<ArgFormatter<Char>, Char> {
1998 template <
typename CharType,
typename ArgFormatter>
1999 class BasicFormatter :
private internal::FormatterBase {
2010 using internal::FormatterBase::get_arg;
2045 # define FMT_GEN(n, f) FMT_GEN##n(f)
2046 # define FMT_GEN1(f) f(0)
2047 # define FMT_GEN2(f) FMT_GEN1(f), f(1)
2048 # define FMT_GEN3(f) FMT_GEN2(f), f(2)
2049 # define FMT_GEN4(f) FMT_GEN3(f), f(3)
2050 # define FMT_GEN5(f) FMT_GEN4(f), f(4)
2051 # define FMT_GEN6(f) FMT_GEN5(f), f(5)
2052 # define FMT_GEN7(f) FMT_GEN6(f), f(6)
2053 # define FMT_GEN8(f) FMT_GEN7(f), f(7)
2054 # define FMT_GEN9(f) FMT_GEN8(f), f(8)
2055 # define FMT_GEN10(f) FMT_GEN9(f), f(9)
2056 # define FMT_GEN11(f) FMT_GEN10(f), f(10)
2057 # define FMT_GEN12(f) FMT_GEN11(f), f(11)
2058 # define FMT_GEN13(f) FMT_GEN12(f), f(12)
2059 # define FMT_GEN14(f) FMT_GEN13(f), f(13)
2060 # define FMT_GEN15(f) FMT_GEN14(f), f(14)
2065 template <
typename T>
2070 template <
unsigned N,
bool= (N < ArgList::MAX_PACKED_ARGS)>
2073 template <
unsigned N>
2077 template <
typename Formatter,
typename T>
2091 template <
unsigned N>
2095 template <
typename Formatter,
typename T>
2099 #if FMT_USE_VARIADIC_TEMPLATES
2100 template <
typename Arg,
typename... Args>
2101 inline uint64_t
make_type(
const Arg &first,
const Args & ... tail) {
2112 template <
typename T>
2116 # define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType()
2119 return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) |
2120 (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) |
2121 (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) |
2122 (t12.type << 48) | (t13.type << 52) | (t14.type << 56);
2127 # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
2128 # define FMT_MAKE_ARG_TYPE(n) T##n
2129 # define FMT_MAKE_ARG(n) const T##n &v##n
2130 # define FMT_ASSIGN_char(n) \
2131 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<char> >(v##n)
2132 # define FMT_ASSIGN_wchar_t(n) \
2133 arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<wchar_t> >(v##n)
2135 #if FMT_USE_VARIADIC_TEMPLATES
2137 # define FMT_VARIADIC_VOID(func, arg_type) \
2138 template <typename... Args> \
2139 void func(arg_type arg0, const Args & ... args) { \
2140 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2141 typename ArgArray::Type array{ \
2142 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2143 func(arg0, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2147 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2148 template <typename... Args> \
2149 ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
2150 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2151 typename ArgArray::Type array{ \
2152 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2153 func(arg0, arg1, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2158 # define FMT_MAKE_REF(n) \
2159 fmt::internal::MakeValue< fmt::BasicFormatter<Char> >(v##n)
2160 # define FMT_MAKE_REF2(n) v##n
2164 # define FMT_WRAP1(func, arg_type, n) \
2165 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2166 inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2167 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2168 func(arg1, fmt::ArgList( \
2169 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2173 # define FMT_VARIADIC_VOID(func, arg_type) \
2174 inline void func(arg_type arg) { func(arg, fmt::ArgList()); } \
2175 FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \
2176 FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \
2177 FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \
2178 FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \
2179 FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10)
2181 # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
2182 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2183 ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2184 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2185 func(arg0, arg1, fmt::ArgList( \
2186 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2190 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2191 FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \
2192 FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \
2193 FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \
2194 FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \
2195 FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \
2196 FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \
2197 FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \
2198 FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \
2199 FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \
2200 FMT_CTOR(ctor, func, arg0_type, arg1_type, 10)
2205 #define FMT_FOR_EACH1(f, x0) f(x0, 0)
2206 #define FMT_FOR_EACH2(f, x0, x1) \
2207 FMT_FOR_EACH1(f, x0), f(x1, 1)
2208 #define FMT_FOR_EACH3(f, x0, x1, x2) \
2209 FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2)
2210 #define FMT_FOR_EACH4(f, x0, x1, x2, x3) \
2211 FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3)
2212 #define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \
2213 FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4)
2214 #define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \
2215 FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5)
2216 #define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \
2217 FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6)
2218 #define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \
2219 FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7)
2220 #define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \
2221 FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8)
2222 #define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \
2223 FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
2260 init(error_code, message,
ArgList());
2266 int error_code()
const {
return error_code_; }
2306 template <
typename Char>
2318 static Char *
get(
CharPtr p) {
return p.base(); }
2320 static Char *
get(Char *p) {
return p; }
2325 static CharPtr fill_padding(CharPtr buffer,
2326 unsigned total_size, std::size_t content_size,
wchar_t fill);
2331 std::size_t size = buffer_.
size();
2332 buffer_.
resize(size + n);
2337 template <
typename UInt>
2340 Char *ptr =
get(grow_buffer(prefix_size + num_digits));
2346 template <
typename Int>
2349 MainType abs_value =
static_cast<MainType
>(
value);
2351 abs_value = 0 - abs_value;
2352 *write_unsigned_decimal(abs_value, 1) =
'-';
2354 write_unsigned_decimal(abs_value, 0);
2360 const EmptySpec &,
const char *prefix,
unsigned prefix_size) {
2361 unsigned size = prefix_size + num_digits;
2362 CharPtr p = grow_buffer(size);
2363 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2364 return p + size - 1;
2367 template <
typename Spec>
2368 CharPtr prepare_int_buffer(
unsigned num_digits,
2369 const Spec &spec,
const char *prefix,
unsigned prefix_size);
2372 template <
typename T,
typename Spec>
2373 void write_int(T
value, Spec spec);
2376 template <
typename T>
2380 template <
typename StrChar>
2381 CharPtr write_str(
const StrChar *s, std::size_t size,
const AlignSpec &spec);
2383 template <
typename StrChar>
2398 *format_ptr++ =
'L';
2401 template<
typename T>
2404 template <
typename Impl,
typename Char_>
2407 template <
typename Impl,
typename Char_>
2440 std::size_t size = buffer_.
size();
2442 buffer_[size] =
'\0';
2451 std::basic_string<Char>
str()
const {
2452 return std::basic_string<Char>(&buffer_[0], buffer_.
size());
2486 write_decimal(
value);
2490 return *this << IntFormatSpec<unsigned>(
value);
2493 write_decimal(
value);
2497 return *this << IntFormatSpec<unsigned long>(
value);
2500 write_decimal(
value);
2510 return *this << IntFormatSpec<ULongLong>(
value);
2549 const Char *str =
value.data();
2556 const char *str =
value.data();
2561 template <
typename T,
typename Spec,
typename FillChar>
2564 write_int(spec.
value(), spec);
2568 template <
typename StrChar>
2570 const StrChar *s = spec.
str();
2571 write_str(s, std::char_traits<Char>::length(s), spec);
2580 template <
typename Char>
2581 template <
typename StrChar>
2583 const StrChar *s, std::size_t size,
const AlignSpec &spec) {
2585 if (spec.
width() > size) {
2586 out = grow_buffer(spec.
width());
2589 std::uninitialized_fill_n(out, spec.
width() - size, fill);
2590 out += spec.
width() - size;
2592 out = fill_padding(out, spec.
width(), size, fill);
2594 std::uninitialized_fill_n(out + size, spec.
width() - size, fill);
2597 out = grow_buffer(size);
2599 std::uninitialized_copy(s, s + size, out);
2603 template <
typename Char>
2604 template <
typename StrChar>
2611 const StrChar *str_value = s.
value;
2612 std::size_t str_size = s.
size;
2613 if (str_size == 0) {
2619 std::size_t precision =
static_cast<std::size_t
>(spec.
precision_);
2620 if (spec.
precision_ >= 0 && precision < str_size)
2621 str_size = precision;
2622 write_str(str_value, str_size, spec);
2625 template <
typename Char>
2628 CharPtr buffer,
unsigned total_size,
2629 std::size_t content_size,
wchar_t fill) {
2630 std::size_t padding = total_size - content_size;
2631 std::size_t left_padding = padding / 2;
2633 std::uninitialized_fill_n(buffer, left_padding, fill_char);
2634 buffer += left_padding;
2636 std::uninitialized_fill_n(buffer + content_size,
2637 padding - left_padding, fill_char);
2641 template <
typename Char>
2642 template <
typename Spec>
2645 unsigned num_digits,
const Spec &spec,
2646 const char *prefix,
unsigned prefix_size) {
2647 unsigned width = spec.width();
2650 if (spec.precision() >
static_cast<int>(num_digits)) {
2653 if (prefix_size > 0 && prefix[prefix_size - 1] ==
'0')
2655 unsigned number_size =
2658 if (number_size >= width)
2659 return prepare_int_buffer(num_digits, subspec, prefix, prefix_size);
2661 unsigned fill_size = width - number_size;
2663 CharPtr p = grow_buffer(fill_size);
2664 std::uninitialized_fill(p, p + fill_size, fill);
2666 CharPtr result = prepare_int_buffer(
2667 num_digits, subspec, prefix, prefix_size);
2669 CharPtr p = grow_buffer(fill_size);
2670 std::uninitialized_fill(p, p + fill_size, fill);
2674 unsigned size = prefix_size + num_digits;
2675 if (width <= size) {
2676 CharPtr p = grow_buffer(size);
2677 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2678 return p + size - 1;
2680 CharPtr p = grow_buffer(width);
2683 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2685 std::uninitialized_fill(p, end, fill);
2687 p = fill_padding(p, width, size, fill);
2688 std::uninitialized_copy(prefix, prefix + prefix_size, p);
2692 if (prefix_size != 0) {
2693 p = std::uninitialized_copy(prefix, prefix + prefix_size, p);
2694 size -= prefix_size;
2697 std::uninitialized_copy(prefix, prefix + prefix_size, end - size);
2699 std::uninitialized_fill(p, end - size, fill);
2705 template <
typename Char>
2706 template <
typename T,
typename Spec>
2708 unsigned prefix_size = 0;
2710 UnsignedType abs_value =
static_cast<UnsignedType
>(
value);
2711 char prefix[4] =
"";
2715 abs_value = 0 - abs_value;
2717 prefix[0] = spec.flag(
PLUS_FLAG) ?
'+' :
' ';
2720 switch (spec.type()) {
2723 CharPtr p = prepare_int_buffer(num_digits, spec, prefix, prefix_size) + 1;
2727 case 'x':
case 'X': {
2728 UnsignedType n = abs_value;
2730 prefix[prefix_size++] =
'0';
2731 prefix[prefix_size++] = spec.type();
2733 unsigned num_digits = 0;
2736 }
while ((n >>= 4) != 0);
2737 Char *p =
get(prepare_int_buffer(
2738 num_digits, spec, prefix, prefix_size));
2740 const char *digits = spec.type() ==
'x' ?
2741 "0123456789abcdef" :
"0123456789ABCDEF";
2743 *p-- = digits[n & 0xf];
2744 }
while ((n >>= 4) != 0);
2747 case 'b':
case 'B': {
2748 UnsignedType n = abs_value;
2750 prefix[prefix_size++] =
'0';
2751 prefix[prefix_size++] = spec.type();
2753 unsigned num_digits = 0;
2756 }
while ((n >>= 1) != 0);
2757 Char *p =
get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2760 *p-- =
static_cast<Char
>(
'0' + (n & 1));
2761 }
while ((n >>= 1) != 0);
2765 UnsignedType n = abs_value;
2767 prefix[prefix_size++] =
'0';
2768 unsigned num_digits = 0;
2771 }
while ((n >>= 3) != 0);
2772 Char *p =
get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2775 *p-- =
static_cast<Char
>(
'0' + (n & 7));
2776 }
while ((n >>= 3) != 0);
2782 unsigned size =
static_cast<unsigned>(
2783 num_digits + sep.
size() * (num_digits - 1) / 3);
2784 CharPtr p = prepare_int_buffer(size, spec, prefix, prefix_size) + 1;
2790 spec.type(), spec.flag(
CHAR_FLAG) ?
"char" :
"integer");
2795 template <
typename Char>
2796 template <
typename T>
2799 char type = spec.
type();
2805 case 'e':
case 'f':
case 'g':
case 'a':
2813 case 'E':
case 'G':
case 'A':
2824 if (internal::FPUtil::isnegative(
static_cast<double>(
value))) {
2831 if (internal::FPUtil::isnotanumber(
value)) {
2834 std::size_t nan_size = 4;
2835 const char *nan = upper ?
" NAN" :
" nan";
2840 CharPtr out = write_str(nan, nan_size, spec);
2846 if (internal::FPUtil::isinfinity(
value)) {
2849 std::size_t inf_size = 4;
2850 const char *inf = upper ?
" INF" :
" inf";
2855 CharPtr out = write_str(inf, inf_size, spec);
2861 std::size_t offset = buffer_.
size();
2862 unsigned width = spec.
width();
2864 buffer_.
reserve(buffer_.
size() + (width > 1u ? width : 1u));
2871 enum { MAX_FORMAT_SIZE = 10};
2872 Char
format[MAX_FORMAT_SIZE];
2873 Char *format_ptr =
format;
2874 *format_ptr++ =
'%';
2875 unsigned width_for_sprintf = width;
2877 *format_ptr++ =
'#';
2879 width_for_sprintf = 0;
2882 *format_ptr++ =
'-';
2884 *format_ptr++ =
'*';
2887 *format_ptr++ =
'.';
2888 *format_ptr++ =
'*';
2891 append_float_length(format_ptr,
value);
2892 *format_ptr++ = type;
2900 std::size_t buffer_size = buffer_.
capacity() - offset;
2905 if (buffer_size == 0) {
2907 buffer_size = buffer_.
capacity() - offset;
2910 start = &buffer_[offset];
2915 if (offset + n < buffer_.
capacity())
2917 buffer_.
reserve(offset + n + 1);
2927 *(start - 1) = sign;
2930 *(start - 1) = fill;
2935 width = spec.
width();
2936 CharPtr p = grow_buffer(width);
2937 std::memmove(
get(p) + (width - n) / 2,
get(p), n *
sizeof(Char));
2938 fill_padding(p, spec.
width(), n, fill);
2941 if (spec.
fill() !=
' ' || sign) {
2942 while (*start ==
' ')
2945 *(start - 1) = sign;
2984 template <
typename Char,
typename Allocator = std::allocator<Char> >
2993 #if FMT_USE_RVALUE_REFERENCES
3009 BasicMemoryWriter &operator=(BasicMemoryWriter &&other) {
3039 template <
typename Char>
3052 :
BasicWriter<Char>(buffer_), buffer_(array, size) {}
3060 template <std::
size_t SIZE>
3062 :
BasicWriter<Char>(buffer_), buffer_(array, SIZE) {}
3073 #if FMT_USE_WINDOWS_H
3109 WindowsError(
int error_code,
CStringRef message) {
3110 init(error_code, message,
ArgList());
3117 FMT_API void report_windows_error(
int error_code,
3143 w.
write(format_str, args);
3149 w.
write(format_str, args);
3182 enum {BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3};
3183 mutable char buffer_[BUFFER_SIZE];
3188 char *buffer_end = buffer_ + BUFFER_SIZE - 1;
3189 while (
value >= 100) {
3193 unsigned index =
static_cast<unsigned>((
value % 100) * 2);
3195 *--buffer_end = internal::Data::DIGITS[index + 1];
3196 *--buffer_end = internal::Data::DIGITS[index];
3199 *--buffer_end =
static_cast<char>(
'0' +
value);
3202 unsigned index =
static_cast<unsigned>(
value * 2);
3203 *--buffer_end = internal::Data::DIGITS[index + 1];
3204 *--buffer_end = internal::Data::DIGITS[index];
3212 abs_value = 0 - abs_value;
3235 const char *
data()
const {
return str_; }
3242 buffer_[BUFFER_SIZE - 1] =
'\0';
3251 std::string
str()
const {
return std::string(str_, size()); }
3257 template <
typename T>
3260 MainType abs_value =
static_cast<MainType
>(
value);
3263 abs_value = 0 - abs_value;
3265 if (abs_value < 100) {
3266 if (abs_value < 10) {
3267 *buffer++ =
static_cast<char>(
'0' + abs_value);
3270 unsigned index =
static_cast<unsigned>(abs_value * 2);
3271 *buffer++ = internal::Data::DIGITS[index];
3272 *buffer++ = internal::Data::DIGITS[index + 1];
3277 buffer += num_digits;
3290 template <
typename T>
3295 template <
typename T>
3302 template <
typename Char>
3304 template <
typename Char>
3313 # pragma GCC system_header
3317 #define FMT_EXPAND(args) args
3321 #define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N())
3322 #define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
3323 #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
3324 #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
3326 #define FMT_CONCAT(a, b) a##b
3327 #define FMT_FOR_EACH_(N, f, ...) \
3328 FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
3329 #define FMT_FOR_EACH(f, ...) \
3330 FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__))
3332 #define FMT_ADD_ARG_NAME(type, index) type arg##index
3333 #define FMT_GET_ARG_NAME(type, index) arg##index
3335 #if FMT_USE_VARIADIC_TEMPLATES
3336 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3337 template <typename... Args> \
3338 ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3339 const Args & ... args) { \
3340 typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
3341 typename ArgArray::Type array{ \
3342 ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
3343 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
3344 fmt::ArgList(fmt::internal::make_type(args...), array)); \
3349 # define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
3350 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
3351 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3352 FMT_GEN(n, FMT_MAKE_ARG)) { \
3353 fmt::internal::ArgArray<n>::Type arr; \
3354 FMT_GEN(n, FMT_ASSIGN_##Char); \
3355 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
3356 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \
3359 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3360 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \
3361 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \
3363 FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \
3364 FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \
3365 FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \
3366 FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \
3367 FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \
3368 FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \
3369 FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \
3370 FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \
3371 FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \
3372 FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \
3373 FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \
3374 FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \
3375 FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \
3376 FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \
3377 FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__)
3378 #endif // FMT_USE_VARIADIC_TEMPLATES
3407 #define FMT_VARIADIC(ReturnType, func, ...) \
3408 FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
3410 #define FMT_VARIADIC_W(ReturnType, func, ...) \
3411 FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__)
3413 #define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id)
3415 #define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id)
3431 #define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__)
3433 #define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__)
3443 template <
typename Char>
3445 return (
'a' <= c && c <=
'z') || (
'A' <= c && c <=
'Z') ||
'_' == c;
3450 template <
typename Char>
3452 assert(
'0' <= *s && *s <=
'9');
3455 unsigned new_value =
value * 10 + (*s++ -
'0');
3457 if (new_value <
value) {
3458 value = (std::numeric_limits<unsigned>::max)();
3462 }
while (
'0' <= *s && *s <=
'9');
3464 unsigned max_int = (std::numeric_limits<int>::max)();
3465 if (
value > max_int)
3471 if (
arg.type > Arg::LAST_NUMERIC_TYPE) {
3472 std::string message =
3473 fmt::format(
"format specifier '{}' requires numeric argument", spec);
3478 template <
typename Char>
3480 char sign =
static_cast<char>(*s);
3482 if (
arg.type == Arg::UINT ||
arg.type == Arg::ULONG_LONG) {
3484 "format specifier '{}' requires signed argument", sign)));
3490 template <
typename Char,
typename AF>
3493 if (check_no_auto_index(error)) {
3498 error =
"argument not found";
3503 template <
typename Char,
typename AF>
3505 const char *error = 0;
3510 *s !=
'}' && *s !=
':' ?
"invalid format string" : error));
3515 template <
typename Char,
typename AF>
3518 const Char *start = s;
3523 const char *error = 0;
3530 template <
typename Char,
typename ArgFormatter>
3534 const Char *s = format_str;
3537 if (
arg.type == Arg::CUSTOM) {
3538 arg.custom.format(
this,
arg.custom.value, &s);
3544 const Char *p = s + 1;
3563 if (c ==
'}')
break;
3607 if (
'0' <= *s && *s <=
'9') {
3609 }
else if (*s ==
'{') {
3612 parse_arg_name(s) : parse_arg_index(s);
3616 switch (width_arg.
type) {
3625 case Arg::LONG_LONG:
3630 case Arg::ULONG_LONG:
3636 if (
value > (std::numeric_limits<int>::max)())
3645 if (
'0' <= *s && *s <=
'9') {
3647 }
else if (*s ==
'{') {
3650 parse_arg_name(s) : parse_arg_index(s);
3654 switch (precision_arg.
type) {
3663 case Arg::LONG_LONG:
3668 case Arg::ULONG_LONG:
3674 if (
value > (std::numeric_limits<int>::max)())
3680 if (
arg.type <= Arg::LAST_INTEGER_TYPE ||
arg.type == Arg::POINTER) {
3682 fmt::format(
"precision not allowed in {} format specifier",
3683 arg.type == Arg::POINTER ?
"pointer" :
"integer")));
3688 if (*s !=
'}' && *s)
3689 spec.
type_ =
static_cast<char>(*s++);
3700 template <
typename Char,
typename AF>
3703 const Char *start = s;
3706 if (c !=
'{' && c !=
'}')
continue;
3708 write(writer_, start, s);
3714 write(writer_, start, s - 1);
3716 parse_arg_name(s) : parse_arg_index(s);
3719 write(writer_, start, s);
3723 #if FMT_USE_USER_DEFINED_LITERALS
3727 template <
typename Char>
3731 template <
typename... Args>
3732 auto operator()(Args && ... args)
const
3733 -> decltype(
format(str, std::forward<Args>(args)...)) {
3734 return format(str, std::forward<Args>(args)...);
3738 template <
typename Char>
3742 template <
typename T>
3744 return {str, std::forward<T>(
value)};
3750 inline namespace literals {
3762 inline internal::UdlFormat<char>
3763 operator"" _format(
const char *s, std::size_t) {
return {s}; }
3764 inline internal::UdlFormat<wchar_t>
3765 operator"" _format(
const wchar_t *s, std::size_t) {
return {s}; }
3777 inline internal::UdlArg<char>
3778 operator"" _a(
const char *s, std::size_t) {
return {s}; }
3779 inline internal::UdlArg<wchar_t>
3780 operator"" _a(
const wchar_t *s, std::size_t) {
return {s}; }
3784 #endif // FMT_USE_USER_DEFINED_LITERALS
3787 #if FMT_GCC_VERSION >= 406
3788 # pragma GCC diagnostic pop
3791 #if defined(__clang__) && !defined(FMT_ICC_VERSION)
3792 # pragma clang diagnostic pop
3795 #ifdef FMT_HEADER_ONLY
3796 # define FMT_FUNC inline
3802 #endif // FMT_FORMAT_H_