WPILibC++ 2023.4.3
format.h
Go to the documentation of this file.
1/*
2 Formatting library for C++
3
4 Copyright (c) 2012 - present, Victor Zverovich
5
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:
13
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
16
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.
24
25 --- Optional exception to the license ---
26
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.
31 */
32
33#ifndef FMT_FORMAT_H_
34#define FMT_FORMAT_H_
35
36#include <cmath> // std::signbit
37#include <cstdint> // uint32_t
38#include <cstring> // std::memcpy
39#include <limits> // std::numeric_limits
40#include <memory> // std::uninitialized_copy
41#include <stdexcept> // std::runtime_error
42#include <system_error> // std::system_error
43
44#ifdef __cpp_lib_bit_cast
45# include <bit> // std::bitcast
46#endif
47
48#include "core.h"
49
50#if FMT_GCC_VERSION
51# define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
52#else
53# define FMT_GCC_VISIBILITY_HIDDEN
54#endif
55
56#ifdef __NVCC__
57# define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
58#else
59# define FMT_CUDA_VERSION 0
60#endif
61
62#ifdef __has_builtin
63# define FMT_HAS_BUILTIN(x) __has_builtin(x)
64#else
65# define FMT_HAS_BUILTIN(x) 0
66#endif
67
68#if FMT_GCC_VERSION || FMT_CLANG_VERSION
69# define FMT_NOINLINE __attribute__((noinline))
70#else
71# define FMT_NOINLINE
72#endif
73
74#if FMT_MSC_VERSION
75# define FMT_MSC_DEFAULT = default
76#else
77# define FMT_MSC_DEFAULT
78#endif
79
80#ifndef FMT_THROW
81# if FMT_EXCEPTIONS
82# if FMT_MSC_VERSION || defined(__NVCC__)
84namespace detail {
85template <typename Exception> inline void do_throw(const Exception& x) {
86 // Silence unreachable code warnings in MSVC and NVCC because these
87 // are nearly impossible to fix in a generic code.
88 volatile bool b = true;
89 if (b) throw x;
90}
91} // namespace detail
93# define FMT_THROW(x) detail::do_throw(x)
94# else
95# define FMT_THROW(x) throw x
96# endif
97# else
98# define FMT_THROW(x) \
99 do { \
100 FMT_ASSERT(false, (x).what()); \
101 } while (false)
102# endif
103#endif
104
105#if FMT_EXCEPTIONS
106# define FMT_TRY try
107# define FMT_CATCH(x) catch (x)
108#else
109# define FMT_TRY if (true)
110# define FMT_CATCH(x) if (false)
111#endif
112
113#ifndef FMT_MAYBE_UNUSED
114# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
115# define FMT_MAYBE_UNUSED [[maybe_unused]]
116# else
117# define FMT_MAYBE_UNUSED
118# endif
119#endif
120
121#ifndef FMT_USE_USER_DEFINED_LITERALS
122// EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
123# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
124 FMT_MSC_VERSION >= 1900) && \
125 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480)
126# define FMT_USE_USER_DEFINED_LITERALS 1
127# else
128# define FMT_USE_USER_DEFINED_LITERALS 0
129# endif
130#endif
131
132// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
133// integer formatter template instantiations to just one by only using the
134// largest integer type. This results in a reduction in binary size but will
135// cause a decrease in integer formatting performance.
136#if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
137# define FMT_REDUCE_INT_INSTANTIATIONS 0
138#endif
139
140// __builtin_clz is broken in clang with Microsoft CodeGen:
141// https://github.com/fmtlib/fmt/issues/519.
142#if !FMT_MSC_VERSION
143# if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
144# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
145# endif
146# if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
147# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
148# endif
149#endif
150
151// __builtin_ctz is broken in Intel Compiler Classic on Windows:
152// https://github.com/fmtlib/fmt/issues/2510.
153#ifndef __ICL
154# if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION || \
155 defined(__NVCOMPILER)
156# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
157# endif
158# if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || \
159 FMT_ICC_VERSION || defined(__NVCOMPILER)
160# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
161# endif
162#endif
163
164#if FMT_MSC_VERSION
165# include <intrin.h> // _BitScanReverse[64], _BitScanForward[64], _umul128
166#endif
167
168// Some compilers masquerade as both MSVC and GCC-likes or otherwise support
169// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
170// MSVC intrinsics if the clz and clzll builtins are not available.
171#if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) && \
172 !defined(FMT_BUILTIN_CTZLL)
174namespace detail {
175// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
176# if !defined(__clang__)
177# pragma intrinsic(_BitScanForward)
178# pragma intrinsic(_BitScanReverse)
179# if defined(_WIN64)
180# pragma intrinsic(_BitScanForward64)
181# pragma intrinsic(_BitScanReverse64)
182# endif
183# endif
184
185inline auto clz(uint32_t x) -> int {
186 unsigned long r = 0;
187 _BitScanReverse(&r, x);
188 FMT_ASSERT(x != 0, "");
189 // Static analysis complains about using uninitialized data
190 // "r", but the only way that can happen is if "x" is 0,
191 // which the callers guarantee to not happen.
192 FMT_MSC_WARNING(suppress : 6102)
193 return 31 ^ static_cast<int>(r);
194}
195# define FMT_BUILTIN_CLZ(n) detail::clz(n)
196
197inline auto clzll(uint64_t x) -> int {
198 unsigned long r = 0;
199# ifdef _WIN64
200 _BitScanReverse64(&r, x);
201# else
202 // Scan the high 32 bits.
203 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 ^ (r + 32);
204 // Scan the low 32 bits.
205 _BitScanReverse(&r, static_cast<uint32_t>(x));
206# endif
207 FMT_ASSERT(x != 0, "");
208 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
209 return 63 ^ static_cast<int>(r);
210}
211# define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
212
213inline auto ctz(uint32_t x) -> int {
214 unsigned long r = 0;
215 _BitScanForward(&r, x);
216 FMT_ASSERT(x != 0, "");
217 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
218 return static_cast<int>(r);
219}
220# define FMT_BUILTIN_CTZ(n) detail::ctz(n)
221
222inline auto ctzll(uint64_t x) -> int {
223 unsigned long r = 0;
224 FMT_ASSERT(x != 0, "");
225 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
226# ifdef _WIN64
227 _BitScanForward64(&r, x);
228# else
229 // Scan the low 32 bits.
230 if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r);
231 // Scan the high 32 bits.
232 _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
233 r += 32;
234# endif
235 return static_cast<int>(r);
236}
237# define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
238} // namespace detail
240#endif
241
243namespace detail {
244
245FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) {
246 ignore_unused(condition);
247#ifdef FMT_FUZZ
248 if (condition) throw std::runtime_error("fuzzing limit reached");
249#endif
250}
251
252template <typename CharT, CharT... C> struct string_literal {
253 static constexpr CharT value[sizeof...(C)] = {C...};
254 constexpr operator basic_string_view<CharT>() const {
255 return {value, sizeof...(C)};
256 }
257};
258
259#if FMT_CPLUSPLUS < 201703L
260template <typename CharT, CharT... C>
261constexpr CharT string_literal<CharT, C...>::value[sizeof...(C)];
262#endif
263
264template <typename Streambuf> class formatbuf : public Streambuf {
265 private:
266 using char_type = typename Streambuf::char_type;
267 using streamsize = decltype(std::declval<Streambuf>().sputn(nullptr, 0));
268 using int_type = typename Streambuf::int_type;
269 using traits_type = typename Streambuf::traits_type;
270
271 buffer<char_type>& buffer_;
272
273 public:
274 explicit formatbuf(buffer<char_type>& buf) : buffer_(buf) {}
275
276 protected:
277 // The put area is always empty. This makes the implementation simpler and has
278 // the advantage that the streambuf and the buffer are always in sync and
279 // sputc never writes into uninitialized memory. A disadvantage is that each
280 // call to sputc always results in a (virtual) call to overflow. There is no
281 // disadvantage here for sputn since this always results in a call to xsputn.
282
283 auto overflow(int_type ch) -> int_type override {
284 if (!traits_type::eq_int_type(ch, traits_type::eof()))
285 buffer_.push_back(static_cast<char_type>(ch));
286 return ch;
287 }
288
289 auto xsputn(const char_type* s, streamsize count) -> streamsize override {
290 buffer_.append(s, s + count);
291 return count;
292 }
293};
294
295// Implementation of std::bit_cast for pre-C++20.
296template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>
297FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
298#ifdef __cpp_lib_bit_cast
299 if (is_constant_evaluated()) return std::bit_cast<To>(from);
300#endif
301 auto to = To();
302 // The cast suppresses a bogus -Wclass-memaccess on GCC.
303 std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
304 return to;
305}
306
307inline auto is_big_endian() -> bool {
308#ifdef _WIN32
309 return false;
310#elif defined(__BIG_ENDIAN__)
311 return true;
312#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
313 return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
314#else
315 struct bytes {
316 char data[sizeof(int)];
317 };
318 return bit_cast<bytes>(1).data[0] == 0;
319#endif
320}
321
323 private:
324 uint64_t lo_, hi_;
325
326 friend uint128_fallback umul128(uint64_t x, uint64_t y) noexcept;
327
328 public:
329 constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}
330 constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}
331
332 constexpr uint64_t high() const noexcept { return hi_; }
333 constexpr uint64_t low() const noexcept { return lo_; }
334
335 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
336 constexpr explicit operator T() const {
337 return static_cast<T>(lo_);
338 }
339
340 friend constexpr auto operator==(const uint128_fallback& lhs,
341 const uint128_fallback& rhs) -> bool {
342 return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
343 }
344 friend constexpr auto operator!=(const uint128_fallback& lhs,
345 const uint128_fallback& rhs) -> bool {
346 return !(lhs == rhs);
347 }
348 friend constexpr auto operator>(const uint128_fallback& lhs,
349 const uint128_fallback& rhs) -> bool {
350 return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;
351 }
352 friend constexpr auto operator|(const uint128_fallback& lhs,
353 const uint128_fallback& rhs)
355 return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};
356 }
357 friend constexpr auto operator&(const uint128_fallback& lhs,
358 const uint128_fallback& rhs)
360 return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
361 }
362 friend auto operator+(const uint128_fallback& lhs,
363 const uint128_fallback& rhs) -> uint128_fallback {
364 auto result = uint128_fallback(lhs);
365 result += rhs;
366 return result;
367 }
368 friend auto operator*(const uint128_fallback& lhs, uint32_t rhs)
370 FMT_ASSERT(lhs.hi_ == 0, "");
371 uint64_t hi = (lhs.lo_ >> 32) * rhs;
372 uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;
373 uint64_t new_lo = (hi << 32) + lo;
374 return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};
375 }
376 friend auto operator-(const uint128_fallback& lhs, uint64_t rhs)
378 return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};
379 }
380 FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback {
381 if (shift == 64) return {0, hi_};
382 if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64);
383 return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
384 }
385 FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback {
386 if (shift == 64) return {lo_, 0};
387 if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64);
388 return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
389 }
391 return *this = *this >> shift;
392 }
394 uint64_t new_lo = lo_ + n.lo_;
395 uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0);
396 FMT_ASSERT(new_hi >= hi_, "");
397 lo_ = new_lo;
398 hi_ = new_hi;
399 }
400
402 if (is_constant_evaluated()) {
403 lo_ += n;
404 hi_ += (lo_ < n ? 1 : 0);
405 return *this;
406 }
407#if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)
408 unsigned long long carry;
409 lo_ = __builtin_addcll(lo_, n, 0, &carry);
410 hi_ += carry;
411#elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)
412 unsigned long long result;
413 auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result);
414 lo_ = result;
415 hi_ += carry;
416#elif defined(_MSC_VER) && defined(_M_X64)
417 auto carry = _addcarry_u64(0, lo_, n, &lo_);
418 _addcarry_u64(carry, hi_, 0, &hi_);
419#else
420 lo_ += n;
421 hi_ += (lo_ < n ? 1 : 0);
422#endif
423 return *this;
424 }
425};
426
428
429#ifdef UINTPTR_MAX
430using uintptr_t = ::uintptr_t;
431#else
433#endif
434
435// Returns the largest possible value for type T. Same as
436// std::numeric_limits<T>::max() but shorter and not affected by the max macro.
437template <typename T> constexpr auto max_value() -> T {
439}
440template <typename T> constexpr auto num_bits() -> int {
441 return std::numeric_limits<T>::digits;
442}
443// std::numeric_limits<T>::digits may return 0 for 128-bit ints.
444template <> constexpr auto num_bits<int128_opt>() -> int { return 128; }
445template <> constexpr auto num_bits<uint128_t>() -> int { return 128; }
446
447// A heterogeneous bit_cast used for converting 96-bit long double to uint128_t
448// and 128-bit pointers to uint128_fallback.
449template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) > sizeof(From))>
450inline auto bit_cast(const From& from) -> To {
451 constexpr auto size = static_cast<int>(sizeof(From) / sizeof(unsigned));
452 struct data_t {
453 unsigned value[static_cast<unsigned>(size)];
454 } data = bit_cast<data_t>(from);
455 auto result = To();
456 if (const_check(is_big_endian())) {
457 for (int i = 0; i < size; ++i)
458 result = (result << num_bits<unsigned>()) | data.value[i];
459 } else {
460 for (int i = size - 1; i >= 0; --i)
461 result = (result << num_bits<unsigned>()) | data.value[i];
462 }
463 return result;
464}
465
466FMT_INLINE void assume(bool condition) {
467 (void)condition;
468#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
469 __builtin_assume(condition);
470#endif
471}
472
473// An approximation of iterator_t for pre-C++20 systems.
474template <typename T>
475using iterator_t = decltype(std::begin(std::declval<T&>()));
476template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>()));
477
478// A workaround for std::string not having mutable data() until C++17.
479template <typename Char>
480inline auto get_data(std::basic_string<Char>& s) -> Char* {
481 return &s[0];
482}
483template <typename Container>
484inline auto get_data(Container& c) -> typename Container::value_type* {
485 return c.data();
486}
487
488#if defined(_SECURE_SCL) && _SECURE_SCL
489// Make a checked iterator to avoid MSVC warnings.
490template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
491template <typename T>
492constexpr auto make_checked(T* p, size_t size) -> checked_ptr<T> {
493 return {p, size};
494}
495#else
496template <typename T> using checked_ptr = T*;
497template <typename T> constexpr auto make_checked(T* p, size_t) -> T* {
498 return p;
499}
500#endif
501
502// Attempts to reserve space for n extra characters in the output range.
503// Returns a pointer to the reserved range or a reference to it.
504template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
505#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
506__attribute__((no_sanitize("undefined")))
507#endif
508inline auto
509reserve(std::back_insert_iterator<Container> it, size_t n)
511 Container& c = get_container(it);
512 size_t size = c.size();
513 c.resize(size + n);
514 return make_checked(get_data(c) + size, n);
515}
516
517template <typename T>
518inline auto reserve(buffer_appender<T> it, size_t n) -> buffer_appender<T> {
519 buffer<T>& buf = get_container(it);
520 buf.try_reserve(buf.size() + n);
521 return it;
522}
523
524template <typename Iterator>
525constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
526 return it;
527}
528
529template <typename OutputIt>
532
533template <typename T, typename OutputIt>
534constexpr auto to_pointer(OutputIt, size_t) -> T* {
535 return nullptr;
536}
537template <typename T> auto to_pointer(buffer_appender<T> it, size_t n) -> T* {
538 buffer<T>& buf = get_container(it);
539 auto size = buf.size();
540 if (buf.capacity() < size + n) return nullptr;
541 buf.try_resize(size + n);
542 return buf.data() + size;
543}
544
545template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
546inline auto base_iterator(std::back_insert_iterator<Container>& it,
548 -> std::back_insert_iterator<Container> {
549 return it;
550}
551
552template <typename Iterator>
553constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
554 return it;
555}
556
557// <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
558// instead (#1998).
559template <typename OutputIt, typename Size, typename T>
560FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
561 -> OutputIt {
562 for (Size i = 0; i < count; ++i) *out++ = value;
563 return out;
564}
565template <typename T, typename Size>
566FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
567 if (is_constant_evaluated()) {
568 return fill_n<T*, Size, T>(out, count, value);
569 }
570 std::memset(out, value, to_unsigned(count));
571 return out + count;
572}
573
574#ifdef __cpp_char8_t
575using char8_type = char8_t;
576#else
577enum char8_type : unsigned char {};
578#endif
579
580template <typename OutChar, typename InputIt, typename OutputIt>
582 OutputIt out) -> OutputIt {
583 return copy_str<OutChar>(begin, end, out);
584}
585
586// A public domain branchless UTF-8 decoder by Christopher Wellons:
587// https://github.com/skeeto/branchless-utf8
588/* Decode the next character, c, from s, reporting errors in e.
589 *
590 * Since this is a branchless decoder, four bytes will be read from the
591 * buffer regardless of the actual length of the next character. This
592 * means the buffer _must_ have at least three bytes of zero padding
593 * following the end of the data stream.
594 *
595 * Errors are reported in e, which will be non-zero if the parsed
596 * character was somehow invalid: invalid byte sequence, non-canonical
597 * encoding, or a surrogate half.
598 *
599 * The function returns a pointer to the next character. When an error
600 * occurs, this pointer will be a guess that depends on the particular
601 * error, but it will always advance at least one byte.
602 */
603FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
604 -> const char* {
605 constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
606 constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
607 constexpr const int shiftc[] = {0, 18, 12, 6, 0};
608 constexpr const int shifte[] = {0, 6, 4, 2, 0};
609
610 int len = code_point_length_impl(*s);
611 // Compute the pointer to the next character early so that the next
612 // iteration can start working on the next character. Neither Clang
613 // nor GCC figure out this reordering on their own.
614 const char* next = s + len + !len;
615
616 using uchar = unsigned char;
617
618 // Assume a four-byte character and load four bytes. Unused bits are
619 // shifted out.
620 *c = uint32_t(uchar(s[0]) & masks[len]) << 18;
621 *c |= uint32_t(uchar(s[1]) & 0x3f) << 12;
622 *c |= uint32_t(uchar(s[2]) & 0x3f) << 6;
623 *c |= uint32_t(uchar(s[3]) & 0x3f) << 0;
624 *c >>= shiftc[len];
625
626 // Accumulate the various error conditions.
627 *e = (*c < mins[len]) << 6; // non-canonical encoding
628 *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half?
629 *e |= (*c > 0x10FFFF) << 8; // out of range?
630 *e |= (uchar(s[1]) & 0xc0) >> 2;
631 *e |= (uchar(s[2]) & 0xc0) >> 4;
632 *e |= uchar(s[3]) >> 6;
633 *e ^= 0x2a; // top two bits of each tail byte correct?
634 *e >>= shifte[len];
635
636 return next;
637}
638
639constexpr uint32_t invalid_code_point = ~uint32_t();
640
641// Invokes f(cp, sv) for every code point cp in s with sv being the string view
642// corresponding to the code point. cp is invalid_code_point on error.
643template <typename F>
645 auto decode = [f](const char* buf_ptr, const char* ptr) {
646 auto cp = uint32_t();
647 auto error = 0;
648 auto end = utf8_decode(buf_ptr, &cp, &error);
649 bool result = f(error ? invalid_code_point : cp,
650 string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));
651 return result ? (error ? buf_ptr + 1 : end) : nullptr;
652 };
653 auto p = s.data();
654 const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars.
655 if (s.size() >= block_size) {
656 for (auto end = p + s.size() - block_size + 1; p < end;) {
657 p = decode(p, p);
658 if (!p) return;
659 }
660 }
661 if (auto num_chars_left = s.data() + s.size() - p) {
662 char buf[2 * block_size - 1] = {};
663 copy_str<char>(p, p + num_chars_left, buf);
664 const char* buf_ptr = buf;
665 do {
666 auto end = decode(buf_ptr, p);
667 if (!end) return;
668 p += end - buf_ptr;
669 buf_ptr = end;
670 } while (buf_ptr - buf < num_chars_left);
671 }
672}
673
674template <typename Char>
675inline auto compute_width(basic_string_view<Char> s) -> size_t {
676 return s.size();
677}
678
679// Computes approximate display width of a UTF-8 string.
681 size_t num_code_points = 0;
682 // It is not a lambda for compatibility with C++14.
683 struct count_code_points {
684 size_t* count;
685 FMT_CONSTEXPR auto operator()(uint32_t cp, string_view) const -> bool {
687 1 +
688 (cp >= 0x1100 &&
689 (cp <= 0x115f || // Hangul Jamo init. consonants
690 cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET
691 cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET
692 // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:
693 (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
694 (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables
695 (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs
696 (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms
697 (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms
698 (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms
699 (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms
700 (cp >= 0x20000 && cp <= 0x2fffd) || // CJK
701 (cp >= 0x30000 && cp <= 0x3fffd) ||
702 // Miscellaneous Symbols and Pictographs + Emoticons:
703 (cp >= 0x1f300 && cp <= 0x1f64f) ||
704 // Supplemental Symbols and Pictographs:
705 (cp >= 0x1f900 && cp <= 0x1f9ff))));
706 return true;
707 }
708 };
709 for_each_codepoint(s, count_code_points{&num_code_points});
710 return num_code_points;
711}
712
714 return compute_width(
715 string_view(reinterpret_cast<const char*>(s.data()), s.size()));
716}
717
718template <typename Char>
719inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
720 size_t size = s.size();
721 return n < size ? n : size;
722}
723
724// Calculates the index of the nth code point in a UTF-8 string.
725inline auto code_point_index(string_view s, size_t n) -> size_t {
726 const char* data = s.data();
727 size_t num_code_points = 0;
728 for (size_t i = 0, size = s.size(); i != size; ++i) {
729 if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) return i;
730 }
731 return s.size();
732}
733
735 -> size_t {
736 return code_point_index(
737 string_view(reinterpret_cast<const char*>(s.data()), s.size()), n);
738}
739
740#ifndef FMT_USE_FLOAT128
741# ifdef __SIZEOF_FLOAT128__
742# define FMT_USE_FLOAT128 1
743# else
744# define FMT_USE_FLOAT128 0
745# endif
746#endif
747#if FMT_USE_FLOAT128
748using float128 = __float128;
749#else
750using float128 = void;
751#endif
752template <typename T> using is_float128 = std::is_same<T, float128>;
753
754template <typename T>
757
758template <typename T, bool = std::is_floating_point<T>::value>
759struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&
760 sizeof(T) <= sizeof(double)> {};
761template <typename T> struct is_fast_float<T, false> : std::false_type {};
762
763template <typename T>
764using is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;
765
766#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
767# define FMT_USE_FULL_CACHE_DRAGONBOX 0
768#endif
769
770template <typename T>
771template <typename U>
772void buffer<T>::append(const U* begin, const U* end) {
773 while (begin != end) {
774 auto count = to_unsigned(end - begin);
775 try_reserve(size_ + count);
776 auto free_cap = capacity_ - size_;
777 if (free_cap < count) count = free_cap;
778 std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
779 size_ += count;
780 begin += count;
781 }
782}
783
784template <typename T, typename Enable = void>
785struct is_locale : std::false_type {};
786template <typename T>
787struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {};
788} // namespace detail
789
790FMT_MODULE_EXPORT_BEGIN
791
792// The number of characters to store in the basic_memory_buffer object itself
793// to avoid dynamic memory allocation.
794enum { inline_buffer_size = 500 };
795
796/**
797 \rst
798 A dynamically growing memory buffer for trivially copyable/constructible types
799 with the first ``SIZE`` elements stored in the object itself.
800
801 You can use the ``memory_buffer`` type alias for ``char`` instead.
802
803 **Example**::
804
805 auto out = fmt::memory_buffer();
806 format_to(std::back_inserter(out), "The answer is {}.", 42);
807
808 This will append the following output to the ``out`` object:
809
810 .. code-block:: none
811
812 The answer is 42.
813
814 The output can be converted to an ``std::string`` with ``to_string(out)``.
815 \endrst
816 */
817template <typename T, size_t SIZE = inline_buffer_size,
818 typename Allocator = std::allocator<T>>
819class basic_memory_buffer final : public detail::buffer<T> {
820 private:
821 T store_[SIZE];
822
823 // Don't inherit from Allocator avoid generating type_info for it.
824 Allocator alloc_;
825
826 // Deallocate memory allocated by the buffer.
827 FMT_CONSTEXPR20 void deallocate() {
828 T* data = this->data();
829 if (data != store_) alloc_.deallocate(data, this->capacity());
830 }
831
832 protected:
833 FMT_CONSTEXPR20 void grow(size_t size) override;
834
835 public:
836 using value_type = T;
837 using const_reference = const T&;
838
840 const Allocator& alloc = Allocator())
841 : alloc_(alloc) {
842 this->set(store_, SIZE);
843 if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
844 }
846
847 private:
848 // Move data from other to this buffer.
849 FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
850 alloc_ = std::move(other.alloc_);
851 T* data = other.data();
852 size_t size = other.size(), capacity = other.capacity();
853 if (data == other.store_) {
854 this->set(store_, capacity);
855 detail::copy_str<T>(other.store_, other.store_ + size,
856 detail::make_checked(store_, capacity));
857 } else {
858 this->set(data, capacity);
859 // Set pointer to the inline array so that delete is not called
860 // when deallocating.
861 other.set(other.store_, 0);
862 other.clear();
863 }
864 this->resize(size);
865 }
866
867 public:
868 /**
869 \rst
870 Constructs a :class:`fmt::basic_memory_buffer` object moving the content
871 of the other object to it.
872 \endrst
873 */
875 move(other);
876 }
877
878 /**
879 \rst
880 Moves the content of the other ``basic_memory_buffer`` object to this one.
881 \endrst
882 */
884 FMT_ASSERT(this != &other, "");
885 deallocate();
886 move(other);
887 return *this;
888 }
889
890 // Returns a copy of the allocator associated with this buffer.
891 auto get_allocator() const -> Allocator { return alloc_; }
892
893 /**
894 Resizes the buffer to contain *count* elements. If T is a POD type new
895 elements may not be initialized.
896 */
897 FMT_CONSTEXPR20 void resize(size_t count) { this->try_resize(count); }
898
899 /** Increases the buffer capacity to *new_capacity*. */
900 void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
901
902 // Directly append data into the buffer
903 using detail::buffer<T>::append;
904 template <typename ContiguousRange>
905 void append(const ContiguousRange& range) {
906 append(range.data(), range.data() + range.size());
907 }
908};
909
910template <typename T, size_t SIZE, typename Allocator>
912 size_t size) {
914 const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
915 size_t old_capacity = this->capacity();
916 size_t new_capacity = old_capacity + old_capacity / 2;
917 if (size > new_capacity)
918 new_capacity = size;
919 else if (new_capacity > max_size)
920 new_capacity = size > max_size ? size : max_size;
921 T* old_data = this->data();
922 T* new_data =
923 std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
924 // The following code doesn't throw, so the raw pointer above doesn't leak.
925 std::uninitialized_copy(old_data, old_data + this->size(),
926 detail::make_checked(new_data, new_capacity));
927 this->set(new_data, new_capacity);
928 // deallocate must not throw according to the standard, but even if it does,
929 // the buffer already uses the new storage and will deallocate it in
930 // destructor.
931 if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
932}
933
935
936template <typename T, size_t SIZE, typename Allocator>
937struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
938};
939
940namespace detail {
941#ifdef _WIN32
942FMT_API bool write_console(std::FILE* f, string_view text);
943#endif
944FMT_API void print(std::FILE*, string_view);
945} // namespace detail
946
947/** A formatting error such as invalid format string. */
949class FMT_API format_error : public std::runtime_error {
950 public:
951 explicit format_error(const char* message) : std::runtime_error(message) {}
952 explicit format_error(const std::string& message)
953 : std::runtime_error(message) {}
954 format_error(const format_error&) = default;
958 ~format_error() noexcept override FMT_MSC_DEFAULT;
959};
960
962#if FMT_USE_NONTYPE_TEMPLATE_ARGS
963template <typename Char, size_t N> struct fixed_string {
964 constexpr fixed_string(const Char (&str)[N]) {
965 detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str),
966 str + N, data);
967 }
968 Char data[N] = {};
969};
970#endif
971
972// Converts a compile-time string to basic_string_view.
973template <typename Char, size_t N>
974constexpr auto compile_string_to_view(const Char (&s)[N])
976 // Remove trailing NUL character if needed. Won't be present if this is used
977 // with a raw character array (i.e. not defined as a string).
978 return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
979}
980template <typename Char>
981constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
983 return {s.data(), s.size()};
984}
985} // namespace detail_exported
986
988
989template <typename T> struct is_integral : std::is_integral<T> {};
990template <> struct is_integral<int128_opt> : std::true_type {};
991template <> struct is_integral<uint128_t> : std::true_type {};
992
993template <typename T>
996 std::is_same<T, int128_opt>::value>;
997
998// Returns true if value is negative, false otherwise.
999// Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
1000template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
1001constexpr auto is_negative(T value) -> bool {
1002 return value < 0;
1003}
1004template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
1005constexpr auto is_negative(T) -> bool {
1006 return false;
1007}
1008
1009template <typename T>
1011 if (std::is_same<T, float>()) return FMT_USE_FLOAT;
1012 if (std::is_same<T, double>()) return FMT_USE_DOUBLE;
1013 if (std::is_same<T, long double>()) return FMT_USE_LONG_DOUBLE;
1014 return true;
1015}
1016
1017// Smallest of uint32_t, uint64_t, uint128_t that is large enough to
1018// represent all values of an integral type T.
1019template <typename T>
1022 uint32_t,
1024template <typename T>
1026
1027#define FMT_POWERS_OF_10(factor) \
1028 factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
1029 (factor)*1000000, (factor)*10000000, (factor)*100000000, \
1030 (factor)*1000000000
1031
1032// Converts value in the range [0, 100) to a string.
1033constexpr const char* digits2(size_t value) {
1034 // GCC generates slightly better code when value is pointer-size.
1035 return &"0001020304050607080910111213141516171819"
1036 "2021222324252627282930313233343536373839"
1037 "4041424344454647484950515253545556575859"
1038 "6061626364656667686970717273747576777879"
1039 "8081828384858687888990919293949596979899"[value * 2];
1040}
1041
1042// Sign is a template parameter to workaround a bug in gcc 4.8.
1043template <typename Char, typename Sign> constexpr Char sign(Sign s) {
1044#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604
1045 static_assert(std::is_same<Sign, sign_t>::value, "");
1046#endif
1047 return static_cast<Char>("\0-+ "[s]);
1048}
1049
1050template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
1051 int count = 1;
1052 for (;;) {
1053 // Integer division is slow so do it for a group of four digits instead
1054 // of for every digit. The idea comes from the talk by Alexandrescu
1055 // "Three Optimization Tips for C++". See speed-test for a comparison.
1056 if (n < 10) return count;
1057 if (n < 100) return count + 1;
1058 if (n < 1000) return count + 2;
1059 if (n < 10000) return count + 3;
1060 n /= 10000u;
1061 count += 4;
1062 }
1063}
1064#if FMT_USE_INT128
1065FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int {
1066 return count_digits_fallback(n);
1067}
1068#endif
1069
1070#ifdef FMT_BUILTIN_CLZLL
1071// It is a separate function rather than a part of count_digits to workaround
1072// the lack of static constexpr in constexpr functions.
1073inline auto do_count_digits(uint64_t n) -> int {
1074 // This has comparable performance to the version by Kendall Willets
1075 // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)
1076 // but uses smaller tables.
1077 // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
1078 static constexpr uint8_t bsr2log10[] = {
1079 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
1080 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
1081 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1082 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1083 auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
1084 static constexpr const uint64_t zero_or_powers_of_10[] = {
1085 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
1086 10000000000000000000ULL};
1087 return t - (n < zero_or_powers_of_10[t]);
1088}
1089#endif
1090
1091// Returns the number of decimal digits in n. Leading zeros are not counted
1092// except for n == 0 in which case count_digits returns 1.
1094#ifdef FMT_BUILTIN_CLZLL
1095 if (!is_constant_evaluated()) {
1096 return do_count_digits(n);
1097 }
1098#endif
1099 return count_digits_fallback(n);
1100}
1101
1102// Counts the number of digits in n. BITS = log2(radix).
1103template <int BITS, typename UInt>
1104FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1105#ifdef FMT_BUILTIN_CLZ
1106 if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1107 return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1108#endif
1109 // Lambda avoids unreachable code warnings from NVHPC.
1110 return [](UInt m) {
1111 int num_digits = 0;
1112 do {
1113 ++num_digits;
1114 } while ((m >>= BITS) != 0);
1115 return num_digits;
1116 }(n);
1117}
1118
1119#ifdef FMT_BUILTIN_CLZ
1120// It is a separate function rather than a part of count_digits to workaround
1121// the lack of static constexpr in constexpr functions.
1122FMT_INLINE auto do_count_digits(uint32_t n) -> int {
1123// An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
1124// This increments the upper 32 bits (log10(T) - 1) when >= T is added.
1125# define FMT_INC(T) (((sizeof(# T) - 1ull) << 32) - T)
1126 static constexpr uint64_t table[] = {
1127 FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8
1128 FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64
1129 FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512
1130 FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096
1131 FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k
1132 FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k
1133 FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k
1134 FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M
1135 FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M
1136 FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M
1137 FMT_INC(1000000000), FMT_INC(1000000000) // 4B
1138 };
1139 auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
1140 return static_cast<int>((n + inc) >> 32);
1141}
1142#endif
1143
1144// Optional version of count_digits for better performance on 32-bit platforms.
1146#ifdef FMT_BUILTIN_CLZ
1147 if (!is_constant_evaluated()) {
1148 return do_count_digits(n);
1149 }
1150#endif
1151 return count_digits_fallback(n);
1152}
1153
1154template <typename Int> constexpr auto digits10() noexcept -> int {
1156}
1157template <> constexpr auto digits10<int128_opt>() noexcept -> int { return 38; }
1158template <> constexpr auto digits10<uint128_t>() noexcept -> int { return 38; }
1159
1160template <typename Char> struct thousands_sep_result {
1161 std::string grouping;
1163};
1164
1165template <typename Char>
1167template <typename Char>
1169 auto result = thousands_sep_impl<char>(loc);
1170 return {result.grouping, Char(result.thousands_sep)};
1171}
1172template <>
1174 return thousands_sep_impl<wchar_t>(loc);
1175}
1176
1177template <typename Char>
1179template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1180 return Char(decimal_point_impl<char>(loc));
1181}
1182template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1183 return decimal_point_impl<wchar_t>(loc);
1184}
1185
1186// Compares two characters for equality.
1187template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1188 return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1189}
1190inline auto equal2(const char* lhs, const char* rhs) -> bool {
1191 return memcmp(lhs, rhs, 2) == 0;
1192}
1193
1194// Copies two characters from src to dst.
1195template <typename Char>
1196FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) {
1197 if (!is_constant_evaluated() && sizeof(Char) == sizeof(char)) {
1198 memcpy(dst, src, 2);
1199 return;
1200 }
1201 *dst++ = static_cast<Char>(*src++);
1202 *dst = static_cast<Char>(*src);
1203}
1204
1205template <typename Iterator> struct format_decimal_result {
1206 Iterator begin;
1207 Iterator end;
1208};
1209
1210// Formats a decimal unsigned integer value writing into out pointing to a
1211// buffer of specified size. The caller must ensure that the buffer is large
1212// enough.
1213template <typename Char, typename UInt>
1214FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
1216 FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1217 out += size;
1218 Char* end = out;
1219 while (value >= 100) {
1220 // Integer division is slow so do it for a group of two digits instead
1221 // of for every digit. The idea comes from the talk by Alexandrescu
1222 // "Three Optimization Tips for C++". See speed-test for a comparison.
1223 out -= 2;
1224 copy2(out, digits2(static_cast<size_t>(value % 100)));
1225 value /= 100;
1226 }
1227 if (value < 10) {
1228 *--out = static_cast<Char>('0' + value);
1229 return {out, end};
1230 }
1231 out -= 2;
1232 copy2(out, digits2(static_cast<size_t>(value)));
1233 return {out, end};
1234}
1235
1236template <typename Char, typename UInt, typename Iterator,
1238FMT_CONSTEXPR inline auto format_decimal(Iterator out, UInt value, int size)
1240 // Buffer is large enough to hold all digits (digits10 + 1).
1241 Char buffer[digits10<UInt>() + 1];
1242 auto end = format_decimal(buffer, value, size).end;
1243 return {out, detail::copy_str_noinline<Char>(buffer, end, out)};
1244}
1245
1246template <unsigned BASE_BITS, typename Char, typename UInt>
1247FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits,
1248 bool upper = false) -> Char* {
1249 buffer += num_digits;
1250 Char* end = buffer;
1251 do {
1252 const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1253 unsigned digit = static_cast<unsigned>(value & ((1 << BASE_BITS) - 1));
1254 *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
1255 : digits[digit]);
1256 } while ((value >>= BASE_BITS) != 0);
1257 return end;
1258}
1259
1260template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1261inline auto format_uint(It out, UInt value, int num_digits, bool upper = false)
1262 -> It {
1263 if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1264 format_uint<BASE_BITS>(ptr, value, num_digits, upper);
1265 return out;
1266 }
1267 // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
1268 char buffer[num_bits<UInt>() / BASE_BITS + 1];
1269 format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1270 return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out);
1271}
1272
1273// A converter from UTF-8 to UTF-16.
1275 private:
1277
1278 public:
1279 FMT_API explicit utf8_to_utf16(string_view s);
1280 operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; }
1281 auto size() const -> size_t { return buffer_.size() - 1; }
1282 auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1283 auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1284};
1285
1286namespace dragonbox {
1287
1288// Type-specific information that Dragonbox uses.
1289template <typename T, typename Enable = void> struct float_info;
1290
1291template <> struct float_info<float> {
1293 static const int exponent_bits = 8;
1294 static const int kappa = 1;
1295 static const int big_divisor = 100;
1296 static const int small_divisor = 10;
1297 static const int min_k = -31;
1298 static const int max_k = 46;
1299 static const int shorter_interval_tie_lower_threshold = -35;
1300 static const int shorter_interval_tie_upper_threshold = -35;
1301};
1302
1303template <> struct float_info<double> {
1305 static const int exponent_bits = 11;
1306 static const int kappa = 2;
1307 static const int big_divisor = 1000;
1308 static const int small_divisor = 100;
1309 static const int min_k = -292;
1310 static const int max_k = 326;
1311 static const int shorter_interval_tie_lower_threshold = -77;
1312 static const int shorter_interval_tie_upper_threshold = -77;
1313};
1314
1315// An 80- or 128-bit floating point number.
1316template <typename T>
1317struct float_info<T, enable_if_t<std::numeric_limits<T>::digits == 64 ||
1318 std::numeric_limits<T>::digits == 113 ||
1319 is_float128<T>::value>> {
1321 static const int exponent_bits = 15;
1322};
1323
1324// A double-double floating point number.
1325template <typename T>
1326struct float_info<T, enable_if_t<is_double_double<T>::value>> {
1328};
1329
1330template <typename T> struct decimal_fp {
1334};
1335
1336template <typename T> FMT_API auto to_decimal(T x) noexcept -> decimal_fp<T>;
1337} // namespace dragonbox
1338
1339// Returns true iff Float has the implicit bit which is not stored.
1340template <typename Float> constexpr bool has_implicit_bit() {
1341 // An 80-bit FP number has a 64-bit significand an no implicit bit.
1342 return std::numeric_limits<Float>::digits != 64;
1343}
1344
1345// Returns the number of significand bits stored in Float. The implicit bit is
1346// not counted since it is not stored.
1347template <typename Float> constexpr int num_significand_bits() {
1348 // std::numeric_limits may not support __float128.
1349 return is_float128<Float>() ? 112
1350 : (std::numeric_limits<Float>::digits -
1351 (has_implicit_bit<Float>() ? 1 : 0));
1352}
1353
1354template <typename Float>
1355constexpr auto exponent_mask() ->
1357 using uint = typename dragonbox::float_info<Float>::carrier_uint;
1358 return ((uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1359 << num_significand_bits<Float>();
1360}
1361template <typename Float> constexpr auto exponent_bias() -> int {
1362 // std::numeric_limits may not support __float128.
1363 return is_float128<Float>() ? 16383
1364 : std::numeric_limits<Float>::max_exponent - 1;
1365}
1366
1367// Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1368template <typename Char, typename It>
1369FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It {
1370 FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1371 if (exp < 0) {
1372 *it++ = static_cast<Char>('-');
1373 exp = -exp;
1374 } else {
1375 *it++ = static_cast<Char>('+');
1376 }
1377 if (exp >= 100) {
1378 const char* top = digits2(to_unsigned(exp / 100));
1379 if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
1380 *it++ = static_cast<Char>(top[1]);
1381 exp %= 100;
1382 }
1383 const char* d = digits2(to_unsigned(exp));
1384 *it++ = static_cast<Char>(d[0]);
1385 *it++ = static_cast<Char>(d[1]);
1386 return it;
1387}
1388
1389// A floating-point number f * pow(2, e) where F is an unsigned type.
1390template <typename F> struct basic_fp {
1392 int e;
1393
1394 static constexpr const int num_significand_bits =
1395 static_cast<int>(sizeof(F) * num_bits<unsigned char>());
1396
1397 constexpr basic_fp() : f(0), e(0) {}
1398 constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
1399
1400 // Constructs fp from an IEEE754 floating-point number.
1401 template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
1402
1403 // Assigns n to this and return true iff predecessor is closer than successor.
1404 template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
1405 FMT_CONSTEXPR auto assign(Float n) -> bool {
1406 static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1407 // Assume Float is in the format [sign][exponent][significand].
1408 using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1409 const auto num_float_significand_bits =
1410 detail::num_significand_bits<Float>();
1411 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1412 const auto significand_mask = implicit_bit - 1;
1413 auto u = bit_cast<carrier_uint>(n);
1414 f = static_cast<F>(u & significand_mask);
1415 auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1416 num_float_significand_bits);
1417 // The predecessor is closer if n is a normalized power of 2 (f == 0)
1418 // other than the smallest normalized number (biased_e > 1).
1419 auto is_predecessor_closer = f == 0 && biased_e > 1;
1420 if (biased_e == 0)
1421 biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
1422 else if (has_implicit_bit<Float>())
1423 f += static_cast<F>(implicit_bit);
1424 e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1425 if (!has_implicit_bit<Float>()) ++e;
1426 return is_predecessor_closer;
1427 }
1428
1429 template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
1430 FMT_CONSTEXPR auto assign(Float n) -> bool {
1431 static_assert(std::numeric_limits<double>::is_iec559, "unsupported FP");
1432 return assign(static_cast<double>(n));
1433 }
1434};
1435
1437
1438// Normalizes the value converted from double and multiplied by (1 << SHIFT).
1439template <int SHIFT = 0, typename F>
1441 // Handle subnormals.
1442 const auto implicit_bit = F(1) << num_significand_bits<double>();
1443 const auto shifted_implicit_bit = implicit_bit << SHIFT;
1444 while ((value.f & shifted_implicit_bit) == 0) {
1445 value.f <<= 1;
1446 --value.e;
1447 }
1448 // Subtract 1 to account for hidden bit.
1449 const auto offset = basic_fp<F>::num_significand_bits -
1450 num_significand_bits<double>() - SHIFT - 1;
1451 value.f <<= offset;
1452 value.e -= offset;
1453 return value;
1454}
1455
1456// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
1458#if FMT_USE_INT128
1459 auto product = static_cast<__uint128_t>(lhs) * rhs;
1460 auto f = static_cast<uint64_t>(product >> 64);
1461 return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1462#else
1463 // Multiply 32-bit parts of significands.
1464 uint64_t mask = (1ULL << 32) - 1;
1465 uint64_t a = lhs >> 32, b = lhs & mask;
1466 uint64_t c = rhs >> 32, d = rhs & mask;
1467 uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
1468 // Compute mid 64-bit of result and round.
1469 uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1470 return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1471#endif
1472}
1473
1475 return {multiply(x.f, y.f), x.e + y.e + 64};
1476}
1477
1478template <typename T = void> struct basic_data {
1479 // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
1480 // These are generated by support/compute-powers.py.
1481 static constexpr uint64_t pow10_significands[87] = {
1482 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
1483 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
1484 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
1485 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
1486 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
1487 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
1488 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
1489 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
1490 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
1491 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
1492 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
1493 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
1494 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
1495 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
1496 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
1497 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
1498 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
1499 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
1500 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
1501 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
1502 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
1503 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
1504 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
1505 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
1506 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
1507 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
1508 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
1509 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
1510 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
1511 };
1512
1513#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1514# pragma GCC diagnostic push
1515# pragma GCC diagnostic ignored "-Wnarrowing"
1516#endif
1517 // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
1518 // to significands above.
1519 static constexpr int16_t pow10_exponents[87] = {
1520 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
1521 -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
1522 -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
1523 -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
1524 -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
1525 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
1526 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
1527 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
1528#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1529# pragma GCC diagnostic pop
1530#endif
1531
1532 static constexpr uint64_t power_of_10_64[20] = {
1533 1, FMT_POWERS_OF_10(1ULL), FMT_POWERS_OF_10(1000000000ULL),
1534 10000000000000000000ULL};
1535};
1536
1537#if FMT_CPLUSPLUS < 201703L
1538template <typename T> constexpr uint64_t basic_data<T>::pow10_significands[];
1539template <typename T> constexpr int16_t basic_data<T>::pow10_exponents[];
1540template <typename T> constexpr uint64_t basic_data<T>::power_of_10_64[];
1541#endif
1542
1543// This is a struct rather than an alias to avoid shadowing warnings in gcc.
1544struct data : basic_data<> {};
1545
1546// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
1547// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
1548FMT_CONSTEXPR inline fp get_cached_power(int min_exponent,
1549 int& pow10_exponent) {
1550 const int shift = 32;
1551 // log10(2) = 0x0.4d104d427de7fbcc...
1552 const int64_t significand = 0x4d104d427de7fbcc;
1553 int index = static_cast<int>(
1554 ((min_exponent + fp::num_significand_bits - 1) * (significand >> shift) +
1555 ((int64_t(1) << shift) - 1)) // ceil
1556 >> 32 // arithmetic shift
1557 );
1558 // Decimal exponent of the first (smallest) cached power of 10.
1559 const int first_dec_exp = -348;
1560 // Difference between 2 consecutive decimal exponents in cached powers of 10.
1561 const int dec_exp_step = 8;
1562 index = (index - first_dec_exp - 1) / dec_exp_step + 1;
1563 pow10_exponent = first_dec_exp + index * dec_exp_step;
1564 // Using *(x + index) instead of x[index] avoids an issue with some compilers
1565 // using the EDG frontend (e.g. nvhpc/22.3 in C++17 mode).
1566 return {*(data::pow10_significands + index),
1568}
1569
1570#ifndef _MSC_VER
1571# define FMT_SNPRINTF snprintf
1572#else
1573FMT_API auto fmt_snprintf(char* buf, size_t size, const char* fmt, ...) -> int;
1574# define FMT_SNPRINTF fmt_snprintf
1575#endif // _MSC_VER
1576
1577// Formats a floating-point number with snprintf using the hexfloat format.
1578template <typename T>
1579auto snprintf_float(T value, int precision, float_specs specs,
1580 buffer<char>& buf) -> int {
1581 // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
1582 FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer");
1583 FMT_ASSERT(specs.format == float_format::hex, "");
1584 static_assert(!std::is_same<T, float>::value, "");
1585
1586 // Build the format string.
1587 char format[7]; // The longest format is "%#.*Le".
1588 char* format_ptr = format;
1589 *format_ptr++ = '%';
1590 if (specs.showpoint) *format_ptr++ = '#';
1591 if (precision >= 0) {
1592 *format_ptr++ = '.';
1593 *format_ptr++ = '*';
1594 }
1595 if (std::is_same<T, long double>()) *format_ptr++ = 'L';
1596 *format_ptr++ = specs.upper ? 'A' : 'a';
1597 *format_ptr = '\0';
1598
1599 // Format using snprintf.
1600 auto offset = buf.size();
1601 for (;;) {
1602 auto begin = buf.data() + offset;
1603 auto capacity = buf.capacity() - offset;
1604 abort_fuzzing_if(precision > 100000);
1605 // Suppress the warning about a nonliteral format string.
1606 // Cannot use auto because of a bug in MinGW (#1532).
1607 int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
1608 int result = precision >= 0
1609 ? snprintf_ptr(begin, capacity, format, precision, value)
1610 : snprintf_ptr(begin, capacity, format, value);
1611 if (result < 0) {
1612 // The buffer will grow exponentially.
1613 buf.try_reserve(buf.capacity() + 1);
1614 continue;
1615 }
1616 auto size = to_unsigned(result);
1617 // Size equal to capacity means that the last character was truncated.
1618 if (size < capacity) {
1619 buf.try_resize(size + offset);
1620 return 0;
1621 }
1622 buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'.
1623 }
1624}
1625
1626template <typename T>
1628 conditional_t<std::is_same<T, float>::value || sizeof(T) == sizeof(double),
1629 double, T>;
1630
1631template <typename T>
1633 return static_cast<convert_float_result<T>>(value);
1634}
1635
1636template <typename OutputIt, typename Char>
1637FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
1638 const fill_t<Char>& fill) -> OutputIt {
1639 auto fill_size = fill.size();
1640 if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
1641 auto data = fill.data();
1642 for (size_t i = 0; i < n; ++i)
1643 it = copy_str<Char>(data, data + fill_size, it);
1644 return it;
1645}
1646
1647// Writes the output of f, padded according to format specifications in specs.
1648// size: output size in code units.
1649// width: output display width in (terminal) column positions.
1650template <align::type align = align::left, typename OutputIt, typename Char,
1651 typename F>
1652FMT_CONSTEXPR auto write_padded(OutputIt out,
1653 const basic_format_specs<Char>& specs,
1654 size_t size, size_t width, F&& f) -> OutputIt {
1655 static_assert(align == align::left || align == align::right, "");
1656 unsigned spec_width = to_unsigned(specs.width);
1657 size_t padding = spec_width > width ? spec_width - width : 0;
1658 // Shifts are encoded as string literals because static constexpr is not
1659 // supported in constexpr functions.
1660 auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1661 size_t left_padding = padding >> shifts[specs.align];
1662 size_t right_padding = padding - left_padding;
1663 auto it = reserve(out, size + padding * specs.fill.size());
1664 if (left_padding != 0) it = fill(it, left_padding, specs.fill);
1665 it = f(it);
1666 if (right_padding != 0) it = fill(it, right_padding, specs.fill);
1667 return base_iterator(out, it);
1668}
1669
1670template <align::type align = align::left, typename OutputIt, typename Char,
1671 typename F>
1672constexpr auto write_padded(OutputIt out, const basic_format_specs<Char>& specs,
1673 size_t size, F&& f) -> OutputIt {
1674 return write_padded<align>(out, specs, size, size, f);
1675}
1676
1677template <align::type align = align::left, typename Char, typename OutputIt>
1679 const basic_format_specs<Char>& specs)
1680 -> OutputIt {
1681 return write_padded<align>(
1682 out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1683 const char* data = bytes.data();
1684 return copy_str<Char>(data, data + bytes.size(), it);
1685 });
1686}
1687
1688template <typename Char, typename OutputIt, typename UIntPtr>
1689auto write_ptr(OutputIt out, UIntPtr value,
1690 const basic_format_specs<Char>* specs) -> OutputIt {
1691 int num_digits = count_digits<4>(value);
1692 auto size = to_unsigned(num_digits) + size_t(2);
1693 auto write = [=](reserve_iterator<OutputIt> it) {
1694 *it++ = static_cast<Char>('0');
1695 *it++ = static_cast<Char>('x');
1696 return format_uint<4, Char>(it, value, num_digits);
1697 };
1698 return specs ? write_padded<align::right>(out, *specs, size, write)
1699 : base_iterator(out, write(reserve(out, size)));
1700}
1701
1702// Returns true iff the code point cp is printable.
1704
1705inline auto needs_escape(uint32_t cp) -> bool {
1706 return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' ||
1707 !is_printable(cp);
1708}
1709
1710template <typename Char> struct find_escape_result {
1711 const Char* begin;
1712 const Char* end;
1714};
1715
1716template <typename Char>
1719 std::make_unsigned<Char>,
1721
1722template <typename Char>
1723auto find_escape(const Char* begin, const Char* end)
1725 for (; begin != end; ++begin) {
1726 uint32_t cp = static_cast<make_unsigned_char<Char>>(*begin);
1727 if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue;
1728 if (needs_escape(cp)) return {begin, begin + 1, cp};
1729 }
1730 return {begin, nullptr, 0};
1731}
1732
1733inline auto find_escape(const char* begin, const char* end)
1735 if (!is_utf8()) return find_escape<char>(begin, end);
1736 auto result = find_escape_result<char>{end, nullptr, 0};
1738 [&](uint32_t cp, string_view sv) {
1739 if (needs_escape(cp)) {
1740 result = {sv.begin(), sv.end(), cp};
1741 return false;
1742 }
1743 return true;
1744 });
1745 return result;
1746}
1747
1748#define FMT_STRING_IMPL(s, base, explicit) \
1749 [] { \
1750 /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
1751 /* Use a macro-like name to avoid shadowing warnings. */ \
1752 struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
1753 using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t<decltype(s[0])>; \
1754 FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
1755 operator fmt::basic_string_view<char_type>() const { \
1756 return fmt::detail_exported::compile_string_to_view<char_type>(s); \
1757 } \
1758 }; \
1759 return FMT_COMPILE_STRING(); \
1760 }()
1761
1762/**
1763 \rst
1764 Constructs a compile-time format string from a string literal *s*.
1765
1766 **Example**::
1767
1768 // A compile-time error because 'd' is an invalid specifier for strings.
1769 std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
1770 \endrst
1771 */
1772#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
1773
1774template <size_t width, typename Char, typename OutputIt>
1775auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {
1776 *out++ = static_cast<Char>('\\');
1777 *out++ = static_cast<Char>(prefix);
1778 Char buf[width];
1779 fill_n(buf, width, static_cast<Char>('0'));
1780 format_uint<4>(buf, cp, width);
1781 return copy_str<Char>(buf, buf + width, out);
1782}
1783
1784template <typename OutputIt, typename Char>
1785auto write_escaped_cp(OutputIt out, const find_escape_result<Char>& escape)
1786 -> OutputIt {
1787 auto c = static_cast<Char>(escape.cp);
1788 switch (escape.cp) {
1789 case '\n':
1790 *out++ = static_cast<Char>('\\');
1791 c = static_cast<Char>('n');
1792 break;
1793 case '\r':
1794 *out++ = static_cast<Char>('\\');
1795 c = static_cast<Char>('r');
1796 break;
1797 case '\t':
1798 *out++ = static_cast<Char>('\\');
1799 c = static_cast<Char>('t');
1800 break;
1801 case '"':
1803 case '\'':
1805 case '\\':
1806 *out++ = static_cast<Char>('\\');
1807 break;
1808 default:
1809 if (is_utf8()) {
1810 if (escape.cp < 0x100) {
1811 return write_codepoint<2, Char>(out, 'x', escape.cp);
1812 }
1813 if (escape.cp < 0x10000) {
1814 return write_codepoint<4, Char>(out, 'u', escape.cp);
1815 }
1816 if (escape.cp < 0x110000) {
1817 return write_codepoint<8, Char>(out, 'U', escape.cp);
1818 }
1819 }
1820 for (Char escape_char : basic_string_view<Char>(
1821 escape.begin, to_unsigned(escape.end - escape.begin))) {
1822 out = write_codepoint<2, Char>(out, 'x',
1823 static_cast<uint32_t>(escape_char) & 0xFF);
1824 }
1825 return out;
1826 }
1827 *out++ = c;
1828 return out;
1829}
1830
1831template <typename Char, typename OutputIt>
1833 -> OutputIt {
1834 *out++ = static_cast<Char>('"');
1835 auto begin = str.begin(), end = str.end();
1836 do {
1837 auto escape = find_escape(begin, end);
1838 out = copy_str<Char>(begin, escape.begin, out);
1839 begin = escape.end;
1840 if (!begin) break;
1841 out = write_escaped_cp<OutputIt, Char>(out, escape);
1842 } while (begin != end);
1843 *out++ = static_cast<Char>('"');
1844 return out;
1845}
1846
1847template <typename Char, typename OutputIt>
1848auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
1849 *out++ = static_cast<Char>('\'');
1850 if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('"')) ||
1851 v == static_cast<Char>('\'')) {
1852 out = write_escaped_cp(
1853 out, find_escape_result<Char>{&v, &v + 1, static_cast<uint32_t>(v)});
1854 } else {
1855 *out++ = v;
1856 }
1857 *out++ = static_cast<Char>('\'');
1858 return out;
1859}
1860
1861template <typename Char, typename OutputIt>
1862FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1863 const basic_format_specs<Char>& specs)
1864 -> OutputIt {
1865 bool is_debug = specs.type == presentation_type::debug;
1866 return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1867 if (is_debug) return write_escaped_char(it, value);
1868 *it++ = value;
1869 return it;
1870 });
1871}
1872template <typename Char, typename OutputIt>
1873FMT_CONSTEXPR auto write(OutputIt out, Char value,
1874 const basic_format_specs<Char>& specs,
1875 locale_ref loc = {}) -> OutputIt {
1876 return check_char_specs(specs)
1877 ? write_char(out, value, specs)
1878 : write(out, static_cast<int>(value), specs, loc);
1879}
1880
1881// Data for write_int that doesn't depend on output iterator type. It is used to
1882// avoid template code bloat.
1883template <typename Char> struct write_int_data {
1884 size_t size;
1885 size_t padding;
1886
1887 FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
1888 const basic_format_specs<Char>& specs)
1889 : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
1890 if (specs.align == align::numeric) {
1891 auto width = to_unsigned(specs.width);
1892 if (width > size) {
1893 padding = width - size;
1894 size = width;
1895 }
1896 } else if (specs.precision > num_digits) {
1897 size = (prefix >> 24) + to_unsigned(specs.precision);
1898 padding = to_unsigned(specs.precision - num_digits);
1899 }
1900 }
1901};
1902
1903// Writes an integer in the format
1904// <left-padding><prefix><numeric-padding><digits><right-padding>
1905// where <digits> are written by write_digits(it).
1906// prefix contains chars in three lower bytes and the size in the fourth byte.
1907template <typename OutputIt, typename Char, typename W>
1908FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
1909 unsigned prefix,
1910 const basic_format_specs<Char>& specs,
1911 W write_digits) -> OutputIt {
1912 // Slightly faster check for specs.width == 0 && specs.precision == -1.
1913 if ((specs.width | (specs.precision + 1)) == 0) {
1914 auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
1915 if (prefix != 0) {
1916 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1917 *it++ = static_cast<Char>(p & 0xff);
1918 }
1919 return base_iterator(out, write_digits(it));
1920 }
1921 auto data = write_int_data<Char>(num_digits, prefix, specs);
1922 return write_padded<align::right>(
1923 out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
1924 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1925 *it++ = static_cast<Char>(p & 0xff);
1926 it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
1927 return write_digits(it);
1928 });
1929}
1930
1931template <typename Char> class digit_grouping {
1932 private:
1934
1935 struct next_state {
1936 std::string::const_iterator group;
1937 int pos;
1938 };
1939 next_state initial_state() const { return {sep_.grouping.begin(), 0}; }
1940
1941 // Returns the next digit group separator position.
1942 int next(next_state& state) const {
1943 if (!sep_.thousands_sep) return max_value<int>();
1944 if (state.group == sep_.grouping.end())
1945 return state.pos += sep_.grouping.back();
1946 if (*state.group <= 0 || *state.group == max_value<char>())
1947 return max_value<int>();
1948 state.pos += *state.group++;
1949 return state.pos;
1950 }
1951
1952 public:
1953 explicit digit_grouping(locale_ref loc, bool localized = true) {
1954 if (localized)
1955 sep_ = thousands_sep<Char>(loc);
1956 else
1957 sep_.thousands_sep = Char();
1958 }
1959 explicit digit_grouping(thousands_sep_result<Char> sep) : sep_(sep) {}
1960
1961 Char separator() const { return sep_.thousands_sep; }
1962
1963 int count_separators(int num_digits) const {
1964 int count = 0;
1965 auto state = initial_state();
1966 while (num_digits > next(state)) ++count;
1967 return count;
1968 }
1969
1970 // Applies grouping to digits and write the output to out.
1971 template <typename Out, typename C>
1972 Out apply(Out out, basic_string_view<C> digits) const {
1973 auto num_digits = static_cast<int>(digits.size());
1974 auto separators = basic_memory_buffer<int>();
1975 separators.push_back(0);
1976 auto state = initial_state();
1977 while (int i = next(state)) {
1978 if (i >= num_digits) break;
1979 separators.push_back(i);
1980 }
1981 for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);
1982 i < num_digits; ++i) {
1983 if (num_digits - i == separators[sep_index]) {
1984 *out++ = separator();
1985 --sep_index;
1986 }
1987 *out++ = static_cast<Char>(digits[to_unsigned(i)]);
1988 }
1989 return out;
1990 }
1991};
1992
1993template <typename OutputIt, typename UInt, typename Char>
1994auto write_int_localized(OutputIt out, UInt value, unsigned prefix,
1995 const basic_format_specs<Char>& specs,
1996 const digit_grouping<Char>& grouping) -> OutputIt {
1997 static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
1998 int num_digits = count_digits(value);
1999 char digits[40];
2000 format_decimal(digits, value, num_digits);
2001 unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
2002 grouping.count_separators(num_digits));
2003 return write_padded<align::right>(
2004 out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
2005 if (prefix != 0) {
2006 char sign = static_cast<char>(prefix);
2007 *it++ = static_cast<Char>(sign);
2008 }
2009 return grouping.apply(it, string_view(digits, to_unsigned(num_digits)));
2010 });
2011}
2012
2013template <typename OutputIt, typename UInt, typename Char>
2014auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
2015 const basic_format_specs<Char>& specs, locale_ref loc)
2016 -> bool {
2017 auto grouping = digit_grouping<Char>(loc);
2018 out = write_int_localized(out, value, prefix, specs, grouping);
2019 return true;
2020}
2021
2022FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
2023 prefix |= prefix != 0 ? value << 8 : value;
2024 prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
2025}
2026
2027template <typename UInt> struct write_int_arg {
2029 unsigned prefix;
2030};
2031
2032template <typename T>
2035 auto prefix = 0u;
2036 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2037 if (is_negative(value)) {
2038 prefix = 0x01000000 | '-';
2039 abs_value = 0 - abs_value;
2040 } else {
2041 constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
2042 0x1000000u | ' '};
2043 prefix = prefixes[sign];
2044 }
2045 return {abs_value, prefix};
2046}
2047
2048template <typename Char, typename OutputIt, typename T>
2050 const basic_format_specs<Char>& specs,
2051 locale_ref loc) -> OutputIt {
2052 static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2053 auto abs_value = arg.abs_value;
2054 auto prefix = arg.prefix;
2055 switch (specs.type) {
2058 if (specs.localized &&
2059 write_int_localized(out, static_cast<uint64_or_128_t<T>>(abs_value),
2060 prefix, specs, loc)) {
2061 return out;
2062 }
2063 auto num_digits = count_digits(abs_value);
2064 return write_int(
2065 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2066 return format_decimal<Char>(it, abs_value, num_digits).end;
2067 });
2068 }
2071 bool upper = specs.type == presentation_type::hex_upper;
2072 if (specs.alt)
2073 prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
2074 int num_digits = count_digits<4>(abs_value);
2075 return write_int(
2076 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2077 return format_uint<4, Char>(it, abs_value, num_digits, upper);
2078 });
2079 }
2082 bool upper = specs.type == presentation_type::bin_upper;
2083 if (specs.alt)
2084 prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
2085 int num_digits = count_digits<1>(abs_value);
2086 return write_int(out, num_digits, prefix, specs,
2087 [=](reserve_iterator<OutputIt> it) {
2088 return format_uint<1, Char>(it, abs_value, num_digits);
2089 });
2090 }
2092 int num_digits = count_digits<3>(abs_value);
2093 // Octal prefix '0' is counted as a digit, so only add it if precision
2094 // is not greater than the number of digits.
2095 if (specs.alt && specs.precision <= num_digits && abs_value != 0)
2096 prefix_append(prefix, '0');
2097 return write_int(out, num_digits, prefix, specs,
2098 [=](reserve_iterator<OutputIt> it) {
2099 return format_uint<3, Char>(it, abs_value, num_digits);
2100 });
2101 }
2103 return write_char(out, static_cast<Char>(abs_value), specs);
2104 default:
2105 throw_format_error("invalid type specifier");
2106 }
2107 return out;
2108}
2109template <typename Char, typename OutputIt, typename T>
2111 OutputIt out, write_int_arg<T> arg, const basic_format_specs<Char>& specs,
2112 locale_ref loc) -> OutputIt {
2113 return write_int(out, arg, specs, loc);
2114}
2115template <typename Char, typename OutputIt, typename T,
2117 !std::is_same<T, bool>::value &&
2118 std::is_same<OutputIt, buffer_appender<Char>>::value)>
2120 const basic_format_specs<Char>& specs,
2121 locale_ref loc) -> OutputIt {
2122 return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
2123 loc);
2124}
2125// An inlined version of write used in format string compilation.
2126template <typename Char, typename OutputIt, typename T,
2128 !std::is_same<T, bool>::value &&
2129 !std::is_same<OutputIt, buffer_appender<Char>>::value)>
2130FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2131 const basic_format_specs<Char>& specs,
2132 locale_ref loc) -> OutputIt {
2133 return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
2134}
2135
2136// An output iterator that counts the number of objects written to it and
2137// discards them.
2139 private:
2140 size_t count_;
2141
2142 public:
2143 using iterator_category = std::output_iterator_tag;
2144 using difference_type = std::ptrdiff_t;
2145 using pointer = void;
2146 using reference = void;
2148
2149 struct value_type {
2150 template <typename T> FMT_CONSTEXPR void operator=(const T&) {}
2151 };
2152
2154
2155 FMT_CONSTEXPR size_t count() const { return count_; }
2156
2158 ++count_;
2159 return *this;
2160 }
2162 auto it = *this;
2163 ++*this;
2164 return it;
2165 }
2166
2168 difference_type n) {
2169 it.count_ += static_cast<size_t>(n);
2170 return it;
2171 }
2172
2173 FMT_CONSTEXPR value_type operator*() const { return {}; }
2174};
2175
2176template <typename Char, typename OutputIt>
2178 const basic_format_specs<Char>& specs) -> OutputIt {
2179 auto data = s.data();
2180 auto size = s.size();
2181 if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
2183 bool is_debug = specs.type == presentation_type::debug;
2184 size_t width = 0;
2185 if (specs.width != 0) {
2186 if (is_debug)
2188 else
2190 }
2191 return write_padded(out, specs, size, width,
2192 [=](reserve_iterator<OutputIt> it) {
2193 if (is_debug) return write_escaped_string(it, s);
2194 return copy_str<Char>(data, data + size, it);
2195 });
2196}
2197template <typename Char, typename OutputIt>
2198FMT_CONSTEXPR auto write(OutputIt out,
2201 -> OutputIt {
2203 return write(out, s, specs);
2204}
2205template <typename Char, typename OutputIt>
2206FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
2208 -> OutputIt {
2209 return check_cstring_type_spec(specs.type)
2210 ? write(out, basic_string_view<Char>(s), specs, {})
2211 : write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
2212}
2213
2214template <typename Char, typename OutputIt, typename T,
2216 !std::is_same<T, bool>::value &&
2217 !std::is_same<T, Char>::value)>
2218FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2219 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2220 bool negative = is_negative(value);
2221 // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2222 if (negative) abs_value = ~abs_value + 1;
2223 int num_digits = count_digits(abs_value);
2224 auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2225 auto it = reserve(out, size);
2226 if (auto ptr = to_pointer<Char>(it, size)) {
2227 if (negative) *ptr++ = static_cast<Char>('-');
2228 format_decimal<Char>(ptr, abs_value, num_digits);
2229 return out;
2230 }
2231 if (negative) *it++ = static_cast<Char>('-');
2232 it = format_decimal<Char>(it, abs_value, num_digits).end;
2233 return base_iterator(out, it);
2234}
2235
2236template <typename Char, typename OutputIt>
2237FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
2239 const float_specs& fspecs) -> OutputIt {
2240 auto str =
2241 isnan ? (fspecs.upper ? "NAN" : "nan") : (fspecs.upper ? "INF" : "inf");
2242 constexpr size_t str_size = 3;
2243 auto sign = fspecs.sign;
2244 auto size = str_size + (sign ? 1 : 0);
2245 // Replace '0'-padding with space for non-finite values.
2246 const bool is_zero_fill =
2247 specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
2248 if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
2249 return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
2250 if (sign) *it++ = detail::sign<Char>(sign);
2251 return copy_str<Char>(str, str + str_size, it);
2252 });
2253}
2254
2255// A decimal floating-point number significand * pow(10, exp).
2257 const char* significand;
2260};
2261
2262constexpr auto get_significand_size(const big_decimal_fp& f) -> int {
2263 return f.significand_size;
2264}
2265template <typename T>
2267 return count_digits(f.significand);
2268}
2269
2270template <typename Char, typename OutputIt>
2271constexpr auto write_significand(OutputIt out, const char* significand,
2272 int significand_size) -> OutputIt {
2273 return copy_str<Char>(significand, significand + significand_size, out);
2274}
2275template <typename Char, typename OutputIt, typename UInt>
2276inline auto write_significand(OutputIt out, UInt significand,
2277 int significand_size) -> OutputIt {
2278 return format_decimal<Char>(out, significand, significand_size).end;
2279}
2280template <typename Char, typename OutputIt, typename T, typename Grouping>
2281FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2282 int significand_size, int exponent,
2283 const Grouping& grouping) -> OutputIt {
2284 if (!grouping.separator()) {
2285 out = write_significand<Char>(out, significand, significand_size);
2286 return detail::fill_n(out, exponent, static_cast<Char>('0'));
2287 }
2288 auto buffer = memory_buffer();
2289 write_significand<char>(appender(buffer), significand, significand_size);
2290 detail::fill_n(appender(buffer), exponent, '0');
2291 return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2292}
2293
2294template <typename Char, typename UInt,
2295 FMT_ENABLE_IF(std::is_integral<UInt>::value)>
2296inline auto write_significand(Char* out, UInt significand, int significand_size,
2297 int integral_size, Char decimal_point) -> Char* {
2298 if (!decimal_point)
2299 return format_decimal(out, significand, significand_size).end;
2300 out += significand_size + 1;
2301 Char* end = out;
2302 int floating_size = significand_size - integral_size;
2303 for (int i = floating_size / 2; i > 0; --i) {
2304 out -= 2;
2305 copy2(out, digits2(static_cast<std::size_t>(significand % 100)));
2306 significand /= 100;
2307 }
2308 if (floating_size % 2 != 0) {
2309 *--out = static_cast<Char>('0' + significand % 10);
2310 significand /= 10;
2311 }
2312 *--out = decimal_point;
2313 format_decimal(out - integral_size, significand, integral_size);
2314 return end;
2315}
2316
2317template <typename OutputIt, typename UInt, typename Char,
2319inline auto write_significand(OutputIt out, UInt significand,
2320 int significand_size, int integral_size,
2321 Char decimal_point) -> OutputIt {
2322 // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2323 Char buffer[digits10<UInt>() + 2];
2324 auto end = write_significand(buffer, significand, significand_size,
2325 integral_size, decimal_point);
2326 return detail::copy_str_noinline<Char>(buffer, end, out);
2327}
2328
2329template <typename OutputIt, typename Char>
2330FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,
2331 int significand_size, int integral_size,
2332 Char decimal_point) -> OutputIt {
2333 out = detail::copy_str_noinline<Char>(significand,
2334 significand + integral_size, out);
2335 if (!decimal_point) return out;
2336 *out++ = decimal_point;
2337 return detail::copy_str_noinline<Char>(significand + integral_size,
2338 significand + significand_size, out);
2339}
2340
2341template <typename OutputIt, typename Char, typename T, typename Grouping>
2342FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2343 int significand_size, int integral_size,
2344 Char decimal_point,
2345 const Grouping& grouping) -> OutputIt {
2346 if (!grouping.separator()) {
2347 return write_significand(out, significand, significand_size, integral_size,
2349 }
2352 significand_size, integral_size, decimal_point);
2353 grouping.apply(
2354 out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2355 return detail::copy_str_noinline<Char>(buffer.data() + integral_size,
2356 buffer.end(), out);
2357}
2358
2359template <typename OutputIt, typename DecimalFP, typename Char,
2360 typename Grouping = digit_grouping<Char>>
2361FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
2362 const basic_format_specs<Char>& specs,
2363 float_specs fspecs, locale_ref loc)
2364 -> OutputIt {
2365 auto significand = f.significand;
2366 int significand_size = get_significand_size(f);
2367 const Char zero = static_cast<Char>('0');
2368 auto sign = fspecs.sign;
2369 size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
2370 using iterator = reserve_iterator<OutputIt>;
2371
2372 Char decimal_point =
2373 fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>('.');
2374
2375 int output_exp = f.exponent + significand_size - 1;
2376 auto use_exp_format = [=]() {
2377 if (fspecs.format == float_format::exp) return true;
2378 if (fspecs.format != float_format::general) return false;
2379 // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
2380 // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
2381 const int exp_lower = -4, exp_upper = 16;
2382 return output_exp < exp_lower ||
2383 output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
2384 };
2385 if (use_exp_format()) {
2386 int num_zeros = 0;
2387 if (fspecs.showpoint) {
2388 num_zeros = fspecs.precision - significand_size;
2389 if (num_zeros < 0) num_zeros = 0;
2390 size += to_unsigned(num_zeros);
2391 } else if (significand_size == 1) {
2392 decimal_point = Char();
2393 }
2394 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2395 int exp_digits = 2;
2396 if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2397
2398 size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
2399 char exp_char = fspecs.upper ? 'E' : 'e';
2400 auto write = [=](iterator it) {
2401 if (sign) *it++ = detail::sign<Char>(sign);
2402 // Insert a decimal point after the first digit and add an exponent.
2403 it = write_significand(it, significand, significand_size, 1,
2405 if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
2406 *it++ = static_cast<Char>(exp_char);
2407 return write_exponent<Char>(output_exp, it);
2408 };
2409 return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
2410 : base_iterator(out, write(reserve(out, size)));
2411 }
2412
2413 int exp = f.exponent + significand_size;
2414 if (f.exponent >= 0) {
2415 // 1234e5 -> 123400000[.0+]
2416 size += to_unsigned(f.exponent);
2417 int num_zeros = fspecs.precision - exp;
2418 abort_fuzzing_if(num_zeros > 5000);
2419 if (fspecs.showpoint) {
2420 ++size;
2421 if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1;
2422 if (num_zeros > 0) size += to_unsigned(num_zeros);
2423 }
2424 auto grouping = Grouping(loc, fspecs.locale);
2425 size += to_unsigned(grouping.count_separators(exp));
2426 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2427 if (sign) *it++ = detail::sign<Char>(sign);
2428 it = write_significand<Char>(it, significand, significand_size,
2429 f.exponent, grouping);
2430 if (!fspecs.showpoint) return it;
2431 *it++ = decimal_point;
2432 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2433 });
2434 } else if (exp > 0) {
2435 // 1234e-2 -> 12.34[0+]
2436 int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
2437 size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
2438 auto grouping = Grouping(loc, fspecs.locale);
2439 size += to_unsigned(grouping.count_separators(significand_size));
2440 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2441 if (sign) *it++ = detail::sign<Char>(sign);
2442 it = write_significand(it, significand, significand_size, exp,
2443 decimal_point, grouping);
2444 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2445 });
2446 }
2447 // 1234e-6 -> 0.001234
2448 int num_zeros = -exp;
2449 if (significand_size == 0 && fspecs.precision >= 0 &&
2450 fspecs.precision < num_zeros) {
2451 num_zeros = fspecs.precision;
2452 }
2453 bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
2454 size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
2455 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2456 if (sign) *it++ = detail::sign<Char>(sign);
2457 *it++ = zero;
2458 if (!pointy) return it;
2459 *it++ = decimal_point;
2460 it = detail::fill_n(it, num_zeros, zero);
2461 return write_significand<Char>(it, significand, significand_size);
2462 });
2463}
2464
2465template <typename Char> class fallback_digit_grouping {
2466 public:
2468
2469 constexpr Char separator() const { return Char(); }
2470
2471 constexpr int count_separators(int) const { return 0; }
2472
2473 template <typename Out, typename C>
2474 constexpr Out apply(Out out, basic_string_view<C>) const {
2475 return out;
2476 }
2477};
2478
2479template <typename OutputIt, typename DecimalFP, typename Char>
2480FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,
2481 const basic_format_specs<Char>& specs,
2482 float_specs fspecs, locale_ref loc)
2483 -> OutputIt {
2484 if (is_constant_evaluated()) {
2485 return do_write_float<OutputIt, DecimalFP, Char,
2486 fallback_digit_grouping<Char>>(out, f, specs, fspecs,
2487 loc);
2488 } else {
2489 return do_write_float(out, f, specs, fspecs, loc);
2490 }
2491}
2492
2493template <typename T> constexpr bool isnan(T value) {
2494 return !(value >= value); // std::isnan doesn't support __float128.
2495}
2496
2497template <typename T, typename Enable = void>
2498struct has_isfinite : std::false_type {};
2499
2500template <typename T>
2501struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
2502 : std::true_type {};
2503
2504template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&&
2505 has_isfinite<T>::value)>
2507 constexpr T inf = T(std::numeric_limits<double>::infinity());
2509 return !detail::isnan(value) && value != inf && value != -inf;
2510 return std::isfinite(value);
2511}
2512template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
2514 T inf = T(std::numeric_limits<double>::infinity());
2515 // std::isfinite doesn't support __float128.
2516 return !detail::isnan(value) && value != inf && value != -inf;
2517}
2518
2519template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
2521 if (is_constant_evaluated()) {
2522#ifdef __cpp_if_constexpr
2523 if constexpr (std::numeric_limits<double>::is_iec559) {
2524 auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2525 return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2526 }
2527#endif
2528 }
2529 return std::signbit(static_cast<double>(value));
2530}
2531
2533
2534// Given the divisor (normally a power of 10), the remainder = v % divisor for
2535// some number v and the error, returns whether v should be rounded up, down, or
2536// whether the rounding direction can't be determined due to error.
2537// error should be less than divisor / 2.
2539 uint64_t remainder,
2540 uint64_t error) {
2541 FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow.
2542 FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow.
2543 FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow.
2544 // Round down if (remainder + error) * 2 <= divisor.
2545 if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
2546 return round_direction::down;
2547 // Round up if (remainder - error) * 2 >= divisor.
2548 if (remainder >= error &&
2549 remainder - error >= divisor - (remainder - error)) {
2550 return round_direction::up;
2551 }
2553}
2554
2555namespace digits {
2557 more, // Generate more digits.
2558 done, // Done generating digits.
2559 error // Digit generation cancelled due to an error.
2561}
2562
2564 char* buf;
2565 int size;
2568 bool fixed;
2569
2571 uint64_t remainder, uint64_t error,
2572 bool integral) {
2573 FMT_ASSERT(remainder < divisor, "");
2574 buf[size++] = digit;
2575 if (!integral && error >= remainder) return digits::error;
2576 if (size < precision) return digits::more;
2577 if (!integral) {
2578 // Check if error * 2 < divisor with overflow prevention.
2579 // The check is not needed for the integral part because error = 1
2580 // and divisor > (1 << 32) there.
2581 if (error >= divisor || error >= divisor - error) return digits::error;
2582 } else {
2583 FMT_ASSERT(error == 1 && divisor > 2, "");
2584 }
2585 auto dir = get_round_direction(divisor, remainder, error);
2586 if (dir != round_direction::up)
2588 ++buf[size - 1];
2589 for (int i = size - 1; i > 0 && buf[i] > '9'; --i) {
2590 buf[i] = '0';
2591 ++buf[i - 1];
2592 }
2593 if (buf[0] > '9') {
2594 buf[0] = '1';
2595 if (fixed)
2596 buf[size++] = '0';
2597 else
2598 ++exp10;
2599 }
2600 return digits::done;
2601 }
2602};
2603
2604inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {
2605 // Adjust fixed precision by exponent because it is relative to decimal
2606 // point.
2607 if (exp10 > 0 && precision > max_value<int>() - exp10)
2608 FMT_THROW(format_error("number is too big"));
2609 precision += exp10;
2610}
2611
2612// Generates output using the Grisu digit-gen algorithm.
2613// error: the size of the region (lower, upper) outside of which numbers
2614// definitely do not round to value (Delta in Grisu3).
2616 int& exp,
2617 gen_digits_handler& handler)
2618 -> digits::result {
2619 const fp one(1ULL << -value.e, value.e);
2620 // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be
2621 // zero because it contains a product of two 64-bit numbers with MSB set (due
2622 // to normalization) - 1, shifted right by at most 60 bits.
2623 auto integral = static_cast<uint32_t>(value.f >> -one.e);
2624 FMT_ASSERT(integral != 0, "");
2625 FMT_ASSERT(integral == value.f >> -one.e, "");
2626 // The fractional part of scaled value (p2 in Grisu) c = value % one.
2627 uint64_t fractional = value.f & (one.f - 1);
2628 exp = count_digits(integral); // kappa in Grisu.
2629 // Non-fixed formats require at least one digit and no precision adjustment.
2630 if (handler.fixed) {
2631 adjust_precision(handler.precision, exp + handler.exp10);
2632 // Check if precision is satisfied just by leading zeros, e.g.
2633 // format("{:.2f}", 0.001) gives "0.00" without generating any digits.
2634 if (handler.precision <= 0) {
2635 if (handler.precision < 0) return digits::done;
2636 // Divide by 10 to prevent overflow.
2637 uint64_t divisor = data::power_of_10_64[exp - 1] << -one.e;
2638 auto dir = get_round_direction(divisor, value.f / 10, error * 10);
2639 if (dir == round_direction::unknown) return digits::error;
2640 handler.buf[handler.size++] = dir == round_direction::up ? '1' : '0';
2641 return digits::done;
2642 }
2643 }
2644 // Generate digits for the integral part. This can produce up to 10 digits.
2645 do {
2646 uint32_t digit = 0;
2647 auto divmod_integral = [&](uint32_t divisor) {
2648 digit = integral / divisor;
2649 integral %= divisor;
2650 };
2651 // This optimization by Milo Yip reduces the number of integer divisions by
2652 // one per iteration.
2653 switch (exp) {
2654 case 10:
2655 divmod_integral(1000000000);
2656 break;
2657 case 9:
2658 divmod_integral(100000000);
2659 break;
2660 case 8:
2661 divmod_integral(10000000);
2662 break;
2663 case 7:
2664 divmod_integral(1000000);
2665 break;
2666 case 6:
2667 divmod_integral(100000);
2668 break;
2669 case 5:
2670 divmod_integral(10000);
2671 break;
2672 case 4:
2673 divmod_integral(1000);
2674 break;
2675 case 3:
2676 divmod_integral(100);
2677 break;
2678 case 2:
2679 divmod_integral(10);
2680 break;
2681 case 1:
2682 digit = integral;
2683 integral = 0;
2684 break;
2685 default:
2686 FMT_ASSERT(false, "invalid number of digits");
2687 }
2688 --exp;
2689 auto remainder = (static_cast<uint64_t>(integral) << -one.e) + fractional;
2690 auto result = handler.on_digit(static_cast<char>('0' + digit),
2691 data::power_of_10_64[exp] << -one.e,
2692 remainder, error, true);
2693 if (result != digits::more) return result;
2694 } while (exp > 0);
2695 // Generate digits for the fractional part.
2696 for (;;) {
2697 fractional *= 10;
2698 error *= 10;
2699 char digit = static_cast<char>('0' + (fractional >> -one.e));
2700 fractional &= one.f - 1;
2701 --exp;
2702 auto result = handler.on_digit(digit, one.f, fractional, error, false);
2703 if (result != digits::more) return result;
2704 }
2705}
2706
2707class bigint {
2708 private:
2709 // A bigint is stored as an array of bigits (big digits), with bigit at index
2710 // 0 being the least significant one.
2711 using bigit = uint32_t;
2712 using double_bigit = uint64_t;
2713 enum { bigits_capacity = 32 };
2715 int exp_;
2716
2717 FMT_CONSTEXPR20 bigit operator[](int index) const {
2718 return bigits_[to_unsigned(index)];
2719 }
2720 FMT_CONSTEXPR20 bigit& operator[](int index) {
2721 return bigits_[to_unsigned(index)];
2722 }
2723
2724 static constexpr const int bigit_bits = num_bits<bigit>();
2725
2726 friend struct formatter<bigint>;
2727
2728 FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit& borrow) {
2729 auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
2730 (*this)[index] = static_cast<bigit>(result);
2731 borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
2732 }
2733
2734 FMT_CONSTEXPR20 void remove_leading_zeros() {
2735 int num_bigits = static_cast<int>(bigits_.size()) - 1;
2736 while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
2737 bigits_.resize(to_unsigned(num_bigits + 1));
2738 }
2739
2740 // Computes *this -= other assuming aligned bigints and *this >= other.
2741 FMT_CONSTEXPR20 void subtract_aligned(const bigint& other) {
2742 FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
2743 FMT_ASSERT(compare(*this, other) >= 0, "");
2744 bigit borrow = 0;
2745 int i = other.exp_ - exp_;
2746 for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
2747 subtract_bigits(i, other.bigits_[j], borrow);
2748 while (borrow > 0) subtract_bigits(i, 0, borrow);
2749 remove_leading_zeros();
2750 }
2751
2753 const double_bigit wide_value = value;
2754 bigit carry = 0;
2755 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2756 double_bigit result = bigits_[i] * wide_value + carry;
2757 bigits_[i] = static_cast<bigit>(result);
2758 carry = static_cast<bigit>(result >> bigit_bits);
2759 }
2760 if (carry != 0) bigits_.push_back(carry);
2761 }
2762
2763 template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2764 std::is_same<UInt, uint128_t>::value)>
2765 FMT_CONSTEXPR20 void multiply(UInt value) {
2766 using half_uint =
2768 const int shift = num_bits<half_uint>() - bigit_bits;
2769 const UInt lower = static_cast<half_uint>(value);
2770 const UInt upper = value >> num_bits<half_uint>();
2771 UInt carry = 0;
2772 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2773 UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
2774 carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
2775 (carry >> bigit_bits);
2776 bigits_[i] = static_cast<bigit>(result);
2777 }
2778 while (carry != 0) {
2779 bigits_.push_back(static_cast<bigit>(carry));
2780 carry >>= bigit_bits;
2781 }
2782 }
2783
2784 template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2785 std::is_same<UInt, uint128_t>::value)>
2786 FMT_CONSTEXPR20 void assign(UInt n) {
2787 size_t num_bigits = 0;
2788 do {
2789 bigits_[num_bigits++] = static_cast<bigit>(n);
2790 n >>= bigit_bits;
2791 } while (n != 0);
2792 bigits_.resize(num_bigits);
2793 exp_ = 0;
2794 }
2795
2796 public:
2798 explicit bigint(uint64_t n) { assign(n); }
2799
2800 bigint(const bigint&) = delete;
2801 void operator=(const bigint&) = delete;
2802
2803 FMT_CONSTEXPR20 void assign(const bigint& other) {
2804 auto size = other.bigits_.size();
2805 bigits_.resize(size);
2806 auto data = other.bigits_.data();
2807 std::copy(data, data + size, make_checked(bigits_.data(), size));
2808 exp_ = other.exp_;
2809 }
2810
2811 template <typename Int> FMT_CONSTEXPR20 void operator=(Int n) {
2812 FMT_ASSERT(n > 0, "");
2813 assign(uint64_or_128_t<Int>(n));
2814 }
2815
2817 return static_cast<int>(bigits_.size()) + exp_;
2818 }
2819
2821 FMT_ASSERT(shift >= 0, "");
2822 exp_ += shift / bigit_bits;
2823 shift %= bigit_bits;
2824 if (shift == 0) return *this;
2825 bigit carry = 0;
2826 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2827 bigit c = bigits_[i] >> (bigit_bits - shift);
2828 bigits_[i] = (bigits_[i] << shift) + carry;
2829 carry = c;
2830 }
2831 if (carry != 0) bigits_.push_back(carry);
2832 return *this;
2833 }
2834
2835 template <typename Int> FMT_CONSTEXPR20 bigint& operator*=(Int value) {
2836 FMT_ASSERT(value > 0, "");
2838 return *this;
2839 }
2840
2841 friend FMT_CONSTEXPR20 int compare(const bigint& lhs, const bigint& rhs) {
2842 int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
2843 if (num_lhs_bigits != num_rhs_bigits)
2844 return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
2845 int i = static_cast<int>(lhs.bigits_.size()) - 1;
2846 int j = static_cast<int>(rhs.bigits_.size()) - 1;
2847 int end = i - j;
2848 if (end < 0) end = 0;
2849 for (; i >= end; --i, --j) {
2850 bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
2851 if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
2852 }
2853 if (i != j) return i > j ? 1 : -1;
2854 return 0;
2855 }
2856
2857 // Returns compare(lhs1 + lhs2, rhs).
2858 friend FMT_CONSTEXPR20 int add_compare(const bigint& lhs1, const bigint& lhs2,
2859 const bigint& rhs) {
2860 auto minimum = [](int a, int b) { return a < b ? a : b; };
2861 auto maximum = [](int a, int b) { return a > b ? a : b; };
2862 int max_lhs_bigits = maximum(lhs1.num_bigits(), lhs2.num_bigits());
2863 int num_rhs_bigits = rhs.num_bigits();
2864 if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
2865 if (max_lhs_bigits > num_rhs_bigits) return 1;
2866 auto get_bigit = [](const bigint& n, int i) -> bigit {
2867 return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
2868 };
2869 double_bigit borrow = 0;
2870 int min_exp = minimum(minimum(lhs1.exp_, lhs2.exp_), rhs.exp_);
2871 for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
2872 double_bigit sum =
2873 static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
2874 bigit rhs_bigit = get_bigit(rhs, i);
2875 if (sum > rhs_bigit + borrow) return 1;
2876 borrow = rhs_bigit + borrow - sum;
2877 if (borrow > 1) return -1;
2878 borrow <<= bigit_bits;
2879 }
2880 return borrow != 0 ? -1 : 0;
2881 }
2882
2883 // Assigns pow(10, exp) to this bigint.
2885 FMT_ASSERT(exp >= 0, "");
2886 if (exp == 0) return *this = 1;
2887 // Find the top bit.
2888 int bitmask = 1;
2889 while (exp >= bitmask) bitmask <<= 1;
2890 bitmask >>= 1;
2891 // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
2892 // repeated squaring and multiplication.
2893 *this = 5;
2894 bitmask >>= 1;
2895 while (bitmask != 0) {
2896 square();
2897 if ((exp & bitmask) != 0) *this *= 5;
2898 bitmask >>= 1;
2899 }
2900 *this <<= exp; // Multiply by pow(2, exp) by shifting.
2901 }
2902
2904 int num_bigits = static_cast<int>(bigits_.size());
2905 int num_result_bigits = 2 * num_bigits;
2906 basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
2907 bigits_.resize(to_unsigned(num_result_bigits));
2908 auto sum = uint128_t();
2909 for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
2910 // Compute bigit at position bigit_index of the result by adding
2911 // cross-product terms n[i] * n[j] such that i + j == bigit_index.
2912 for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
2913 // Most terms are multiplied twice which can be optimized in the future.
2914 sum += static_cast<double_bigit>(n[i]) * n[j];
2915 }
2916 (*this)[bigit_index] = static_cast<bigit>(sum);
2917 sum >>= num_bits<bigit>(); // Compute the carry.
2918 }
2919 // Do the same for the top half.
2920 for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
2921 ++bigit_index) {
2922 for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
2923 sum += static_cast<double_bigit>(n[i++]) * n[j--];
2924 (*this)[bigit_index] = static_cast<bigit>(sum);
2925 sum >>= num_bits<bigit>();
2926 }
2927 remove_leading_zeros();
2928 exp_ *= 2;
2929 }
2930
2931 // If this bigint has a bigger exponent than other, adds trailing zero to make
2932 // exponents equal. This simplifies some operations such as subtraction.
2933 FMT_CONSTEXPR20 void align(const bigint& other) {
2934 int exp_difference = exp_ - other.exp_;
2935 if (exp_difference <= 0) return;
2936 int num_bigits = static_cast<int>(bigits_.size());
2937 bigits_.resize(to_unsigned(num_bigits + exp_difference));
2938 for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
2939 bigits_[j] = bigits_[i];
2940 std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
2941 exp_ -= exp_difference;
2942 }
2943
2944 // Divides this bignum by divisor, assigning the remainder to this and
2945 // returning the quotient.
2947 FMT_ASSERT(this != &divisor, "");
2948 if (compare(*this, divisor) < 0) return 0;
2949 FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
2950 align(divisor);
2951 int quotient = 0;
2952 do {
2953 subtract_aligned(divisor);
2954 ++quotient;
2955 } while (compare(*this, divisor) >= 0);
2956 return quotient;
2957 }
2958};
2959
2960// format_dragon flags.
2963 fixup = 2, // Run fixup to correct exp10 which can be off by one.
2965};
2966
2967// Formats a floating-point number using a variation of the Fixed-Precision
2968// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
2969// https://fmt.dev/papers/p372-steele.pdf.
2971 unsigned flags, int num_digits,
2972 buffer<char>& buf, int& exp10) {
2973 bigint numerator; // 2 * R in (FPP)^2.
2974 bigint denominator; // 2 * S in (FPP)^2.
2975 // lower and upper are differences between value and corresponding boundaries.
2976 bigint lower; // (M^- in (FPP)^2).
2977 bigint upper_store; // upper's value if different from lower.
2978 bigint* upper = nullptr; // (M^+ in (FPP)^2).
2979 // Shift numerator and denominator by an extra bit or two (if lower boundary
2980 // is closer) to make lower and upper integers. This eliminates multiplication
2981 // by 2 during later computations.
2982 bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0;
2983 int shift = is_predecessor_closer ? 2 : 1;
2984 if (value.e >= 0) {
2985 numerator = value.f;
2986 numerator <<= value.e + shift;
2987 lower = 1;
2988 lower <<= value.e;
2989 if (is_predecessor_closer) {
2990 upper_store = 1;
2991 upper_store <<= value.e + 1;
2992 upper = &upper_store;
2993 }
2994 denominator.assign_pow10(exp10);
2995 denominator <<= shift;
2996 } else if (exp10 < 0) {
2997 numerator.assign_pow10(-exp10);
2998 lower.assign(numerator);
2999 if (is_predecessor_closer) {
3000 upper_store.assign(numerator);
3001 upper_store <<= 1;
3002 upper = &upper_store;
3003 }
3004 numerator *= value.f;
3005 numerator <<= shift;
3006 denominator = 1;
3007 denominator <<= shift - value.e;
3008 } else {
3009 numerator = value.f;
3010 numerator <<= shift;
3011 denominator.assign_pow10(exp10);
3012 denominator <<= shift - value.e;
3013 lower = 1;
3014 if (is_predecessor_closer) {
3015 upper_store = 1ULL << 1;
3016 upper = &upper_store;
3017 }
3018 }
3019 int even = static_cast<int>((value.f & 1) == 0);
3020 if (!upper) upper = &lower;
3021 if ((flags & dragon::fixup) != 0) {
3022 if (add_compare(numerator, *upper, denominator) + even <= 0) {
3023 --exp10;
3024 numerator *= 10;
3025 if (num_digits < 0) {
3026 lower *= 10;
3027 if (upper != &lower) *upper *= 10;
3028 }
3029 }
3030 if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1);
3031 }
3032 // Invariant: value == (numerator / denominator) * pow(10, exp10).
3033 if (num_digits < 0) {
3034 // Generate the shortest representation.
3035 num_digits = 0;
3036 char* data = buf.data();
3037 for (;;) {
3038 int digit = numerator.divmod_assign(denominator);
3039 bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower.
3040 // numerator + upper >[=] pow10:
3041 bool high = add_compare(numerator, *upper, denominator) + even > 0;
3042 data[num_digits++] = static_cast<char>('0' + digit);
3043 if (low || high) {
3044 if (!low) {
3045 ++data[num_digits - 1];
3046 } else if (high) {
3047 int result = add_compare(numerator, numerator, denominator);
3048 // Round half to even.
3049 if (result > 0 || (result == 0 && (digit % 2) != 0))
3050 ++data[num_digits - 1];
3051 }
3052 buf.try_resize(to_unsigned(num_digits));
3053 exp10 -= num_digits - 1;
3054 return;
3055 }
3056 numerator *= 10;
3057 lower *= 10;
3058 if (upper != &lower) *upper *= 10;
3059 }
3060 }
3061 // Generate the given number of digits.
3062 exp10 -= num_digits - 1;
3063 if (num_digits == 0) {
3064 denominator *= 10;
3065 auto digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
3066 buf.push_back(digit);
3067 return;
3068 }
3069 buf.try_resize(to_unsigned(num_digits));
3070 for (int i = 0; i < num_digits - 1; ++i) {
3071 int digit = numerator.divmod_assign(denominator);
3072 buf[i] = static_cast<char>('0' + digit);
3073 numerator *= 10;
3074 }
3075 int digit = numerator.divmod_assign(denominator);
3076 auto result = add_compare(numerator, numerator, denominator);
3077 if (result > 0 || (result == 0 && (digit % 2) != 0)) {
3078 if (digit == 9) {
3079 const auto overflow = '0' + 10;
3080 buf[num_digits - 1] = overflow;
3081 // Propagate the carry.
3082 for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
3083 buf[i] = '0';
3084 ++buf[i - 1];
3085 }
3086 if (buf[0] == overflow) {
3087 buf[0] = '1';
3088 ++exp10;
3089 }
3090 return;
3091 }
3092 ++digit;
3093 }
3094 buf[num_digits - 1] = static_cast<char>('0' + digit);
3095}
3096
3097template <typename Float>
3098FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
3099 buffer<char>& buf) -> int {
3100 // float is passed as double to reduce the number of instantiations.
3101 static_assert(!std::is_same<Float, float>::value, "");
3102 FMT_ASSERT(value >= 0, "value is negative");
3103 auto converted_value = convert_float(value);
3104
3105 const bool fixed = specs.format == float_format::fixed;
3106 if (value <= 0) { // <= instead of == to silence a warning.
3107 if (precision <= 0 || !fixed) {
3108 buf.push_back('0');
3109 return 0;
3110 }
3111 buf.try_resize(to_unsigned(precision));
3112 fill_n(buf.data(), precision, '0');
3113 return -precision;
3114 }
3115
3116 int exp = 0;
3117 bool use_dragon = true;
3118 unsigned dragon_flags = 0;
3119 if (!is_fast_float<Float>()) {
3120 const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10)
3121 using info = dragonbox::float_info<decltype(converted_value)>;
3122 const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3123 // Compute exp, an approximate power of 10, such that
3124 // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3125 // This is based on log10(value) == log2(value) / log2(10) and approximation
3126 // of log2(value) by e + num_fraction_bits idea from double-conversion.
3127 exp = static_cast<int>(
3128 std::ceil((f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10));
3129 dragon_flags = dragon::fixup;
3130 } else if (!is_constant_evaluated() && precision < 0) {
3131 // Use Dragonbox for the shortest format.
3132 if (specs.binary32) {
3133 auto dec = dragonbox::to_decimal(static_cast<float>(value));
3134 write<char>(buffer_appender<char>(buf), dec.significand);
3135 return dec.exponent;
3136 }
3137 auto dec = dragonbox::to_decimal(static_cast<double>(value));
3138 write<char>(buffer_appender<char>(buf), dec.significand);
3139 return dec.exponent;
3140 } else {
3141 // Use Grisu + Dragon4 for the given precision:
3142 // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf.
3143 const int min_exp = -60; // alpha in Grisu.
3144 int cached_exp10 = 0; // K in Grisu.
3145 fp normalized = normalize(fp(converted_value));
3146 const auto cached_pow = get_cached_power(
3147 min_exp - (normalized.e + fp::num_significand_bits), cached_exp10);
3148 normalized = normalized * cached_pow;
3149 gen_digits_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
3150 if (grisu_gen_digits(normalized, 1, exp, handler) != digits::error &&
3152 exp += handler.exp10;
3153 buf.try_resize(to_unsigned(handler.size));
3154 use_dragon = false;
3155 } else {
3156 exp += handler.size - cached_exp10 - 1;
3157 precision = handler.precision;
3158 }
3159 }
3160 if (use_dragon) {
3161 auto f = basic_fp<uint128_t>();
3162 bool is_predecessor_closer = specs.binary32
3163 ? f.assign(static_cast<float>(value))
3164 : f.assign(converted_value);
3165 if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3166 if (fixed) dragon_flags |= dragon::fixed;
3167 // Limit precision to the maximum possible number of significant digits in
3168 // an IEEE754 double because we don't need to generate zeros.
3169 const int max_double_digits = 767;
3170 if (precision > max_double_digits) precision = max_double_digits;
3171 format_dragon(f, dragon_flags, precision, buf, exp);
3172 }
3173 if (!fixed && !specs.showpoint) {
3174 // Remove trailing zeros.
3175 auto num_digits = buf.size();
3176 while (num_digits > 0 && buf[num_digits - 1] == '0') {
3177 --num_digits;
3178 ++exp;
3179 }
3180 buf.try_resize(num_digits);
3181 }
3182 return exp;
3183}
3184
3185template <typename Char, typename OutputIt, typename T,
3186 FMT_ENABLE_IF(is_floating_point<T>::value)>
3187FMT_CONSTEXPR20 auto write(OutputIt out, T value,
3188 basic_format_specs<Char> specs, locale_ref loc = {})
3189 -> OutputIt {
3191 float_specs fspecs = parse_float_type_spec(specs);
3192 fspecs.sign = specs.sign;
3193 if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit.
3194 fspecs.sign = sign::minus;
3195 value = -value;
3196 } else if (fspecs.sign == sign::minus) {
3197 fspecs.sign = sign::none;
3198 }
3199
3200 if (!detail::isfinite(value))
3201 return write_nonfinite(out, detail::isnan(value), specs, fspecs);
3202
3203 if (specs.align == align::numeric && fspecs.sign) {
3204 auto it = reserve(out, 1);
3205 *it++ = detail::sign<Char>(fspecs.sign);
3206 out = base_iterator(out, it);
3207 fspecs.sign = sign::none;
3208 if (specs.width != 0) --specs.width;
3209 }
3210
3212 if (fspecs.format == float_format::hex) {
3213 if (fspecs.sign) buffer.push_back(detail::sign<char>(fspecs.sign));
3215 return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
3216 specs);
3217 }
3218 int precision = specs.precision >= 0 || specs.type == presentation_type::none
3219 ? specs.precision
3220 : 6;
3221 if (fspecs.format == float_format::exp) {
3222 if (precision == max_value<int>())
3223 throw_format_error("number is too big");
3224 else
3225 ++precision;
3226 } else if (fspecs.format != float_format::fixed && precision == 0) {
3227 precision = 1;
3228 }
3229 if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
3230 int exp = format_float(convert_float(value), precision, fspecs, buffer);
3231 fspecs.precision = precision;
3232 auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3233 return write_float(out, f, specs, fspecs, loc);
3234}
3235
3236template <typename Char, typename OutputIt, typename T,
3237 FMT_ENABLE_IF(is_fast_float<T>::value)>
3238FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3240 return write(out, value, basic_format_specs<Char>());
3242
3243 auto fspecs = float_specs();
3244 if (detail::signbit(value)) {
3245 fspecs.sign = sign::minus;
3246 value = -value;
3247 }
3248
3249 constexpr auto specs = basic_format_specs<Char>();
3250 using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
3251 using uint = typename dragonbox::float_info<floaty>::carrier_uint;
3252 uint mask = exponent_mask<floaty>();
3253 if ((bit_cast<uint>(value) & mask) == mask)
3254 return write_nonfinite(out, std::isnan(value), specs, fspecs);
3255
3256 auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
3257 return write_float(out, dec, specs, fspecs, {});
3258}
3259
3260template <typename Char, typename OutputIt, typename T,
3261 FMT_ENABLE_IF(is_floating_point<T>::value &&
3262 !is_fast_float<T>::value)>
3263inline auto write(OutputIt out, T value) -> OutputIt {
3264 return write(out, value, basic_format_specs<Char>());
3265}
3266
3267template <typename Char, typename OutputIt>
3269 locale_ref = {}) -> OutputIt {
3270 FMT_ASSERT(false, "");
3271 return out;
3272}
3273
3274template <typename Char, typename OutputIt>
3276 -> OutputIt {
3277 auto it = reserve(out, value.size());
3278 it = copy_str_noinline<Char>(value.begin(), value.end(), it);
3279 return base_iterator(out, it);
3280}
3281
3282template <typename Char, typename OutputIt, typename T,
3284constexpr auto write(OutputIt out, const T& value) -> OutputIt {
3285 return write<Char>(out, to_string_view(value));
3286}
3287
3288// FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
3289template <
3290 typename Char, typename OutputIt, typename T,
3291 bool check =
3292 std::is_enum<T>::value && !std::is_same<T, Char>::value &&
3295 FMT_ENABLE_IF(check)>
3296FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
3297 return write<Char>(out, static_cast<underlying_t<T>>(value));
3298}
3299
3300template <typename Char, typename OutputIt, typename T,
3301 FMT_ENABLE_IF(std::is_same<T, bool>::value)>
3302FMT_CONSTEXPR auto write(OutputIt out, T value,
3303 const basic_format_specs<Char>& specs = {},
3304 locale_ref = {}) -> OutputIt {
3305 return specs.type != presentation_type::none &&
3307 ? write(out, value ? 1 : 0, specs, {})
3308 : write_bytes(out, value ? "true" : "false", specs);
3309}
3310
3311template <typename Char, typename OutputIt>
3312FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
3313 auto it = reserve(out, 1);
3314 *it++ = value;
3315 return base_iterator(out, it);
3316}
3317
3318template <typename Char, typename OutputIt>
3319FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
3320 -> OutputIt {
3321 if (!value) {
3322 throw_format_error("string pointer is null");
3323 } else {
3324 out = write(out, basic_string_view<Char>(value));
3325 }
3326 return out;
3327}
3328
3329template <typename Char, typename OutputIt, typename T,
3330 FMT_ENABLE_IF(std::is_same<T, void>::value)>
3331auto write(OutputIt out, const T* value,
3332 const basic_format_specs<Char>& specs = {}, locale_ref = {})
3333 -> OutputIt {
3335 return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
3336}
3337
3338// A write overload that handles implicit conversions.
3339template <typename Char, typename OutputIt, typename T,
3340 typename Context = basic_format_context<OutputIt, Char>>
3341FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> enable_if_t<
3342 std::is_class<T>::value && !is_string<T>::value &&
3343 !is_floating_point<T>::value && !std::is_same<T, Char>::value &&
3344 !std::is_same<const T&,
3345 decltype(arg_mapper<Context>().map(value))>::value,
3346 OutputIt> {
3347 return write<Char>(out, arg_mapper<Context>().map(value));
3348}
3349
3350template <typename Char, typename OutputIt, typename T,
3351 typename Context = basic_format_context<OutputIt, Char>>
3352FMT_CONSTEXPR auto write(OutputIt out, const T& value)
3354 OutputIt> {
3355 using formatter_type =
3357 typename Context::template formatter_type<T>,
3359 auto ctx = Context(out, {}, {});
3360 return formatter_type().format(value, ctx);
3361}
3362
3363// An argument visitor that formats the argument and writes it via the output
3364// iterator. It's a class and not a generic lambda for compatibility with C++11.
3365template <typename Char> struct default_arg_formatter {
3368
3372
3373 template <typename T> auto operator()(T value) -> iterator {
3374 return write<Char>(out, value);
3375 }
3378 context format_ctx(out, args, loc);
3379 h.format(parse_ctx, format_ctx);
3380 return format_ctx.out();
3381 }
3382};
3383
3384template <typename Char> struct arg_formatter {
3387
3391
3392 template <typename T>
3394 return detail::write(out, value, specs, locale);
3395 }
3397 // User-defined types are handled separately because they require access
3398 // to the parse context.
3399 return out;
3400 }
3401};
3402
3403template <typename Char> struct custom_formatter {
3406
3408 typename basic_format_arg<buffer_context<Char>>::handle h) const {
3409 h.format(parse_ctx, ctx);
3410 }
3411 template <typename T> void operator()(T) const {}
3412};
3413
3414template <typename T>
3416 bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
3417 !std::is_same<T, char>::value &&
3418 !std::is_same<T, wchar_t>::value>;
3419
3420template <typename ErrorHandler> class width_checker {
3421 public:
3422 explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}
3423
3424 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3425 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3426 if (is_negative(value)) handler_.on_error("negative width");
3427 return static_cast<unsigned long long>(value);
3428 }
3429
3430 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3431 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3432 handler_.on_error("width is not integer");
3433 return 0;
3434 }
3435
3436 private:
3437 ErrorHandler& handler_;
3438};
3439
3440template <typename ErrorHandler> class precision_checker {
3441 public:
3442 explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}
3443
3444 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3445 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3446 if (is_negative(value)) handler_.on_error("negative precision");
3447 return static_cast<unsigned long long>(value);
3448 }
3449
3450 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3451 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3452 handler_.on_error("precision is not integer");
3453 return 0;
3454 }
3455
3456 private:
3457 ErrorHandler& handler_;
3458};
3459
3460template <template <typename> class Handler, typename FormatArg,
3461 typename ErrorHandler>
3462FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int {
3463 unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg);
3464 if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big");
3465 return static_cast<int>(value);
3466}
3467
3468template <typename Context, typename ID>
3469FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) ->
3470 typename Context::format_arg {
3471 auto arg = ctx.arg(id);
3472 if (!arg) ctx.on_error("argument not found");
3473 return arg;
3474}
3475
3476// The standard format specifier handler with checking.
3477template <typename Char> class specs_handler : public specs_setter<Char> {
3478 private:
3479 basic_format_parse_context<Char>& parse_context_;
3480 buffer_context<Char>& context_;
3481
3482 // This is only needed for compatibility with gcc 4.4.
3484
3486 return detail::get_arg(context_, parse_context_.next_arg_id());
3487 }
3488
3489 FMT_CONSTEXPR auto get_arg(int arg_id) -> format_arg {
3490 parse_context_.check_arg_id(arg_id);
3491 return detail::get_arg(context_, arg_id);
3492 }
3493
3495 parse_context_.check_arg_id(arg_id);
3496 return detail::get_arg(context_, arg_id);
3497 }
3498
3499 public:
3503 : specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {}
3504
3505 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
3506 this->specs_.width = get_dynamic_spec<width_checker>(
3507 get_arg(arg_id), context_.error_handler());
3508 }
3509
3510 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
3511 this->specs_.precision = get_dynamic_spec<precision_checker>(
3512 get_arg(arg_id), context_.error_handler());
3513 }
3514
3515 void on_error(const char* message) { context_.on_error(message); }
3516};
3517
3518template <template <typename> class Handler, typename Context>
3521 Context& ctx) {
3522 switch (ref.kind) {
3523 case arg_id_kind::none:
3524 break;
3525 case arg_id_kind::index:
3526 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.index),
3527 ctx.error_handler());
3528 break;
3529 case arg_id_kind::name:
3530 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
3531 ctx.error_handler());
3532 break;
3533 }
3534}
3535
3536#if FMT_USE_USER_DEFINED_LITERALS
3537template <typename Char> struct udl_formatter {
3539
3540 template <typename... T>
3541 auto operator()(T&&... args) const -> std::basic_string<Char> {
3542 return vformat(str, fmt::make_format_args<buffer_context<Char>>(args...));
3543 }
3544};
3545
3546# if FMT_USE_NONTYPE_TEMPLATE_ARGS
3547template <typename T, typename Char, size_t N,
3548 fmt::detail_exported::fixed_string<Char, N> Str>
3549struct statically_named_arg : view {
3550 static constexpr auto name = Str.data;
3551
3552 const T& value;
3553 statically_named_arg(const T& v) : value(v) {}
3554};
3555
3556template <typename T, typename Char, size_t N,
3557 fmt::detail_exported::fixed_string<Char, N> Str>
3558struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
3559
3560template <typename T, typename Char, size_t N,
3561 fmt::detail_exported::fixed_string<Char, N> Str>
3562struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
3563 : std::true_type {};
3564
3565template <typename Char, size_t N,
3566 fmt::detail_exported::fixed_string<Char, N> Str>
3567struct udl_arg {
3568 template <typename T> auto operator=(T&& value) const {
3569 return statically_named_arg<T, Char, N, Str>(std::forward<T>(value));
3570 }
3571};
3572# else
3573template <typename Char> struct udl_arg {
3574 const Char* str;
3575
3576 template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
3577 return {str, std::forward<T>(value)};
3578 }
3579};
3580# endif
3581#endif // FMT_USE_USER_DEFINED_LITERALS
3582
3583template <typename Locale, typename Char>
3584auto vformat(const Locale& loc, basic_string_view<Char> format_str,
3586 -> std::basic_string<Char> {
3588 detail::vformat_to(buffer, format_str, args, detail::locale_ref(loc));
3589 return {buffer.data(), buffer.size()};
3590}
3591
3592using format_func = void (*)(detail::buffer<char>&, int, const char*);
3593
3594FMT_API void format_error_code(buffer<char>& out, int error_code,
3595 string_view message) noexcept;
3596
3597FMT_API void report_error(format_func func, int error_code,
3598 const char* message) noexcept;
3600
3601FMT_API auto vsystem_error(int error_code, string_view format_str,
3603
3604/**
3605 \rst
3606 Constructs :class:`std::system_error` with a message formatted with
3607 ``fmt::format(fmt, args...)``.
3608 *error_code* is a system error code as given by ``errno``.
3609
3610 **Example**::
3611
3612 // This throws std::system_error with the description
3613 // cannot open file 'madeup': No such file or directory
3614 // or similar (system message may vary).
3615 const char* filename = "madeup";
3616 std::FILE* file = std::fopen(filename, "r");
3617 if (!file)
3618 throw fmt::system_error(errno, "cannot open file '{}'", filename);
3619 \endrst
3620*/
3621template <typename... T>
3622auto system_error(int error_code, format_string<T...> fmt, T&&... args)
3624 return vsystem_error(error_code, fmt, fmt::make_format_args(args...));
3625}
3626
3627/**
3628 \rst
3629 Formats an error message for an error returned by an operating system or a
3630 language runtime, for example a file opening error, and writes it to *out*.
3631 The format is the same as the one used by ``std::system_error(ec, message)``
3632 where ``ec`` is ``std::error_code(error_code, std::generic_category()})``.
3633 It is implementation-defined but normally looks like:
3634
3635 .. parsed-literal::
3636 *<message>*: *<system-message>*
3637
3638 where *<message>* is the passed message and *<system-message>* is the system
3639 message corresponding to the error code.
3640 *error_code* is a system error code as given by ``errno``.
3641 \endrst
3642 */
3643FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
3644 const char* message) noexcept;
3645
3646// Reports a system error without throwing an exception.
3647// Can be used to report errors from destructors.
3648FMT_API void report_system_error(int error_code, const char* message) noexcept;
3649
3650/** Fast integer formatter. */
3652 private:
3653 // Buffer should be large enough to hold all digits (digits10 + 1),
3654 // a sign and a null character.
3655 enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
3656 mutable char buffer_[buffer_size];
3657 char* str_;
3658
3659 template <typename UInt> auto format_unsigned(UInt value) -> char* {
3660 auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
3661 return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
3662 }
3663
3664 template <typename Int> auto format_signed(Int value) -> char* {
3665 auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
3666 bool negative = value < 0;
3667 if (negative) abs_value = 0 - abs_value;
3668 auto begin = format_unsigned(abs_value);
3669 if (negative) *--begin = '-';
3670 return begin;
3671 }
3672
3673 public:
3674 explicit format_int(int value) : str_(format_signed(value)) {}
3675 explicit format_int(long value) : str_(format_signed(value)) {}
3676 explicit format_int(long long value) : str_(format_signed(value)) {}
3677 explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
3678 explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
3679 explicit format_int(unsigned long long value)
3680 : str_(format_unsigned(value)) {}
3681
3682 /** Returns the number of characters written to the output buffer. */
3683 auto size() const -> size_t {
3684 return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
3685 }
3686
3687 /**
3688 Returns a pointer to the output buffer content. No terminating null
3689 character is appended.
3690 */
3691 auto data() const -> const char* { return str_; }
3692
3693 /**
3694 Returns a pointer to the output buffer content with terminating null
3695 character appended.
3696 */
3697 auto c_str() const -> const char* {
3698 buffer_[buffer_size - 1] = '\0';
3699 return str_;
3700 }
3701
3702 /**
3703 \rst
3704 Returns the content of the output buffer as an ``std::string``.
3705 \endrst
3706 */
3707 auto str() const -> std::string { return std::string(str_, size()); }
3708};
3709
3710template <typename T, typename Char>
3711template <typename FormatContext>
3713formatter<T, Char,
3715 detail::type::custom_type>>::format(const T& val,
3716 FormatContext& ctx)
3717 const -> decltype(ctx.out()) {
3718 if (specs_.width_ref.kind != detail::arg_id_kind::none ||
3719 specs_.precision_ref.kind != detail::arg_id_kind::none) {
3720 auto specs = specs_;
3721 detail::handle_dynamic_spec<detail::width_checker>(specs.width,
3722 specs.width_ref, ctx);
3723 detail::handle_dynamic_spec<detail::precision_checker>(
3724 specs.precision, specs.precision_ref, ctx);
3725 return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
3726 }
3727 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
3728}
3729
3730template <typename Char>
3732 template <typename FormatContext>
3733 auto format(void* val, FormatContext& ctx) const -> decltype(ctx.out()) {
3734 return formatter<const void*, Char>::format(val, ctx);
3735 }
3736};
3737
3738template <typename Char, size_t N>
3739struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
3740 template <typename FormatContext>
3741 FMT_CONSTEXPR auto format(const Char* val, FormatContext& ctx) const
3742 -> decltype(ctx.out()) {
3743 return formatter<basic_string_view<Char>, Char>::format(val, ctx);
3744 }
3745};
3746
3747// A formatter for types known only at run time such as variant alternatives.
3748//
3749// Usage:
3750// using variant = std::variant<int, std::string>;
3751// template <>
3752// struct formatter<variant>: dynamic_formatter<> {
3753// auto format(const variant& v, format_context& ctx) {
3754// return visit([&](const auto& val) {
3755// return dynamic_formatter<>::format(val, ctx);
3756// }, v);
3757// }
3758// };
3759template <typename Char = char> class dynamic_formatter {
3760 private:
3761 detail::dynamic_format_specs<Char> specs_;
3762 const Char* format_str_;
3763
3764 struct null_handler : detail::error_handler {
3765 void on_align(align_t) {}
3766 void on_sign(sign_t) {}
3767 void on_hash() {}
3768 };
3769
3770 template <typename Context> void handle_specs(Context& ctx) {
3771 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
3772 specs_.width_ref, ctx);
3773 detail::handle_dynamic_spec<detail::precision_checker>(
3774 specs_.precision, specs_.precision_ref, ctx);
3775 }
3776
3777 public:
3778 template <typename ParseContext>
3779 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3780 format_str_ = ctx.begin();
3781 // Checks are deferred to formatting time when the argument type is known.
3782 detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
3783 return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
3784 }
3785
3786 template <typename T, typename FormatContext>
3787 auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3788 handle_specs(ctx);
3789 detail::specs_checker<null_handler> checker(
3790 null_handler(), detail::mapped_type_constant<T, FormatContext>::value);
3791 checker.on_align(specs_.align);
3792 if (specs_.sign != sign::none) checker.on_sign(specs_.sign);
3793 if (specs_.alt) checker.on_hash();
3794 if (specs_.precision >= 0) checker.end_precision();
3795 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
3796 }
3797};
3798
3799/**
3800 \rst
3801 Converts ``p`` to ``const void*`` for pointer formatting.
3802
3803 **Example**::
3804
3805 auto s = fmt::format("{}", fmt::ptr(p));
3806 \endrst
3807 */
3808template <typename T> auto ptr(T p) -> const void* {
3809 static_assert(std::is_pointer<T>::value, "");
3810 return detail::bit_cast<const void*>(p);
3811}
3812template <typename T> auto ptr(const std::unique_ptr<T>& p) -> const void* {
3813 return p.get();
3814}
3815template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
3816 return p.get();
3817}
3818
3819/**
3820 \rst
3821 Converts ``e`` to the underlying type.
3822
3823 **Example**::
3824
3825 enum class color { red, green, blue };
3826 auto s = fmt::format("{}", fmt::underlying(color::red));
3827 \endrst
3828 */
3829template <typename Enum>
3830constexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {
3831 return static_cast<underlying_t<Enum>>(e);
3832}
3833
3834namespace enums {
3835template <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
3836constexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {
3837 return static_cast<underlying_t<Enum>>(e);
3838}
3839} // namespace enums
3840
3841class bytes {
3842 private:
3844 friend struct formatter<bytes>;
3845
3846 public:
3847 explicit bytes(string_view data) : data_(data) {}
3848};
3849
3850template <> struct formatter<bytes> {
3851 private:
3852 detail::dynamic_format_specs<char> specs_;
3853
3854 public:
3855 template <typename ParseContext>
3856 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3857 using handler_type = detail::dynamic_specs_handler<ParseContext>;
3858 detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
3859 detail::type::string_type);
3860 auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
3861 detail::check_string_type_spec(specs_.type, ctx.error_handler());
3862 return it;
3863 }
3864
3865 template <typename FormatContext>
3866 auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
3867 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
3868 specs_.width_ref, ctx);
3869 detail::handle_dynamic_spec<detail::precision_checker>(
3870 specs_.precision, specs_.precision_ref, ctx);
3871 return detail::write_bytes(ctx.out(), b.data_, specs_);
3872 }
3873};
3874
3875// group_digits_view is not derived from view because it copies the argument.
3876template <typename T> struct group_digits_view { T value; };
3877
3878/**
3879 \rst
3880 Returns a view that formats an integer value using ',' as a locale-independent
3881 thousands separator.
3882
3883 **Example**::
3884
3885 fmt::print("{}", fmt::group_digits(12345));
3886 // Output: "12,345"
3887 \endrst
3888 */
3889template <typename T> auto group_digits(T value) -> group_digits_view<T> {
3890 return {value};
3891}
3892
3893template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
3894 private:
3895 detail::dynamic_format_specs<char> specs_;
3896
3897 public:
3898 template <typename ParseContext>
3899 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3900 using handler_type = detail::dynamic_specs_handler<ParseContext>;
3901 detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
3902 detail::type::int_type);
3903 auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
3904 detail::check_string_type_spec(specs_.type, ctx.error_handler());
3905 return it;
3906 }
3907
3908 template <typename FormatContext>
3909 auto format(group_digits_view<T> t, FormatContext& ctx)
3910 -> decltype(ctx.out()) {
3911 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
3912 specs_.width_ref, ctx);
3913 detail::handle_dynamic_spec<detail::precision_checker>(
3914 specs_.precision, specs_.precision_ref, ctx);
3916 ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_,
3917 detail::digit_grouping<char>({"\3", ','}));
3918 }
3919};
3920
3921template <typename It, typename Sentinel, typename Char = char>
3922struct join_view : detail::view {
3924 Sentinel end;
3926
3928 : begin(b), end(e), sep(s) {}
3929};
3930
3931template <typename It, typename Sentinel, typename Char>
3932struct formatter<join_view<It, Sentinel, Char>, Char> {
3933 private:
3934 using value_type =
3935#ifdef __cpp_lib_ranges
3936 std::iter_value_t<It>;
3937#else
3938 typename std::iterator_traits<It>::value_type;
3939#endif
3941 using mapper = detail::arg_mapper<context>;
3942
3943 template <typename T, FMT_ENABLE_IF(has_formatter<T, context>::value)>
3944 static auto map(const T& value) -> const T& {
3945 return value;
3946 }
3947 template <typename T, FMT_ENABLE_IF(!has_formatter<T, context>::value)>
3948 static auto map(const T& value) -> decltype(mapper().map(value)) {
3949 return mapper().map(value);
3950 }
3951
3952 using formatter_type =
3954 formatter<remove_cvref_t<decltype(map(
3955 std::declval<const value_type&>()))>,
3956 Char>,
3957 detail::fallback_formatter<value_type, Char>>;
3958
3959 formatter_type value_formatter_;
3960
3961 public:
3962 template <typename ParseContext>
3963 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3964 return value_formatter_.parse(ctx);
3965 }
3966
3967 template <typename FormatContext>
3969 FormatContext& ctx) const -> decltype(ctx.out()) {
3970 auto it = value.begin;
3971 auto out = ctx.out();
3972 if (it != value.end) {
3973 out = value_formatter_.format(map(*it), ctx);
3974 ++it;
3975 while (it != value.end) {
3976 out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
3977 ctx.advance_to(out);
3978 out = value_formatter_.format(map(*it), ctx);
3979 ++it;
3980 }
3981 }
3982 return out;
3983 }
3984};
3985
3986/**
3987 Returns a view that formats the iterator range `[begin, end)` with elements
3988 separated by `sep`.
3989 */
3990template <typename It, typename Sentinel>
3992 return {begin, end, sep};
3993}
3994
3995/**
3996 \rst
3997 Returns a view that formats `range` with elements separated by `sep`.
3998
3999 **Example**::
4000
4001 std::vector<int> v = {1, 2, 3};
4002 fmt::print("{}", fmt::join(v, ", "));
4003 // Output: "1, 2, 3"
4004
4005 ``fmt::join`` applies passed format specifiers to the range elements::
4006
4007 fmt::print("{:02}", fmt::join(v, ", "));
4008 // Output: "01, 02, 03"
4009 \endrst
4010 */
4011template <typename Range>
4012auto join(Range&& range, string_view sep)
4014 return join(std::begin(range), std::end(range), sep);
4015}
4016
4017/**
4018 \rst
4019 Converts *value* to ``std::string`` using the default format for type *T*.
4020
4021 **Example**::
4022
4023 #include <fmt/format.h>
4024
4025 std::string answer = fmt::to_string(42);
4026 \endrst
4027 */
4028template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
4029inline auto to_string(const T& value) -> std::string {
4030 auto result = std::string();
4031 detail::write<char>(std::back_inserter(result), value);
4032 return result;
4033}
4034
4035template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
4036FMT_NODISCARD inline auto to_string(T value) -> std::string {
4037 // The buffer should be large enough to store the number including the sign
4038 // or "false" for bool.
4039 constexpr int max_size = detail::digits10<T>() + 2;
4040 char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
4041 char* begin = buffer;
4042 return std::string(begin, detail::write<char>(begin, value));
4043}
4044
4045template <typename Char, size_t SIZE>
4047 -> std::basic_string<Char> {
4048 auto size = buf.size();
4049 detail::assume(size < std::basic_string<Char>().max_size());
4050 return std::basic_string<Char>(buf.data(), size);
4051}
4052
4054
4055template <typename Char>
4059 locale_ref loc) {
4060 // workaround for msvc bug regarding name-lookup in module
4061 // link names into function scope
4062 using detail::arg_formatter;
4064 using detail::custom_formatter;
4065 using detail::default_arg_formatter;
4066 using detail::get_arg;
4067 using detail::locale_ref;
4069 using detail::specs_checker;
4070 using detail::specs_handler;
4071 using detail::to_unsigned;
4072 using detail::type;
4073 using detail::write;
4074 auto out = buffer_appender<Char>(buf);
4075 if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
4076 auto arg = args.get(0);
4077 if (!arg) error_handler().on_error("argument not found");
4079 return;
4080 }
4081
4082 struct format_handler : error_handler {
4084 buffer_context<Char> context;
4085
4086 format_handler(buffer_appender<Char> p_out, basic_string_view<Char> str,
4088 locale_ref p_loc)
4089 : parse_context(str), context(p_out, p_args, p_loc) {}
4090
4091 void on_text(const Char* begin, const Char* end) {
4093 context.advance_to(write<Char>(context.out(), text));
4094 }
4095
4096 FMT_CONSTEXPR auto on_arg_id() -> int {
4097 return parse_context.next_arg_id();
4098 }
4099 FMT_CONSTEXPR auto on_arg_id(int id) -> int {
4100 return parse_context.check_arg_id(id), id;
4101 }
4102 FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
4103 int arg_id = context.arg_id(id);
4104 if (arg_id < 0) on_error("argument not found");
4105 return arg_id;
4106 }
4107
4108 FMT_INLINE void on_replacement_field(int id, const Char*) {
4109 auto arg = get_arg(context, id);
4111 default_arg_formatter<Char>{context.out(), context.args(),
4112 context.locale()},
4113 arg));
4114 }
4115
4116 auto on_format_specs(int id, const Char* begin, const Char* end)
4117 -> const Char* {
4118 auto arg = get_arg(context, id);
4119 if (arg.type() == type::custom_type) {
4120 parse_context.advance_to(parse_context.begin() +
4121 (begin - &*parse_context.begin()));
4122 visit_format_arg(custom_formatter<Char>{parse_context, context}, arg);
4123 return parse_context.begin();
4124 }
4125 auto specs = basic_format_specs<Char>();
4127 specs_handler<Char>(specs, parse_context, context), arg.type());
4128 begin = parse_format_specs(begin, end, handler);
4129 if (begin == end || *begin != '}')
4130 on_error("missing '}' in format string");
4131 auto f = arg_formatter<Char>{context.out(), specs, context.locale()};
4132 context.advance_to(visit_format_arg(f, arg));
4133 return begin;
4134 }
4135 };
4136 detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
4137}
4138
4139#ifndef FMT_HEADER_ONLY
4144extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
4145extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
4146#endif // FMT_HEADER_ONLY
4147
4149
4150#if FMT_USE_USER_DEFINED_LITERALS
4151inline namespace literals {
4152/**
4153 \rst
4154 User-defined literal equivalent of :func:`fmt::arg`.
4155
4156 **Example**::
4157
4158 using namespace fmt::literals;
4159 fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
4160 \endrst
4161 */
4162# if FMT_USE_NONTYPE_TEMPLATE_ARGS
4163template <detail_exported::fixed_string Str> constexpr auto operator""_a() {
4164 using char_t = remove_cvref_t<decltype(Str.data[0])>;
4165 return detail::udl_arg<char_t, sizeof(Str.data) / sizeof(char_t), Str>();
4166}
4167# else
4168constexpr auto operator"" _a(const char* s, size_t) -> detail::udl_arg<char> {
4169 return {s};
4170}
4171# endif
4172} // namespace literals
4173#endif // FMT_USE_USER_DEFINED_LITERALS
4174
4175template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4176inline auto vformat(const Locale& loc, string_view fmt, format_args args)
4177 -> std::string {
4178 return detail::vformat(loc, fmt, args);
4179}
4180
4181template <typename Locale, typename... T,
4182 FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4183inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
4184 -> std::string {
4185 return vformat(loc, string_view(fmt), fmt::make_format_args(args...));
4186}
4187
4188template <typename OutputIt, typename Locale,
4189 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
4190 detail::is_locale<Locale>::value)>
4191auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
4192 format_args args) -> OutputIt {
4193 using detail::get_buffer;
4194 auto&& buf = get_buffer<char>(out);
4195 detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
4196 return detail::get_iterator(buf);
4197}
4198
4199template <typename OutputIt, typename Locale, typename... T,
4200 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
4201 detail::is_locale<Locale>::value)>
4202FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
4203 format_string<T...> fmt, T&&... args) -> OutputIt {
4204 return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
4205}
4206
4209
4210#ifdef FMT_HEADER_ONLY
4211# define FMT_FUNC inline
4212# include "format-inl.h"
4213#else
4214# define FMT_FUNC
4215#endif
4216
4217#endif // FMT_FORMAT_H_
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArgReturnType arg() const
Definition: ArrayCwiseUnaryOps.h:66
EIGEN_DEVICE_FUNC const SquareReturnType square() const
Definition: ArrayCwiseUnaryOps.h:425
internal::enable_if< internal::valid_indexed_view_overload< RowIndices, ColIndices >::value &&internal::traits< typenameEIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::ReturnAsIndexedView, typenameEIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::type operator()(const RowIndices &rowIndices, const ColIndices &colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
Definition: IndexedViewMethods.h:73
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source including but not limited to compiled object generated and conversions to other media types Work shall mean the work of whether in Source or Object made available under the as indicated by a copyright notice that is included in or attached to the whether in Source or Object that is based or other modifications as a an original work of authorship For the purposes of this Derivative Works shall not include works that remain separable from
Definition: ThirdPartyNotices.txt:131
Definition: core.h:1543
Definition: core.h:1588
Definition: core.h:1562
\rst A view of a collection of formatting arguments.
Definition: core.h:1948
Definition: core.h:1788
FMT_CONSTEXPR auto locale() -> detail::locale_ref
Definition: core.h:1838
FMT_CONSTEXPR auto out() -> iterator
Definition: core.h:1831
FMT_CONSTEXPR auto arg_id(basic_string_view< char_type > name) -> int
Definition: core.h:1820
void on_error(const char *message)
Definition: core.h:1828
FMT_CONSTEXPR auto error_handler() -> detail::error_handler
Definition: core.h:1827
auto args() const -> const basic_format_args< basic_format_context > &
Definition: core.h:1823
void advance_to(iterator it)
Definition: core.h:1834
\rst Parsing context consisting of a format string range being parsed and an argument counter for aut...
Definition: core.h:654
FMT_CONSTEXPR void check_arg_id(int id)
Reports an error if using the automatic argument indexing; otherwise switches to the manual indexing.
Definition: core.h:706
FMT_CONSTEXPR auto next_arg_id() -> int
Reports an error if using the manual argument indexing; otherwise returns the next argument index and...
Definition: core.h:692
FMT_CONSTEXPR void advance_to(iterator it)
Advances the begin iterator to it.
Definition: core.h:684
constexpr auto begin() const noexcept -> iterator
Returns an iterator to the beginning of the format string range being parsed.
Definition: core.h:674
A compile-time format string.
Definition: core.h:3140
\rst A dynamically growing memory buffer for trivially copyable/constructible types with the first SI...
Definition: format.h:819
const T & const_reference
Definition: format.h:837
FMT_CONSTEXPR20 void resize(size_t count)
Resizes the buffer to contain count elements.
Definition: format.h:897
FMT_CONSTEXPR20 ~basic_memory_buffer()
Definition: format.h:845
auto operator=(basic_memory_buffer &&other) noexcept -> basic_memory_buffer &
\rst Moves the content of the other basic_memory_buffer object to this one.
Definition: format.h:883
void reserve(size_t new_capacity)
Increases the buffer capacity to new_capacity.
Definition: format.h:900
auto get_allocator() const -> Allocator
Definition: format.h:891
FMT_CONSTEXPR20 void grow(size_t size) override
Definition: format.h:911
void append(const ContiguousRange &range)
Definition: format.h:905
FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer &&other) noexcept
\rst Constructs a :class:fmt::basic_memory_buffer object moving the content of the other object to it...
Definition: format.h:874
T value_type
Definition: format.h:836
An implementation of std::basic_string_view for pre-C++17.
Definition: core.h:430
constexpr auto end() const noexcept -> iterator
Definition: core.h:478
constexpr auto size() const noexcept -> size_t
Returns the string size.
Definition: core.h:475
constexpr auto data() const noexcept -> const Char *
Returns a pointer to the string data.
Definition: core.h:472
constexpr auto begin() const noexcept -> iterator
Definition: core.h:477
Definition: format.h:2707
friend FMT_CONSTEXPR20 int compare(const bigint &lhs, const bigint &rhs)
Definition: format.h:2841
FMT_CONSTEXPR20 void assign_pow10(int exp)
Definition: format.h:2884
FMT_CONSTEXPR20 bigint()
Definition: format.h:2797
bigint(const bigint &)=delete
FMT_CONSTEXPR20 void assign(const bigint &other)
Definition: format.h:2803
FMT_CONSTEXPR20 void square()
Definition: format.h:2903
friend FMT_CONSTEXPR20 int add_compare(const bigint &lhs1, const bigint &lhs2, const bigint &rhs)
Definition: format.h:2858
FMT_NOINLINE FMT_CONSTEXPR20 bigint & operator<<=(int shift)
Definition: format.h:2820
FMT_CONSTEXPR20 int divmod_assign(const bigint &divisor)
Definition: format.h:2946
bigint(uint64_t n)
Definition: format.h:2798
FMT_CONSTEXPR20 bigint & operator*=(Int value)
Definition: format.h:2835
FMT_CONSTEXPR20 int num_bigits() const
Definition: format.h:2816
void operator=(const bigint &)=delete
FMT_CONSTEXPR20 void align(const bigint &other)
Definition: format.h:2933
FMT_CONSTEXPR20 void operator=(Int n)
Definition: format.h:2811
void append(const U *begin, const U *end)
Appends data to the end of the buffer.
auto end() noexcept -> T *
Definition: core.h:896
FMT_CONSTEXPR20 void push_back(const T &value)
Definition: core.h:931
FMT_CONSTEXPR auto data() noexcept -> T *
Returns a pointer to the buffer data.
Definition: core.h:908
FMT_CONSTEXPR20 void try_resize(size_t count)
Definition: core.h:918
constexpr auto size() const noexcept -> size_t
Returns the size of this buffer.
Definition: core.h:902
Definition: format.h:3841
bytes(string_view data)
Definition: format.h:3847
Definition: format.h:2138
std::ptrdiff_t difference_type
Definition: format.h:2144
void pointer
Definition: format.h:2145
FMT_CONSTEXPR value_type operator*() const
Definition: format.h:2173
FMT_CONSTEXPR size_t count() const
Definition: format.h:2155
FMT_CONSTEXPR friend counting_iterator operator+(counting_iterator it, difference_type n)
Definition: format.h:2167
std::output_iterator_tag iterator_category
Definition: format.h:2143
FMT_CONSTEXPR counting_iterator & operator++()
Definition: format.h:2157
FMT_UNCHECKED_ITERATOR(counting_iterator)
void reference
Definition: format.h:2146
FMT_CONSTEXPR counting_iterator operator++(int)
Definition: format.h:2161
FMT_CONSTEXPR counting_iterator()
Definition: format.h:2153
Definition: format.h:264
auto xsputn(const char_type *s, streamsize count) -> streamsize override
Definition: format.h:289
auto overflow(int_type ch) -> int_type override
Definition: format.h:283
formatbuf(buffer< char_type > &buf)
Definition: format.h:274
Definition: format.h:322
FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback &
Definition: format.h:390
constexpr uint64_t low() const noexcept
Definition: format.h:333
friend uint128_fallback umul128(uint64_t x, uint64_t y) noexcept
Definition: format-inl.h:145
constexpr uint128_fallback(uint64_t hi, uint64_t lo)
Definition: format.h:329
FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback
Definition: format.h:380
friend constexpr auto operator==(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition: format.h:340
friend auto operator-(const uint128_fallback &lhs, uint64_t rhs) -> uint128_fallback
Definition: format.h:376
friend constexpr auto operator|(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition: format.h:352
friend auto operator*(const uint128_fallback &lhs, uint32_t rhs) -> uint128_fallback
Definition: format.h:368
FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback
Definition: format.h:385
FMT_CONSTEXPR20 uint128_fallback & operator+=(uint64_t n) noexcept
Definition: format.h:401
friend constexpr auto operator!=(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition: format.h:344
friend auto operator+(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition: format.h:362
friend constexpr auto operator>(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition: format.h:348
constexpr uint128_fallback(uint64_t value=0)
Definition: format.h:330
FMT_CONSTEXPR void operator+=(uint128_fallback n)
Definition: format.h:393
friend constexpr auto operator&(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition: format.h:357
constexpr uint64_t high() const noexcept
Definition: format.h:332
Definition: format.h:1931
Out apply(Out out, basic_string_view< C > digits) const
Definition: format.h:1972
digit_grouping(thousands_sep_result< Char > sep)
Definition: format.h:1959
digit_grouping(locale_ref loc, bool localized=true)
Definition: format.h:1953
int count_separators(int num_digits) const
Definition: format.h:1963
Char separator() const
Definition: format.h:1961
Definition: format.h:3759
auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3787
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3779
Definition: format.h:2465
constexpr fallback_digit_grouping(locale_ref, bool)
Definition: format.h:2467
constexpr Char separator() const
Definition: format.h:2469
constexpr int count_separators(int) const
Definition: format.h:2471
constexpr Out apply(Out out, basic_string_view< C >) const
Definition: format.h:2474
A formatting error such as invalid format string.
Definition: format.h:949
format_error(const format_error &)=default
format_error & operator=(format_error &&)=default
~format_error() noexcept override FMT_MSC_DEFAULT
format_error & operator=(const format_error &)=default
format_error(format_error &&)=default
format_error(const char *message)
Definition: format.h:951
format_error(const std::string &message)
Definition: format.h:952
Fast integer formatter.
Definition: format.h:3651
format_int(unsigned long long value)
Definition: format.h:3679
auto str() const -> std::string
\rst Returns the content of the output buffer as an std::string.
Definition: format.h:3707
auto size() const -> size_t
Returns the number of characters written to the output buffer.
Definition: format.h:3683
format_int(int value)
Definition: format.h:3674
format_int(long value)
Definition: format.h:3675
format_int(long long value)
Definition: format.h:3676
auto c_str() const -> const char *
Returns a pointer to the output buffer content with terminating null character appended.
Definition: format.h:3697
auto data() const -> const char *
Returns a pointer to the output buffer content.
Definition: format.h:3691
format_int(unsigned value)
Definition: format.h:3677
format_int(unsigned long value)
Definition: format.h:3678
Definition: core.h:1710
Definition: format.h:3440
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition: format.h:3451
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
Definition: format.h:3442
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition: format.h:3445
Definition: core.h:2860
Definition: format.h:3477
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition: format.h:3505
void on_error(const char *message)
Definition: format.h:3515
FMT_CONSTEXPR specs_handler(basic_format_specs< Char > &specs, basic_format_parse_context< Char > &parse_ctx, buffer_context< Char > &ctx)
Definition: format.h:3500
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition: format.h:3510
Definition: core.h:2197
Definition: format.h:1274
auto str() const -> std::wstring
Definition: format.h:1283
auto size() const -> size_t
Definition: format.h:1281
auto c_str() const -> const wchar_t *
Definition: format.h:1282
Definition: core.h:1240
Definition: format.h:3420
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition: format.h:3431
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition: format.h:3425
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
Definition: format.h:3422
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:298
constexpr FMT_INLINE auto const_check(T value) -> T
Definition: core.h:356
#define FMT_ASSERT(condition, message)
Definition: core.h:369
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
\rst Visits an argument dispatching to the appropriate visit method based on the argument type.
Definition: core.h:1623
FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler) -> const Char *
Definition: core.h:2561
std::integral_constant< bool, B > bool_constant
Definition: core.h:301
#define FMT_USE_LONG_DOUBLE
Definition: core.h:192
basic_string_view< char > string_view
Definition: core.h:520
FMT_CONSTEXPR auto code_point_length_impl(char c) -> int
Definition: core.h:2300
align::type align_t
Definition: core.h:2077
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> bool
Definition: core.h:2758
#define FMT_FALLTHROUGH
Definition: core.h:174
#define FMT_NODISCARD
Definition: core.h:181
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:303
uint128_opt
Definition: core.h:400
typename detail::char_t_impl< S >::type char_t
String's character type.
Definition: core.h:644
#define FMT_END_DETAIL_NAMESPACE
Definition: core.h:227
#define FMT_USE_FLOAT
Definition: core.h:186
FMT_CONSTEXPR void check_string_type_spec(presentation_type type, ErrorHandler &&eh={})
Definition: core.h:2844
constexpr auto count() -> size_t
Definition: core.h:1204
#define FMT_CLASS_API
Definition: core.h:238
int128_opt
Definition: core.h:399
constexpr auto make_format_args(Args &&... args) -> format_arg_store< Context, remove_cvref_t< Args >... >
\rst Constructs a ~fmtformat_arg_store object that contains references to arguments and can be implic...
Definition: core.h:1916
#define FMT_CONSTEXPR
Definition: core.h:106
FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type, ErrorHandler &&eh)
Definition: core.h:2852
type
Definition: core.h:575
@ custom_type
#define FMT_BEGIN_NAMESPACE
Definition: core.h:214
#define FMT_BEGIN_DETAIL_NAMESPACE
Definition: core.h:226
#define FMT_API
Definition: core.h:246
FMT_BEGIN_DETAIL_NAMESPACE FMT_CONSTEXPR void ignore_unused(const T &...)
Definition: core.h:343
constexpr FMT_INLINE auto is_constant_evaluated(bool default_value=false) noexcept -> bool
Definition: core.h:345
#define FMT_BUFFER_CONTEXT(Char)
Definition: core.h:1847
constexpr auto is_utf8() -> bool
Definition: core.h:415
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T > > > buffer_appender
Definition: core.h:1106
FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type, ErrorHandler &&eh={}) -> bool
Definition: core.h:2834
FMT_MSC_WARNING(suppress :4566) const expr unsigned char micro[]
auto get_buffer(OutputIt out) -> iterator_buffer< OutputIt, T >
Definition: core.h:1110
#define FMT_ENABLE_IF(...)
Definition: core.h:335
#define FMT_CONSTEXPR_CHAR_TRAITS
Definition: core.h:130
#define FMT_INLINE
Definition: core.h:199
auto get_iterator(Buffer &buf) -> decltype(buf.out())
Definition: core.h:1115
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition: core.h:407
FMT_NORETURN FMT_API void throw_format_error(const char *message)
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:536
typename type_identity< T >::type type_identity_t
Definition: core.h:309
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:300
#define FMT_CONSTEXPR20
Definition: core.h:114
auto get_container(std::back_insert_iterator< Container > it) -> Container &
Definition: core.h:829
sign::type sign_t
Definition: core.h:2081
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition: core.h:307
#define FMT_USE_DOUBLE
Definition: core.h:189
typename std::underlying_type< T >::type underlying_t
Definition: core.h:311
#define FMT_END_NAMESPACE
Definition: core.h:217
#define FMT_MODULE_EXPORT_END
Definition: core.h:225
FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> float_specs
Definition: core.h:2790
FMT_INLINE FMT_CONSTEXPR20 auto grisu_gen_digits(fp value, uint64_t error, int &exp, gen_digits_handler &handler) -> digits::result
Definition: format.h:2615
auto system_error(int error_code, format_string< T... > fmt, T &&... args) -> std::system_error
\rst Constructs :class:std::system_error with a message formatted with fmt::format(fmt,...
Definition: format.h:3622
FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(OutputIt out, write_int_arg< T > arg, const basic_format_specs< Char > &specs, locale_ref loc) -> OutputIt
Definition: format.h:2110
constexpr auto digits10() noexcept -> int
Definition: format.h:1154
FMT_API void report_system_error(int error_code, const char *message) noexcept
Definition: format-inl.h:1461
auto find_escape(const Char *begin, const Char *end) -> find_escape_result< Char >
Definition: format.h:1723
round_direction
Definition: format.h:2532
bool_constant< is_integral< T >::value &&!std::is_same< T, bool >::value &&!std::is_same< T, char >::value &&!std::is_same< T, wchar_t >::value > is_integer
Definition: format.h:3418
constexpr bool isnan(T value)
Definition: format.h:2493
auto decimal_point(locale_ref loc) -> Char
Definition: format.h:1179
FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP &f, const basic_format_specs< Char > &specs, float_specs fspecs, locale_ref loc) -> OutputIt
Definition: format.h:2480
FMT_API auto decimal_point_impl(locale_ref loc) -> Char
FMT_INLINE auto format_to(OutputIt out, const Locale &loc, format_string< T... > fmt, T &&... args) -> OutputIt
Definition: format.h:4202
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const basic_format_specs< Char > &specs) -> OutputIt
Definition: format.h:1678
auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt
Definition: format.h:1775
FMT_API void format_error_code(buffer< char > &out, int error_code, string_view message) noexcept
typename conditional_t< std::is_integral< Char >::value, std::make_unsigned< Char >, type_identity< uint32_t > >::type make_unsigned_char
Definition: format.h:1720
FMT_API void format_system_error(detail::buffer< char > &out, int error_code, const char *message) noexcept
\rst Formats an error message for an error returned by an operating system or a language runtime,...
Definition: format-inl.h:1450
FMT_CONSTEXPR20 auto count_digits(uint64_t n) -> int
Definition: format.h:1093
auto join(It begin, Sentinel end, string_view sep) -> join_view< It, Sentinel >
Returns a view that formats the iterator range [begin, end) with elements separated by sep.
Definition: format.h:3991
auto write_escaped_cp(OutputIt out, const find_escape_result< Char > &escape) -> OutputIt
Definition: format.h:1785
FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It
Definition: format.h:1369
FMT_CONSTEXPR auto count_digits_fallback(T n) -> int
Definition: format.h:1050
FMT_CONSTEXPR20 FMT_INLINE void copy2(Char *dst, const char *src)
Definition: format.h:1196
FMT_END_DETAIL_NAMESPACE FMT_API auto vsystem_error(int error_code, string_view format_str, format_args args) -> std::system_error
Definition: format-inl.h:122
void(*)(detail::buffer< char > &, int, const char *) format_func
Definition: format.h:3592
dragon
Definition: format.h:2961
@ predecessor_closer
Definition: format.h:2962
@ fixup
Definition: format.h:2963
@ fixed
Definition: format.h:2964
FMT_CONSTEXPR20 void format_dragon(basic_fp< uint128_t > value, unsigned flags, int num_digits, buffer< char > &buf, int &exp10)
Definition: format.h:2970
#define FMT_MSC_DEFAULT
Definition: format.h:77
FMT_CONSTEXPR fp operator*(fp x, fp y)
Definition: format.h:1474
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_opt >::value > is_signed
Definition: format.h:996
auto snprintf_float(T value, int precision, float_specs specs, buffer< char > &buf) -> int
Definition: format.h:1579
constexpr Char sign(Sign s)
Definition: format.h:1043
FMT_CONSTEXPR auto write_char(OutputIt out, Char value, const basic_format_specs< Char > &specs) -> OutputIt
Definition: format.h:1862
FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result< Char >
FMT_CONSTEXPR void handle_dynamic_spec(int &value, arg_ref< typename Context::char_type > ref, Context &ctx)
Definition: format.h:3519
constexpr auto convert_float(T value) -> convert_float_result< T >
Definition: format.h:1632
FMT_API void report_error(format_func func, int error_code, const char *message) noexcept
conditional_t< num_bits< T >()<=64, uint64_t, uint128_t > uint64_or_128_t
Definition: format.h:1025
constexpr auto is_negative(T value) -> bool
Definition: format.h:1001
auto write_int_localized(OutputIt out, UInt value, unsigned prefix, const basic_format_specs< Char > &specs, const digit_grouping< Char > &grouping) -> OutputIt
Definition: format.h:1994
FMT_CONSTEXPR20 auto format_decimal(Char *out, UInt value, int size) -> format_decimal_result< Char * >
Definition: format.h:1214
FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int
Definition: format.h:3462
conditional_t< num_bits< T >()<=32 &&!FMT_REDUCE_INT_INSTANTIATIONS, uint32_t, conditional_t< num_bits< T >()<=64, uint64_t, uint128_t > > uint32_or_64_or_128_t
Definition: format.h:1023
constexpr auto exponent_mask() -> typename dragonbox::float_info< Float >::carrier_uint
Definition: format.h:1355
FMT_CONSTEXPR auto write_padded(OutputIt out, const basic_format_specs< Char > &specs, size_t size, size_t width, F &&f) -> OutputIt
Definition: format.h:1652
auto write_escaped_string(OutputIt out, basic_string_view< Char > str) -> OutputIt
Definition: format.h:1832
constexpr auto exponent_bias() -> int
Definition: format.h:1361
template FMT_API auto thousands_sep_impl< char >(locale_ref) -> thousands_sep_result< char >
auto vformat(const Locale &loc, basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char > > > args) -> std::basic_string< Char >
Definition: format.h:3584
conditional_t< std::is_same< T, float >::value||sizeof(T)==sizeof(double), double, T > convert_float_result
Definition: format.h:1629
constexpr bool has_implicit_bit()
Definition: format.h:1340
constexpr const char * digits2(size_t value)
Definition: format.h:1033
FMT_CONSTEXPR void prefix_append(unsigned &prefix, unsigned value)
Definition: format.h:2022
#define FMT_SNPRINTF
Definition: format.h:1571
FMT_INLINE FMT_CONSTEXPR bool signbit(T value)
Definition: format.h:2520
auto to_string(const T &value) -> std::string
\rst Converts value to std::string using the default format for type T.
Definition: format.h:4029
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1637
FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, unsigned prefix, const basic_format_specs< Char > &specs, W write_digits) -> OutputIt
Definition: format.h:1908
basic_memory_buffer< char > memory_buffer
Definition: format.h:934
constexpr int num_significand_bits()
Definition: format.h:1347
auto write_escaped_char(OutputIt out, Char v) -> OutputIt
Definition: format.h:1848
constexpr auto write_significand(OutputIt out, const char *significand, int significand_size) -> OutputIt
Definition: format.h:2271
constexpr auto digits10< int128_opt >() noexcept -> int
Definition: format.h:1157
auto format(const Locale &loc, format_string< T... > fmt, T &&... args) -> std::string
Definition: format.h:4183
auto write_ptr(OutputIt out, UIntPtr value, const basic_format_specs< Char > *specs) -> OutputIt
Definition: format.h:1689
#define FMT_NOINLINE
Definition: format.h:71
FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan, basic_format_specs< Char > specs, const float_specs &fspecs) -> OutputIt
Definition: format.h:2237
FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP &f, const basic_format_specs< Char > &specs, float_specs fspecs, locale_ref loc) -> OutputIt
Definition: format.h:2361
auto group_digits(T value) -> group_digits_view< T >
\rst Returns a view that formats an integer value using ',' as a locale-independent thousands separat...
Definition: format.h:3889
FMT_CONSTEXPR round_direction get_round_direction(uint64_t divisor, uint64_t remainder, uint64_t error)
Definition: format.h:2538
auto thousands_sep(locale_ref loc) -> thousands_sep_result< Char >
Definition: format.h:1168
auto needs_escape(uint32_t cp) -> bool
Definition: format.h:1705
constexpr auto underlying(Enum e) noexcept -> underlying_t< Enum >
\rst Converts e to the underlying type.
Definition: format.h:3830
auto equal2(const Char *lhs, const char *rhs) -> bool
Definition: format.h:1187
FMT_CONSTEXPR auto is_supported_floating_point(T) -> bool
Definition: format.h:1010
#define FMT_THROW(x)
Definition: format.h:95
FMT_CONSTEXPR auto get_arg(Context &ctx, ID id) -> typename Context::format_arg
Definition: format.h:3469
auto ptr(T p) -> const void *
\rst Converts p to const void* for pointer formatting.
Definition: format.h:3808
basic_fp< unsigned long long > fp
Definition: format.h:1436
FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign) -> write_int_arg< uint32_or_64_or_128_t< T > >
Definition: format.h:2033
FMT_API auto is_printable(uint32_t cp) -> bool
FMT_CONSTEXPR fp get_cached_power(int min_exponent, int &pow10_exponent)
Definition: format.h:1548
FMT_CONSTEXPR auto write(OutputIt out, Char value, const basic_format_specs< Char > &specs, locale_ref loc={}) -> OutputIt
Definition: format.h:1873
FMT_BEGIN_DETAIL_NAMESPACE void vformat_to(buffer< Char > &buf, basic_string_view< Char > fmt, basic_format_args< FMT_BUFFER_CONTEXT(type_identity_t< Char >)> args, locale_ref loc)
Definition: format.h:4056
FMT_CONSTEXPR20 void adjust_precision(int &precision, int exp10)
Definition: format.h:2604
#define FMT_REDUCE_INT_INSTANTIATIONS
Definition: format.h:137
FMT_CONSTEXPR basic_fp< F > normalize(basic_fp< F > value)
Definition: format.h:1440
FMT_CONSTEXPR auto format_uint(Char *buffer, UInt value, int num_digits, bool upper=false) -> Char *
Definition: format.h:1247
#define FMT_POWERS_OF_10(factor)
Definition: format.h:1027
template FMT_API auto thousands_sep_impl< wchar_t >(locale_ref) -> thousands_sep_result< wchar_t >
FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs, buffer< char > &buf) -> int
Definition: format.h:3098
FMT_CONSTEXPR uint64_t multiply(uint64_t lhs, uint64_t rhs)
Definition: format.h:1457
constexpr auto get_significand_size(const big_decimal_fp &f) -> int
Definition: format.h:2262
constexpr auto digits10< uint128_t >() noexcept -> int
Definition: format.h:1158
FMT_CONSTEXPR20 bool isfinite(T value)
Definition: format.h:2506
UnitType ceil(const UnitType x) noexcept
Round up value.
Definition: math.h:528
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
std::size_t UIntPtr
Definition: Meta.h:92
const Scalar & y
Definition: MathFunctions.h:821
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
::uint64_t uint64_t
Definition: Meta.h:58
::int16_t int16_t
Definition: Meta.h:55
::uint32_t uint32_t
Definition: Meta.h:56
::int64_t int64_t
Definition: Meta.h:59
::uint8_t uint8_t
Definition: Meta.h:52
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: core.h:2073
uint32_t divisor
Definition: format-inl.h:236
Definition: format.h:961
constexpr auto compile_string_to_view(detail::std_string_view< Char > s) -> basic_string_view< Char >
Definition: format.h:981
Definition: chrono.h:303
constexpr auto base_iterator(Iterator, Iterator it) -> Iterator
Definition: format.h:553
FMT_CONSTEXPR20 auto bit_cast(const From &from) -> To
Definition: format.h:297
decltype(std::end(std::declval< T & >())) sentinel_t
Definition: format.h:476
FMT_INLINE void assume(bool condition)
Definition: format.h:466
constexpr auto num_bits() -> int
Definition: format.h:440
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:426
auto is_big_endian() -> bool
Definition: format.h:307
auto compute_width(basic_string_view< Char > s) -> size_t
Definition: format.h:675
constexpr auto num_bits< uint128_t >() -> int
Definition: format.h:445
auto base_iterator(std::back_insert_iterator< Container > &it, checked_ptr< typename Container::value_type >) -> std::back_insert_iterator< Container >
Definition: format.h:546
auto compute_width(basic_string_view< char8_type > s) -> size_t
Definition: format.h:713
std::is_same< T, float128 > is_float128
Definition: format.h:752
constexpr auto max_value() -> T
Definition: format.h:437
void float128
Definition: format.h:750
decltype(std::begin(std::declval< T & >())) iterator_t
Definition: format.h:475
FMT_FUNC void print(std::FILE *f, string_view text)
Definition: format-inl.h:1499
constexpr uint32_t invalid_code_point
Definition: format.h:639
FMT_CONSTEXPR20 auto fill_n(T *out, Size count, char value) -> T *
Definition: format.h:566
constexpr auto to_pointer(OutputIt, size_t) -> T *
Definition: format.h:534
OutputIterator copy(const RangeT &range, OutputIterator out)
Definition: ranges.h:26
constexpr auto reserve(Iterator &it, size_t) -> Iterator &
Definition: format.h:525
bool_constant< std::is_floating_point< T >::value||is_float128< T >::value > is_floating_point
Definition: format.h:756
remove_reference_t< decltype(reserve(std::declval< OutputIt & >(), 0))> reserve_iterator
Definition: format.h:531
auto reserve(std::back_insert_iterator< Container > it, size_t n) -> checked_ptr< typename Container::value_type >
Definition: format.h:509
constexpr auto num_bits< int128_opt >() -> int
Definition: format.h:444
conditional_t< FMT_USE_INT128, uint128_opt, uint128_fallback > uint128_t
Definition: format.h:427
FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T &value) -> OutputIt
Definition: format.h:560
constexpr auto make_checked(T *p, size_t) -> T *
Definition: format.h:497
FMT_CONSTEXPR auto utf8_decode(const char *s, uint32_t *c, int *e) -> const char *
Definition: format.h:603
FMT_CONSTEXPR void abort_fuzzing_if(bool condition)
Definition: format.h:245
auto code_point_index(basic_string_view< Char > s, size_t n) -> size_t
Definition: format.h:719
auto get_data(std::basic_string< Char > &s) -> Char *
Definition: format.h:480
FMT_CONSTEXPR void for_each_codepoint(string_view s, F f)
Definition: format.h:644
uint128_t uintptr_t
Definition: format.h:432
T * checked_ptr
Definition: format.h:496
auto code_point_index(basic_string_view< char8_type > s, size_t n) -> size_t
Definition: format.h:734
FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition: format.h:581
char8_type
Definition: format.h:577
Definition: format.h:2555
result
Definition: format.h:2556
@ done
Definition: format.h:2558
@ error
Definition: format.h:2559
@ more
Definition: format.h:2557
Definition: format.h:1286
FMT_API auto to_decimal(T x) noexcept -> decimal_fp< T >
Definition: format.h:3834
constexpr auto format_as(Enum e) noexcept -> underlying_t< Enum >
Definition: format.h:3836
GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept
Definition: filesystem.hpp:5746
Definition: xchar.h:50
Definition: core.h:2078
Definition: StdDeque.h:50
static constexpr const unit_t< compound_unit< energy::joule, time::seconds > > h(6.626070040e-34)
Planck constant.
static constexpr const unit_t< compound_unit< charge::coulomb, inverse< substance::mol > > > F(N_A *e)
Faraday constant.
static constexpr const charge::coulomb_t e(1.6021766208e-19)
elementary charge.
static constexpr const velocity::meters_per_second_t c(299792458.0)
Speed of light in vacuum.
b
Definition: data.h:44
bits
Definition: data.h:44
flags
Definition: http_parser.h:206
Definition: format.h:3384
FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator
Definition: format.h:3393
const basic_format_specs< Char > & specs
Definition: format.h:3389
auto operator()(typename basic_format_arg< context >::handle) -> iterator
Definition: format.h:3396
locale_ref locale
Definition: format.h:3390
iterator out
Definition: format.h:3388
buffer_appender< Char > iterator
Definition: format.h:3385
Definition: core.h:1345
FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int
Definition: core.h:1348
Definition: core.h:2161
union arg_ref::value val
arg_id_kind kind
Definition: core.h:2175
Definition: core.h:2194
Definition: format.h:1478
static constexpr uint64_t pow10_significands[87]
Definition: format.h:1481
static constexpr uint64_t power_of_10_64[20]
Definition: format.h:1532
static constexpr int16_t pow10_exponents[87]
Definition: format.h:1519
Definition: core.h:2134
presentation_type type
Definition: core.h:2137
sign_t sign
Definition: core.h:2139
detail::fill_t< Char > fill
Definition: core.h:2142
align_t align
Definition: core.h:2138
bool alt
Definition: core.h:2140
int precision
Definition: core.h:2136
int width
Definition: core.h:2135
bool localized
Definition: core.h:2141
Definition: format.h:1390
int e
Definition: format.h:1392
FMT_CONSTEXPR auto assign(Float n) -> bool
Definition: format.h:1405
constexpr basic_fp()
Definition: format.h:1397
F f
Definition: format.h:1391
FMT_CONSTEXPR basic_fp(Float n)
Definition: format.h:1401
static constexpr const int num_significand_bits
Definition: format.h:1394
constexpr basic_fp(uint64_t f_val, int e_val)
Definition: format.h:1398
Definition: format.h:2256
int significand_size
Definition: format.h:2258
int exponent
Definition: format.h:2259
const char * significand
Definition: format.h:2257
Definition: format.h:2149
FMT_CONSTEXPR void operator=(const T &)
Definition: format.h:2150
Definition: format.h:3403
void operator()(T) const
Definition: format.h:3411
void operator()(typename basic_format_arg< buffer_context< Char > >::handle h) const
Definition: format.h:3407
buffer_context< Char > & ctx
Definition: format.h:3405
basic_format_parse_context< Char > & parse_ctx
Definition: format.h:3404
Definition: format.h:1544
Definition: format.h:3365
iterator out
Definition: format.h:3369
basic_format_args< context > args
Definition: format.h:3370
auto operator()(T value) -> iterator
Definition: format.h:3373
locale_ref loc
Definition: format.h:3371
auto operator()(typename basic_format_arg< context >::handle h) -> iterator
Definition: format.h:3376
buffer_appender< Char > iterator
Definition: format.h:3366
Definition: format.h:252
static constexpr CharT value[sizeof...(C)]
Definition: format.h:253
Definition: format.h:1330
int exponent
Definition: format.h:1333
typename float_info< T >::carrier_uint significand_type
Definition: format.h:1331
significand_type significand
Definition: format.h:1332
uint64_t carrier_uint
Definition: format.h:1304
uint32_t carrier_uint
Definition: format.h:1292
Definition: format.h:1289
Definition: core.h:632
FMT_NORETURN void on_error(const char *message)
Definition: core.h:637
Definition: core.h:1123
Definition: core.h:2086
Definition: format.h:1710
const Char * end
Definition: format.h:1712
uint32_t cp
Definition: format.h:1713
const Char * begin
Definition: format.h:1711
Definition: core.h:2779
float_format format
Definition: core.h:2781
int precision
Definition: core.h:2780
sign_t sign
Definition: core.h:2782
bool binary32
Definition: core.h:2785
Definition: format.h:1205
Iterator end
Definition: format.h:1207
Iterator begin
Definition: format.h:1206
FMT_CONSTEXPR auto format(const Char *val, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:3741
auto format(bytes b, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3866
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3856
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3899
auto format(group_digits_view< T > t, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3909
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3963
auto format(const join_view< It, Sentinel, Char > &value, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:3968
auto format(void *val, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:3733
Definition: core.h:791
Definition: format.h:2563
bool fixed
Definition: format.h:2568
FMT_CONSTEXPR digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, uint64_t error, bool integral)
Definition: format.h:2570
int exp10
Definition: format.h:2567
int size
Definition: format.h:2565
int precision
Definition: format.h:2566
char * buf
Definition: format.h:2564
Definition: format.h:3876
T value
Definition: format.h:3876
Definition: format.h:2498
Definition: core.h:803
Definition: format.h:989
Definition: core.h:1179
Definition: core.h:1180
Definition: core.h:566
Definition: format.h:3922
It begin
Definition: format.h:3923
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition: format.h:3927
Sentinel end
Definition: format.h:3924
basic_string_view< Char > sep
Definition: format.h:3925
Definition: core.h:325
Definition: core.h:1138
Definition: format.h:1160
std::string grouping
Definition: format.h:1161
Char thousands_sep
Definition: format.h:1162
Definition: core.h:600
Definition: core.h:308
Definition: core.h:1136
Definition: format.h:2027
UInt abs_value
Definition: format.h:2028
unsigned prefix
Definition: format.h:2029
Definition: format.h:1883
FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, const basic_format_specs< Char > &specs)
Definition: format.h:1887
size_t padding
Definition: format.h:1885
size_t size
Definition: format.h:1884
int index
Definition: core.h:2180
basic_string_view< Char > name
Definition: core.h:2181