49 # pragma intrinsic(_BitScanReverse) 50 inline uint32_t clz(uint32_t x) {
52 _BitScanReverse(&r, x);
55 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n) 58 # pragma intrinsic(_BitScanReverse64) 61 inline uint32_t clzll(uint64_t x) {
64 _BitScanReverse64(&r, x);
67 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
71 _BitScanReverse(&r, static_cast<uint32_t>(x));
75 # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n) 81 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 82 # define FMT_GCC_EXTENSION __extension__ 83 # if FMT_GCC_VERSION >= 406 84 # pragma GCC diagnostic push 87 # pragma GCC diagnostic ignored "-Wlong-long" 90 # pragma GCC diagnostic ignored "-Wshadow" 92 # if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__ 93 # define FMT_HAS_GXX_CXX11 1 96 # define FMT_GCC_EXTENSION 100 # pragma clang diagnostic push 101 # pragma clang diagnostic ignored "-Wdocumentation" 104 #ifdef __GNUC_LIBSTD__ 105 # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) 109 # define FMT_HAS_FEATURE(x) __has_feature(x) 111 # define FMT_HAS_FEATURE(x) 0 115 # define FMT_HAS_BUILTIN(x) __has_builtin(x) 117 # define FMT_HAS_BUILTIN(x) 0 120 #ifdef __has_cpp_attribute 121 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) 123 # define FMT_HAS_CPP_ATTRIBUTE(x) 0 126 #ifndef FMT_USE_VARIADIC_TEMPLATES 130 # define FMT_USE_VARIADIC_TEMPLATES \ 131 (FMT_HAS_FEATURE(cxx_variadic_templates) || \ 132 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800) 135 #ifndef FMT_USE_RVALUE_REFERENCES 138 # if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402 139 # define FMT_USE_RVALUE_REFERENCES 0 141 # define FMT_USE_RVALUE_REFERENCES \ 142 (FMT_HAS_FEATURE(cxx_rvalue_references) || \ 143 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600) 147 #if FMT_USE_RVALUE_REFERENCES 153 # if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ 154 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) 155 # define FMT_NOEXCEPT noexcept 157 # define FMT_NOEXCEPT throw() 163 #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \ 164 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800 165 # define FMT_DELETED_OR_UNDEFINED = delete 166 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 167 TypeName(const TypeName&) = delete; \ 168 TypeName& operator=(const TypeName&) = delete 170 # define FMT_DELETED_OR_UNDEFINED 171 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 172 TypeName(const TypeName&); \ 173 TypeName& operator=(const TypeName&) 177 # define FMT_ASSERT(condition, message) assert((condition) && message) 184 FMT_GCC_EXTENSION
typedef long long LongLong;
185 FMT_GCC_EXTENSION
typedef unsigned long long ULongLong;
187 #if FMT_USE_RVALUE_REFERENCES 191 template <
typename Char>
197 template <
typename Char>
198 class BasicFormatter;
200 template <
typename Char,
typename T>
201 void format(BasicFormatter<Char> &f,
const Char *&format_str,
const T &value);
223 template <
typename Char>
240 : data_(s), size_(
std::char_traits<Char>::length(s)) {}
248 : data_(s.c_str()), size_(s.size()) {}
256 return std::basic_string<Char>(data_, size_);
260 const Char *
data()
const {
return data_; }
263 std::size_t
size()
const {
return size_; }
266 return lhs.data_ == rhs.data_;
269 return lhs.data_ != rhs.data_;
272 return std::lexicographical_compare(
273 lhs.data_, lhs.data_ + lhs.size_, rhs.data_, rhs.data_ + rhs.size_);
300 template <
typename Char>
317 const Char *
c_str()
const {
return data_; }
329 : std::runtime_error(message.
c_str()) {}
335 enum { INLINE_BUFFER_SIZE = 500 };
339 template <
typename T>
340 inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) {
341 return stdext::checked_array_iterator<T*>(ptr, size);
344 template <
typename T>
345 inline T *make_ptr(T *ptr, std::size_t) {
return ptr; }
354 template <
typename T>
357 FMT_DISALLOW_COPY_AND_ASSIGN(
Buffer);
362 std::size_t capacity_;
364 Buffer(T *ptr = 0, std::size_t capacity = 0)
365 : ptr_(ptr), size_(0), capacity_(capacity) {}
373 virtual void grow(std::size_t size) = 0;
379 std::size_t
size()
const {
return size_; }
388 if (new_size > capacity_)
399 if (capacity > capacity_)
403 void clear() FMT_NOEXCEPT{ size_ = 0; }
405 void push_back(
const T &value) {
406 if (size_ == capacity_)
408 ptr_[size_++] = value;
412 template <
typename U>
413 void append(
const U *begin,
const U *end);
415 T &operator[](std::size_t index) {
return ptr_[index]; }
416 const T &operator[](std::size_t index)
const {
return ptr_[index]; }
419 template <
typename T>
420 template <
typename U>
422 std::ptrdiff_t num_elements = end - begin;
423 if (size_ + num_elements > capacity_)
424 grow(size_ + num_elements);
425 std::copy(begin, end, internal::make_ptr(ptr_, capacity_) + size_);
426 size_ += num_elements;
433 template <
typename T, std::
size_t SIZE,
typename Allocator = std::allocator<T> >
434 class MemoryBuffer :
private Allocator,
public Buffer<T> {
440 if (this->ptr_ != data_) this->deallocate(this->ptr_, this->capacity_);
444 void grow(std::size_t size);
447 explicit MemoryBuffer(
const Allocator &alloc = Allocator())
448 : Allocator(alloc),
Buffer<T>(data_, SIZE) {}
449 ~MemoryBuffer() { free(); }
451 #if FMT_USE_RVALUE_REFERENCES 454 void move(MemoryBuffer &other) {
455 Allocator &this_alloc = *
this, &other_alloc = other;
456 this_alloc = std::move(other_alloc);
457 this->size_ = other.size_;
458 this->capacity_ = other.capacity_;
459 if (other.ptr_ == other.data_) {
461 std::copy(other.data_,
462 other.data_ + this->size_, make_ptr(data_, this->capacity_));
465 this->ptr_ = other.ptr_;
468 other.ptr_ = other.data_;
473 MemoryBuffer(MemoryBuffer &&other) {
477 MemoryBuffer &operator=(MemoryBuffer &&other) {
478 assert(
this != &other);
486 Allocator get_allocator()
const {
return *
this; }
489 template <
typename T, std::
size_t SIZE,
typename Allocator>
490 void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
491 std::size_t new_capacity =
492 (
std::max)(size, this->capacity_ + this->capacity_ / 2);
493 T *new_ptr = this->allocate(new_capacity);
495 std::copy(this->ptr_,
496 this->ptr_ + this->size_, make_ptr(new_ptr, new_capacity));
497 std::size_t old_capacity = this->capacity_;
498 T *old_ptr = this->ptr_;
499 this->capacity_ = new_capacity;
500 this->ptr_ = new_ptr;
504 if (old_ptr != data_)
505 this->deallocate(old_ptr, old_capacity);
509 template <
typename Char>
515 void grow(std::size_t size);
520 inline int getsign(
double x) {
526 return std::signbit(x);
532 inline int isinfinity(
double x) {
return isinf(x); }
533 inline int isinfinity(
long double x) {
return isinf(x); }
535 inline int isinfinity(
double x) {
return std::isinf(x); }
536 inline int isinfinity(
long double x) {
return std::isinf(x); }
539 inline int getsign(
double value) {
540 if (value < 0)
return 1;
541 if (value == value)
return 0;
542 int dec = 0, sign = 0;
544 _ecvt_s(buffer,
sizeof(buffer), value, 0, &dec, &sign);
547 inline int isinfinity(
double x) {
return !_finite(x); }
548 inline int isinfinity(
long double x) {
549 return !_finite(static_cast<double>(x));
553 template <
typename Char>
554 class BasicCharTraits {
557 typedef stdext::checked_array_iterator<Char*> CharPtr;
559 typedef Char *CharPtr;
561 static Char cast(
wchar_t value) {
return static_cast<Char
>(value); }
564 template <
typename Char>
568 class CharTraits<char> :
public BasicCharTraits<char>{
571 static char convert(
wchar_t);
574 static char convert(
char value) {
return value; }
577 template <
typename T>
578 static int format_float(
char *buffer, std::size_t size,
579 const char *format,
unsigned width,
int precision, T value);
583 class CharTraits<wchar_t> :
public BasicCharTraits<wchar_t>{
585 static wchar_t convert(
char value) {
return value; }
586 static wchar_t convert(
wchar_t value) {
return value; }
588 template <
typename T>
589 static int format_float(
wchar_t *buffer, std::size_t size,
590 const wchar_t *format,
unsigned width,
int precision, T value);
594 template <
bool IsSigned>
596 template <
typename T>
597 static bool is_negative(T value) {
return value < 0; }
601 struct SignChecker<false> {
602 template <
typename T>
603 static bool is_negative(T) {
return false; }
608 template <
typename T>
609 inline bool is_negative(T value) {
610 return SignChecker<std::numeric_limits<T>::is_signed>::is_negative(value);
614 template <
bool FitsIn32Bits>
615 struct TypeSelector {
typedef uint32_t Type; };
618 struct TypeSelector<false> {
typedef uint64_t Type; };
620 template <
typename T>
625 TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
629 template <
typename T>
630 struct MakeUnsigned {
typedef T Type; };
632 #define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \ 634 struct MakeUnsigned<T> { typedef U Type; } 636 FMT_SPECIALIZE_MAKE_UNSIGNED(
char,
unsigned char);
637 FMT_SPECIALIZE_MAKE_UNSIGNED(
signed char,
unsigned char);
638 FMT_SPECIALIZE_MAKE_UNSIGNED(
short,
unsigned short);
639 FMT_SPECIALIZE_MAKE_UNSIGNED(
int,
unsigned);
640 FMT_SPECIALIZE_MAKE_UNSIGNED(
long,
unsigned long);
641 FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
643 void report_unknown_type(
char code,
const char *type);
647 template <
typename T =
void>
649 static const uint32_t POWERS_OF_10_32[];
650 static const uint64_t POWERS_OF_10_64[];
651 static const char DIGITS[];
654 typedef BasicData<> Data;
656 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) 657 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) 660 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) 661 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) 664 #ifdef FMT_BUILTIN_CLZLL 667 inline unsigned count_digits(uint64_t n) {
670 unsigned t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
671 return t - (n < Data::POWERS_OF_10_64[t]) + 1;
675 inline unsigned count_digits(uint64_t n) {
681 if (n < 10)
return count;
682 if (n < 100)
return count + 1;
683 if (n < 1000)
return count + 2;
684 if (n < 10000)
return count + 3;
691 #ifdef FMT_BUILTIN_CLZ 693 inline unsigned count_digits(uint32_t n) {
694 uint32_t t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
695 return t - (n < Data::POWERS_OF_10_32[t]) + 1;
700 template <
typename UInt,
typename Char>
701 inline void format_decimal(Char *buffer, UInt value,
unsigned num_digits) {
702 buffer += num_digits;
703 while (value >= 100) {
707 unsigned index = (value % 100) * 2;
709 *--buffer = Data::DIGITS[index + 1];
710 *--buffer = Data::DIGITS[index];
713 *--buffer =
static_cast<char>(
'0' + value);
716 unsigned index =
static_cast<unsigned>(value * 2);
717 *--buffer = Data::DIGITS[index + 1];
718 *--buffer = Data::DIGITS[index];
722 # define FMT_USE_WINDOWS_H 0 723 #elif !defined(FMT_USE_WINDOWS_H) 724 # define FMT_USE_WINDOWS_H 1 729 #if FMT_USE_WINDOWS_H 734 MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_;
737 explicit UTF8ToUTF16(StringRef s);
738 operator WStringRef()
const {
return WStringRef(&buffer_[0], size()); }
739 size_t size()
const {
return buffer_.size() - 1; }
740 const wchar_t *c_str()
const {
return &buffer_[0]; }
741 std::wstring str()
const {
return std::wstring(&buffer_[0], size()); }
748 MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer_;
752 explicit UTF16ToUTF8(WStringRef s);
753 operator StringRef()
const {
return StringRef(&buffer_[0], size()); }
754 size_t size()
const {
return buffer_.size() - 1; }
755 const char *c_str()
const {
return &buffer_[0]; }
756 std::string str()
const {
return std::string(&buffer_[0], size()); }
761 int convert(WStringRef s);
764 void format_windows_error(
fmt::Writer &out,
int error_code,
768 void format_system_error(
fmt::Writer &out,
int error_code,
773 template <
typename Char>
779 typedef void(*FormatFunc)(
780 void *formatter,
const void *arg,
void *format_str_ptr);
790 LongLong long_long_value;
791 ULongLong ulong_long_value;
793 long double long_double_value;
795 StringValue<char> string;
796 StringValue<signed char> sstring;
797 StringValue<unsigned char> ustring;
798 StringValue<wchar_t> wstring;
805 INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
807 DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
808 CSTRING, STRING, WSTRING, POINTER, CUSTOM
818 template <
typename Char>
821 template <
typename T =
void>
826 template <
typename T,
typename Char>
828 typedef Null<T> Supported;
829 typedef T Unsupported;
832 template <
typename T>
833 struct WCharHelper<T, wchar_t> {
835 typedef Null<T> Unsupported;
838 template <
typename T>
839 class IsConvertibleToInt {
844 static const T &
get();
846 static yes &convert(fmt::ULongLong);
847 static no &convert(...);
850 enum { value = (
sizeof(convert(
get())) ==
sizeof(yes)) };
853 #define FMT_CONVERTIBLE_TO_INT(Type) \ 855 class IsConvertibleToInt<Type> { \ 857 enum { value = 1 }; \ 861 FMT_CONVERTIBLE_TO_INT(
float);
862 FMT_CONVERTIBLE_TO_INT(
double);
863 FMT_CONVERTIBLE_TO_INT(
long double);
865 template<
bool B,
class T =
void>
869 struct EnableIf<true, T> {
typedef T type; };
871 template<
bool B,
class T,
class F>
872 struct Conditional {
typedef T type; };
874 template<
class T,
class F>
875 struct Conditional<false, T, F> {
typedef F type; };
879 inline bool check(
bool value) {
return value; }
882 template <
typename Char>
883 class MakeValue :
public Arg {
890 template <
typename T>
891 MakeValue(
const T *value);
892 template <
typename T>
899 MakeValue(
typename WCharHelper<wchar_t, Char>::Unsupported);
900 MakeValue(
typename WCharHelper<wchar_t *, Char>::Unsupported);
901 MakeValue(
typename WCharHelper<const wchar_t *, Char>::Unsupported);
902 MakeValue(
typename WCharHelper<const std::wstring &, Char>::Unsupported);
903 MakeValue(
typename WCharHelper<WStringRef, Char>::Unsupported);
905 void set_string(StringRef str) {
906 string.value = str.
data();
907 string.size = str.
size();
910 void set_string(WStringRef str) {
911 wstring.value = str.
data();
912 wstring.size = str.
size();
916 template <
typename T>
917 static void format_custom_arg(
918 void *formatter,
const void *arg,
void *format_str_ptr) {
919 format(*
static_cast<BasicFormatter<Char>*
>(formatter),
920 *static_cast<const Char**>(format_str_ptr),
921 *static_cast<const T*>(arg));
927 #define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \ 928 MakeValue(Type value) { field = rhs; } \ 929 static uint64_t type(Type) { return Arg::TYPE; } 931 #define FMT_MAKE_VALUE(Type, field, TYPE) \ 932 FMT_MAKE_VALUE_(Type, field, TYPE, value) 934 FMT_MAKE_VALUE(
bool, int_value, BOOL)
935 FMT_MAKE_VALUE(
short, int_value, INT)
936 FMT_MAKE_VALUE(
unsigned short, uint_value, UINT)
937 FMT_MAKE_VALUE(
int, int_value, INT)
938 FMT_MAKE_VALUE(
unsigned, uint_value, UINT)
940 MakeValue(
long value) {
943 if (check(
sizeof(
long) ==
sizeof(
int)))
944 int_value =
static_cast<int>(value);
946 long_long_value = value;
948 static uint64_t type(
long) {
949 return sizeof(long) ==
sizeof(
int) ? Arg::INT : Arg::LONG_LONG;
952 MakeValue(
unsigned long value) {
953 if (check(
sizeof(
unsigned long) ==
sizeof(
unsigned)))
954 uint_value =
static_cast<unsigned>(value);
956 ulong_long_value = value;
958 static uint64_t type(
unsigned long) {
959 return sizeof(
unsigned long) ==
sizeof(
unsigned) ?
960 Arg::UINT : Arg::ULONG_LONG;
963 FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG)
964 FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG)
965 FMT_MAKE_VALUE(
float, double_value, DOUBLE)
966 FMT_MAKE_VALUE(
double, double_value, DOUBLE)
967 FMT_MAKE_VALUE(
long double, long_double_value, LONG_DOUBLE)
968 FMT_MAKE_VALUE(
signed char, int_value, CHAR)
969 FMT_MAKE_VALUE(
unsigned char, int_value, CHAR)
970 FMT_MAKE_VALUE(
char, int_value, CHAR)
972 MakeValue(
typename WCharHelper<wchar_t, Char>::Supported value) {
975 static uint64_t type(
wchar_t) {
return Arg::CHAR; }
977 #define FMT_MAKE_STR_VALUE(Type, TYPE) \ 978 MakeValue(Type value) { set_string(value); } \ 979 static uint64_t type(Type) { return Arg::TYPE; } 981 FMT_MAKE_VALUE(
char *,
string.value, CSTRING)
982 FMT_MAKE_VALUE(
const char *,
string.value, CSTRING)
983 FMT_MAKE_VALUE(
const signed char *, sstring.value, CSTRING)
984 FMT_MAKE_VALUE(
const unsigned char *, ustring.value, CSTRING)
985 FMT_MAKE_STR_VALUE(
const std::string &, STRING)
986 FMT_MAKE_STR_VALUE(StringRef, STRING)
987 FMT_MAKE_VALUE_(CStringRef,
string.value, CSTRING, value.c_str())
989 #define FMT_MAKE_WSTR_VALUE(Type, TYPE) \
990 MakeValue(
typename WCharHelper<Type, Char>::Supported value) { \
993 static uint64_t type(Type) {
return Arg::TYPE; }
995 FMT_MAKE_WSTR_VALUE(
wchar_t *, WSTRING)
996 FMT_MAKE_WSTR_VALUE(
const wchar_t *, WSTRING)
997 FMT_MAKE_WSTR_VALUE(
const std::wstring &, WSTRING)
998 FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING)
1000 FMT_MAKE_VALUE(
void *, pointer, POINTER)
1001 FMT_MAKE_VALUE(
const void *, pointer, POINTER)
1003 template <
typename T>
1004 MakeValue(
const T &value,
1005 typename EnableIf<!IsConvertibleToInt<T>::value,
int>::type = 0) {
1006 custom.value = &value;
1007 custom.format = &format_custom_arg<T>;
1010 template <
typename T>
1011 MakeValue(
const T &value,
1012 typename EnableIf<IsConvertibleToInt<T>::value,
int>::type = 0) {
1016 template <
typename T>
1017 static uint64_t type(
const T &) {
1018 return IsConvertibleToInt<T>::value ? Arg::INT : Arg::CUSTOM;
1023 template <
typename Char_>
1024 MakeValue(
const NamedArg<Char_> &value) { pointer = &value; }
1026 template <
typename Char_>
1027 static uint64_t type(
const NamedArg<Char_> &) {
return Arg::NAMED_ARG; }
1030 template <
typename Char>
1031 struct NamedArg : Arg {
1034 template <
typename T>
1036 : Arg(MakeValue<Char>(value)), name(argname) {
1037 type =
static_cast<internal::Arg::Type
>(MakeValue<Char>::type(value));
1041 #define FMT_DISPATCH(call) static_cast<Impl*>(this)->call 1063 template <
typename Impl,
typename Result>
1066 void report_unhandled_arg() {}
1068 Result visit_unhandled_arg() {
1069 FMT_DISPATCH(report_unhandled_arg());
1073 Result visit_int(
int value) {
1074 return FMT_DISPATCH(visit_any_int(value));
1076 Result visit_long_long(LongLong value) {
1077 return FMT_DISPATCH(visit_any_int(value));
1079 Result visit_uint(
unsigned value) {
1080 return FMT_DISPATCH(visit_any_int(value));
1082 Result visit_ulong_long(ULongLong value) {
1083 return FMT_DISPATCH(visit_any_int(value));
1085 Result visit_bool(
bool value) {
1086 return FMT_DISPATCH(visit_any_int(value));
1088 Result visit_char(
int value) {
1089 return FMT_DISPATCH(visit_any_int(value));
1091 template <
typename T>
1092 Result visit_any_int(T) {
1093 return FMT_DISPATCH(visit_unhandled_arg());
1096 Result visit_double(
double value) {
1097 return FMT_DISPATCH(visit_any_double(value));
1099 Result visit_long_double(
long double value) {
1100 return FMT_DISPATCH(visit_any_double(value));
1102 template <
typename T>
1103 Result visit_any_double(T) {
1104 return FMT_DISPATCH(visit_unhandled_arg());
1107 Result visit_string(Arg::StringValue<char>) {
1108 return FMT_DISPATCH(visit_unhandled_arg());
1110 Result visit_wstring(Arg::StringValue<wchar_t>) {
1111 return FMT_DISPATCH(visit_unhandled_arg());
1113 Result visit_pointer(
const void *) {
1114 return FMT_DISPATCH(visit_unhandled_arg());
1116 Result visit_custom(Arg::CustomValue) {
1117 return FMT_DISPATCH(visit_unhandled_arg());
1120 Result visit(
const Arg &arg) {
1123 FMT_ASSERT(
false,
"invalid argument type");
1126 return FMT_DISPATCH(visit_int(arg.int_value));
1128 return FMT_DISPATCH(visit_uint(arg.uint_value));
1129 case Arg::LONG_LONG:
1130 return FMT_DISPATCH(visit_long_long(arg.long_long_value));
1131 case Arg::ULONG_LONG:
1132 return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value));
1134 return FMT_DISPATCH(visit_bool(arg.int_value != 0));
1136 return FMT_DISPATCH(visit_char(arg.int_value));
1138 return FMT_DISPATCH(visit_double(arg.double_value));
1139 case Arg::LONG_DOUBLE:
1140 return FMT_DISPATCH(visit_long_double(arg.long_double_value));
1141 case Arg::CSTRING: {
1142 Arg::StringValue<char> str = arg.string;
1144 return FMT_DISPATCH(visit_string(str));
1147 return FMT_DISPATCH(visit_string(arg.string));
1149 return FMT_DISPATCH(visit_wstring(arg.wstring));
1151 return FMT_DISPATCH(visit_pointer(arg.pointer));
1153 return FMT_DISPATCH(visit_custom(arg.custom));
1158 class RuntimeError :
public std::runtime_error {
1160 RuntimeError() : std::runtime_error(
"") {}
1163 template <
typename Impl,
typename Char>
1164 class BasicArgFormatter;
1166 template <
typename Char>
1167 class PrintfArgFormatter;
1169 template <
typename Char>
1185 const internal::Value *values_;
1186 const internal::Arg *args_;
1189 internal::Arg::Type type(
unsigned index)
const {
1190 unsigned shift = index * 4;
1191 uint64_t mask = 0xf;
1192 return static_cast<internal::Arg::Type
>(
1193 (types_ & (mask << shift)) >> shift);
1196 template <
typename Char>
1197 friend class internal::ArgMap;
1201 enum { MAX_PACKED_ARGS = 16 };
1205 ArgList(ULongLong types,
const internal::Value *values)
1206 : types_(types), values_(values) {}
1207 ArgList(ULongLong types,
const internal::Arg *args)
1208 : types_(types), args_(args) {}
1212 using internal::Arg;
1214 bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE;
1215 if (index < MAX_PACKED_ARGS) {
1216 Arg::Type arg_type = type(index);
1217 internal::Value &val = arg;
1218 if (arg_type != Arg::NONE)
1219 val = use_values ? values_[index] : args_[index];
1220 arg.type = arg_type;
1226 arg.type = Arg::NONE;
1229 for (
unsigned i = MAX_PACKED_ARGS; i <= index; ++i) {
1230 if (args_[i].type == Arg::NONE)
1233 return args_[index];
1239 namespace internal {
1241 template <
typename Char>
1244 typedef std::map<fmt::BasicStringRef<Char>, internal::Arg> MapType;
1245 typedef typename MapType::value_type Pair;
1250 void init(
const ArgList &args);
1253 typename MapType::const_iterator it = map_.find(name);
1254 return it != map_.end() ? &it->second : 0;
1258 class FormatterBase {
1261 int next_arg_index_;
1264 Arg do_get_arg(
unsigned arg_index,
const char *&error);
1267 const ArgList &args()
const {
return args_; }
1269 explicit FormatterBase(
const ArgList &args) {
1271 next_arg_index_ = 0;
1275 Arg next_arg(
const char *&error);
1279 Arg get_arg(
unsigned arg_index,
const char *&error);
1281 bool check_no_auto_index(
const char *&error);
1283 template <
typename Char>
1286 w << BasicStringRef<Char>(start, end - start);
1291 template <
typename Char>
1292 class PrintfFormatter :
private FormatterBase {
1294 void parse_flags(FormatSpec &spec,
const Char *&s);
1298 Arg get_arg(
const Char *s,
1302 unsigned parse_header(
const Char *&s, FormatSpec &spec);
1305 explicit PrintfFormatter(
const ArgList &args) : FormatterBase(args) {}
1311 template <
typename Char>
1312 class BasicFormatter :
private internal::FormatterBase {
1315 internal::ArgMap<Char> map_;
1317 FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter);
1319 using FormatterBase::get_arg;
1326 internal::Arg parse_arg_index(
const Char *&s);
1329 internal::Arg parse_arg_name(
const Char *&s);
1333 : FormatterBase(args), writer_(w) {}
1339 const Char *format(
const Char *&format_str,
const internal::Arg &arg);
1343 ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
1348 SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8,
1353 struct EmptySpec {};
1356 template <
char TYPE>
1357 struct TypeSpec : EmptySpec {
1358 Alignment align()
const {
return ALIGN_DEFAULT; }
1359 unsigned width()
const {
return 0; }
1360 int precision()
const {
return -1; }
1361 bool flag(
unsigned)
const {
return false; }
1362 char type()
const {
return TYPE; }
1363 char fill()
const {
return ' '; }
1373 WidthSpec(
unsigned width,
wchar_t fill) : width_(width), fill_(fill) {}
1375 unsigned width()
const {
return width_; }
1376 wchar_t fill()
const {
return fill_; }
1380 struct AlignSpec : WidthSpec {
1383 AlignSpec(
unsigned width,
wchar_t fill, Alignment align = ALIGN_DEFAULT)
1384 : WidthSpec(width, fill), align_(align) {}
1386 Alignment align()
const {
return align_; }
1388 int precision()
const {
return -1; }
1392 template <
char TYPE>
1393 struct AlignTypeSpec : AlignSpec {
1394 AlignTypeSpec(
unsigned width,
wchar_t fill) : AlignSpec(width, fill) {}
1396 bool flag(
unsigned)
const {
return false; }
1397 char type()
const {
return TYPE; }
1401 struct FormatSpec : AlignSpec {
1407 unsigned width = 0,
char type = 0,
wchar_t fill =
' ')
1408 : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
1410 bool flag(
unsigned f)
const {
return (flags_ & f) != 0; }
1411 int precision()
const {
return precision_; }
1412 char type()
const {
return type_; }
1416 template <
typename T,
typename SpecT = TypeSpec<0>,
typename Char =
char>
1417 class IntFormatSpec :
public SpecT {
1422 IntFormatSpec(T val,
const SpecT &spec = SpecT())
1423 : SpecT(spec), value_(val) {}
1425 T value()
const {
return value_; }
1429 template <
typename Char>
1430 class StrFormatSpec :
public AlignSpec {
1435 template <
typename FillChar>
1436 StrFormatSpec(
const Char *str,
unsigned width, FillChar fill)
1437 : AlignSpec(width, fill), str_(str) {
1438 internal::CharTraits<Char>::convert(FillChar());
1441 const Char *str()
const {
return str_; }
1447 IntFormatSpec<int, TypeSpec<'b'> > bin(
int value);
1452 IntFormatSpec<int, TypeSpec<'o'> > oct(
int value);
1458 IntFormatSpec<int, TypeSpec<'x'> > hex(
int value);
1464 IntFormatSpec<int, TypeSpec<'X'> > hexu(
int value);
1477 template <
char TYPE_CODE,
typename Char>
1478 IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad(
1479 int value,
unsigned width, Char fill =
' ');
1481 #define FMT_DEFINE_INT_FORMATTERS(TYPE) \ 1482 inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \ 1483 return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \ 1486 inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \ 1487 return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \ 1490 inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \ 1491 return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \ 1494 inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \ 1495 return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \ 1498 template <char TYPE_CODE> \ 1499 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \ 1500 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \ 1501 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \ 1502 f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \ 1509 template <char TYPE_CODE, typename Char> \ 1510 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \ 1511 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f, \ 1512 unsigned width, Char fill) { \ 1513 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \ 1514 f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \ 1517 inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \ 1518 TYPE value, unsigned width) { \ 1519 return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \ 1520 value, AlignTypeSpec<0>(width, ' ')); \ 1523 template <typename Char> \ 1524 inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \ 1525 TYPE value, unsigned width, Char fill) { \ 1526 return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \ 1527 value, AlignTypeSpec<0>(width, fill)); \ 1530 FMT_DEFINE_INT_FORMATTERS(
int)
1531 FMT_DEFINE_INT_FORMATTERS(
long)
1532 FMT_DEFINE_INT_FORMATTERS(
unsigned)
1533 FMT_DEFINE_INT_FORMATTERS(
unsigned long)
1534 FMT_DEFINE_INT_FORMATTERS(LongLong)
1535 FMT_DEFINE_INT_FORMATTERS(ULongLong)
1546 template <
typename Char>
1547 inline StrFormatSpec<Char> pad(
1548 const Char *str,
unsigned width, Char fill =
' ') {
1549 return StrFormatSpec<Char>(str, width, fill);
1552 inline StrFormatSpec<wchar_t> pad(
1553 const wchar_t *str,
unsigned width,
char fill =
' ') {
1554 return StrFormatSpec<wchar_t>(str, width, fill);
1559 # define FMT_GEN(n, f) FMT_GEN##n(f) 1560 # define FMT_GEN1(f) f(0) 1561 # define FMT_GEN2(f) FMT_GEN1(f), f(1) 1562 # define FMT_GEN3(f) FMT_GEN2(f), f(2) 1563 # define FMT_GEN4(f) FMT_GEN3(f), f(3) 1564 # define FMT_GEN5(f) FMT_GEN4(f), f(4) 1565 # define FMT_GEN6(f) FMT_GEN5(f), f(5) 1566 # define FMT_GEN7(f) FMT_GEN6(f), f(6) 1567 # define FMT_GEN8(f) FMT_GEN7(f), f(7) 1568 # define FMT_GEN9(f) FMT_GEN8(f), f(8) 1569 # define FMT_GEN10(f) FMT_GEN9(f), f(9) 1570 # define FMT_GEN11(f) FMT_GEN10(f), f(10) 1571 # define FMT_GEN12(f) FMT_GEN11(f), f(11) 1572 # define FMT_GEN13(f) FMT_GEN12(f), f(12) 1573 # define FMT_GEN14(f) FMT_GEN13(f), f(13) 1574 # define FMT_GEN15(f) FMT_GEN14(f), f(14) 1576 namespace internal {
1577 inline uint64_t make_type() {
return 0; }
1579 template <
typename T>
1580 inline uint64_t make_type(
const T &arg) {
return MakeValue<char>::type(arg); }
1582 template <
unsigned N>
1588 enum { SIZE = N + (N == 0 || N >= ArgList::MAX_PACKED_ARGS ? 1 : 0) };
1590 typedef typename Conditional<
1591 (N < ArgList::MAX_PACKED_ARGS), Value, Arg>::type Type[SIZE];
1594 #if FMT_USE_VARIADIC_TEMPLATES 1595 template <
typename Arg,
typename... Args>
1596 inline uint64_t make_type(
const Arg &first,
const Args & ... tail) {
1597 return make_type(first) | (make_type(tail...) << 4);
1600 inline void do_set_types(Arg *) {}
1602 template <
typename T,
typename... Args>
1603 inline void do_set_types(Arg *args,
const T &arg,
const Args & ... tail) {
1604 args->type =
static_cast<Arg::Type
>(MakeValue<T>::type(arg));
1605 do_set_types(args + 1, tail...);
1608 template <
typename... Args>
1609 inline void set_types(Arg *array,
const Args & ... args) {
1610 if (check(
sizeof...(Args) > ArgList::MAX_PACKED_ARGS))
1611 do_set_types(array, args...);
1612 array[
sizeof...(Args)].type = Arg::NONE;
1615 template <
typename... Args>
1616 inline void set_types(Value *,
const Args & ...) {
1620 template <
typename Char,
typename Value>
1621 inline void store_args(Value *) {}
1623 template <
typename Char,
typename Arg,
typename T,
typename... Args>
1624 inline void store_args(Arg *args,
const T &arg,
const Args & ... tail) {
1627 Value &value = *args;
1628 value = MakeValue<Char>(arg);
1629 store_args<Char>(args + 1, tail...);
1632 template <
typename Char,
typename... Args>
1633 ArgList make_arg_list(
typename ArgArray<
sizeof...(Args)>::Type array,
1634 const Args & ... args) {
1635 if (check(
sizeof...(Args) >= ArgList::MAX_PACKED_ARGS))
1636 set_types(array, args...);
1637 store_args<Char>(array, args...);
1638 return ArgList(make_type(args...), array);
1645 ArgType() : type(0) {}
1647 template <
typename T>
1648 ArgType(
const T &arg) : type(make_type(arg)) {}
1651 # define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType() 1653 inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) {
1654 return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) |
1655 (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) |
1656 (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) |
1657 (t12.type << 48) | (t13.type << 52) | (t14.type << 56);
1662 # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n 1663 # define FMT_MAKE_ARG_TYPE(n) T##n 1664 # define FMT_MAKE_ARG(n) const T##n &v##n 1665 # define FMT_MAKE_REF_char(n) fmt::internal::MakeValue<char>(v##n) 1666 # define FMT_MAKE_REF_wchar_t(n) fmt::internal::MakeValue<wchar_t>(v##n) 1668 #if FMT_USE_VARIADIC_TEMPLATES 1670 # define FMT_VARIADIC_VOID(func, arg_type) \ 1671 template <typename... Args> \ 1672 void func(arg_type arg0, const Args & ... args) { \ 1673 typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ 1674 func(arg0, fmt::internal::make_arg_list<Char>(array, args...)); \ 1678 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ 1679 template <typename... Args> \ 1680 ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ 1681 typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ 1682 func(arg0, arg1, fmt::internal::make_arg_list<Char>(array, args...)); \ 1687 # define FMT_MAKE_REF(n) fmt::internal::MakeValue<Char>(v##n) 1688 # define FMT_MAKE_REF2(n) v##n 1692 # define FMT_WRAP1(func, arg_type, n) \ 1693 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 1694 inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ 1695 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1696 func(arg1, fmt::ArgList( \ 1697 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \ 1701 # define FMT_VARIADIC_VOID(func, arg_type) \ 1702 inline void func(arg_type arg) { func(arg, fmt::ArgList()); } \ 1703 FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \ 1704 FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \ 1705 FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \ 1706 FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \ 1707 FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10) 1709 # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \ 1710 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 1711 ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ 1712 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1713 func(arg0, arg1, fmt::ArgList( \ 1714 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \ 1718 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ 1719 FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \ 1720 FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \ 1721 FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \ 1722 FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \ 1723 FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \ 1724 FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \ 1725 FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \ 1726 FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \ 1727 FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \ 1728 FMT_CTOR(ctor, func, arg0_type, arg1_type, 10) 1733 #define FMT_FOR_EACH1(f, x0) f(x0, 0) 1734 #define FMT_FOR_EACH2(f, x0, x1) \ 1735 FMT_FOR_EACH1(f, x0), f(x1, 1) 1736 #define FMT_FOR_EACH3(f, x0, x1, x2) \ 1737 FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2) 1738 #define FMT_FOR_EACH4(f, x0, x1, x2, x3) \ 1739 FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3) 1740 #define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \ 1741 FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4) 1742 #define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \ 1743 FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5) 1744 #define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \ 1745 FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6) 1746 #define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \ 1747 FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7) 1748 #define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \ 1749 FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8) 1750 #define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \ 1751 FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9) 1759 void init(
int err_code, CStringRef format_str,
ArgList args);
1792 init(error_code, message,
ArgList());
1794 FMT_VARIADIC_CTOR(
SystemError, init,
int, CStringRef)
1796 int error_code()
const {
return error_code_; }
1814 template <
typename Char>
1822 typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
1826 static Char *
get(CharPtr p) {
return p.base(); }
1828 static Char *
get(Char *p) {
return p; }
1833 static CharPtr fill_padding(CharPtr buffer,
1834 unsigned total_size, std::size_t content_size,
wchar_t fill);
1838 CharPtr grow_buffer(std::size_t n) {
1839 std::size_t size = buffer_.
size();
1840 buffer_.
resize(size + n);
1841 return internal::make_ptr(&buffer_[size], n);
1845 template <
typename UInt>
1846 Char *write_unsigned_decimal(UInt value,
unsigned prefix_size = 0) {
1847 unsigned num_digits = internal::count_digits(value);
1848 Char *ptr =
get(grow_buffer(prefix_size + num_digits));
1849 internal::format_decimal(ptr + prefix_size, value, num_digits);
1854 template <
typename Int>
1855 void write_decimal(Int value) {
1856 typename internal::IntTraits<Int>::MainType abs_value = value;
1857 if (internal::is_negative(value)) {
1858 abs_value = 0 - abs_value;
1859 *write_unsigned_decimal(abs_value, 1) =
'-';
1862 write_unsigned_decimal(abs_value, 0);
1867 CharPtr prepare_int_buffer(
unsigned num_digits,
1868 const EmptySpec &,
const char *prefix,
unsigned prefix_size) {
1869 unsigned size = prefix_size + num_digits;
1870 CharPtr p = grow_buffer(size);
1871 std::copy(prefix, prefix + prefix_size, p);
1872 return p + size - 1;
1875 template <
typename Spec>
1876 CharPtr prepare_int_buffer(
unsigned num_digits,
1877 const Spec &spec,
const char *prefix,
unsigned prefix_size);
1880 template <
typename T,
typename Spec>
1881 void write_int(T value, Spec spec);
1884 template <
typename T>
1885 void write_double(T value,
const FormatSpec &spec);
1888 template <
typename StrChar>
1890 const StrChar *s, std::size_t size,
const AlignSpec &spec);
1892 template <
typename StrChar>
1894 const internal::Arg::StringValue<StrChar> &str,
const FormatSpec &spec);
1900 void operator<<(typename internal::WCharHelper<wchar_t, Char>::Unsupported);
1902 typename internal::WCharHelper<const wchar_t *, Char>::Unsupported);
1906 void append_float_length(Char *&format_ptr,
long double) {
1907 *format_ptr++ =
'L';
1910 template<
typename T>
1911 void append_float_length(Char *&, T) {}
1913 template <
typename Impl,
typename Char_>
1914 friend class internal::BasicArgFormatter;
1916 friend class internal::PrintfArgFormatter<Char>;
1941 const Char *
data() const FMT_NOEXCEPT{
return &buffer_[0]; }
1948 std::size_t size = buffer_.
size();
1950 buffer_[size] =
'\0';
1959 std::basic_string<Char>
str()
const {
1960 return std::basic_string<Char>(&buffer_[0], buffer_.
size());
1982 BasicFormatter<Char>(args, *
this).format(format);
1987 write_decimal(value);
1991 return *this << IntFormatSpec<unsigned>(value);
1994 write_decimal(value);
1998 return *this << IntFormatSpec<unsigned long>(value);
2001 write_decimal(value);
2011 return *this << IntFormatSpec<ULongLong>(value);
2015 write_double(value, FormatSpec());
2026 write_double(value, FormatSpec());
2034 buffer_.push_back(value);
2039 typename internal::WCharHelper<wchar_t, Char>::Supported value) {
2040 buffer_.push_back(value);
2050 const Char *str = value.data();
2051 buffer_.
append(str, str + value.size());
2056 typename internal::WCharHelper<StringRef, Char>::Supported value) {
2057 const char *str = value.data();
2058 buffer_.
append(str, str + value.size());
2062 template <
typename T,
typename Spec,
typename FillChar>
2063 BasicWriter &operator<<(IntFormatSpec<T, Spec, FillChar> spec) {
2064 internal::CharTraits<Char>::convert(FillChar());
2065 write_int(spec.value(), spec);
2069 template <
typename StrChar>
2070 BasicWriter &operator<<(const StrFormatSpec<StrChar> &spec) {
2071 const StrChar *s = spec.str();
2072 write_str(s, std::char_traits<Char>::length(s), spec);
2076 void clear() FMT_NOEXCEPT{ buffer_.clear(); }
2079 template <
typename Char>
2080 template <
typename StrChar>
2082 const StrChar *s, std::size_t size,
const AlignSpec &spec) {
2083 CharPtr out = CharPtr();
2084 if (spec.width() > size) {
2085 out = grow_buffer(spec.width());
2086 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2087 if (spec.align() == ALIGN_RIGHT) {
2088 std::fill_n(out, spec.width() - size, fill);
2089 out += spec.width() - size;
2091 else if (spec.align() == ALIGN_CENTER) {
2092 out = fill_padding(out, spec.width(), size, fill);
2095 std::fill_n(out + size, spec.width() - size, fill);
2099 out = grow_buffer(size);
2101 std::copy(s, s + size, out);
2105 template <
typename Char>
2106 typename BasicWriter<Char>::CharPtr
2108 CharPtr buffer,
unsigned total_size,
2109 std::size_t content_size,
wchar_t fill) {
2110 std::size_t padding = total_size - content_size;
2111 std::size_t left_padding = padding / 2;
2112 Char fill_char = internal::CharTraits<Char>::cast(fill);
2113 std::fill_n(buffer, left_padding, fill_char);
2114 buffer += left_padding;
2115 CharPtr content = buffer;
2116 std::fill_n(buffer + content_size, padding - left_padding, fill_char);
2120 template <
typename Char>
2121 template <
typename Spec>
2122 typename BasicWriter<Char>::CharPtr
2124 unsigned num_digits,
const Spec &spec,
2125 const char *prefix,
unsigned prefix_size) {
2126 unsigned width = spec.width();
2127 Alignment align = spec.align();
2128 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2129 if (spec.precision() >
static_cast<int>(num_digits)) {
2132 if (prefix_size > 0 && prefix[prefix_size - 1] ==
'0')
2134 unsigned number_size = prefix_size + spec.precision();
2135 AlignSpec subspec(number_size,
'0', ALIGN_NUMERIC);
2136 if (number_size >= width)
2137 return prepare_int_buffer(num_digits, subspec, prefix, prefix_size);
2138 buffer_.reserve(width);
2139 unsigned fill_size = width - number_size;
2140 if (align != ALIGN_LEFT) {
2141 CharPtr p = grow_buffer(fill_size);
2142 std::fill(p, p + fill_size, fill);
2144 CharPtr result = prepare_int_buffer(
2145 num_digits, subspec, prefix, prefix_size);
2146 if (align == ALIGN_LEFT) {
2147 CharPtr p = grow_buffer(fill_size);
2148 std::fill(p, p + fill_size, fill);
2152 unsigned size = prefix_size + num_digits;
2153 if (width <= size) {
2154 CharPtr p = grow_buffer(size);
2155 std::copy(prefix, prefix + prefix_size, p);
2156 return p + size - 1;
2158 CharPtr p = grow_buffer(width);
2159 CharPtr end = p + width;
2160 if (align == ALIGN_LEFT) {
2161 std::copy(prefix, prefix + prefix_size, p);
2163 std::fill(p, end, fill);
2165 else if (align == ALIGN_CENTER) {
2166 p = fill_padding(p, width, size, fill);
2167 std::copy(prefix, prefix + prefix_size, p);
2171 if (align == ALIGN_NUMERIC) {
2172 if (prefix_size != 0) {
2173 p = std::copy(prefix, prefix + prefix_size, p);
2174 size -= prefix_size;
2178 std::copy(prefix, prefix + prefix_size, end - size);
2180 std::fill(p, end - size, fill);
2186 template <
typename Char>
2187 template <
typename T,
typename Spec>
2189 unsigned prefix_size = 0;
2190 typedef typename internal::IntTraits<T>::MainType UnsignedType;
2191 UnsignedType abs_value = value;
2192 char prefix[4] =
"";
2193 if (internal::is_negative(value)) {
2196 abs_value = 0 - abs_value;
2198 else if (spec.flag(SIGN_FLAG)) {
2199 prefix[0] = spec.flag(PLUS_FLAG) ?
'+' :
' ';
2202 switch (spec.type()) {
2204 unsigned num_digits = internal::count_digits(abs_value);
2205 CharPtr p = prepare_int_buffer(
2206 num_digits, spec, prefix, prefix_size) + 1 - num_digits;
2207 internal::format_decimal(
get(p), abs_value, num_digits);
2210 case 'x':
case 'X': {
2211 UnsignedType n = abs_value;
2212 if (spec.flag(HASH_FLAG)) {
2213 prefix[prefix_size++] =
'0';
2214 prefix[prefix_size++] = spec.type();
2216 unsigned num_digits = 0;
2219 }
while ((n >>= 4) != 0);
2220 Char *p =
get(prepare_int_buffer(
2221 num_digits, spec, prefix, prefix_size));
2223 const char *digits = spec.type() ==
'x' ?
2224 "0123456789abcdef" :
"0123456789ABCDEF";
2226 *p-- = digits[n & 0xf];
2227 }
while ((n >>= 4) != 0);
2230 case 'b':
case 'B': {
2231 UnsignedType n = abs_value;
2232 if (spec.flag(HASH_FLAG)) {
2233 prefix[prefix_size++] =
'0';
2234 prefix[prefix_size++] = spec.type();
2236 unsigned num_digits = 0;
2239 }
while ((n >>= 1) != 0);
2240 Char *p =
get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2243 *p-- =
'0' + (n & 1);
2244 }
while ((n >>= 1) != 0);
2248 UnsignedType n = abs_value;
2249 if (spec.flag(HASH_FLAG))
2250 prefix[prefix_size++] =
'0';
2251 unsigned num_digits = 0;
2254 }
while ((n >>= 3) != 0);
2255 Char *p =
get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2258 *p-- =
'0' + (n & 7);
2259 }
while ((n >>= 3) != 0);
2263 internal::report_unknown_type(
2264 spec.type(), spec.flag(CHAR_FLAG) ?
"char" :
"integer");
2269 template <
typename Char>
2270 template <
typename T>
2272 T value,
const FormatSpec &spec) {
2274 char type = spec.type();
2280 case 'e':
case 'f':
case 'g':
case 'a':
2288 case 'E':
case 'G':
case 'A':
2292 internal::report_unknown_type(type,
"double");
2299 if (internal::getsign(static_cast<double>(value))) {
2303 else if (spec.flag(SIGN_FLAG)) {
2304 sign = spec.flag(PLUS_FLAG) ?
'+' :
' ';
2307 if (value != value) {
2310 std::size_t nan_size = 4;
2311 const char *nan = upper ?
" NAN" :
" nan";
2316 CharPtr out = write_str(nan, nan_size, spec);
2322 if (internal::isinfinity(value)) {
2325 std::size_t inf_size = 4;
2326 const char *inf = upper ?
" INF" :
" inf";
2331 CharPtr out = write_str(inf, inf_size, spec);
2337 std::size_t offset = buffer_.size();
2338 unsigned width = spec.width();
2340 buffer_.reserve(buffer_.size() + (
std::max)(width, 1u));
2347 enum { MAX_FORMAT_SIZE = 10 };
2348 Char format[MAX_FORMAT_SIZE];
2349 Char *format_ptr = format;
2350 *format_ptr++ =
'%';
2351 unsigned width_for_sprintf = width;
2352 if (spec.flag(HASH_FLAG))
2353 *format_ptr++ =
'#';
2354 if (spec.align() == ALIGN_CENTER) {
2355 width_for_sprintf = 0;
2358 if (spec.align() == ALIGN_LEFT)
2359 *format_ptr++ =
'-';
2361 *format_ptr++ =
'*';
2363 if (spec.precision() >= 0) {
2364 *format_ptr++ =
'.';
2365 *format_ptr++ =
'*';
2368 append_float_length(format_ptr, value);
2369 *format_ptr++ = type;
2373 Char fill = internal::CharTraits<Char>::cast(spec.fill());
2375 std::size_t buffer_size = buffer_.capacity() - offset;
2380 if (buffer_size == 0) {
2381 buffer_.reserve(offset + 1);
2382 buffer_size = buffer_.capacity() - offset;
2385 Char *start = &buffer_[offset];
2386 int n = internal::CharTraits<Char>::format_float(
2387 start, buffer_size, format, width_for_sprintf, spec.precision(), value);
2388 if (n >= 0 && offset + n < buffer_.capacity()) {
2390 if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
2392 *(start - 1) = sign;
2396 *(start - 1) = fill;
2400 if (spec.align() == ALIGN_CENTER &&
2401 spec.width() >
static_cast<unsigned>(n)) {
2402 width = spec.width();
2403 CharPtr p = grow_buffer(width);
2404 std::copy(p, p + n, p + (width - n) / 2);
2405 fill_padding(p, spec.width(), n, fill);
2408 if (spec.fill() !=
' ' || sign) {
2409 while (*start ==
' ')
2412 *(start - 1) = sign;
2419 buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1);
2449 template <
typename Char,
typename Allocator = std::allocator<Char> >
2452 internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE, Allocator> buffer_;
2458 #if FMT_USE_RVALUE_REFERENCES 2475 buffer_ = std::move(other.buffer_);
2502 template <
typename Char>
2505 internal::FixedBuffer<Char> buffer_;
2515 :
BasicWriter<Char>(buffer_), buffer_(array, size) {}
2523 template <std::
size_t SIZE>
2525 :
BasicWriter<Char>(buffer_), buffer_(array, SIZE) {}
2532 template <
typename Char,
typename T>
2533 void format(BasicFormatter<Char> &f,
const Char *&format_str,
const T &value) {
2534 std::basic_ostringstream<Char> os;
2536 std::basic_string<Char> str = os.str();
2537 internal::Arg arg = internal::MakeValue<Char>(str);
2538 arg.type =
static_cast<internal::Arg::Type
>(
2539 internal::MakeValue<Char>::type(str));
2540 format_str = f.format(format_str, arg);
2545 void report_system_error(
int error_code, StringRef message) FMT_NOEXCEPT;
2547 #if FMT_USE_WINDOWS_H 2552 void init(
int error_code, CStringRef format_str,
ArgList args);
2579 WindowsError(
int error_code, CStringRef message) {
2580 init(error_code, message,
ArgList());
2582 FMT_VARIADIC_CTOR(WindowsError, init,
int, CStringRef)
2587 void report_windows_error(
int error_code, StringRef message) FMT_NOEXCEPT;
2591 enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
2599 void print_colored(Color c, CStringRef format,
ArgList args);
2608 inline std::string format(CStringRef format_str,
ArgList args) {
2610 w.
write(format_str, args);
2614 inline std::wstring format(WCStringRef format_str,
ArgList args) {
2616 w.
write(format_str, args);
2627 void print(std::FILE *f, CStringRef format_str,
ArgList args);
2636 void print(CStringRef format_str,
ArgList args);
2645 void print(std::ostream &os, CStringRef format_str,
ArgList args);
2647 template <
typename Char>
2649 internal::PrintfFormatter<Char>(args).format(w, format);
2659 inline std::string sprintf(CStringRef format,
ArgList args) {
2661 printf(w, format, args);
2672 int fprintf(std::FILE *f, CStringRef format,
ArgList args);
2681 inline int printf(CStringRef format,
ArgList args) {
2682 return fprintf(stdout, format, args);
2692 enum { BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3 };
2693 mutable char buffer_[BUFFER_SIZE];
2697 char *format_decimal(ULongLong value) {
2698 char *buffer_end = buffer_ + BUFFER_SIZE - 1;
2699 while (value >= 100) {
2703 unsigned index = (value % 100) * 2;
2705 *--buffer_end = internal::Data::DIGITS[index + 1];
2706 *--buffer_end = internal::Data::DIGITS[index];
2709 *--buffer_end =
static_cast<char>(
'0' + value);
2712 unsigned index =
static_cast<unsigned>(value * 2);
2713 *--buffer_end = internal::Data::DIGITS[index + 1];
2714 *--buffer_end = internal::Data::DIGITS[index];
2718 void FormatSigned(LongLong value) {
2719 ULongLong abs_value =
static_cast<ULongLong
>(value);
2720 bool negative = value < 0;
2722 abs_value = 0 - abs_value;
2723 str_ = format_decimal(abs_value);
2729 explicit FormatInt(
int value) { FormatSigned(value); }
2730 explicit FormatInt(
long value) { FormatSigned(value); }
2731 explicit FormatInt(LongLong value) { FormatSigned(value); }
2732 explicit FormatInt(
unsigned value) : str_(format_decimal(value)) {}
2733 explicit FormatInt(
unsigned long value) : str_(format_decimal(value)) {}
2734 explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
2739 std::size_t
size()
const {
return buffer_ - str_ + BUFFER_SIZE - 1; }
2745 const char *
data()
const {
return str_; }
2752 buffer_[BUFFER_SIZE - 1] =
'\0';
2761 std::string
str()
const {
return std::string(str_, size()); }
2767 template <
typename T>
2768 inline void format_decimal(
char *&buffer, T value) {
2769 typename internal::IntTraits<T>::MainType abs_value = value;
2770 if (internal::is_negative(value)) {
2772 abs_value = 0 - abs_value;
2774 if (abs_value < 100) {
2775 if (abs_value < 10) {
2776 *buffer++ =
static_cast<char>(
'0' + abs_value);
2779 unsigned index =
static_cast<unsigned>(abs_value * 2);
2780 *buffer++ = internal::Data::DIGITS[index];
2781 *buffer++ = internal::Data::DIGITS[index + 1];
2784 unsigned num_digits = internal::count_digits(abs_value);
2785 internal::format_decimal(buffer, abs_value, num_digits);
2786 buffer += num_digits;
2796 template <
typename T>
2797 inline internal::NamedArg<char> arg(StringRef name,
const T &arg) {
2798 return internal::NamedArg<char>(name, arg);
2801 template <
typename T>
2802 inline internal::NamedArg<wchar_t> arg(WStringRef name,
const T &arg) {
2803 return internal::NamedArg<wchar_t>(name, arg);
2808 template <
typename Char>
2809 void arg(StringRef,
const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
2810 template <
typename Char>
2811 void arg(WStringRef,
const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
2819 # pragma GCC system_header 2823 #define FMT_EXPAND(args) args 2827 #define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N()) 2828 #define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__)) 2829 #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N 2830 #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 2832 #define FMT_CONCAT(a, b) a##b 2833 #define FMT_FOR_EACH_(N, f, ...) \ 2834 FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) 2835 #define FMT_FOR_EACH(f, ...) \ 2836 FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__)) 2838 #define FMT_ADD_ARG_NAME(type, index) type arg##index 2839 #define FMT_GET_ARG_NAME(type, index) arg##index 2841 #if FMT_USE_VARIADIC_TEMPLATES 2842 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ 2843 template <typename... Args> \ 2844 ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ 2845 const Args & ... args) { \ 2846 typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ 2847 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ 2848 fmt::internal::make_arg_list<Char>(array, args...)); \ 2853 # define FMT_WRAP(Char, ReturnType, func, call, n, ...) \ 2854 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 2855 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ 2856 FMT_GEN(n, FMT_MAKE_ARG)) { \ 2857 fmt::internal::ArgArray<n>::Type arr = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ 2858 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \ 2859 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \ 2862 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ 2863 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \ 2864 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \ 2866 FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \ 2867 FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \ 2868 FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \ 2869 FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \ 2870 FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \ 2871 FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \ 2872 FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \ 2873 FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \ 2874 FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \ 2875 FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \ 2876 FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \ 2877 FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \ 2878 FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \ 2879 FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \ 2880 FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__) 2881 #endif // FMT_USE_VARIADIC_TEMPLATES 2906 #define FMT_VARIADIC(ReturnType, func, ...) \ 2907 FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__) 2909 #define FMT_VARIADIC_W(ReturnType, func, ...) \ 2910 FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) 2912 #define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id) 2914 #define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id) 2927 #define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__) 2929 #define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__) 2932 FMT_VARIADIC(std::string, format, CStringRef)
2933 FMT_VARIADIC_W(std::wstring, format, WCStringRef)
2934 FMT_VARIADIC(
void, print, CStringRef)
2935 FMT_VARIADIC(
void, print, std::FILE *, CStringRef)
2936 FMT_VARIADIC(
void, print, std::ostream &, CStringRef)
2937 FMT_VARIADIC(
void, print_colored, Color, CStringRef)
2938 FMT_VARIADIC(std::string, sprintf, CStringRef)
2939 FMT_VARIADIC(
int, printf, CStringRef)
2940 FMT_VARIADIC(
int, fprintf, std::FILE *, CStringRef)
2944 #if FMT_GCC_VERSION >= 406 2945 # pragma GCC diagnostic pop 2949 # pragma clang diagnostic pop 2952 #ifdef FMT_HEADER_ONLY 2953 # include "format.cc" 2956 #endif // FMT_FORMAT_H_ BasicCStringRef(const Char *s)
Definition: format.h:307
double max(const series< double > &series, size_t period)
Returns the highest value found in series over given .
Definition: TSAFunctionsScalar.cpp:180
BasicStringRef(const Char *s)
Definition: format.h:239
const Char * data() const
Definition: format.h:260
void resize(std::size_t new_size)
Definition: format.h:387
BasicWriter(Buffer< Char > &b)
Definition: format.h:1922
void write(BasicCStringRef< Char > format, ArgList args)
Definition: format.h:1981
std::size_t capacity() const
Definition: format.h:382
BasicArrayWriter(Char *array, std::size_t size)
Definition: format.h:2514
const Char * c_str() const
Definition: format.h:317
Definition: TSASQLite.h:39
Definition: format.h:2503
std::basic_string< Char > str() const
Definition: format.h:1959
BasicWriter & operator<<(ULongLong value)
Definition: format.h:2010
BasicStringRef(const Char *s, std::size_t size)
Definition: format.h:231
const Char * data() const FMT_NOEXCEPT
Definition: format.h:1941
virtual ~BasicWriter()
Definition: format.h:1930
BasicCStringRef(const std::basic_string< Char > &s)
Definition: format.h:314
void append(const U *begin, const U *end)
Definition: format.h:421
std::basic_string< Char > to_string() const
Definition: format.h:255
Definition: format.h:2450
std::ostream & operator<<(std::ostream &s, const transaction &t)
Writes human readable transaction information to stream.
Definition: TSAOrder.cpp:779
Definition: format.h:1174
std::size_t size() const
Definition: format.h:379
std::size_t size() const
Definition: format.h:1935
SystemError(int error_code, CStringRef message)
Definition: format.h:1791
BasicWriter & operator<<(char value)
Definition: format.h:2033
internal::Arg operator[](unsigned index) const
Definition: format.h:1211
sref< bool > operator==(numeric_series_cref a, numeric_series_cref b)
comparison.
Definition: TSADSLBase.cpp:130
std::size_t size() const
Definition: format.h:263
BasicWriter & operator<<(long double value)
Definition: format.h:2025
BasicArrayWriter(Char(&array)[SIZE])
Definition: format.h:2524
BasicStringRef(const std::basic_string< Char > &s)
Definition: format.h:247
void reserve(std::size_t capacity)
Definition: format.h:398
Definition: format.cpp:101
Definition: format.h:1757
const Char * c_str() const
Definition: format.h:1947
sref< bool > operator<(numeric_series_cref a, numeric_series_cref b)
comparison.
Definition: TSADSLBase.cpp:78