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