2 Formatting library for C++
4 Copyright (c) 2012 - present, Victor Zverovich
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 --- Optional exception to the license ---
27 As an exception, if, as a result of your compiling your source code, portions
28 of this Software are embedded into a machine-executable object form of such
29 source code, you may redistribute such embedded portions in such object form
30 without including the above copyright and permission notices.
36 #include <cmath> // std::signbit
37 #include <cstdint> // uint32_t
38 #include <cstring> // std::memcpy
39 #include <initializer_list> // std::initializer_list
40 #include <limits> // std::numeric_limits
41 #include <memory> // std::uninitialized_copy
42 #include <stdexcept> // std::runtime_error
43 #include <system_error> // std::system_error
45 #ifdef __cpp_lib_bit_cast
46 # include <bit> // std::bit_cast
51 #if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L
52 # define FMT_INLINE_VARIABLE inline
54 # define FMT_INLINE_VARIABLE
57 #if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
58 # define FMT_FALLTHROUGH [[fallthrough]]
59 #elif defined(__clang__)
60 # define FMT_FALLTHROUGH [[clang::fallthrough]]
61 #elif FMT_GCC_VERSION >= 700 && \
62 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
63 # define FMT_FALLTHROUGH [[gnu::fallthrough]]
65 # define FMT_FALLTHROUGH
68 #ifndef FMT_DEPRECATED
69 # if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VERSION >= 1900
70 # define FMT_DEPRECATED [[deprecated]]
72 # if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
73 # define FMT_DEPRECATED __attribute__((deprecated))
74 # elif FMT_MSC_VERSION
75 # define FMT_DEPRECATED __declspec(deprecated)
77 # define FMT_DEPRECATED /* deprecated */
82 #ifndef FMT_NO_UNIQUE_ADDRESS
83 # if FMT_CPLUSPLUS >= 202002L
84 # if FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
85 # define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
86 // VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485)
87 # elif (FMT_MSC_VERSION >= 1929) && !FMT_CLANG_VERSION
88 # define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
92 #ifndef FMT_NO_UNIQUE_ADDRESS
93 # define FMT_NO_UNIQUE_ADDRESS
96 // Visibility when compiled as a shared library/object.
97 #if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
98 # define FMT_SO_VISIBILITY(value) FMT_VISIBILITY(value)
100 # define FMT_SO_VISIBILITY(value)
104 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
106 # define FMT_HAS_BUILTIN(x) 0
109 #if FMT_GCC_VERSION || FMT_CLANG_VERSION
110 # define FMT_NOINLINE __attribute__((noinline))
112 # define FMT_NOINLINE
117 # if FMT_MSC_VERSION || defined(__NVCC__)
120 template <typename Exception> inline void do_throw(const Exception& x) {
121 // Silence unreachable code warnings in MSVC and NVCC because these
122 // are nearly impossible to fix in a generic code.
123 volatile bool b = true;
126 } // namespace detail
128 # define FMT_THROW(x) detail::do_throw(x)
130 # define FMT_THROW(x) throw x
133 # define FMT_THROW(x) \
134 ::fmt::detail::assert_fail(__FILE__, __LINE__, (x).what())
140 # define FMT_CATCH(x) catch (x)
142 # define FMT_TRY if (true)
143 # define FMT_CATCH(x) if (false)
146 #ifndef FMT_MAYBE_UNUSED
147 # if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
148 # define FMT_MAYBE_UNUSED [[maybe_unused]]
150 # define FMT_MAYBE_UNUSED
154 #ifndef FMT_USE_USER_DEFINED_LITERALS
155 // EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
157 // GCC before 4.9 requires a space in `operator"" _a` which is invalid in later
158 // compiler versions.
159 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 409 || \
160 FMT_MSC_VERSION >= 1900) && \
161 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480)
162 # define FMT_USE_USER_DEFINED_LITERALS 1
164 # define FMT_USE_USER_DEFINED_LITERALS 0
168 // Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
169 // integer formatter template instantiations to just one by only using the
170 // largest integer type. This results in a reduction in binary size but will
171 // cause a decrease in integer formatting performance.
172 #if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
173 # define FMT_REDUCE_INT_INSTANTIATIONS 0
176 // __builtin_clz is broken in clang with Microsoft CodeGen:
177 // https://github.com/fmtlib/fmt/issues/519.
179 # if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
180 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
182 # if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
183 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
187 // __builtin_ctz is broken in Intel Compiler Classic on Windows:
188 // https://github.com/fmtlib/fmt/issues/2510.
190 # if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION || \
191 defined(__NVCOMPILER)
192 # define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
194 # if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || \
195 FMT_ICC_VERSION || defined(__NVCOMPILER)
196 # define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
201 # include <intrin.h> // _BitScanReverse[64], _BitScanForward[64], _umul128
204 // Some compilers masquerade as both MSVC and GCC-likes or otherwise support
205 // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
206 // MSVC intrinsics if the clz and clzll builtins are not available.
207 #if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) && \
208 !defined(FMT_BUILTIN_CTZLL)
211 // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
212 # if !defined(__clang__)
213 # pragma intrinsic(_BitScanForward)
214 # pragma intrinsic(_BitScanReverse)
216 # pragma intrinsic(_BitScanForward64)
217 # pragma intrinsic(_BitScanReverse64)
221 inline auto clz(uint32_t x) -> int {
223 _BitScanReverse(&r, x);
224 FMT_ASSERT(x != 0, "");
225 // Static analysis complains about using uninitialized data
226 // "r", but the only way that can happen is if "x" is 0,
227 // which the callers guarantee to not happen.
228 FMT_MSC_WARNING(suppress : 6102)
229 return 31 ^ static_cast<int>(r);
231 # define FMT_BUILTIN_CLZ(n) detail::clz(n)
233 inline auto clzll(uint64_t x) -> int {
236 _BitScanReverse64(&r, x);
238 // Scan the high 32 bits.
239 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
240 return 63 ^ static_cast<int>(r + 32);
241 // Scan the low 32 bits.
242 _BitScanReverse(&r, static_cast<uint32_t>(x));
244 FMT_ASSERT(x != 0, "");
245 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
246 return 63 ^ static_cast<int>(r);
248 # define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
250 inline auto ctz(uint32_t x) -> int {
252 _BitScanForward(&r, x);
253 FMT_ASSERT(x != 0, "");
254 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
255 return static_cast<int>(r);
257 # define FMT_BUILTIN_CTZ(n) detail::ctz(n)
259 inline auto ctzll(uint64_t x) -> int {
261 FMT_ASSERT(x != 0, "");
262 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
264 _BitScanForward64(&r, x);
266 // Scan the low 32 bits.
267 if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r);
268 // Scan the high 32 bits.
269 _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
272 return static_cast<int>(r);
274 # define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
275 } // namespace detail
282 FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) {
283 ignore_unused(condition);
285 if (condition) throw std::runtime_error("fuzzing limit reached");
289 template <typename CharT, CharT... C> struct string_literal {
290 static constexpr CharT value[sizeof...(C)] = {C...};
291 constexpr operator basic_string_view<CharT>() const {
292 return {value, sizeof...(C)};
296 #if FMT_CPLUSPLUS < 201703L
297 template <typename CharT, CharT... C>
298 constexpr CharT string_literal<CharT, C...>::value[sizeof...(C)];
301 // Implementation of std::bit_cast for pre-C++20.
302 template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>
303 FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
304 #ifdef __cpp_lib_bit_cast
305 if (is_constant_evaluated()) return std::bit_cast<To>(from);
308 // The cast suppresses a bogus -Wclass-memaccess on GCC.
309 std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
313 inline auto is_big_endian() -> bool {
316 #elif defined(__BIG_ENDIAN__)
318 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
319 return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
322 char data[sizeof(int)];
324 return bit_cast<bytes>(1).data[0] == 0;
328 class uint128_fallback {
333 constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}
334 constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}
336 constexpr auto high() const noexcept -> uint64_t { return hi_; }
337 constexpr auto low() const noexcept -> uint64_t { return lo_; }
339 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
340 constexpr explicit operator T() const {
341 return static_cast<T>(lo_);
344 friend constexpr auto operator==(const uint128_fallback& lhs,
345 const uint128_fallback& rhs) -> bool {
346 return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
348 friend constexpr auto operator!=(const uint128_fallback& lhs,
349 const uint128_fallback& rhs) -> bool {
350 return !(lhs == rhs);
352 friend constexpr auto operator>(const uint128_fallback& lhs,
353 const uint128_fallback& rhs) -> bool {
354 return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;
356 friend constexpr auto operator|(const uint128_fallback& lhs,
357 const uint128_fallback& rhs)
358 -> uint128_fallback {
359 return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};
361 friend constexpr auto operator&(const uint128_fallback& lhs,
362 const uint128_fallback& rhs)
363 -> uint128_fallback {
364 return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
366 friend constexpr auto operator~(const uint128_fallback& n)
367 -> uint128_fallback {
368 return {~n.hi_, ~n.lo_};
370 friend auto operator+(const uint128_fallback& lhs,
371 const uint128_fallback& rhs) -> uint128_fallback {
372 auto result = uint128_fallback(lhs);
376 friend auto operator*(const uint128_fallback& lhs, uint32_t rhs)
377 -> uint128_fallback {
378 FMT_ASSERT(lhs.hi_ == 0, "");
379 uint64_t hi = (lhs.lo_ >> 32) * rhs;
380 uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;
381 uint64_t new_lo = (hi << 32) + lo;
382 return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};
384 friend auto operator-(const uint128_fallback& lhs, uint64_t rhs)
385 -> uint128_fallback {
386 return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};
388 FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback {
389 if (shift == 64) return {0, hi_};
390 if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64);
391 return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
393 FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback {
394 if (shift == 64) return {lo_, 0};
395 if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64);
396 return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
398 FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& {
399 return *this = *this >> shift;
401 FMT_CONSTEXPR void operator+=(uint128_fallback n) {
402 uint64_t new_lo = lo_ + n.lo_;
403 uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0);
404 FMT_ASSERT(new_hi >= hi_, "");
408 FMT_CONSTEXPR void operator&=(uint128_fallback n) {
413 FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback& {
414 if (is_constant_evaluated()) {
416 hi_ += (lo_ < n ? 1 : 0);
419 #if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)
420 unsigned long long carry;
421 lo_ = __builtin_addcll(lo_, n, 0, &carry);
423 #elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)
424 unsigned long long result;
425 auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result);
428 #elif defined(_MSC_VER) && defined(_M_X64)
429 auto carry = _addcarry_u64(0, lo_, n, &lo_);
430 _addcarry_u64(carry, hi_, 0, &hi_);
433 hi_ += (lo_ < n ? 1 : 0);
439 using uint128_t = conditional_t<FMT_USE_INT128, uint128_opt, uint128_fallback>;
442 using uintptr_t = ::uintptr_t;
444 using uintptr_t = uint128_t;
447 // Returns the largest possible value for type T. Same as
448 // std::numeric_limits<T>::max() but shorter and not affected by the max macro.
449 template <typename T> constexpr auto max_value() -> T {
450 return (std::numeric_limits<T>::max)();
452 template <typename T> constexpr auto num_bits() -> int {
453 return std::numeric_limits<T>::digits;
455 // std::numeric_limits<T>::digits may return 0 for 128-bit ints.
456 template <> constexpr auto num_bits<int128_opt>() -> int { return 128; }
457 template <> constexpr auto num_bits<uint128_t>() -> int { return 128; }
459 // A heterogeneous bit_cast used for converting 96-bit long double to uint128_t
460 // and 128-bit pointers to uint128_fallback.
461 template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) > sizeof(From))>
462 inline auto bit_cast(const From& from) -> To {
463 constexpr auto size = static_cast<int>(sizeof(From) / sizeof(unsigned));
465 unsigned value[static_cast<unsigned>(size)];
466 } data = bit_cast<data_t>(from);
468 if (const_check(is_big_endian())) {
469 for (int i = 0; i < size; ++i)
470 result = (result << num_bits<unsigned>()) | data.value[i];
472 for (int i = size - 1; i >= 0; --i)
473 result = (result << num_bits<unsigned>()) | data.value[i];
478 template <typename UInt>
479 FMT_CONSTEXPR20 inline auto countl_zero_fallback(UInt n) -> int {
481 constexpr UInt msb_mask = static_cast<UInt>(1) << (num_bits<UInt>() - 1);
482 for (; (n & msb_mask) == 0; n <<= 1) lz++;
486 FMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int {
487 #ifdef FMT_BUILTIN_CLZ
488 if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n);
490 return countl_zero_fallback(n);
493 FMT_CONSTEXPR20 inline auto countl_zero(uint64_t n) -> int {
494 #ifdef FMT_BUILTIN_CLZLL
495 if (!is_constant_evaluated()) return FMT_BUILTIN_CLZLL(n);
497 return countl_zero_fallback(n);
500 FMT_INLINE void assume(bool condition) {
502 #if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
503 __builtin_assume(condition);
504 #elif FMT_GCC_VERSION
505 if (!condition) __builtin_unreachable();
509 // An approximation of iterator_t for pre-C++20 systems.
510 template <typename T>
511 using iterator_t = decltype(std::begin(std::declval<T&>()));
512 template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>()));
514 // A workaround for std::string not having mutable data() until C++17.
515 template <typename Char>
516 inline auto get_data(std::basic_string<Char>& s) -> Char* {
519 template <typename Container>
520 inline auto get_data(Container& c) -> typename Container::value_type* {
524 // Attempts to reserve space for n extra characters in the output range.
525 // Returns a pointer to the reserved range or a reference to it.
526 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
527 #if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
528 __attribute__((no_sanitize("undefined")))
531 reserve(std::back_insert_iterator<Container> it, size_t n) ->
532 typename Container::value_type* {
533 Container& c = get_container(it);
534 size_t size = c.size();
536 return get_data(c) + size;
539 template <typename T>
540 inline auto reserve(buffer_appender<T> it, size_t n) -> buffer_appender<T> {
541 buffer<T>& buf = get_container(it);
542 buf.try_reserve(buf.size() + n);
546 template <typename Iterator>
547 constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
551 template <typename OutputIt>
552 using reserve_iterator =
553 remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>;
555 template <typename T, typename OutputIt>
556 constexpr auto to_pointer(OutputIt, size_t) -> T* {
559 template <typename T> auto to_pointer(buffer_appender<T> it, size_t n) -> T* {
560 buffer<T>& buf = get_container(it);
561 auto size = buf.size();
562 if (buf.capacity() < size + n) return nullptr;
563 buf.try_resize(size + n);
564 return buf.data() + size;
567 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
568 inline auto base_iterator(std::back_insert_iterator<Container> it,
569 typename Container::value_type*)
570 -> std::back_insert_iterator<Container> {
574 template <typename Iterator>
575 constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
579 // <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
581 template <typename OutputIt, typename Size, typename T>
582 FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
584 for (Size i = 0; i < count; ++i) *out++ = value;
587 template <typename T, typename Size>
588 FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
589 if (is_constant_evaluated()) {
590 return fill_n<T*, Size, T>(out, count, value);
592 std::memset(out, value, to_unsigned(count));
597 using char8_type = char8_t;
599 enum char8_type : unsigned char {};
602 template <typename OutChar, typename InputIt, typename OutputIt>
603 FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end,
604 OutputIt out) -> OutputIt {
605 return copy_str<OutChar>(begin, end, out);
608 // A public domain branchless UTF-8 decoder by Christopher Wellons:
609 // https://github.com/skeeto/branchless-utf8
610 /* Decode the next character, c, from s, reporting errors in e.
612 * Since this is a branchless decoder, four bytes will be read from the
613 * buffer regardless of the actual length of the next character. This
614 * means the buffer _must_ have at least three bytes of zero padding
615 * following the end of the data stream.
617 * Errors are reported in e, which will be non-zero if the parsed
618 * character was somehow invalid: invalid byte sequence, non-canonical
619 * encoding, or a surrogate half.
621 * The function returns a pointer to the next character. When an error
622 * occurs, this pointer will be a guess that depends on the particular
623 * error, but it will always advance at least one byte.
625 FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
627 constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
628 constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
629 constexpr const int shiftc[] = {0, 18, 12, 6, 0};
630 constexpr const int shifte[] = {0, 6, 4, 2, 0};
632 int len = "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4"
633 [static_cast<unsigned char>(*s) >> 3];
634 // Compute the pointer to the next character early so that the next
635 // iteration can start working on the next character. Neither Clang
636 // nor GCC figure out this reordering on their own.
637 const char* next = s + len + !len;
639 using uchar = unsigned char;
641 // Assume a four-byte character and load four bytes. Unused bits are
643 *c = uint32_t(uchar(s[0]) & masks[len]) << 18;
644 *c |= uint32_t(uchar(s[1]) & 0x3f) << 12;
645 *c |= uint32_t(uchar(s[2]) & 0x3f) << 6;
646 *c |= uint32_t(uchar(s[3]) & 0x3f) << 0;
649 // Accumulate the various error conditions.
650 *e = (*c < mins[len]) << 6; // non-canonical encoding
651 *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half?
652 *e |= (*c > 0x10FFFF) << 8; // out of range?
653 *e |= (uchar(s[1]) & 0xc0) >> 2;
654 *e |= (uchar(s[2]) & 0xc0) >> 4;
655 *e |= uchar(s[3]) >> 6;
656 *e ^= 0x2a; // top two bits of each tail byte correct?
662 constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point = ~uint32_t();
664 // Invokes f(cp, sv) for every code point cp in s with sv being the string view
665 // corresponding to the code point. cp is invalid_code_point on error.
666 template <typename F>
667 FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) {
668 auto decode = [f](const char* buf_ptr, const char* ptr) {
669 auto cp = uint32_t();
671 auto end = utf8_decode(buf_ptr, &cp, &error);
672 bool result = f(error ? invalid_code_point : cp,
673 string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));
674 return result ? (error ? buf_ptr + 1 : end) : nullptr;
677 const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars.
678 if (s.size() >= block_size) {
679 for (auto end = p + s.size() - block_size + 1; p < end;) {
684 if (auto num_chars_left = s.data() + s.size() - p) {
685 char buf[2 * block_size - 1] = {};
686 copy_str<char>(p, p + num_chars_left, buf);
687 const char* buf_ptr = buf;
689 auto end = decode(buf_ptr, p);
693 } while (buf_ptr - buf < num_chars_left);
697 template <typename Char>
698 inline auto compute_width(basic_string_view<Char> s) -> size_t {
702 // Computes approximate display width of a UTF-8 string.
703 FMT_CONSTEXPR inline auto compute_width(string_view s) -> size_t {
704 size_t num_code_points = 0;
705 // It is not a lambda for compatibility with C++14.
706 struct count_code_points {
708 FMT_CONSTEXPR auto operator()(uint32_t cp, string_view) const -> bool {
709 *count += detail::to_unsigned(
712 (cp <= 0x115f || // Hangul Jamo init. consonants
713 cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET
714 cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET
715 // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:
716 (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
717 (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables
718 (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs
719 (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms
720 (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms
721 (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms
722 (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms
723 (cp >= 0x20000 && cp <= 0x2fffd) || // CJK
724 (cp >= 0x30000 && cp <= 0x3fffd) ||
725 // Miscellaneous Symbols and Pictographs + Emoticons:
726 (cp >= 0x1f300 && cp <= 0x1f64f) ||
727 // Supplemental Symbols and Pictographs:
728 (cp >= 0x1f900 && cp <= 0x1f9ff))));
732 // We could avoid branches by using utf8_decode directly.
733 for_each_codepoint(s, count_code_points{&num_code_points});
734 return num_code_points;
737 inline auto compute_width(basic_string_view<char8_type> s) -> size_t {
738 return compute_width(
739 string_view(reinterpret_cast<const char*>(s.data()), s.size()));
742 template <typename Char>
743 inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
744 size_t size = s.size();
745 return n < size ? n : size;
748 // Calculates the index of the nth code point in a UTF-8 string.
749 inline auto code_point_index(string_view s, size_t n) -> size_t {
750 size_t result = s.size();
751 const char* begin = s.begin();
752 for_each_codepoint(s, [begin, &n, &result](uint32_t, string_view sv) {
757 result = to_unsigned(sv.begin() - begin);
763 inline auto code_point_index(basic_string_view<char8_type> s, size_t n)
765 return code_point_index(
766 string_view(reinterpret_cast<const char*>(s.data()), s.size()), n);
769 template <typename T> struct is_integral : std::is_integral<T> {};
770 template <> struct is_integral<int128_opt> : std::true_type {};
771 template <> struct is_integral<uint128_t> : std::true_type {};
773 template <typename T>
775 std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
776 std::is_same<T, int128_opt>::value>;
778 template <typename T>
780 bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
781 !std::is_same<T, char>::value &&
782 !std::is_same<T, wchar_t>::value>;
784 #ifndef FMT_USE_FLOAT
785 # define FMT_USE_FLOAT 1
787 #ifndef FMT_USE_DOUBLE
788 # define FMT_USE_DOUBLE 1
790 #ifndef FMT_USE_LONG_DOUBLE
791 # define FMT_USE_LONG_DOUBLE 1
794 #ifndef FMT_USE_FLOAT128
796 // Clang emulates GCC, so it has to appear early.
797 # if FMT_HAS_INCLUDE(<quadmath.h>)
798 # define FMT_USE_FLOAT128 1
800 # elif defined(__GNUC__)
802 # if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__)
803 # define FMT_USE_FLOAT128 1
806 # ifndef FMT_USE_FLOAT128
807 # define FMT_USE_FLOAT128 0
812 using float128 = __float128;
814 using float128 = void;
816 template <typename T> using is_float128 = std::is_same<T, float128>;
818 template <typename T>
819 using is_floating_point =
820 bool_constant<std::is_floating_point<T>::value || is_float128<T>::value>;
822 template <typename T, bool = std::is_floating_point<T>::value>
823 struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&
824 sizeof(T) <= sizeof(double)> {};
825 template <typename T> struct is_fast_float<T, false> : std::false_type {};
827 template <typename T>
828 using is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;
830 #ifndef FMT_USE_FULL_CACHE_DRAGONBOX
831 # define FMT_USE_FULL_CACHE_DRAGONBOX 0
834 template <typename T>
835 template <typename U>
836 void buffer<T>::append(const U* begin, const U* end) {
837 while (begin != end) {
838 auto count = to_unsigned(end - begin);
839 try_reserve(size_ + count);
840 auto free_cap = capacity_ - size_;
841 if (free_cap < count) count = free_cap;
842 std::uninitialized_copy_n(begin, count, ptr_ + size_);
848 template <typename T, typename Enable = void>
849 struct is_locale : std::false_type {};
850 template <typename T>
851 struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {};
852 } // namespace detail
856 // The number of characters to store in the basic_memory_buffer object itself
857 // to avoid dynamic memory allocation.
858 enum { inline_buffer_size = 500 };
862 A dynamically growing memory buffer for trivially copyable/constructible types
863 with the first ``SIZE`` elements stored in the object itself.
865 You can use the ``memory_buffer`` type alias for ``char`` instead.
869 auto out = fmt::memory_buffer();
870 fmt::format_to(std::back_inserter(out), "The answer is {}.", 42);
872 This will append the following output to the ``out`` object:
878 The output can be converted to an ``std::string`` with ``to_string(out)``.
881 template <typename T, size_t SIZE = inline_buffer_size,
882 typename Allocator = std::allocator<T>>
883 class basic_memory_buffer final : public detail::buffer<T> {
887 // Don't inherit from Allocator to avoid generating type_info for it.
888 FMT_NO_UNIQUE_ADDRESS Allocator alloc_;
890 // Deallocate memory allocated by the buffer.
891 FMT_CONSTEXPR20 void deallocate() {
892 T* data = this->data();
893 if (data != store_) alloc_.deallocate(data, this->capacity());
897 FMT_CONSTEXPR20 void grow(size_t size) override {
898 detail::abort_fuzzing_if(size > 5000);
899 const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
900 size_t old_capacity = this->capacity();
901 size_t new_capacity = old_capacity + old_capacity / 2;
902 if (size > new_capacity)
904 else if (new_capacity > max_size)
905 new_capacity = size > max_size ? size : max_size;
906 T* old_data = this->data();
908 std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
909 // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
910 detail::assume(this->size() <= new_capacity);
911 // The following code doesn't throw, so the raw pointer above doesn't leak.
912 std::uninitialized_copy_n(old_data, this->size(), new_data);
913 this->set(new_data, new_capacity);
914 // deallocate must not throw according to the standard, but even if it does,
915 // the buffer already uses the new storage and will deallocate it in
917 if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
921 using value_type = T;
922 using const_reference = const T&;
924 FMT_CONSTEXPR20 explicit basic_memory_buffer(
925 const Allocator& alloc = Allocator())
927 this->set(store_, SIZE);
928 if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
930 FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
933 // Move data from other to this buffer.
934 FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
935 alloc_ = std::move(other.alloc_);
936 T* data = other.data();
937 size_t size = other.size(), capacity = other.capacity();
938 if (data == other.store_) {
939 this->set(store_, capacity);
940 detail::copy_str<T>(other.store_, other.store_ + size, store_);
942 this->set(data, capacity);
943 // Set pointer to the inline array so that delete is not called
944 // when deallocating.
945 other.set(other.store_, 0);
954 Constructs a :class:`fmt::basic_memory_buffer` object moving the content
955 of the other object to it.
958 FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) noexcept {
964 Moves the content of the other ``basic_memory_buffer`` object to this one.
967 auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& {
968 FMT_ASSERT(this != &other, "");
974 // Returns a copy of the allocator associated with this buffer.
975 auto get_allocator() const -> Allocator { return alloc_; }
978 Resizes the buffer to contain *count* elements. If T is a POD type new
979 elements may not be initialized.
981 FMT_CONSTEXPR20 void resize(size_t count) { this->try_resize(count); }
983 /** Increases the buffer capacity to *new_capacity*. */
984 void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
986 using detail::buffer<T>::append;
987 template <typename ContiguousRange>
988 void append(const ContiguousRange& range) {
989 append(range.data(), range.data() + range.size());
993 using memory_buffer = basic_memory_buffer<char>;
995 template <typename T, size_t SIZE, typename Allocator>
996 struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
1001 FMT_API auto write_console(int fd, string_view text) -> bool;
1002 FMT_API auto write_console(std::FILE* f, string_view text) -> bool;
1003 FMT_API void print(std::FILE*, string_view);
1004 } // namespace detail
1008 // Suppress a misleading warning in older versions of clang.
1009 #if FMT_CLANG_VERSION
1010 # pragma clang diagnostic ignored "-Wweak-vtables"
1013 /** An error reported from a formatting function. */
1014 class FMT_SO_VISIBILITY("default") format_error : public std::runtime_error {
1016 using std::runtime_error::runtime_error;
1019 namespace detail_exported {
1020 #if FMT_USE_NONTYPE_TEMPLATE_ARGS
1021 template <typename Char, size_t N> struct fixed_string {
1022 constexpr fixed_string(const Char (&str)[N]) {
1023 detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str),
1030 // Converts a compile-time string to basic_string_view.
1031 template <typename Char, size_t N>
1032 constexpr auto compile_string_to_view(const Char (&s)[N])
1033 -> basic_string_view<Char> {
1034 // Remove trailing NUL character if needed. Won't be present if this is used
1035 // with a raw character array (i.e. not defined as a string).
1036 return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
1038 template <typename Char>
1039 constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
1040 -> basic_string_view<Char> {
1041 return {s.data(), s.size()};
1043 } // namespace detail_exported
1047 basic_format_arg<format_context> value_;
1050 template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>
1051 loc_value(T value) : value_(detail::make_arg<format_context>(value)) {}
1053 template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>
1056 template <typename Visitor> auto visit(Visitor&& vis) -> decltype(vis(0)) {
1057 return visit_format_arg(vis, value_);
1061 // A locale facet that formats values in UTF-8.
1062 // It is parameterized on the locale to avoid the heavy <locale> include.
1063 template <typename Locale> class format_facet : public Locale::facet {
1065 std::string separator_;
1066 std::string grouping_;
1067 std::string decimal_point_;
1070 virtual auto do_put(appender out, loc_value val,
1071 const format_specs<>& specs) const -> bool;
1074 static FMT_API typename Locale::id id;
1076 explicit format_facet(Locale& loc);
1077 explicit format_facet(string_view sep = "",
1078 std::initializer_list<unsigned char> g = {3},
1079 std::string decimal_point = ".")
1080 : separator_(sep.data(), sep.size()),
1081 grouping_(g.begin(), g.end()),
1082 decimal_point_(decimal_point) {}
1084 auto put(appender out, loc_value val, const format_specs<>& specs) const
1086 return do_put(out, val, specs);
1092 // Returns true if value is negative, false otherwise.
1093 // Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
1094 template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
1095 constexpr auto is_negative(T value) -> bool {
1098 template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
1099 constexpr auto is_negative(T) -> bool {
1103 template <typename T>
1104 FMT_CONSTEXPR auto is_supported_floating_point(T) -> bool {
1105 if (std::is_same<T, float>()) return FMT_USE_FLOAT;
1106 if (std::is_same<T, double>()) return FMT_USE_DOUBLE;
1107 if (std::is_same<T, long double>()) return FMT_USE_LONG_DOUBLE;
1111 // Smallest of uint32_t, uint64_t, uint128_t that is large enough to
1112 // represent all values of an integral type T.
1113 template <typename T>
1114 using uint32_or_64_or_128_t =
1115 conditional_t<num_bits<T>() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS,
1117 conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
1118 template <typename T>
1119 using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;
1121 #define FMT_POWERS_OF_10(factor) \
1122 factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \
1123 (factor) * 100000, (factor) * 1000000, (factor) * 10000000, \
1124 (factor) * 100000000, (factor) * 1000000000
1126 // Converts value in the range [0, 100) to a string.
1127 constexpr auto digits2(size_t value) -> const char* {
1128 // GCC generates slightly better code when value is pointer-size.
1129 return &"0001020304050607080910111213141516171819"
1130 "2021222324252627282930313233343536373839"
1131 "4041424344454647484950515253545556575859"
1132 "6061626364656667686970717273747576777879"
1133 "8081828384858687888990919293949596979899"[value * 2];
1136 // Sign is a template parameter to workaround a bug in gcc 4.8.
1137 template <typename Char, typename Sign> constexpr auto sign(Sign s) -> Char {
1138 #if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604
1139 static_assert(std::is_same<Sign, sign_t>::value, "");
1141 return static_cast<Char>("\0-+ "[s]);
1144 template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
1147 // Integer division is slow so do it for a group of four digits instead
1148 // of for every digit. The idea comes from the talk by Alexandrescu
1149 // "Three Optimization Tips for C++". See speed-test for a comparison.
1150 if (n < 10) return count;
1151 if (n < 100) return count + 1;
1152 if (n < 1000) return count + 2;
1153 if (n < 10000) return count + 3;
1159 FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int {
1160 return count_digits_fallback(n);
1164 #ifdef FMT_BUILTIN_CLZLL
1165 // It is a separate function rather than a part of count_digits to workaround
1166 // the lack of static constexpr in constexpr functions.
1167 inline auto do_count_digits(uint64_t n) -> int {
1168 // This has comparable performance to the version by Kendall Willets
1169 // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)
1170 // but uses smaller tables.
1171 // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
1172 static constexpr uint8_t bsr2log10[] = {
1173 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
1174 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
1175 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1176 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1177 auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
1178 static constexpr const uint64_t zero_or_powers_of_10[] = {
1179 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
1180 10000000000000000000ULL};
1181 return t - (n < zero_or_powers_of_10[t]);
1185 // Returns the number of decimal digits in n. Leading zeros are not counted
1186 // except for n == 0 in which case count_digits returns 1.
1187 FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {
1188 #ifdef FMT_BUILTIN_CLZLL
1189 if (!is_constant_evaluated()) {
1190 return do_count_digits(n);
1193 return count_digits_fallback(n);
1196 // Counts the number of digits in n. BITS = log2(radix).
1197 template <int BITS, typename UInt>
1198 FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1199 #ifdef FMT_BUILTIN_CLZ
1200 if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1201 return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1203 // Lambda avoids unreachable code warnings from NVHPC.
1208 } while ((m >>= BITS) != 0);
1213 #ifdef FMT_BUILTIN_CLZ
1214 // It is a separate function rather than a part of count_digits to workaround
1215 // the lack of static constexpr in constexpr functions.
1216 FMT_INLINE auto do_count_digits(uint32_t n) -> int {
1217 // An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
1218 // This increments the upper 32 bits (log10(T) - 1) when >= T is added.
1219 # define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)
1220 static constexpr uint64_t table[] = {
1221 FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8
1222 FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64
1223 FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512
1224 FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096
1225 FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k
1226 FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k
1227 FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k
1228 FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M
1229 FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M
1230 FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M
1231 FMT_INC(1000000000), FMT_INC(1000000000) // 4B
1233 auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
1234 return static_cast<int>((n + inc) >> 32);
1238 // Optional version of count_digits for better performance on 32-bit platforms.
1239 FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {
1240 #ifdef FMT_BUILTIN_CLZ
1241 if (!is_constant_evaluated()) {
1242 return do_count_digits(n);
1245 return count_digits_fallback(n);
1248 template <typename Int> constexpr auto digits10() noexcept -> int {
1249 return std::numeric_limits<Int>::digits10;
1251 template <> constexpr auto digits10<int128_opt>() noexcept -> int { return 38; }
1252 template <> constexpr auto digits10<uint128_t>() noexcept -> int { return 38; }
1254 template <typename Char> struct thousands_sep_result {
1255 std::string grouping;
1259 template <typename Char>
1260 FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>;
1261 template <typename Char>
1262 inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> {
1263 auto result = thousands_sep_impl<char>(loc);
1264 return {result.grouping, Char(result.thousands_sep)};
1267 inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<wchar_t> {
1268 return thousands_sep_impl<wchar_t>(loc);
1271 template <typename Char>
1272 FMT_API auto decimal_point_impl(locale_ref loc) -> Char;
1273 template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1274 return Char(decimal_point_impl<char>(loc));
1276 template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1277 return decimal_point_impl<wchar_t>(loc);
1280 // Compares two characters for equality.
1281 template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1282 return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1284 inline auto equal2(const char* lhs, const char* rhs) -> bool {
1285 return memcmp(lhs, rhs, 2) == 0;
1288 // Copies two characters from src to dst.
1289 template <typename Char>
1290 FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) {
1291 if (!is_constant_evaluated() && sizeof(Char) == sizeof(char)) {
1292 memcpy(dst, src, 2);
1295 *dst++ = static_cast<Char>(*src++);
1296 *dst = static_cast<Char>(*src);
1299 template <typename Iterator> struct format_decimal_result {
1304 // Formats a decimal unsigned integer value writing into out pointing to a
1305 // buffer of specified size. The caller must ensure that the buffer is large
1307 template <typename Char, typename UInt>
1308 FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
1309 -> format_decimal_result<Char*> {
1310 FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1313 while (value >= 100) {
1314 // Integer division is slow so do it for a group of two digits instead
1315 // of for every digit. The idea comes from the talk by Alexandrescu
1316 // "Three Optimization Tips for C++". See speed-test for a comparison.
1318 copy2(out, digits2(static_cast<size_t>(value % 100)));
1322 *--out = static_cast<Char>('0' + value);
1326 copy2(out, digits2(static_cast<size_t>(value)));
1330 template <typename Char, typename UInt, typename Iterator,
1331 FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)>
1332 FMT_CONSTEXPR inline auto format_decimal(Iterator out, UInt value, int size)
1333 -> format_decimal_result<Iterator> {
1334 // Buffer is large enough to hold all digits (digits10 + 1).
1335 Char buffer[digits10<UInt>() + 1] = {};
1336 auto end = format_decimal(buffer, value, size).end;
1337 return {out, detail::copy_str_noinline<Char>(buffer, end, out)};
1340 template <unsigned BASE_BITS, typename Char, typename UInt>
1341 FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits,
1342 bool upper = false) -> Char* {
1343 buffer += num_digits;
1346 const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1347 unsigned digit = static_cast<unsigned>(value & ((1 << BASE_BITS) - 1));
1348 *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
1350 } while ((value >>= BASE_BITS) != 0);
1354 template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1355 FMT_CONSTEXPR inline auto format_uint(It out, UInt value, int num_digits,
1356 bool upper = false) -> It {
1357 if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1358 format_uint<BASE_BITS>(ptr, value, num_digits, upper);
1361 // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
1362 char buffer[num_bits<UInt>() / BASE_BITS + 1] = {};
1363 format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1364 return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out);
1367 // A converter from UTF-8 to UTF-16.
1368 class utf8_to_utf16 {
1370 basic_memory_buffer<wchar_t> buffer_;
1373 FMT_API explicit utf8_to_utf16(string_view s);
1374 operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; }
1375 auto size() const -> size_t { return buffer_.size() - 1; }
1376 auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1377 auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1380 enum class to_utf8_error_policy { abort, replace };
1382 // A converter from UTF-16/UTF-32 (host endian) to UTF-8.
1383 template <typename WChar, typename Buffer = memory_buffer> class to_utf8 {
1389 explicit to_utf8(basic_string_view<WChar> s,
1390 to_utf8_error_policy policy = to_utf8_error_policy::abort) {
1391 static_assert(sizeof(WChar) == 2 || sizeof(WChar) == 4,
1392 "Expect utf16 or utf32");
1393 if (!convert(s, policy))
1394 FMT_THROW(std::runtime_error(sizeof(WChar) == 2 ? "invalid utf16"
1395 : "invalid utf32"));
1397 operator string_view() const { return string_view(&buffer_[0], size()); }
1398 auto size() const -> size_t { return buffer_.size() - 1; }
1399 auto c_str() const -> const char* { return &buffer_[0]; }
1400 auto str() const -> std::string { return std::string(&buffer_[0], size()); }
1402 // Performs conversion returning a bool instead of throwing exception on
1403 // conversion error. This method may still throw in case of memory allocation
1405 auto convert(basic_string_view<WChar> s,
1406 to_utf8_error_policy policy = to_utf8_error_policy::abort)
1408 if (!convert(buffer_, s, policy)) return false;
1409 buffer_.push_back(0);
1412 static auto convert(Buffer& buf, basic_string_view<WChar> s,
1413 to_utf8_error_policy policy = to_utf8_error_policy::abort)
1415 for (auto p = s.begin(); p != s.end(); ++p) {
1416 uint32_t c = static_cast<uint32_t>(*p);
1417 if (sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) {
1418 // Handle a surrogate pair.
1420 if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) {
1421 if (policy == to_utf8_error_policy::abort) return false;
1422 buf.append(string_view("\xEF\xBF\xBD"));
1425 c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00;
1427 } else if (c < 0x80) {
1428 buf.push_back(static_cast<char>(c));
1429 } else if (c < 0x800) {
1430 buf.push_back(static_cast<char>(0xc0 | (c >> 6)));
1431 buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1432 } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) {
1433 buf.push_back(static_cast<char>(0xe0 | (c >> 12)));
1434 buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1435 buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1436 } else if (c >= 0x10000 && c <= 0x10ffff) {
1437 buf.push_back(static_cast<char>(0xf0 | (c >> 18)));
1438 buf.push_back(static_cast<char>(0x80 | ((c & 0x3ffff) >> 12)));
1439 buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1440 buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1449 // Computes 128-bit result of multiplication of two 64-bit unsigned integers.
1450 inline auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback {
1452 auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1453 return {static_cast<uint64_t>(p >> 64), static_cast<uint64_t>(p)};
1454 #elif defined(_MSC_VER) && defined(_M_X64)
1455 auto hi = uint64_t();
1456 auto lo = _umul128(x, y, &hi);
1459 const uint64_t mask = static_cast<uint64_t>(max_value<uint32_t>());
1461 uint64_t a = x >> 32;
1462 uint64_t b = x & mask;
1463 uint64_t c = y >> 32;
1464 uint64_t d = y & mask;
1466 uint64_t ac = a * c;
1467 uint64_t bc = b * c;
1468 uint64_t ad = a * d;
1469 uint64_t bd = b * d;
1471 uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask);
1473 return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
1474 (intermediate << 32) + (bd & mask)};
1478 namespace dragonbox {
1479 // Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from
1480 // https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1.
1481 inline auto floor_log10_pow2(int e) noexcept -> int {
1482 FMT_ASSERT(e <= 2620 && e >= -2620, "too large exponent");
1483 static_assert((-1 >> 1) == -1, "right shift is not arithmetic");
1484 return (e * 315653) >> 20;
1487 inline auto floor_log2_pow10(int e) noexcept -> int {
1488 FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent");
1489 return (e * 1741647) >> 19;
1492 // Computes upper 64 bits of multiplication of two 64-bit unsigned integers.
1493 inline auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t {
1495 auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1496 return static_cast<uint64_t>(p >> 64);
1497 #elif defined(_MSC_VER) && defined(_M_X64)
1498 return __umulh(x, y);
1500 return umul128(x, y).high();
1504 // Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a
1505 // 128-bit unsigned integer.
1506 inline auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept
1507 -> uint128_fallback {
1508 uint128_fallback r = umul128(x, y.high());
1509 r += umul128_upper64(x, y.low());
1513 FMT_API auto get_cached_power(int k) noexcept -> uint128_fallback;
1515 // Type-specific information that Dragonbox uses.
1516 template <typename T, typename Enable = void> struct float_info;
1518 template <> struct float_info<float> {
1519 using carrier_uint = uint32_t;
1520 static const int exponent_bits = 8;
1521 static const int kappa = 1;
1522 static const int big_divisor = 100;
1523 static const int small_divisor = 10;
1524 static const int min_k = -31;
1525 static const int max_k = 46;
1526 static const int shorter_interval_tie_lower_threshold = -35;
1527 static const int shorter_interval_tie_upper_threshold = -35;
1530 template <> struct float_info<double> {
1531 using carrier_uint = uint64_t;
1532 static const int exponent_bits = 11;
1533 static const int kappa = 2;
1534 static const int big_divisor = 1000;
1535 static const int small_divisor = 100;
1536 static const int min_k = -292;
1537 static const int max_k = 341;
1538 static const int shorter_interval_tie_lower_threshold = -77;
1539 static const int shorter_interval_tie_upper_threshold = -77;
1542 // An 80- or 128-bit floating point number.
1543 template <typename T>
1544 struct float_info<T, enable_if_t<std::numeric_limits<T>::digits == 64 ||
1545 std::numeric_limits<T>::digits == 113 ||
1546 is_float128<T>::value>> {
1547 using carrier_uint = detail::uint128_t;
1548 static const int exponent_bits = 15;
1551 // A double-double floating point number.
1552 template <typename T>
1553 struct float_info<T, enable_if_t<is_double_double<T>::value>> {
1554 using carrier_uint = detail::uint128_t;
1557 template <typename T> struct decimal_fp {
1558 using significand_type = typename float_info<T>::carrier_uint;
1559 significand_type significand;
1563 template <typename T> FMT_API auto to_decimal(T x) noexcept -> decimal_fp<T>;
1564 } // namespace dragonbox
1566 // Returns true iff Float has the implicit bit which is not stored.
1567 template <typename Float> constexpr auto has_implicit_bit() -> bool {
1568 // An 80-bit FP number has a 64-bit significand an no implicit bit.
1569 return std::numeric_limits<Float>::digits != 64;
1572 // Returns the number of significand bits stored in Float. The implicit bit is
1573 // not counted since it is not stored.
1574 template <typename Float> constexpr auto num_significand_bits() -> int {
1575 // std::numeric_limits may not support __float128.
1576 return is_float128<Float>() ? 112
1577 : (std::numeric_limits<Float>::digits -
1578 (has_implicit_bit<Float>() ? 1 : 0));
1581 template <typename Float>
1582 constexpr auto exponent_mask() ->
1583 typename dragonbox::float_info<Float>::carrier_uint {
1584 using float_uint = typename dragonbox::float_info<Float>::carrier_uint;
1585 return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1586 << num_significand_bits<Float>();
1588 template <typename Float> constexpr auto exponent_bias() -> int {
1589 // std::numeric_limits may not support __float128.
1590 return is_float128<Float>() ? 16383
1591 : std::numeric_limits<Float>::max_exponent - 1;
1594 // Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1595 template <typename Char, typename It>
1596 FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It {
1597 FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1599 *it++ = static_cast<Char>('-');
1602 *it++ = static_cast<Char>('+');
1605 const char* top = digits2(to_unsigned(exp / 100));
1606 if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
1607 *it++ = static_cast<Char>(top[1]);
1610 const char* d = digits2(to_unsigned(exp));
1611 *it++ = static_cast<Char>(d[0]);
1612 *it++ = static_cast<Char>(d[1]);
1616 // A floating-point number f * pow(2, e) where F is an unsigned type.
1617 template <typename F> struct basic_fp {
1621 static constexpr const int num_significand_bits =
1622 static_cast<int>(sizeof(F) * num_bits<unsigned char>());
1624 constexpr basic_fp() : f(0), e(0) {}
1625 constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
1627 // Constructs fp from an IEEE754 floating-point number.
1628 template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
1630 // Assigns n to this and return true iff predecessor is closer than successor.
1631 template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
1632 FMT_CONSTEXPR auto assign(Float n) -> bool {
1633 static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1634 // Assume Float is in the format [sign][exponent][significand].
1635 using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1636 const auto num_float_significand_bits =
1637 detail::num_significand_bits<Float>();
1638 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1639 const auto significand_mask = implicit_bit - 1;
1640 auto u = bit_cast<carrier_uint>(n);
1641 f = static_cast<F>(u & significand_mask);
1642 auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1643 num_float_significand_bits);
1644 // The predecessor is closer if n is a normalized power of 2 (f == 0)
1645 // other than the smallest normalized number (biased_e > 1).
1646 auto is_predecessor_closer = f == 0 && biased_e > 1;
1648 biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
1649 else if (has_implicit_bit<Float>())
1650 f += static_cast<F>(implicit_bit);
1651 e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1652 if (!has_implicit_bit<Float>()) ++e;
1653 return is_predecessor_closer;
1656 template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
1657 FMT_CONSTEXPR auto assign(Float n) -> bool {
1658 static_assert(std::numeric_limits<double>::is_iec559, "unsupported FP");
1659 return assign(static_cast<double>(n));
1663 using fp = basic_fp<unsigned long long>;
1665 // Normalizes the value converted from double and multiplied by (1 << SHIFT).
1666 template <int SHIFT = 0, typename F>
1667 FMT_CONSTEXPR auto normalize(basic_fp<F> value) -> basic_fp<F> {
1668 // Handle subnormals.
1669 const auto implicit_bit = F(1) << num_significand_bits<double>();
1670 const auto shifted_implicit_bit = implicit_bit << SHIFT;
1671 while ((value.f & shifted_implicit_bit) == 0) {
1675 // Subtract 1 to account for hidden bit.
1676 const auto offset = basic_fp<F>::num_significand_bits -
1677 num_significand_bits<double>() - SHIFT - 1;
1683 // Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
1684 FMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t {
1686 auto product = static_cast<__uint128_t>(lhs) * rhs;
1687 auto f = static_cast<uint64_t>(product >> 64);
1688 return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1690 // Multiply 32-bit parts of significands.
1691 uint64_t mask = (1ULL << 32) - 1;
1692 uint64_t a = lhs >> 32, b = lhs & mask;
1693 uint64_t c = rhs >> 32, d = rhs & mask;
1694 uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
1695 // Compute mid 64-bit of result and round.
1696 uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1697 return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1701 FMT_CONSTEXPR inline auto operator*(fp x, fp y) -> fp {
1702 return {multiply(x.f, y.f), x.e + y.e + 64};
1705 template <typename T, bool doublish = num_bits<T>() == num_bits<double>()>
1706 using convert_float_result =
1707 conditional_t<std::is_same<T, float>::value || doublish, double, T>;
1709 template <typename T>
1710 constexpr auto convert_float(T value) -> convert_float_result<T> {
1711 return static_cast<convert_float_result<T>>(value);
1714 template <typename OutputIt, typename Char>
1715 FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
1716 const fill_t<Char>& fill) -> OutputIt {
1717 auto fill_size = fill.size();
1718 if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
1719 auto data = fill.data();
1720 for (size_t i = 0; i < n; ++i)
1721 it = copy_str<Char>(data, data + fill_size, it);
1725 // Writes the output of f, padded according to format specifications in specs.
1726 // size: output size in code units.
1727 // width: output display width in (terminal) column positions.
1728 template <align::type align = align::left, typename OutputIt, typename Char,
1730 FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs<Char>& specs,
1731 size_t size, size_t width, F&& f) -> OutputIt {
1732 static_assert(align == align::left || align == align::right, "");
1733 unsigned spec_width = to_unsigned(specs.width);
1734 size_t padding = spec_width > width ? spec_width - width : 0;
1735 // Shifts are encoded as string literals because static constexpr is not
1736 // supported in constexpr functions.
1737 auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1738 size_t left_padding = padding >> shifts[specs.align];
1739 size_t right_padding = padding - left_padding;
1740 auto it = reserve(out, size + padding * specs.fill.size());
1741 if (left_padding != 0) it = fill(it, left_padding, specs.fill);
1743 if (right_padding != 0) it = fill(it, right_padding, specs.fill);
1744 return base_iterator(out, it);
1747 template <align::type align = align::left, typename OutputIt, typename Char,
1749 constexpr auto write_padded(OutputIt out, const format_specs<Char>& specs,
1750 size_t size, F&& f) -> OutputIt {
1751 return write_padded<align>(out, specs, size, size, f);
1754 template <align::type align = align::left, typename Char, typename OutputIt>
1755 FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,
1756 const format_specs<Char>& specs) -> OutputIt {
1757 return write_padded<align>(
1758 out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1759 const char* data = bytes.data();
1760 return copy_str<Char>(data, data + bytes.size(), it);
1764 template <typename Char, typename OutputIt, typename UIntPtr>
1765 auto write_ptr(OutputIt out, UIntPtr value, const format_specs<Char>* specs)
1767 int num_digits = count_digits<4>(value);
1768 auto size = to_unsigned(num_digits) + size_t(2);
1769 auto write = [=](reserve_iterator<OutputIt> it) {
1770 *it++ = static_cast<Char>('0');
1771 *it++ = static_cast<Char>('x');
1772 return format_uint<4, Char>(it, value, num_digits);
1774 return specs ? write_padded<align::right>(out, *specs, size, write)
1775 : base_iterator(out, write(reserve(out, size)));
1778 // Returns true iff the code point cp is printable.
1779 FMT_API auto is_printable(uint32_t cp) -> bool;
1781 inline auto needs_escape(uint32_t cp) -> bool {
1782 return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' ||
1786 template <typename Char> struct find_escape_result {
1792 template <typename Char>
1793 using make_unsigned_char =
1794 typename conditional_t<std::is_integral<Char>::value,
1795 std::make_unsigned<Char>,
1796 type_identity<uint32_t>>::type;
1798 template <typename Char>
1799 auto find_escape(const Char* begin, const Char* end)
1800 -> find_escape_result<Char> {
1801 for (; begin != end; ++begin) {
1802 uint32_t cp = static_cast<make_unsigned_char<Char>>(*begin);
1803 if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue;
1804 if (needs_escape(cp)) return {begin, begin + 1, cp};
1806 return {begin, nullptr, 0};
1809 inline auto find_escape(const char* begin, const char* end)
1810 -> find_escape_result<char> {
1811 if (!is_utf8()) return find_escape<char>(begin, end);
1812 auto result = find_escape_result<char>{end, nullptr, 0};
1813 for_each_codepoint(string_view(begin, to_unsigned(end - begin)),
1814 [&](uint32_t cp, string_view sv) {
1815 if (needs_escape(cp)) {
1816 result = {sv.begin(), sv.end(), cp};
1824 #define FMT_STRING_IMPL(s, base, explicit) \
1826 /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
1827 /* Use a macro-like name to avoid shadowing warnings. */ \
1828 struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base { \
1829 using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t<decltype(s[0])>; \
1830 FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
1831 operator fmt::basic_string_view<char_type>() const { \
1832 return fmt::detail_exported::compile_string_to_view<char_type>(s); \
1835 return FMT_COMPILE_STRING(); \
1840 Constructs a compile-time format string from a string literal *s*.
1844 // A compile-time error because 'd' is an invalid specifier for strings.
1845 std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
1848 #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
1850 template <size_t width, typename Char, typename OutputIt>
1851 auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {
1852 *out++ = static_cast<Char>('\\');
1853 *out++ = static_cast<Char>(prefix);
1855 fill_n(buf, width, static_cast<Char>('0'));
1856 format_uint<4>(buf, cp, width);
1857 return copy_str<Char>(buf, buf + width, out);
1860 template <typename OutputIt, typename Char>
1861 auto write_escaped_cp(OutputIt out, const find_escape_result<Char>& escape)
1863 auto c = static_cast<Char>(escape.cp);
1864 switch (escape.cp) {
1866 *out++ = static_cast<Char>('\\');
1867 c = static_cast<Char>('n');
1870 *out++ = static_cast<Char>('\\');
1871 c = static_cast<Char>('r');
1874 *out++ = static_cast<Char>('\\');
1875 c = static_cast<Char>('t');
1882 *out++ = static_cast<Char>('\\');
1885 if (escape.cp < 0x100) {
1886 return write_codepoint<2, Char>(out, 'x', escape.cp);
1888 if (escape.cp < 0x10000) {
1889 return write_codepoint<4, Char>(out, 'u', escape.cp);
1891 if (escape.cp < 0x110000) {
1892 return write_codepoint<8, Char>(out, 'U', escape.cp);
1894 for (Char escape_char : basic_string_view<Char>(
1895 escape.begin, to_unsigned(escape.end - escape.begin))) {
1896 out = write_codepoint<2, Char>(out, 'x',
1897 static_cast<uint32_t>(escape_char) & 0xFF);
1905 template <typename Char, typename OutputIt>
1906 auto write_escaped_string(OutputIt out, basic_string_view<Char> str)
1908 *out++ = static_cast<Char>('"');
1909 auto begin = str.begin(), end = str.end();
1911 auto escape = find_escape(begin, end);
1912 out = copy_str<Char>(begin, escape.begin, out);
1915 out = write_escaped_cp<OutputIt, Char>(out, escape);
1916 } while (begin != end);
1917 *out++ = static_cast<Char>('"');
1921 template <typename Char, typename OutputIt>
1922 auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
1923 Char v_array[1] = {v};
1924 *out++ = static_cast<Char>('\'');
1925 if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('"')) ||
1926 v == static_cast<Char>('\'')) {
1927 out = write_escaped_cp(out,
1928 find_escape_result<Char>{v_array, v_array + 1,
1929 static_cast<uint32_t>(v)});
1933 *out++ = static_cast<Char>('\'');
1937 template <typename Char, typename OutputIt>
1938 FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1939 const format_specs<Char>& specs) -> OutputIt {
1940 bool is_debug = specs.type == presentation_type::debug;
1941 return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1942 if (is_debug) return write_escaped_char(it, value);
1947 template <typename Char, typename OutputIt>
1948 FMT_CONSTEXPR auto write(OutputIt out, Char value,
1949 const format_specs<Char>& specs, locale_ref loc = {})
1951 // char is formatted as unsigned char for consistency across platforms.
1952 using unsigned_type =
1953 conditional_t<std::is_same<Char, char>::value, unsigned char, unsigned>;
1954 return check_char_specs(specs)
1955 ? write_char(out, value, specs)
1956 : write(out, static_cast<unsigned_type>(value), specs, loc);
1959 // Data for write_int that doesn't depend on output iterator type. It is used to
1960 // avoid template code bloat.
1961 template <typename Char> struct write_int_data {
1965 FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
1966 const format_specs<Char>& specs)
1967 : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
1968 if (specs.align == align::numeric) {
1969 auto width = to_unsigned(specs.width);
1971 padding = width - size;
1974 } else if (specs.precision > num_digits) {
1975 size = (prefix >> 24) + to_unsigned(specs.precision);
1976 padding = to_unsigned(specs.precision - num_digits);
1981 // Writes an integer in the format
1982 // <left-padding><prefix><numeric-padding><digits><right-padding>
1983 // where <digits> are written by write_digits(it).
1984 // prefix contains chars in three lower bytes and the size in the fourth byte.
1985 template <typename OutputIt, typename Char, typename W>
1986 FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
1988 const format_specs<Char>& specs,
1989 W write_digits) -> OutputIt {
1990 // Slightly faster check for specs.width == 0 && specs.precision == -1.
1991 if ((specs.width | (specs.precision + 1)) == 0) {
1992 auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
1994 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1995 *it++ = static_cast<Char>(p & 0xff);
1997 return base_iterator(out, write_digits(it));
1999 auto data = write_int_data<Char>(num_digits, prefix, specs);
2000 return write_padded<align::right>(
2001 out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
2002 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2003 *it++ = static_cast<Char>(p & 0xff);
2004 it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
2005 return write_digits(it);
2009 template <typename Char> class digit_grouping {
2011 std::string grouping_;
2012 std::basic_string<Char> thousands_sep_;
2015 std::string::const_iterator group;
2018 auto initial_state() const -> next_state { return {grouping_.begin(), 0}; }
2020 // Returns the next digit group separator position.
2021 auto next(next_state& state) const -> int {
2022 if (thousands_sep_.empty()) return max_value<int>();
2023 if (state.group == grouping_.end()) return state.pos += grouping_.back();
2024 if (*state.group <= 0 || *state.group == max_value<char>())
2025 return max_value<int>();
2026 state.pos += *state.group++;
2031 explicit digit_grouping(locale_ref loc, bool localized = true) {
2032 if (!localized) return;
2033 auto sep = thousands_sep<Char>(loc);
2034 grouping_ = sep.grouping;
2035 if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep);
2037 digit_grouping(std::string grouping, std::basic_string<Char> sep)
2038 : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {}
2040 auto has_separator() const -> bool { return !thousands_sep_.empty(); }
2042 auto count_separators(int num_digits) const -> int {
2044 auto state = initial_state();
2045 while (num_digits > next(state)) ++count;
2049 // Applies grouping to digits and write the output to out.
2050 template <typename Out, typename C>
2051 auto apply(Out out, basic_string_view<C> digits) const -> Out {
2052 auto num_digits = static_cast<int>(digits.size());
2053 auto separators = basic_memory_buffer<int>();
2054 separators.push_back(0);
2055 auto state = initial_state();
2056 while (int i = next(state)) {
2057 if (i >= num_digits) break;
2058 separators.push_back(i);
2060 for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);
2061 i < num_digits; ++i) {
2062 if (num_digits - i == separators[sep_index]) {
2064 copy_str<Char>(thousands_sep_.data(),
2065 thousands_sep_.data() + thousands_sep_.size(), out);
2068 *out++ = static_cast<Char>(digits[to_unsigned(i)]);
2074 FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
2075 prefix |= prefix != 0 ? value << 8 : value;
2076 prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
2079 // Writes a decimal integer with digit grouping.
2080 template <typename OutputIt, typename UInt, typename Char>
2081 auto write_int(OutputIt out, UInt value, unsigned prefix,
2082 const format_specs<Char>& specs,
2083 const digit_grouping<Char>& grouping) -> OutputIt {
2084 static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
2086 auto buffer = memory_buffer();
2087 switch (specs.type) {
2088 case presentation_type::none:
2089 case presentation_type::dec: {
2090 num_digits = count_digits(value);
2091 format_decimal<char>(appender(buffer), value, num_digits);
2094 case presentation_type::hex_lower:
2095 case presentation_type::hex_upper: {
2096 bool upper = specs.type == presentation_type::hex_upper;
2098 prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
2099 num_digits = count_digits<4>(value);
2100 format_uint<4, char>(appender(buffer), value, num_digits, upper);
2103 case presentation_type::bin_lower:
2104 case presentation_type::bin_upper: {
2105 bool upper = specs.type == presentation_type::bin_upper;
2107 prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
2108 num_digits = count_digits<1>(value);
2109 format_uint<1, char>(appender(buffer), value, num_digits);
2112 case presentation_type::oct: {
2113 num_digits = count_digits<3>(value);
2114 // Octal prefix '0' is counted as a digit, so only add it if precision
2115 // is not greater than the number of digits.
2116 if (specs.alt && specs.precision <= num_digits && value != 0)
2117 prefix_append(prefix, '0');
2118 format_uint<3, char>(appender(buffer), value, num_digits);
2121 case presentation_type::chr:
2122 return write_char(out, static_cast<Char>(value), specs);
2124 throw_format_error("invalid format specifier");
2127 unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) +
2128 to_unsigned(grouping.count_separators(num_digits));
2129 return write_padded<align::right>(
2130 out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
2131 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2132 *it++ = static_cast<Char>(p & 0xff);
2133 return grouping.apply(it, string_view(buffer.data(), buffer.size()));
2137 // Writes a localized value.
2138 FMT_API auto write_loc(appender out, loc_value value,
2139 const format_specs<>& specs, locale_ref loc) -> bool;
2140 template <typename OutputIt, typename Char>
2141 inline auto write_loc(OutputIt, loc_value, const format_specs<Char>&,
2142 locale_ref) -> bool {
2146 template <typename UInt> struct write_int_arg {
2151 template <typename T>
2152 FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign)
2153 -> write_int_arg<uint32_or_64_or_128_t<T>> {
2155 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2156 if (is_negative(value)) {
2157 prefix = 0x01000000 | '-';
2158 abs_value = 0 - abs_value;
2160 constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
2162 prefix = prefixes[sign];
2164 return {abs_value, prefix};
2167 template <typename Char = char> struct loc_writer {
2168 buffer_appender<Char> out;
2169 const format_specs<Char>& specs;
2170 std::basic_string<Char> sep;
2171 std::string grouping;
2172 std::basic_string<Char> decimal_point;
2174 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2175 auto operator()(T value) -> bool {
2176 auto arg = make_write_int_arg(value, specs.sign);
2177 write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2178 specs, digit_grouping<Char>(grouping, sep));
2182 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2183 auto operator()(T) -> bool {
2188 template <typename Char, typename OutputIt, typename T>
2189 FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
2190 const format_specs<Char>& specs,
2191 locale_ref) -> OutputIt {
2192 static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2193 auto abs_value = arg.abs_value;
2194 auto prefix = arg.prefix;
2195 switch (specs.type) {
2196 case presentation_type::none:
2197 case presentation_type::dec: {
2198 auto num_digits = count_digits(abs_value);
2200 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2201 return format_decimal<Char>(it, abs_value, num_digits).end;
2204 case presentation_type::hex_lower:
2205 case presentation_type::hex_upper: {
2206 bool upper = specs.type == presentation_type::hex_upper;
2208 prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
2209 int num_digits = count_digits<4>(abs_value);
2211 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2212 return format_uint<4, Char>(it, abs_value, num_digits, upper);
2215 case presentation_type::bin_lower:
2216 case presentation_type::bin_upper: {
2217 bool upper = specs.type == presentation_type::bin_upper;
2219 prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
2220 int num_digits = count_digits<1>(abs_value);
2221 return write_int(out, num_digits, prefix, specs,
2222 [=](reserve_iterator<OutputIt> it) {
2223 return format_uint<1, Char>(it, abs_value, num_digits);
2226 case presentation_type::oct: {
2227 int num_digits = count_digits<3>(abs_value);
2228 // Octal prefix '0' is counted as a digit, so only add it if precision
2229 // is not greater than the number of digits.
2230 if (specs.alt && specs.precision <= num_digits && abs_value != 0)
2231 prefix_append(prefix, '0');
2232 return write_int(out, num_digits, prefix, specs,
2233 [=](reserve_iterator<OutputIt> it) {
2234 return format_uint<3, Char>(it, abs_value, num_digits);
2237 case presentation_type::chr:
2238 return write_char(out, static_cast<Char>(abs_value), specs);
2240 throw_format_error("invalid format specifier");
2244 template <typename Char, typename OutputIt, typename T>
2245 FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(
2246 OutputIt out, write_int_arg<T> arg, const format_specs<Char>& specs,
2247 locale_ref loc) -> OutputIt {
2248 return write_int(out, arg, specs, loc);
2250 template <typename Char, typename OutputIt, typename T,
2251 FMT_ENABLE_IF(is_integral<T>::value &&
2252 !std::is_same<T, bool>::value &&
2253 std::is_same<OutputIt, buffer_appender<Char>>::value)>
2254 FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2255 const format_specs<Char>& specs,
2256 locale_ref loc) -> OutputIt {
2257 if (specs.localized && write_loc(out, value, specs, loc)) return out;
2258 return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
2261 // An inlined version of write used in format string compilation.
2262 template <typename Char, typename OutputIt, typename T,
2263 FMT_ENABLE_IF(is_integral<T>::value &&
2264 !std::is_same<T, bool>::value &&
2265 !std::is_same<OutputIt, buffer_appender<Char>>::value)>
2266 FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2267 const format_specs<Char>& specs,
2268 locale_ref loc) -> OutputIt {
2269 if (specs.localized && write_loc(out, value, specs, loc)) return out;
2270 return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
2273 // An output iterator that counts the number of objects written to it and
2275 class counting_iterator {
2280 using iterator_category = std::output_iterator_tag;
2281 using difference_type = std::ptrdiff_t;
2282 using pointer = void;
2283 using reference = void;
2284 FMT_UNCHECKED_ITERATOR(counting_iterator);
2287 template <typename T> FMT_CONSTEXPR void operator=(const T&) {}
2290 FMT_CONSTEXPR counting_iterator() : count_(0) {}
2292 FMT_CONSTEXPR auto count() const -> size_t { return count_; }
2294 FMT_CONSTEXPR auto operator++() -> counting_iterator& {
2298 FMT_CONSTEXPR auto operator++(int) -> counting_iterator {
2304 FMT_CONSTEXPR friend auto operator+(counting_iterator it, difference_type n)
2305 -> counting_iterator {
2306 it.count_ += static_cast<size_t>(n);
2310 FMT_CONSTEXPR auto operator*() const -> value_type { return {}; }
2313 template <typename Char, typename OutputIt>
2314 FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
2315 const format_specs<Char>& specs) -> OutputIt {
2316 auto data = s.data();
2317 auto size = s.size();
2318 if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
2319 size = code_point_index(s, to_unsigned(specs.precision));
2320 bool is_debug = specs.type == presentation_type::debug;
2322 if (specs.width != 0) {
2324 width = write_escaped_string(counting_iterator{}, s).count();
2326 width = compute_width(basic_string_view<Char>(data, size));
2328 return write_padded(out, specs, size, width,
2329 [=](reserve_iterator<OutputIt> it) {
2330 if (is_debug) return write_escaped_string(it, s);
2331 return copy_str<Char>(data, data + size, it);
2334 template <typename Char, typename OutputIt>
2335 FMT_CONSTEXPR auto write(OutputIt out,
2336 basic_string_view<type_identity_t<Char>> s,
2337 const format_specs<Char>& specs, locale_ref)
2339 return write(out, s, specs);
2341 template <typename Char, typename OutputIt>
2342 FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
2343 const format_specs<Char>& specs, locale_ref)
2345 if (specs.type == presentation_type::pointer)
2346 return write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
2347 if (!s) throw_format_error("string pointer is null");
2348 return write(out, basic_string_view<Char>(s), specs, {});
2351 template <typename Char, typename OutputIt, typename T,
2352 FMT_ENABLE_IF(is_integral<T>::value &&
2353 !std::is_same<T, bool>::value &&
2354 !std::is_same<T, Char>::value)>
2355 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2356 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2357 bool negative = is_negative(value);
2358 // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2359 if (negative) abs_value = ~abs_value + 1;
2360 int num_digits = count_digits(abs_value);
2361 auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2362 auto it = reserve(out, size);
2363 if (auto ptr = to_pointer<Char>(it, size)) {
2364 if (negative) *ptr++ = static_cast<Char>('-');
2365 format_decimal<Char>(ptr, abs_value, num_digits);
2368 if (negative) *it++ = static_cast<Char>('-');
2369 it = format_decimal<Char>(it, abs_value, num_digits).end;
2370 return base_iterator(out, it);
2374 template <typename Char>
2375 FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
2376 format_specs<Char>& specs) -> const Char* {
2377 FMT_ASSERT(begin != end, "");
2378 auto align = align::none;
2379 auto p = begin + code_point_length(begin);
2380 if (end - p <= 0) p = begin;
2382 switch (to_ascii(*p)) {
2384 align = align::left;
2387 align = align::right;
2390 align = align::center;
2393 if (align != align::none) {
2396 if (c == '}') return begin;
2398 throw_format_error("invalid fill character '{'");
2401 specs.fill = {begin, to_unsigned(p - begin)};
2407 } else if (p == begin) {
2412 specs.align = align;
2416 // A floating-point presentation format.
2417 enum class float_format : unsigned char {
2418 general, // General: exponent notation or fixed point based on magnitude.
2419 exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3.
2420 fixed, // Fixed point with the default precision of 6, e.g. 0.0012.
2424 struct float_specs {
2426 float_format format : 8;
2434 template <typename Char>
2435 FMT_CONSTEXPR auto parse_float_type_spec(const format_specs<Char>& specs)
2437 auto result = float_specs();
2438 result.showpoint = specs.alt;
2439 result.locale = specs.localized;
2440 switch (specs.type) {
2441 case presentation_type::none:
2442 result.format = float_format::general;
2444 case presentation_type::general_upper:
2445 result.upper = true;
2447 case presentation_type::general_lower:
2448 result.format = float_format::general;
2450 case presentation_type::exp_upper:
2451 result.upper = true;
2453 case presentation_type::exp_lower:
2454 result.format = float_format::exp;
2455 result.showpoint |= specs.precision != 0;
2457 case presentation_type::fixed_upper:
2458 result.upper = true;
2460 case presentation_type::fixed_lower:
2461 result.format = float_format::fixed;
2462 result.showpoint |= specs.precision != 0;
2464 case presentation_type::hexfloat_upper:
2465 result.upper = true;
2467 case presentation_type::hexfloat_lower:
2468 result.format = float_format::hex;
2471 throw_format_error("invalid format specifier");
2477 template <typename Char, typename OutputIt>
2478 FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
2479 format_specs<Char> specs,
2480 const float_specs& fspecs) -> OutputIt {
2482 isnan ? (fspecs.upper ? "NAN" : "nan") : (fspecs.upper ? "INF" : "inf");
2483 constexpr size_t str_size = 3;
2484 auto sign = fspecs.sign;
2485 auto size = str_size + (sign ? 1 : 0);
2486 // Replace '0'-padding with space for non-finite values.
2487 const bool is_zero_fill =
2488 specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
2489 if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
2490 return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
2491 if (sign) *it++ = detail::sign<Char>(sign);
2492 return copy_str<Char>(str, str + str_size, it);
2496 // A decimal floating-point number significand * pow(10, exp).
2497 struct big_decimal_fp {
2498 const char* significand;
2499 int significand_size;
2503 constexpr auto get_significand_size(const big_decimal_fp& f) -> int {
2504 return f.significand_size;
2506 template <typename T>
2507 inline auto get_significand_size(const dragonbox::decimal_fp<T>& f) -> int {
2508 return count_digits(f.significand);
2511 template <typename Char, typename OutputIt>
2512 constexpr auto write_significand(OutputIt out, const char* significand,
2513 int significand_size) -> OutputIt {
2514 return copy_str<Char>(significand, significand + significand_size, out);
2516 template <typename Char, typename OutputIt, typename UInt>
2517 inline auto write_significand(OutputIt out, UInt significand,
2518 int significand_size) -> OutputIt {
2519 return format_decimal<Char>(out, significand, significand_size).end;
2521 template <typename Char, typename OutputIt, typename T, typename Grouping>
2522 FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2523 int significand_size, int exponent,
2524 const Grouping& grouping) -> OutputIt {
2525 if (!grouping.has_separator()) {
2526 out = write_significand<Char>(out, significand, significand_size);
2527 return detail::fill_n(out, exponent, static_cast<Char>('0'));
2529 auto buffer = memory_buffer();
2530 write_significand<char>(appender(buffer), significand, significand_size);
2531 detail::fill_n(appender(buffer), exponent, '0');
2532 return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2535 template <typename Char, typename UInt,
2536 FMT_ENABLE_IF(std::is_integral<UInt>::value)>
2537 inline auto write_significand(Char* out, UInt significand, int significand_size,
2538 int integral_size, Char decimal_point) -> Char* {
2540 return format_decimal(out, significand, significand_size).end;
2541 out += significand_size + 1;
2543 int floating_size = significand_size - integral_size;
2544 for (int i = floating_size / 2; i > 0; --i) {
2546 copy2(out, digits2(static_cast<std::size_t>(significand % 100)));
2549 if (floating_size % 2 != 0) {
2550 *--out = static_cast<Char>('0' + significand % 10);
2553 *--out = decimal_point;
2554 format_decimal(out - integral_size, significand, integral_size);
2558 template <typename OutputIt, typename UInt, typename Char,
2559 FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
2560 inline auto write_significand(OutputIt out, UInt significand,
2561 int significand_size, int integral_size,
2562 Char decimal_point) -> OutputIt {
2563 // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2564 Char buffer[digits10<UInt>() + 2];
2565 auto end = write_significand(buffer, significand, significand_size,
2566 integral_size, decimal_point);
2567 return detail::copy_str_noinline<Char>(buffer, end, out);
2570 template <typename OutputIt, typename Char>
2571 FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,
2572 int significand_size, int integral_size,
2573 Char decimal_point) -> OutputIt {
2574 out = detail::copy_str_noinline<Char>(significand,
2575 significand + integral_size, out);
2576 if (!decimal_point) return out;
2577 *out++ = decimal_point;
2578 return detail::copy_str_noinline<Char>(significand + integral_size,
2579 significand + significand_size, out);
2582 template <typename OutputIt, typename Char, typename T, typename Grouping>
2583 FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2584 int significand_size, int integral_size,
2586 const Grouping& grouping) -> OutputIt {
2587 if (!grouping.has_separator()) {
2588 return write_significand(out, significand, significand_size, integral_size,
2591 auto buffer = basic_memory_buffer<Char>();
2592 write_significand(buffer_appender<Char>(buffer), significand,
2593 significand_size, integral_size, decimal_point);
2595 out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2596 return detail::copy_str_noinline<Char>(buffer.data() + integral_size,
2600 template <typename OutputIt, typename DecimalFP, typename Char,
2601 typename Grouping = digit_grouping<Char>>
2602 FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
2603 const format_specs<Char>& specs,
2604 float_specs fspecs, locale_ref loc)
2606 auto significand = f.significand;
2607 int significand_size = get_significand_size(f);
2608 const Char zero = static_cast<Char>('0');
2609 auto sign = fspecs.sign;
2610 size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
2611 using iterator = reserve_iterator<OutputIt>;
2613 Char decimal_point =
2614 fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>('.');
2616 int output_exp = f.exponent + significand_size - 1;
2617 auto use_exp_format = [=]() {
2618 if (fspecs.format == float_format::exp) return true;
2619 if (fspecs.format != float_format::general) return false;
2620 // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
2621 // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
2622 const int exp_lower = -4, exp_upper = 16;
2623 return output_exp < exp_lower ||
2624 output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
2626 if (use_exp_format()) {
2628 if (fspecs.showpoint) {
2629 num_zeros = fspecs.precision - significand_size;
2630 if (num_zeros < 0) num_zeros = 0;
2631 size += to_unsigned(num_zeros);
2632 } else if (significand_size == 1) {
2633 decimal_point = Char();
2635 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2637 if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2639 size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
2640 char exp_char = fspecs.upper ? 'E' : 'e';
2641 auto write = [=](iterator it) {
2642 if (sign) *it++ = detail::sign<Char>(sign);
2643 // Insert a decimal point after the first digit and add an exponent.
2644 it = write_significand(it, significand, significand_size, 1,
2646 if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
2647 *it++ = static_cast<Char>(exp_char);
2648 return write_exponent<Char>(output_exp, it);
2650 return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
2651 : base_iterator(out, write(reserve(out, size)));
2654 int exp = f.exponent + significand_size;
2655 if (f.exponent >= 0) {
2656 // 1234e5 -> 123400000[.0+]
2657 size += to_unsigned(f.exponent);
2658 int num_zeros = fspecs.precision - exp;
2659 abort_fuzzing_if(num_zeros > 5000);
2660 if (fspecs.showpoint) {
2662 if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 0;
2663 if (num_zeros > 0) size += to_unsigned(num_zeros);
2665 auto grouping = Grouping(loc, fspecs.locale);
2666 size += to_unsigned(grouping.count_separators(exp));
2667 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2668 if (sign) *it++ = detail::sign<Char>(sign);
2669 it = write_significand<Char>(it, significand, significand_size,
2670 f.exponent, grouping);
2671 if (!fspecs.showpoint) return it;
2672 *it++ = decimal_point;
2673 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2675 } else if (exp > 0) {
2676 // 1234e-2 -> 12.34[0+]
2677 int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
2678 size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
2679 auto grouping = Grouping(loc, fspecs.locale);
2680 size += to_unsigned(grouping.count_separators(exp));
2681 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2682 if (sign) *it++ = detail::sign<Char>(sign);
2683 it = write_significand(it, significand, significand_size, exp,
2684 decimal_point, grouping);
2685 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2688 // 1234e-6 -> 0.001234
2689 int num_zeros = -exp;
2690 if (significand_size == 0 && fspecs.precision >= 0 &&
2691 fspecs.precision < num_zeros) {
2692 num_zeros = fspecs.precision;
2694 bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
2695 size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
2696 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2697 if (sign) *it++ = detail::sign<Char>(sign);
2699 if (!pointy) return it;
2700 *it++ = decimal_point;
2701 it = detail::fill_n(it, num_zeros, zero);
2702 return write_significand<Char>(it, significand, significand_size);
2706 template <typename Char> class fallback_digit_grouping {
2708 constexpr fallback_digit_grouping(locale_ref, bool) {}
2710 constexpr auto has_separator() const -> bool { return false; }
2712 constexpr auto count_separators(int) const -> int { return 0; }
2714 template <typename Out, typename C>
2715 constexpr auto apply(Out out, basic_string_view<C>) const -> Out {
2720 template <typename OutputIt, typename DecimalFP, typename Char>
2721 FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,
2722 const format_specs<Char>& specs,
2723 float_specs fspecs, locale_ref loc)
2725 if (is_constant_evaluated()) {
2726 return do_write_float<OutputIt, DecimalFP, Char,
2727 fallback_digit_grouping<Char>>(out, f, specs, fspecs,
2730 return do_write_float(out, f, specs, fspecs, loc);
2734 template <typename T> constexpr auto isnan(T value) -> bool {
2735 return !(value >= value); // std::isnan doesn't support __float128.
2738 template <typename T, typename Enable = void>
2739 struct has_isfinite : std::false_type {};
2741 template <typename T>
2742 struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
2743 : std::true_type {};
2745 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&&
2746 has_isfinite<T>::value)>
2747 FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
2748 constexpr T inf = T(std::numeric_limits<double>::infinity());
2749 if (is_constant_evaluated())
2750 return !detail::isnan(value) && value < inf && value > -inf;
2751 return std::isfinite(value);
2753 template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
2754 FMT_CONSTEXPR auto isfinite(T value) -> bool {
2755 T inf = T(std::numeric_limits<double>::infinity());
2756 // std::isfinite doesn't support __float128.
2757 return !detail::isnan(value) && value < inf && value > -inf;
2760 template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
2761 FMT_INLINE FMT_CONSTEXPR bool signbit(T value) {
2762 if (is_constant_evaluated()) {
2763 #ifdef __cpp_if_constexpr
2764 if constexpr (std::numeric_limits<double>::is_iec559) {
2765 auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2766 return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2770 return std::signbit(static_cast<double>(value));
2773 inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {
2774 // Adjust fixed precision by exponent because it is relative to decimal
2776 if (exp10 > 0 && precision > max_value<int>() - exp10)
2777 FMT_THROW(format_error("number is too big"));
2783 // A bigint is stored as an array of bigits (big digits), with bigit at index
2784 // 0 being the least significant one.
2785 using bigit = uint32_t;
2786 using double_bigit = uint64_t;
2787 enum { bigits_capacity = 32 };
2788 basic_memory_buffer<bigit, bigits_capacity> bigits_;
2791 FMT_CONSTEXPR20 auto operator[](int index) const -> bigit {
2792 return bigits_[to_unsigned(index)];
2794 FMT_CONSTEXPR20 auto operator[](int index) -> bigit& {
2795 return bigits_[to_unsigned(index)];
2798 static constexpr const int bigit_bits = num_bits<bigit>();
2800 friend struct formatter<bigint>;
2802 FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit& borrow) {
2803 auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
2804 (*this)[index] = static_cast<bigit>(result);
2805 borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
2808 FMT_CONSTEXPR20 void remove_leading_zeros() {
2809 int num_bigits = static_cast<int>(bigits_.size()) - 1;
2810 while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
2811 bigits_.resize(to_unsigned(num_bigits + 1));
2814 // Computes *this -= other assuming aligned bigints and *this >= other.
2815 FMT_CONSTEXPR20 void subtract_aligned(const bigint& other) {
2816 FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
2817 FMT_ASSERT(compare(*this, other) >= 0, "");
2819 int i = other.exp_ - exp_;
2820 for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
2821 subtract_bigits(i, other.bigits_[j], borrow);
2822 while (borrow > 0) subtract_bigits(i, 0, borrow);
2823 remove_leading_zeros();
2826 FMT_CONSTEXPR20 void multiply(uint32_t value) {
2827 const double_bigit wide_value = value;
2829 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2830 double_bigit result = bigits_[i] * wide_value + carry;
2831 bigits_[i] = static_cast<bigit>(result);
2832 carry = static_cast<bigit>(result >> bigit_bits);
2834 if (carry != 0) bigits_.push_back(carry);
2837 template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2838 std::is_same<UInt, uint128_t>::value)>
2839 FMT_CONSTEXPR20 void multiply(UInt value) {
2841 conditional_t<std::is_same<UInt, uint128_t>::value, uint64_t, uint32_t>;
2842 const int shift = num_bits<half_uint>() - bigit_bits;
2843 const UInt lower = static_cast<half_uint>(value);
2844 const UInt upper = value >> num_bits<half_uint>();
2846 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2847 UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
2848 carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
2849 (carry >> bigit_bits);
2850 bigits_[i] = static_cast<bigit>(result);
2852 while (carry != 0) {
2853 bigits_.push_back(static_cast<bigit>(carry));
2854 carry >>= bigit_bits;
2858 template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2859 std::is_same<UInt, uint128_t>::value)>
2860 FMT_CONSTEXPR20 void assign(UInt n) {
2861 size_t num_bigits = 0;
2863 bigits_[num_bigits++] = static_cast<bigit>(n);
2866 bigits_.resize(num_bigits);
2871 FMT_CONSTEXPR20 bigint() : exp_(0) {}
2872 explicit bigint(uint64_t n) { assign(n); }
2874 bigint(const bigint&) = delete;
2875 void operator=(const bigint&) = delete;
2877 FMT_CONSTEXPR20 void assign(const bigint& other) {
2878 auto size = other.bigits_.size();
2879 bigits_.resize(size);
2880 auto data = other.bigits_.data();
2881 copy_str<bigit>(data, data + size, bigits_.data());
2885 template <typename Int> FMT_CONSTEXPR20 void operator=(Int n) {
2886 FMT_ASSERT(n > 0, "");
2887 assign(uint64_or_128_t<Int>(n));
2890 FMT_CONSTEXPR20 auto num_bigits() const -> int {
2891 return static_cast<int>(bigits_.size()) + exp_;
2894 FMT_NOINLINE FMT_CONSTEXPR20 auto operator<<=(int shift) -> bigint& {
2895 FMT_ASSERT(shift >= 0, "");
2896 exp_ += shift / bigit_bits;
2897 shift %= bigit_bits;
2898 if (shift == 0) return *this;
2900 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2901 bigit c = bigits_[i] >> (bigit_bits - shift);
2902 bigits_[i] = (bigits_[i] << shift) + carry;
2905 if (carry != 0) bigits_.push_back(carry);
2909 template <typename Int>
2910 FMT_CONSTEXPR20 auto operator*=(Int value) -> bigint& {
2911 FMT_ASSERT(value > 0, "");
2912 multiply(uint32_or_64_or_128_t<Int>(value));
2916 friend FMT_CONSTEXPR20 auto compare(const bigint& lhs, const bigint& rhs)
2918 int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
2919 if (num_lhs_bigits != num_rhs_bigits)
2920 return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
2921 int i = static_cast<int>(lhs.bigits_.size()) - 1;
2922 int j = static_cast<int>(rhs.bigits_.size()) - 1;
2924 if (end < 0) end = 0;
2925 for (; i >= end; --i, --j) {
2926 bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
2927 if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
2929 if (i != j) return i > j ? 1 : -1;
2933 // Returns compare(lhs1 + lhs2, rhs).
2934 friend FMT_CONSTEXPR20 auto add_compare(const bigint& lhs1,
2935 const bigint& lhs2, const bigint& rhs)
2937 auto minimum = [](int a, int b) { return a < b ? a : b; };
2938 auto maximum = [](int a, int b) { return a > b ? a : b; };
2939 int max_lhs_bigits = maximum(lhs1.num_bigits(), lhs2.num_bigits());
2940 int num_rhs_bigits = rhs.num_bigits();
2941 if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
2942 if (max_lhs_bigits > num_rhs_bigits) return 1;
2943 auto get_bigit = [](const bigint& n, int i) -> bigit {
2944 return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
2946 double_bigit borrow = 0;
2947 int min_exp = minimum(minimum(lhs1.exp_, lhs2.exp_), rhs.exp_);
2948 for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
2950 static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
2951 bigit rhs_bigit = get_bigit(rhs, i);
2952 if (sum > rhs_bigit + borrow) return 1;
2953 borrow = rhs_bigit + borrow - sum;
2954 if (borrow > 1) return -1;
2955 borrow <<= bigit_bits;
2957 return borrow != 0 ? -1 : 0;
2960 // Assigns pow(10, exp) to this bigint.
2961 FMT_CONSTEXPR20 void assign_pow10(int exp) {
2962 FMT_ASSERT(exp >= 0, "");
2963 if (exp == 0) return *this = 1;
2964 // Find the top bit.
2966 while (exp >= bitmask) bitmask <<= 1;
2968 // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
2969 // repeated squaring and multiplication.
2972 while (bitmask != 0) {
2974 if ((exp & bitmask) != 0) *this *= 5;
2977 *this <<= exp; // Multiply by pow(2, exp) by shifting.
2980 FMT_CONSTEXPR20 void square() {
2981 int num_bigits = static_cast<int>(bigits_.size());
2982 int num_result_bigits = 2 * num_bigits;
2983 basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
2984 bigits_.resize(to_unsigned(num_result_bigits));
2985 auto sum = uint128_t();
2986 for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
2987 // Compute bigit at position bigit_index of the result by adding
2988 // cross-product terms n[i] * n[j] such that i + j == bigit_index.
2989 for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
2990 // Most terms are multiplied twice which can be optimized in the future.
2991 sum += static_cast<double_bigit>(n[i]) * n[j];
2993 (*this)[bigit_index] = static_cast<bigit>(sum);
2994 sum >>= num_bits<bigit>(); // Compute the carry.
2996 // Do the same for the top half.
2997 for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
2999 for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
3000 sum += static_cast<double_bigit>(n[i++]) * n[j--];
3001 (*this)[bigit_index] = static_cast<bigit>(sum);
3002 sum >>= num_bits<bigit>();
3004 remove_leading_zeros();
3008 // If this bigint has a bigger exponent than other, adds trailing zero to make
3009 // exponents equal. This simplifies some operations such as subtraction.
3010 FMT_CONSTEXPR20 void align(const bigint& other) {
3011 int exp_difference = exp_ - other.exp_;
3012 if (exp_difference <= 0) return;
3013 int num_bigits = static_cast<int>(bigits_.size());
3014 bigits_.resize(to_unsigned(num_bigits + exp_difference));
3015 for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
3016 bigits_[j] = bigits_[i];
3017 std::uninitialized_fill_n(bigits_.data(), exp_difference, 0u);
3018 exp_ -= exp_difference;
3021 // Divides this bignum by divisor, assigning the remainder to this and
3022 // returning the quotient.
3023 FMT_CONSTEXPR20 auto divmod_assign(const bigint& divisor) -> int {
3024 FMT_ASSERT(this != &divisor, "");
3025 if (compare(*this, divisor) < 0) return 0;
3026 FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
3030 subtract_aligned(divisor);
3032 } while (compare(*this, divisor) >= 0);
3037 // format_dragon flags.
3039 predecessor_closer = 1,
3040 fixup = 2, // Run fixup to correct exp10 which can be off by one.
3044 // Formats a floating-point number using a variation of the Fixed-Precision
3045 // Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
3046 // https://fmt.dev/papers/p372-steele.pdf.
3047 FMT_CONSTEXPR20 inline void format_dragon(basic_fp<uint128_t> value,
3048 unsigned flags, int num_digits,
3049 buffer<char>& buf, int& exp10) {
3050 bigint numerator; // 2 * R in (FPP)^2.
3051 bigint denominator; // 2 * S in (FPP)^2.
3052 // lower and upper are differences between value and corresponding boundaries.
3053 bigint lower; // (M^- in (FPP)^2).
3054 bigint upper_store; // upper's value if different from lower.
3055 bigint* upper = nullptr; // (M^+ in (FPP)^2).
3056 // Shift numerator and denominator by an extra bit or two (if lower boundary
3057 // is closer) to make lower and upper integers. This eliminates multiplication
3058 // by 2 during later computations.
3059 bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0;
3060 int shift = is_predecessor_closer ? 2 : 1;
3062 numerator = value.f;
3063 numerator <<= value.e + shift;
3066 if (is_predecessor_closer) {
3068 upper_store <<= value.e + 1;
3069 upper = &upper_store;
3071 denominator.assign_pow10(exp10);
3072 denominator <<= shift;
3073 } else if (exp10 < 0) {
3074 numerator.assign_pow10(-exp10);
3075 lower.assign(numerator);
3076 if (is_predecessor_closer) {
3077 upper_store.assign(numerator);
3079 upper = &upper_store;
3081 numerator *= value.f;
3082 numerator <<= shift;
3084 denominator <<= shift - value.e;
3086 numerator = value.f;
3087 numerator <<= shift;
3088 denominator.assign_pow10(exp10);
3089 denominator <<= shift - value.e;
3091 if (is_predecessor_closer) {
3092 upper_store = 1ULL << 1;
3093 upper = &upper_store;
3096 int even = static_cast<int>((value.f & 1) == 0);
3097 if (!upper) upper = &lower;
3098 bool shortest = num_digits < 0;
3099 if ((flags & dragon::fixup) != 0) {
3100 if (add_compare(numerator, *upper, denominator) + even <= 0) {
3103 if (num_digits < 0) {
3105 if (upper != &lower) *upper *= 10;
3108 if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1);
3110 // Invariant: value == (numerator / denominator) * pow(10, exp10).
3112 // Generate the shortest representation.
3114 char* data = buf.data();
3116 int digit = numerator.divmod_assign(denominator);
3117 bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower.
3118 // numerator + upper >[=] pow10:
3119 bool high = add_compare(numerator, *upper, denominator) + even > 0;
3120 data[num_digits++] = static_cast<char>('0' + digit);
3123 ++data[num_digits - 1];
3125 int result = add_compare(numerator, numerator, denominator);
3126 // Round half to even.
3127 if (result > 0 || (result == 0 && (digit % 2) != 0))
3128 ++data[num_digits - 1];
3130 buf.try_resize(to_unsigned(num_digits));
3131 exp10 -= num_digits - 1;
3136 if (upper != &lower) *upper *= 10;
3139 // Generate the given number of digits.
3140 exp10 -= num_digits - 1;
3141 if (num_digits <= 0) {
3143 auto digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
3144 buf.push_back(digit);
3147 buf.try_resize(to_unsigned(num_digits));
3148 for (int i = 0; i < num_digits - 1; ++i) {
3149 int digit = numerator.divmod_assign(denominator);
3150 buf[i] = static_cast<char>('0' + digit);
3153 int digit = numerator.divmod_assign(denominator);
3154 auto result = add_compare(numerator, numerator, denominator);
3155 if (result > 0 || (result == 0 && (digit % 2) != 0)) {
3157 const auto overflow = '0' + 10;
3158 buf[num_digits - 1] = overflow;
3159 // Propagate the carry.
3160 for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
3164 if (buf[0] == overflow) {
3166 if ((flags & dragon::fixed) != 0)
3175 buf[num_digits - 1] = static_cast<char>('0' + digit);
3178 // Formats a floating-point number using the hexfloat format.
3179 template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
3180 FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision,
3181 float_specs specs, buffer<char>& buf) {
3182 // float is passed as double to reduce the number of instantiations and to
3183 // simplify implementation.
3184 static_assert(!std::is_same<Float, float>::value, "");
3186 using info = dragonbox::float_info<Float>;
3188 // Assume Float is in the format [sign][exponent][significand].
3189 using carrier_uint = typename info::carrier_uint;
3191 constexpr auto num_float_significand_bits =
3192 detail::num_significand_bits<Float>();
3194 basic_fp<carrier_uint> f(value);
3195 f.e += num_float_significand_bits;
3196 if (!has_implicit_bit<Float>()) --f.e;
3198 constexpr auto num_fraction_bits =
3199 num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3200 constexpr auto num_xdigits = (num_fraction_bits + 3) / 4;
3202 constexpr auto leading_shift = ((num_xdigits - 1) * 4);
3203 const auto leading_mask = carrier_uint(0xF) << leading_shift;
3204 const auto leading_xdigit =
3205 static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
3206 if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
3208 int print_xdigits = num_xdigits - 1;
3209 if (precision >= 0 && print_xdigits > precision) {
3210 const int shift = ((print_xdigits - precision - 1) * 4);
3211 const auto mask = carrier_uint(0xF) << shift;
3212 const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
3215 const auto inc = carrier_uint(1) << (shift + 4);
3220 // Check long double overflow
3221 if (!has_implicit_bit<Float>()) {
3222 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3223 if ((f.f & implicit_bit) == implicit_bit) {
3229 print_xdigits = precision;
3232 char xdigits[num_bits<carrier_uint>() / 4];
3233 detail::fill_n(xdigits, sizeof(xdigits), '0');
3234 format_uint<4>(xdigits, f.f, num_xdigits, specs.upper);
3237 while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
3240 buf.push_back(specs.upper ? 'X' : 'x');
3241 buf.push_back(xdigits[0]);
3242 if (specs.showpoint || print_xdigits > 0 || print_xdigits < precision)
3244 buf.append(xdigits + 1, xdigits + 1 + print_xdigits);
3245 for (; print_xdigits < precision; ++print_xdigits) buf.push_back('0');
3247 buf.push_back(specs.upper ? 'P' : 'p');
3252 abs_e = static_cast<uint32_t>(-f.e);
3255 abs_e = static_cast<uint32_t>(f.e);
3257 format_decimal<char>(appender(buf), abs_e, detail::count_digits(abs_e));
3260 template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
3261 FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision,
3262 float_specs specs, buffer<char>& buf) {
3263 format_hexfloat(static_cast<double>(value), precision, specs, buf);
3266 constexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t {
3267 // For checking rounding thresholds.
3268 // The kth entry is chosen to be the smallest integer such that the
3269 // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k.
3270 // It is equal to ceil(2^31 + 2^32/10^(k + 1)).
3271 // These are stored in a string literal because we cannot have static arrays
3272 // in constexpr functions and non-static ones are poorly optimized.
3273 return U"\x9999999a\x828f5c29\x80418938\x80068db9\x8000a7c6\x800010c7"
3274 U"\x800001ae\x8000002b"[index];
3277 template <typename Float>
3278 FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
3279 buffer<char>& buf) -> int {
3280 // float is passed as double to reduce the number of instantiations.
3281 static_assert(!std::is_same<Float, float>::value, "");
3282 FMT_ASSERT(value >= 0, "value is negative");
3283 auto converted_value = convert_float(value);
3285 const bool fixed = specs.format == float_format::fixed;
3286 if (value <= 0) { // <= instead of == to silence a warning.
3287 if (precision <= 0 || !fixed) {
3291 buf.try_resize(to_unsigned(precision));
3292 fill_n(buf.data(), precision, '0');
3297 bool use_dragon = true;
3298 unsigned dragon_flags = 0;
3299 if (!is_fast_float<Float>() || is_constant_evaluated()) {
3300 const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10)
3301 using info = dragonbox::float_info<decltype(converted_value)>;
3302 const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3303 // Compute exp, an approximate power of 10, such that
3304 // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3305 // This is based on log10(value) == log2(value) / log2(10) and approximation
3306 // of log2(value) by e + num_fraction_bits idea from double-conversion.
3307 auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3308 exp = static_cast<int>(e);
3309 if (e > exp) ++exp; // Compute ceil.
3310 dragon_flags = dragon::fixup;
3311 } else if (precision < 0) {
3312 // Use Dragonbox for the shortest format.
3313 if (specs.binary32) {
3314 auto dec = dragonbox::to_decimal(static_cast<float>(value));
3315 write<char>(buffer_appender<char>(buf), dec.significand);
3316 return dec.exponent;
3318 auto dec = dragonbox::to_decimal(static_cast<double>(value));
3319 write<char>(buffer_appender<char>(buf), dec.significand);
3320 return dec.exponent;
3322 // Extract significand bits and exponent bits.
3323 using info = dragonbox::float_info<double>;
3324 auto br = bit_cast<uint64_t>(static_cast<double>(value));
3326 const uint64_t significand_mask =
3327 (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3328 uint64_t significand = (br & significand_mask);
3329 int exponent = static_cast<int>((br & exponent_mask<double>()) >>
3330 num_significand_bits<double>());
3332 if (exponent != 0) { // Check if normal.
3333 exponent -= exponent_bias<double>() + num_significand_bits<double>();
3335 (static_cast<uint64_t>(1) << num_significand_bits<double>());
3338 // Normalize subnormal inputs.
3339 FMT_ASSERT(significand != 0, "zeros should not appear here");
3340 int shift = countl_zero(significand);
3341 FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3343 shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3344 exponent = (std::numeric_limits<double>::min_exponent -
3345 num_significand_bits<double>()) -
3347 significand <<= shift;
3350 // Compute the first several nonzero decimal significand digits.
3351 // We call the number we get the first segment.
3352 const int k = info::kappa - dragonbox::floor_log10_pow2(exponent);
3354 const int beta = exponent + dragonbox::floor_log2_pow10(k);
3355 uint64_t first_segment;
3356 bool has_more_segments;
3357 int digits_in_the_first_segment;
3359 const auto r = dragonbox::umul192_upper128(
3360 significand << beta, dragonbox::get_cached_power(k));
3361 first_segment = r.high();
3362 has_more_segments = r.low() != 0;
3364 // The first segment can have 18 ~ 19 digits.
3365 if (first_segment >= 1000000000000000000ULL) {
3366 digits_in_the_first_segment = 19;
3368 // When it is of 18-digits, we align it to 19-digits by adding a bogus
3370 digits_in_the_first_segment = 18;
3371 first_segment *= 10;
3375 // Compute the actual number of decimal digits to print.
3376 if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment);
3378 // Use Dragon4 only when there might be not enough digits in the first
3380 if (digits_in_the_first_segment > precision) {
3383 if (precision <= 0) {
3384 exp += digits_in_the_first_segment;
3386 if (precision < 0) {
3387 // Nothing to do, since all we have are just leading zeros.
3390 // We may need to round-up.
3392 if ((first_segment | static_cast<uint64_t>(has_more_segments)) >
3393 5000000000000000000ULL) {
3401 exp += digits_in_the_first_segment - precision;
3403 // When precision > 0, we divide the first segment into three
3404 // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits
3405 // in 32-bits which usually allows faster calculation than in
3406 // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize
3407 // division-by-constant for large 64-bit divisors, we do it here
3408 // manually. The magic number 7922816251426433760 below is equal to
3409 // ceil(2^(64+32) / 10^10).
3410 const uint32_t first_subsegment = static_cast<uint32_t>(
3411 dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >>
3413 const uint64_t second_third_subsegments =
3414 first_segment - first_subsegment * 10000000000ULL;
3418 bool should_round_up;
3419 int number_of_digits_to_print = precision > 9 ? 9 : precision;
3421 // Print a 9-digits subsegment, either the first or the second.
3422 auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
3423 int number_of_digits_printed = 0;
3425 // If we want to print an odd number of digits from the subsegment,
3426 if ((number_of_digits_to_print & 1) != 0) {
3427 // Convert to 64-bit fixed-point fractional form with 1-digit
3428 // integer part. The magic number 720575941 is a good enough
3429 // approximation of 2^(32 + 24) / 10^8; see
3430 // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3432 prod = ((subsegment * static_cast<uint64_t>(720575941)) >> 24) + 1;
3433 digits = static_cast<uint32_t>(prod >> 32);
3434 *buffer = static_cast<char>('0' + digits);
3435 number_of_digits_printed++;
3437 // If we want to print an even number of digits from the
3438 // first_subsegment,
3440 // Convert to 64-bit fixed-point fractional form with 2-digits
3441 // integer part. The magic number 450359963 is a good enough
3442 // approximation of 2^(32 + 20) / 10^7; see
3443 // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3445 prod = ((subsegment * static_cast<uint64_t>(450359963)) >> 20) + 1;
3446 digits = static_cast<uint32_t>(prod >> 32);
3447 copy2(buffer, digits2(digits));
3448 number_of_digits_printed += 2;
3451 // Print all digit pairs.
3452 while (number_of_digits_printed < number_of_digits_to_print) {
3453 prod = static_cast<uint32_t>(prod) * static_cast<uint64_t>(100);
3454 digits = static_cast<uint32_t>(prod >> 32);
3455 copy2(buffer + number_of_digits_printed, digits2(digits));
3456 number_of_digits_printed += 2;
3460 // Print first subsegment.
3461 print_subsegment(first_subsegment, buf.data());
3463 // Perform rounding if the first subsegment is the last subsegment to
3465 if (precision <= 9) {
3466 // Rounding inside the subsegment.
3468 // - either the fractional part is strictly larger than 1/2, or
3469 // - the fractional part is exactly 1/2 and the last digit is odd.
3470 // We rely on the following observations:
3471 // - If fractional_part >= threshold, then the fractional part is
3472 // strictly larger than 1/2.
3473 // - If the MSB of fractional_part is set, then the fractional part
3474 // must be at least 1/2.
3475 // - When the MSB of fractional_part is set, either
3476 // second_third_subsegments being nonzero or has_more_segments
3477 // being true means there are further digits not printed, so the
3478 // fractional part is strictly larger than 1/2.
3479 if (precision < 9) {
3480 uint32_t fractional_part = static_cast<uint32_t>(prod);
3482 fractional_part >= fractional_part_rounding_thresholds(
3483 8 - number_of_digits_to_print) ||
3484 ((fractional_part >> 31) &
3485 ((digits & 1) | (second_third_subsegments != 0) |
3486 has_more_segments)) != 0;
3488 // Rounding at the subsegment boundary.
3489 // In this case, the fractional part is at least 1/2 if and only if
3490 // second_third_subsegments >= 5000000000ULL, and is strictly larger
3491 // than 1/2 if we further have either second_third_subsegments >
3492 // 5000000000ULL or has_more_segments == true.
3494 should_round_up = second_third_subsegments > 5000000000ULL ||
3495 (second_third_subsegments == 5000000000ULL &&
3496 ((digits & 1) != 0 || has_more_segments));
3499 // Otherwise, print the second subsegment.
3501 // Compilers are not aware of how to leverage the maximum value of
3502 // second_third_subsegments to find out a better magic number which
3503 // allows us to eliminate an additional shift. 1844674407370955162 =
3504 // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))).
3505 const uint32_t second_subsegment =
3506 static_cast<uint32_t>(dragonbox::umul128_upper64(
3507 second_third_subsegments, 1844674407370955162ULL));
3508 const uint32_t third_subsegment =
3509 static_cast<uint32_t>(second_third_subsegments) -
3510 second_subsegment * 10;
3512 number_of_digits_to_print = precision - 9;
3513 print_subsegment(second_subsegment, buf.data() + 9);
3515 // Rounding inside the subsegment.
3516 if (precision < 18) {
3517 // The condition third_subsegment != 0 implies that the segment was
3518 // of 19 digits, so in this case the third segment should be
3519 // consisting of a genuine digit from the input.
3520 uint32_t fractional_part = static_cast<uint32_t>(prod);
3522 fractional_part >= fractional_part_rounding_thresholds(
3523 8 - number_of_digits_to_print) ||
3524 ((fractional_part >> 31) &
3525 ((digits & 1) | (third_subsegment != 0) |
3526 has_more_segments)) != 0;
3528 // Rounding at the subsegment boundary.
3530 // In this case, the segment must be of 19 digits, thus
3531 // the third subsegment should be consisting of a genuine digit from
3533 should_round_up = third_subsegment > 5 ||
3534 (third_subsegment == 5 &&
3535 ((digits & 1) != 0 || has_more_segments));
3539 // Round-up if necessary.
3540 if (should_round_up) {
3541 ++buf[precision - 1];
3542 for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) {
3549 buf[precision++] = '0';
3554 buf.try_resize(to_unsigned(precision));
3556 } // if (digits_in_the_first_segment > precision)
3558 // Adjust the exponent for its use in Dragon4.
3559 exp += digits_in_the_first_segment - 1;
3563 auto f = basic_fp<uint128_t>();
3564 bool is_predecessor_closer = specs.binary32
3565 ? f.assign(static_cast<float>(value))
3566 : f.assign(converted_value);
3567 if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3568 if (fixed) dragon_flags |= dragon::fixed;
3569 // Limit precision to the maximum possible number of significant digits in
3570 // an IEEE754 double because we don't need to generate zeros.
3571 const int max_double_digits = 767;
3572 if (precision > max_double_digits) precision = max_double_digits;
3573 format_dragon(f, dragon_flags, precision, buf, exp);
3575 if (!fixed && !specs.showpoint) {
3576 // Remove trailing zeros.
3577 auto num_digits = buf.size();
3578 while (num_digits > 0 && buf[num_digits - 1] == '0') {
3582 buf.try_resize(num_digits);
3586 template <typename Char, typename OutputIt, typename T>
3587 FMT_CONSTEXPR20 auto write_float(OutputIt out, T value,
3588 format_specs<Char> specs, locale_ref loc)
3590 float_specs fspecs = parse_float_type_spec(specs);
3591 fspecs.sign = specs.sign;
3592 if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit.
3593 fspecs.sign = sign::minus;
3595 } else if (fspecs.sign == sign::minus) {
3596 fspecs.sign = sign::none;
3599 if (!detail::isfinite(value))
3600 return write_nonfinite(out, detail::isnan(value), specs, fspecs);
3602 if (specs.align == align::numeric && fspecs.sign) {
3603 auto it = reserve(out, 1);
3604 *it++ = detail::sign<Char>(fspecs.sign);
3605 out = base_iterator(out, it);
3606 fspecs.sign = sign::none;
3607 if (specs.width != 0) --specs.width;
3610 memory_buffer buffer;
3611 if (fspecs.format == float_format::hex) {
3612 if (fspecs.sign) buffer.push_back(detail::sign<char>(fspecs.sign));
3613 format_hexfloat(convert_float(value), specs.precision, fspecs, buffer);
3614 return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
3617 int precision = specs.precision >= 0 || specs.type == presentation_type::none
3620 if (fspecs.format == float_format::exp) {
3621 if (precision == max_value<int>())
3622 throw_format_error("number is too big");
3625 } else if (fspecs.format != float_format::fixed && precision == 0) {
3628 if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
3629 int exp = format_float(convert_float(value), precision, fspecs, buffer);
3630 fspecs.precision = precision;
3631 auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3632 return write_float(out, f, specs, fspecs, loc);
3635 template <typename Char, typename OutputIt, typename T,
3636 FMT_ENABLE_IF(is_floating_point<T>::value)>
3637 FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs<Char> specs,
3638 locale_ref loc = {}) -> OutputIt {
3639 if (const_check(!is_supported_floating_point(value))) return out;
3640 return specs.localized && write_loc(out, value, specs, loc)
3642 : write_float(out, value, specs, loc);
3645 template <typename Char, typename OutputIt, typename T,
3646 FMT_ENABLE_IF(is_fast_float<T>::value)>
3647 FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3648 if (is_constant_evaluated()) return write(out, value, format_specs<Char>());
3649 if (const_check(!is_supported_floating_point(value))) return out;
3651 auto fspecs = float_specs();
3652 if (detail::signbit(value)) {
3653 fspecs.sign = sign::minus;
3657 constexpr auto specs = format_specs<Char>();
3658 using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
3659 using floaty_uint = typename dragonbox::float_info<floaty>::carrier_uint;
3660 floaty_uint mask = exponent_mask<floaty>();
3661 if ((bit_cast<floaty_uint>(value) & mask) == mask)
3662 return write_nonfinite(out, std::isnan(value), specs, fspecs);
3664 auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
3665 return write_float(out, dec, specs, fspecs, {});
3668 template <typename Char, typename OutputIt, typename T,
3669 FMT_ENABLE_IF(is_floating_point<T>::value &&
3670 !is_fast_float<T>::value)>
3671 inline auto write(OutputIt out, T value) -> OutputIt {
3672 return write(out, value, format_specs<Char>());
3675 template <typename Char, typename OutputIt>
3676 auto write(OutputIt out, monostate, format_specs<Char> = {}, locale_ref = {})
3678 FMT_ASSERT(false, "");
3682 template <typename Char, typename OutputIt>
3683 FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value)
3685 auto it = reserve(out, value.size());
3686 it = copy_str_noinline<Char>(value.begin(), value.end(), it);
3687 return base_iterator(out, it);
3690 template <typename Char, typename OutputIt, typename T,
3691 FMT_ENABLE_IF(is_string<T>::value)>
3692 constexpr auto write(OutputIt out, const T& value) -> OutputIt {
3693 return write<Char>(out, to_string_view(value));
3696 // FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
3698 typename Char, typename OutputIt, typename T,
3700 std::is_enum<T>::value && !std::is_same<T, Char>::value &&
3701 mapped_type_constant<T, basic_format_context<OutputIt, Char>>::value !=
3703 FMT_ENABLE_IF(check)>
3704 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
3705 return write<Char>(out, static_cast<underlying_t<T>>(value));
3708 template <typename Char, typename OutputIt, typename T,
3709 FMT_ENABLE_IF(std::is_same<T, bool>::value)>
3710 FMT_CONSTEXPR auto write(OutputIt out, T value,
3711 const format_specs<Char>& specs = {}, locale_ref = {})
3713 return specs.type != presentation_type::none &&
3714 specs.type != presentation_type::string
3715 ? write(out, value ? 1 : 0, specs, {})
3716 : write_bytes(out, value ? "true" : "false", specs);
3719 template <typename Char, typename OutputIt>
3720 FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
3721 auto it = reserve(out, 1);
3723 return base_iterator(out, it);
3726 template <typename Char, typename OutputIt>
3727 FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
3729 if (value) return write(out, basic_string_view<Char>(value));
3730 throw_format_error("string pointer is null");
3734 template <typename Char, typename OutputIt, typename T,
3735 FMT_ENABLE_IF(std::is_same<T, void>::value)>
3736 auto write(OutputIt out, const T* value, const format_specs<Char>& specs = {},
3737 locale_ref = {}) -> OutputIt {
3738 return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
3741 // A write overload that handles implicit conversions.
3742 template <typename Char, typename OutputIt, typename T,
3743 typename Context = basic_format_context<OutputIt, Char>>
3744 FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> enable_if_t<
3745 std::is_class<T>::value && !is_string<T>::value &&
3746 !is_floating_point<T>::value && !std::is_same<T, Char>::value &&
3747 !std::is_same<T, remove_cvref_t<decltype(arg_mapper<Context>().map(
3750 return write<Char>(out, arg_mapper<Context>().map(value));
3753 template <typename Char, typename OutputIt, typename T,
3754 typename Context = basic_format_context<OutputIt, Char>>
3755 FMT_CONSTEXPR auto write(OutputIt out, const T& value)
3756 -> enable_if_t<mapped_type_constant<T, Context>::value == type::custom_type,
3758 auto formatter = typename Context::template formatter_type<T>();
3759 auto parse_ctx = typename Context::parse_context_type({});
3760 formatter.parse(parse_ctx);
3761 auto ctx = Context(out, {}, {});
3762 return formatter.format(value, ctx);
3765 // An argument visitor that formats the argument and writes it via the output
3766 // iterator. It's a class and not a generic lambda for compatibility with C++11.
3767 template <typename Char> struct default_arg_formatter {
3768 using iterator = buffer_appender<Char>;
3769 using context = buffer_context<Char>;
3772 basic_format_args<context> args;
3775 template <typename T> auto operator()(T value) -> iterator {
3776 return write<Char>(out, value);
3778 auto operator()(typename basic_format_arg<context>::handle h) -> iterator {
3779 basic_format_parse_context<Char> parse_ctx({});
3780 context format_ctx(out, args, loc);
3781 h.format(parse_ctx, format_ctx);
3782 return format_ctx.out();
3786 template <typename Char> struct arg_formatter {
3787 using iterator = buffer_appender<Char>;
3788 using context = buffer_context<Char>;
3791 const format_specs<Char>& specs;
3794 template <typename T>
3795 FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator {
3796 return detail::write(out, value, specs, locale);
3798 auto operator()(typename basic_format_arg<context>::handle) -> iterator {
3799 // User-defined types are handled separately because they require access
3800 // to the parse context.
3805 struct width_checker {
3806 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3807 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3808 if (is_negative(value)) throw_format_error("negative width");
3809 return static_cast<unsigned long long>(value);
3812 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3813 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3814 throw_format_error("width is not integer");
3819 struct precision_checker {
3820 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3821 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3822 if (is_negative(value)) throw_format_error("negative precision");
3823 return static_cast<unsigned long long>(value);
3826 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3827 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3828 throw_format_error("precision is not integer");
3833 template <typename Handler, typename FormatArg>
3834 FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg) -> int {
3835 unsigned long long value = visit_format_arg(Handler(), arg);
3836 if (value > to_unsigned(max_value<int>()))
3837 throw_format_error("number is too big");
3838 return static_cast<int>(value);
3841 template <typename Context, typename ID>
3842 FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) -> decltype(ctx.arg(id)) {
3843 auto arg = ctx.arg(id);
3844 if (!arg) ctx.on_error("argument not found");
3848 template <typename Handler, typename Context>
3849 FMT_CONSTEXPR void handle_dynamic_spec(int& value,
3850 arg_ref<typename Context::char_type> ref,
3853 case arg_id_kind::none:
3855 case arg_id_kind::index:
3856 value = detail::get_dynamic_spec<Handler>(get_arg(ctx, ref.val.index));
3858 case arg_id_kind::name:
3859 value = detail::get_dynamic_spec<Handler>(get_arg(ctx, ref.val.name));
3864 #if FMT_USE_USER_DEFINED_LITERALS
3865 # if FMT_USE_NONTYPE_TEMPLATE_ARGS
3866 template <typename T, typename Char, size_t N,
3867 fmt::detail_exported::fixed_string<Char, N> Str>
3868 struct statically_named_arg : view {
3869 static constexpr auto name = Str.data;
3872 statically_named_arg(const T& v) : value(v) {}
3875 template <typename T, typename Char, size_t N,
3876 fmt::detail_exported::fixed_string<Char, N> Str>
3877 struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
3879 template <typename T, typename Char, size_t N,
3880 fmt::detail_exported::fixed_string<Char, N> Str>
3881 struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
3882 : std::true_type {};
3884 template <typename Char, size_t N,
3885 fmt::detail_exported::fixed_string<Char, N> Str>
3887 template <typename T> auto operator=(T&& value) const {
3888 return statically_named_arg<T, Char, N, Str>(std::forward<T>(value));
3892 template <typename Char> struct udl_arg {
3895 template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
3896 return {str, std::forward<T>(value)};
3900 #endif // FMT_USE_USER_DEFINED_LITERALS
3902 template <typename Locale, typename Char>
3903 auto vformat(const Locale& loc, basic_string_view<Char> fmt,
3904 basic_format_args<buffer_context<type_identity_t<Char>>> args)
3905 -> std::basic_string<Char> {
3906 auto buf = basic_memory_buffer<Char>();
3907 detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
3908 return {buf.data(), buf.size()};
3911 using format_func = void (*)(detail::buffer<char>&, int, const char*);
3913 FMT_API void format_error_code(buffer<char>& out, int error_code,
3914 string_view message) noexcept;
3916 FMT_API void report_error(format_func func, int error_code,
3917 const char* message) noexcept;
3918 } // namespace detail
3920 FMT_API auto vsystem_error(int error_code, string_view format_str,
3921 format_args args) -> std::system_error;
3925 Constructs :class:`std::system_error` with a message formatted with
3926 ``fmt::format(fmt, args...)``.
3927 *error_code* is a system error code as given by ``errno``.
3931 // This throws std::system_error with the description
3932 // cannot open file 'madeup': No such file or directory
3933 // or similar (system message may vary).
3934 const char* filename = "madeup";
3935 std::FILE* file = std::fopen(filename, "r");
3937 throw fmt::system_error(errno, "cannot open file '{}'", filename);
3940 template <typename... T>
3941 auto system_error(int error_code, format_string<T...> fmt, T&&... args)
3942 -> std::system_error {
3943 return vsystem_error(error_code, fmt, fmt::make_format_args(args...));
3948 Formats an error message for an error returned by an operating system or a
3949 language runtime, for example a file opening error, and writes it to *out*.
3950 The format is the same as the one used by ``std::system_error(ec, message)``
3951 where ``ec`` is ``std::error_code(error_code, std::generic_category()})``.
3952 It is implementation-defined but normally looks like:
3955 *<message>*: *<system-message>*
3957 where *<message>* is the passed message and *<system-message>* is the system
3958 message corresponding to the error code.
3959 *error_code* is a system error code as given by ``errno``.
3962 FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
3963 const char* message) noexcept;
3965 // Reports a system error without throwing an exception.
3966 // Can be used to report errors from destructors.
3967 FMT_API void report_system_error(int error_code, const char* message) noexcept;
3969 /** Fast integer formatter. */
3972 // Buffer should be large enough to hold all digits (digits10 + 1),
3973 // a sign and a null character.
3974 enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
3975 mutable char buffer_[buffer_size];
3978 template <typename UInt> auto format_unsigned(UInt value) -> char* {
3979 auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
3980 return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
3983 template <typename Int> auto format_signed(Int value) -> char* {
3984 auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
3985 bool negative = value < 0;
3986 if (negative) abs_value = 0 - abs_value;
3987 auto begin = format_unsigned(abs_value);
3988 if (negative) *--begin = '-';
3993 explicit format_int(int value) : str_(format_signed(value)) {}
3994 explicit format_int(long value) : str_(format_signed(value)) {}
3995 explicit format_int(long long value) : str_(format_signed(value)) {}
3996 explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
3997 explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
3998 explicit format_int(unsigned long long value)
3999 : str_(format_unsigned(value)) {}
4001 /** Returns the number of characters written to the output buffer. */
4002 auto size() const -> size_t {
4003 return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
4007 Returns a pointer to the output buffer content. No terminating null
4008 character is appended.
4010 auto data() const -> const char* { return str_; }
4013 Returns a pointer to the output buffer content with terminating null
4016 auto c_str() const -> const char* {
4017 buffer_[buffer_size - 1] = '\0';
4023 Returns the content of the output buffer as an ``std::string``.
4026 auto str() const -> std::string { return std::string(str_, size()); }
4029 template <typename T, typename Char>
4030 struct formatter<T, Char, enable_if_t<detail::has_format_as<T>::value>>
4031 : formatter<detail::format_as_t<T>, Char> {
4032 template <typename FormatContext>
4033 auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) {
4034 using base = formatter<detail::format_as_t<T>, Char>;
4035 return base::format(format_as(value), ctx);
4039 #define FMT_FORMAT_AS(Type, Base) \
4040 template <typename Char> \
4041 struct formatter<Type, Char> : formatter<Base, Char> {}
4043 FMT_FORMAT_AS(signed char, int);
4044 FMT_FORMAT_AS(unsigned char, unsigned);
4045 FMT_FORMAT_AS(short, int);
4046 FMT_FORMAT_AS(unsigned short, unsigned);
4047 FMT_FORMAT_AS(long, detail::long_type);
4048 FMT_FORMAT_AS(unsigned long, detail::ulong_type);
4049 FMT_FORMAT_AS(Char*, const Char*);
4050 FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
4051 FMT_FORMAT_AS(std::nullptr_t, const void*);
4052 FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
4053 FMT_FORMAT_AS(void*, const void*);
4055 template <typename Char, size_t N>
4056 struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {};
4060 Converts ``p`` to ``const void*`` for pointer formatting.
4064 auto s = fmt::format("{}", fmt::ptr(p));
4067 template <typename T> auto ptr(T p) -> const void* {
4068 static_assert(std::is_pointer<T>::value, "");
4069 return detail::bit_cast<const void*>(p);
4071 template <typename T, typename Deleter>
4072 auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
4075 template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
4081 Converts ``e`` to the underlying type.
4085 enum class color { red, green, blue };
4086 auto s = fmt::format("{}", fmt::underlying(color::red));
4089 template <typename Enum>
4090 constexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {
4091 return static_cast<underlying_t<Enum>>(e);
4095 template <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
4096 constexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {
4097 return static_cast<underlying_t<Enum>>(e);
4099 } // namespace enums
4104 friend struct formatter<bytes>;
4107 explicit bytes(string_view data) : data_(data) {}
4110 template <> struct formatter<bytes> {
4112 detail::dynamic_format_specs<> specs_;
4115 template <typename ParseContext>
4116 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const char* {
4117 return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
4118 detail::type::string_type);
4121 template <typename FormatContext>
4122 auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
4123 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4124 specs_.width_ref, ctx);
4125 detail::handle_dynamic_spec<detail::precision_checker>(
4126 specs_.precision, specs_.precision_ref, ctx);
4127 return detail::write_bytes(ctx.out(), b.data_, specs_);
4131 // group_digits_view is not derived from view because it copies the argument.
4132 template <typename T> struct group_digits_view {
4138 Returns a view that formats an integer value using ',' as a locale-independent
4139 thousands separator.
4143 fmt::print("{}", fmt::group_digits(12345));
4147 template <typename T> auto group_digits(T value) -> group_digits_view<T> {
4151 template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
4153 detail::dynamic_format_specs<> specs_;
4156 template <typename ParseContext>
4157 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const char* {
4158 return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
4159 detail::type::int_type);
4162 template <typename FormatContext>
4163 auto format(group_digits_view<T> t, FormatContext& ctx)
4164 -> decltype(ctx.out()) {
4165 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4166 specs_.width_ref, ctx);
4167 detail::handle_dynamic_spec<detail::precision_checker>(
4168 specs_.precision, specs_.precision_ref, ctx);
4169 return detail::write_int(
4170 ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_,
4171 detail::digit_grouping<char>("\3", ","));
4175 template <typename T> struct nested_view {
4176 const formatter<T>* fmt;
4180 template <typename T> struct formatter<nested_view<T>> {
4181 FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> const char* {
4184 auto format(nested_view<T> view, format_context& ctx) const
4185 -> decltype(ctx.out()) {
4186 return view.fmt->format(*view.value, ctx);
4190 template <typename T> struct nested_formatter {
4193 detail::fill_t<char> fill_;
4195 formatter<T> formatter_;
4198 constexpr nested_formatter() : width_(0), align_(align_t::none) {}
4200 FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> const char* {
4201 auto specs = detail::dynamic_format_specs<char>();
4202 auto it = parse_format_specs(ctx.begin(), ctx.end(), specs, ctx,
4203 detail::type::none_type);
4204 width_ = specs.width;
4206 align_ = specs.align;
4208 return formatter_.parse(ctx);
4211 template <typename F>
4212 auto write_padded(format_context& ctx, F write) const -> decltype(ctx.out()) {
4213 if (width_ == 0) return write(ctx.out());
4214 auto buf = memory_buffer();
4215 write(std::back_inserter(buf));
4216 auto specs = format_specs<>();
4217 specs.width = width_;
4219 specs.align = align_;
4220 return detail::write(ctx.out(), string_view(buf.data(), buf.size()), specs);
4223 auto nested(const T& value) const -> nested_view<T> {
4224 return nested_view<T>{&formatter_, &value};
4228 // DEPRECATED! join_view will be moved to ranges.h.
4229 template <typename It, typename Sentinel, typename Char = char>
4230 struct join_view : detail::view {
4233 basic_string_view<Char> sep;
4235 join_view(It b, Sentinel e, basic_string_view<Char> s)
4236 : begin(b), end(e), sep(s) {}
4239 template <typename It, typename Sentinel, typename Char>
4240 struct formatter<join_view<It, Sentinel, Char>, Char> {
4243 #ifdef __cpp_lib_ranges
4244 std::iter_value_t<It>;
4246 typename std::iterator_traits<It>::value_type;
4248 formatter<remove_cvref_t<value_type>, Char> value_formatter_;
4251 template <typename ParseContext>
4252 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const Char* {
4253 return value_formatter_.parse(ctx);
4256 template <typename FormatContext>
4257 auto format(const join_view<It, Sentinel, Char>& value,
4258 FormatContext& ctx) const -> decltype(ctx.out()) {
4259 auto it = value.begin;
4260 auto out = ctx.out();
4261 if (it != value.end) {
4262 out = value_formatter_.format(*it, ctx);
4264 while (it != value.end) {
4265 out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
4266 ctx.advance_to(out);
4267 out = value_formatter_.format(*it, ctx);
4276 Returns a view that formats the iterator range `[begin, end)` with elements
4279 template <typename It, typename Sentinel>
4280 auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
4281 return {begin, end, sep};
4286 Returns a view that formats `range` with elements separated by `sep`.
4290 std::vector<int> v = {1, 2, 3};
4291 fmt::print("{}", fmt::join(v, ", "));
4292 // Output: "1, 2, 3"
4294 ``fmt::join`` applies passed format specifiers to the range elements::
4296 fmt::print("{:02}", fmt::join(v, ", "));
4297 // Output: "01, 02, 03"
4300 template <typename Range>
4301 auto join(Range&& range, string_view sep)
4302 -> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>> {
4303 return join(std::begin(range), std::end(range), sep);
4308 Converts *value* to ``std::string`` using the default format for type *T*.
4312 #include <fmt/format.h>
4314 std::string answer = fmt::to_string(42);
4317 template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
4318 !detail::has_format_as<T>::value)>
4319 inline auto to_string(const T& value) -> std::string {
4320 auto buffer = memory_buffer();
4321 detail::write<char>(appender(buffer), value);
4322 return {buffer.data(), buffer.size()};
4325 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
4326 FMT_NODISCARD inline auto to_string(T value) -> std::string {
4327 // The buffer should be large enough to store the number including the sign
4328 // or "false" for bool.
4329 constexpr int max_size = detail::digits10<T>() + 2;
4330 char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
4331 char* begin = buffer;
4332 return std::string(begin, detail::write<char>(begin, value));
4335 template <typename Char, size_t SIZE>
4336 FMT_NODISCARD auto to_string(const basic_memory_buffer<Char, SIZE>& buf)
4337 -> std::basic_string<Char> {
4338 auto size = buf.size();
4339 detail::assume(size < std::basic_string<Char>().max_size());
4340 return std::basic_string<Char>(buf.data(), size);
4343 template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
4344 detail::has_format_as<T>::value)>
4345 inline auto to_string(const T& value) -> std::string {
4346 return to_string(format_as(value));
4353 template <typename Char>
4354 void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
4355 typename vformat_args<Char>::type args, locale_ref loc) {
4356 auto out = buffer_appender<Char>(buf);
4357 if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
4358 auto arg = args.get(0);
4359 if (!arg) throw_format_error("argument not found");
4360 visit_format_arg(default_arg_formatter<Char>{out, args, loc}, arg);
4364 struct format_handler : error_handler {
4365 basic_format_parse_context<Char> parse_context;
4366 buffer_context<Char> context;
4368 format_handler(buffer_appender<Char> p_out, basic_string_view<Char> str,
4369 basic_format_args<buffer_context<Char>> p_args,
4371 : parse_context(str), context(p_out, p_args, p_loc) {}
4373 void on_text(const Char* begin, const Char* end) {
4374 auto text = basic_string_view<Char>(begin, to_unsigned(end - begin));
4375 context.advance_to(write<Char>(context.out(), text));
4378 FMT_CONSTEXPR auto on_arg_id() -> int {
4379 return parse_context.next_arg_id();
4381 FMT_CONSTEXPR auto on_arg_id(int id) -> int {
4382 return parse_context.check_arg_id(id), id;
4384 FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
4385 int arg_id = context.arg_id(id);
4386 if (arg_id < 0) throw_format_error("argument not found");
4390 FMT_INLINE void on_replacement_field(int id, const Char*) {
4391 auto arg = get_arg(context, id);
4392 context.advance_to(visit_format_arg(
4393 default_arg_formatter<Char>{context.out(), context.args(),
4398 auto on_format_specs(int id, const Char* begin, const Char* end)
4400 auto arg = get_arg(context, id);
4401 // Not using a visitor for custom types gives better codegen.
4402 if (arg.format_custom(begin, parse_context, context))
4403 return parse_context.begin();
4404 auto specs = detail::dynamic_format_specs<Char>();
4405 begin = parse_format_specs(begin, end, specs, parse_context, arg.type());
4406 detail::handle_dynamic_spec<detail::width_checker>(
4407 specs.width, specs.width_ref, context);
4408 detail::handle_dynamic_spec<detail::precision_checker>(
4409 specs.precision, specs.precision_ref, context);
4410 if (begin == end || *begin != '}')
4411 throw_format_error("missing '}' in format string");
4412 auto f = arg_formatter<Char>{context.out(), specs, context.locale()};
4413 context.advance_to(visit_format_arg(f, arg));
4417 detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
4422 #ifndef FMT_HEADER_ONLY
4423 extern template FMT_API void vformat_to(buffer<char>&, string_view,
4424 typename vformat_args<>::type,
4426 extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
4427 -> thousands_sep_result<char>;
4428 extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
4429 -> thousands_sep_result<wchar_t>;
4430 extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
4431 extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
4432 #endif // FMT_HEADER_ONLY
4434 } // namespace detail
4436 #if FMT_USE_USER_DEFINED_LITERALS
4437 inline namespace literals {
4440 User-defined literal equivalent of :func:`fmt::arg`.
4444 using namespace fmt::literals;
4445 fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
4448 # if FMT_USE_NONTYPE_TEMPLATE_ARGS
4449 template <detail_exported::fixed_string Str> constexpr auto operator""_a() {
4450 using char_t = remove_cvref_t<decltype(Str.data[0])>;
4451 return detail::udl_arg<char_t, sizeof(Str.data) / sizeof(char_t), Str>();
4454 constexpr auto operator""_a(const char* s, size_t) -> detail::udl_arg<char> {
4458 } // namespace literals
4459 #endif // FMT_USE_USER_DEFINED_LITERALS
4461 template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4462 inline auto vformat(const Locale& loc, string_view fmt, format_args args)
4464 return detail::vformat(loc, fmt, args);
4467 template <typename Locale, typename... T,
4468 FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4469 inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
4471 return fmt::vformat(loc, string_view(fmt), fmt::make_format_args(args...));
4474 template <typename OutputIt, typename Locale,
4475 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
4476 detail::is_locale<Locale>::value)>
4477 auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
4478 format_args args) -> OutputIt {
4479 using detail::get_buffer;
4480 auto&& buf = get_buffer<char>(out);
4481 detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
4482 return detail::get_iterator(buf, out);
4485 template <typename OutputIt, typename Locale, typename... T,
4486 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
4487 detail::is_locale<Locale>::value)>
4488 FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
4489 format_string<T...> fmt, T&&... args) -> OutputIt {
4490 return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
4493 template <typename Locale, typename... T,
4494 FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4495 FMT_NODISCARD FMT_INLINE auto formatted_size(const Locale& loc,
4496 format_string<T...> fmt,
4497 T&&... args) -> size_t {
4498 auto buf = detail::counting_buffer<>();
4499 detail::vformat_to<char>(buf, fmt, fmt::make_format_args(args...),
4500 detail::locale_ref(loc));
4506 template <typename T, typename Char>
4507 template <typename FormatContext>
4508 FMT_CONSTEXPR FMT_INLINE auto
4510 enable_if_t<detail::type_constant<T, Char>::value !=
4511 detail::type::custom_type>>::format(const T& val,
4513 const -> decltype(ctx.out()) {
4514 if (specs_.width_ref.kind == detail::arg_id_kind::none &&
4515 specs_.precision_ref.kind == detail::arg_id_kind::none) {
4516 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
4518 auto specs = specs_;
4519 detail::handle_dynamic_spec<detail::width_checker>(specs.width,
4520 specs.width_ref, ctx);
4521 detail::handle_dynamic_spec<detail::precision_checker>(
4522 specs.precision, specs.precision_ref, ctx);
4523 return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
4528 #ifdef FMT_HEADER_ONLY
4529 # define FMT_FUNC inline
4530 # include "format-inl.h"
4535 #endif // FMT_FORMAT_H_