WPILibC++ 2023.4.3-108-ge5452e3
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#if FMT_GCC_VERSION && FMT_GCC_VERSION >= 1300
926# pragma GCC diagnostic push
927# pragma GCC diagnostic ignored "-Warray-bounds"
928# pragma GCC diagnostic ignored "-Wstringop-overflow"
929#endif
930 std::uninitialized_copy(old_data, old_data + this->size(),
931 detail::make_checked(new_data, new_capacity));
932#if FMT_GCC_VERSION && FMT_GCC_VERSION >= 1300
933# pragma GCC diagnostic pop
934#endif
935 this->set(new_data, new_capacity);
936 // deallocate must not throw according to the standard, but even if it does,
937 // the buffer already uses the new storage and will deallocate it in
938 // destructor.
939 if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
940}
941
943
944template <typename T, size_t SIZE, typename Allocator>
945struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
946};
947
948namespace detail {
949#ifdef _WIN32
950FMT_API bool write_console(std::FILE* f, string_view text);
951#endif
952FMT_API void print(std::FILE*, string_view);
953} // namespace detail
954
955/** A formatting error such as invalid format string. */
957class FMT_API format_error : public std::runtime_error {
958 public:
959 explicit format_error(const char* message) : std::runtime_error(message) {}
960 explicit format_error(const std::string& message)
961 : std::runtime_error(message) {}
962 format_error(const format_error&) = default;
966 ~format_error() noexcept override FMT_MSC_DEFAULT;
967};
968
970#if FMT_USE_NONTYPE_TEMPLATE_ARGS
971template <typename Char, size_t N> struct fixed_string {
972 constexpr fixed_string(const Char (&str)[N]) {
973 detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str),
974 str + N, data);
975 }
976 Char data[N] = {};
977};
978#endif
979
980// Converts a compile-time string to basic_string_view.
981template <typename Char, size_t N>
982constexpr auto compile_string_to_view(const Char (&s)[N])
984 // Remove trailing NUL character if needed. Won't be present if this is used
985 // with a raw character array (i.e. not defined as a string).
986 return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
987}
988template <typename Char>
989constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
991 return {s.data(), s.size()};
992}
993} // namespace detail_exported
994
996
997template <typename T> struct is_integral : std::is_integral<T> {};
998template <> struct is_integral<int128_opt> : std::true_type {};
999template <> struct is_integral<uint128_t> : std::true_type {};
1000
1001template <typename T>
1004 std::is_same<T, int128_opt>::value>;
1005
1006// Returns true if value is negative, false otherwise.
1007// Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
1008template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
1009constexpr auto is_negative(T value) -> bool {
1010 return value < 0;
1011}
1012template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
1013constexpr auto is_negative(T) -> bool {
1014 return false;
1015}
1016
1017template <typename T>
1019 if (std::is_same<T, float>()) return FMT_USE_FLOAT;
1020 if (std::is_same<T, double>()) return FMT_USE_DOUBLE;
1021 if (std::is_same<T, long double>()) return FMT_USE_LONG_DOUBLE;
1022 return true;
1023}
1024
1025// Smallest of uint32_t, uint64_t, uint128_t that is large enough to
1026// represent all values of an integral type T.
1027template <typename T>
1030 uint32_t,
1032template <typename T>
1034
1035#define FMT_POWERS_OF_10(factor) \
1036 factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
1037 (factor)*1000000, (factor)*10000000, (factor)*100000000, \
1038 (factor)*1000000000
1039
1040// Converts value in the range [0, 100) to a string.
1041constexpr const char* digits2(size_t value) {
1042 // GCC generates slightly better code when value is pointer-size.
1043 return &"0001020304050607080910111213141516171819"
1044 "2021222324252627282930313233343536373839"
1045 "4041424344454647484950515253545556575859"
1046 "6061626364656667686970717273747576777879"
1047 "8081828384858687888990919293949596979899"[value * 2];
1048}
1049
1050// Sign is a template parameter to workaround a bug in gcc 4.8.
1051template <typename Char, typename Sign> constexpr Char sign(Sign s) {
1052#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604
1053 static_assert(std::is_same<Sign, sign_t>::value, "");
1054#endif
1055 return static_cast<Char>("\0-+ "[s]);
1056}
1057
1058template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
1059 int count = 1;
1060 for (;;) {
1061 // Integer division is slow so do it for a group of four digits instead
1062 // of for every digit. The idea comes from the talk by Alexandrescu
1063 // "Three Optimization Tips for C++". See speed-test for a comparison.
1064 if (n < 10) return count;
1065 if (n < 100) return count + 1;
1066 if (n < 1000) return count + 2;
1067 if (n < 10000) return count + 3;
1068 n /= 10000u;
1069 count += 4;
1070 }
1071}
1072#if FMT_USE_INT128
1073FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int {
1074 return count_digits_fallback(n);
1075}
1076#endif
1077
1078#ifdef FMT_BUILTIN_CLZLL
1079// It is a separate function rather than a part of count_digits to workaround
1080// the lack of static constexpr in constexpr functions.
1081inline auto do_count_digits(uint64_t n) -> int {
1082 // This has comparable performance to the version by Kendall Willets
1083 // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)
1084 // but uses smaller tables.
1085 // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
1086 static constexpr uint8_t bsr2log10[] = {
1087 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
1088 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
1089 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1090 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1091 auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
1092 static constexpr const uint64_t zero_or_powers_of_10[] = {
1093 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
1094 10000000000000000000ULL};
1095 return t - (n < zero_or_powers_of_10[t]);
1096}
1097#endif
1098
1099// Returns the number of decimal digits in n. Leading zeros are not counted
1100// except for n == 0 in which case count_digits returns 1.
1102#ifdef FMT_BUILTIN_CLZLL
1103 if (!is_constant_evaluated()) {
1104 return do_count_digits(n);
1105 }
1106#endif
1107 return count_digits_fallback(n);
1108}
1109
1110// Counts the number of digits in n. BITS = log2(radix).
1111template <int BITS, typename UInt>
1112FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1113#ifdef FMT_BUILTIN_CLZ
1114 if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1115 return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1116#endif
1117 // Lambda avoids unreachable code warnings from NVHPC.
1118 return [](UInt m) {
1119 int num_digits = 0;
1120 do {
1121 ++num_digits;
1122 } while ((m >>= BITS) != 0);
1123 return num_digits;
1124 }(n);
1125}
1126
1127#ifdef FMT_BUILTIN_CLZ
1128// It is a separate function rather than a part of count_digits to workaround
1129// the lack of static constexpr in constexpr functions.
1130FMT_INLINE auto do_count_digits(uint32_t n) -> int {
1131// An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
1132// This increments the upper 32 bits (log10(T) - 1) when >= T is added.
1133# define FMT_INC(T) (((sizeof(# T) - 1ull) << 32) - T)
1134 static constexpr uint64_t table[] = {
1135 FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8
1136 FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64
1137 FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512
1138 FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096
1139 FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k
1140 FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k
1141 FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k
1142 FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M
1143 FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M
1144 FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M
1145 FMT_INC(1000000000), FMT_INC(1000000000) // 4B
1146 };
1147 auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
1148 return static_cast<int>((n + inc) >> 32);
1149}
1150#endif
1151
1152// Optional version of count_digits for better performance on 32-bit platforms.
1154#ifdef FMT_BUILTIN_CLZ
1155 if (!is_constant_evaluated()) {
1156 return do_count_digits(n);
1157 }
1158#endif
1159 return count_digits_fallback(n);
1160}
1161
1162template <typename Int> constexpr auto digits10() noexcept -> int {
1164}
1165template <> constexpr auto digits10<int128_opt>() noexcept -> int { return 38; }
1166template <> constexpr auto digits10<uint128_t>() noexcept -> int { return 38; }
1167
1168template <typename Char> struct thousands_sep_result {
1169 std::string grouping;
1171};
1172
1173template <typename Char>
1175template <typename Char>
1177 auto result = thousands_sep_impl<char>(loc);
1178 return {result.grouping, Char(result.thousands_sep)};
1179}
1180template <>
1182 return thousands_sep_impl<wchar_t>(loc);
1183}
1184
1185template <typename Char>
1187template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1188 return Char(decimal_point_impl<char>(loc));
1189}
1190template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1191 return decimal_point_impl<wchar_t>(loc);
1192}
1193
1194// Compares two characters for equality.
1195template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1196 return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1197}
1198inline auto equal2(const char* lhs, const char* rhs) -> bool {
1199 return memcmp(lhs, rhs, 2) == 0;
1200}
1201
1202// Copies two characters from src to dst.
1203template <typename Char>
1204FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) {
1205 if (!is_constant_evaluated() && sizeof(Char) == sizeof(char)) {
1206 memcpy(dst, src, 2);
1207 return;
1208 }
1209 *dst++ = static_cast<Char>(*src++);
1210 *dst = static_cast<Char>(*src);
1211}
1212
1213template <typename Iterator> struct format_decimal_result {
1214 Iterator begin;
1215 Iterator end;
1216};
1217
1218// Formats a decimal unsigned integer value writing into out pointing to a
1219// buffer of specified size. The caller must ensure that the buffer is large
1220// enough.
1221template <typename Char, typename UInt>
1222FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
1224 FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1225 out += size;
1226 Char* end = out;
1227 while (value >= 100) {
1228 // Integer division is slow so do it for a group of two digits instead
1229 // of for every digit. The idea comes from the talk by Alexandrescu
1230 // "Three Optimization Tips for C++". See speed-test for a comparison.
1231 out -= 2;
1232 copy2(out, digits2(static_cast<size_t>(value % 100)));
1233 value /= 100;
1234 }
1235 if (value < 10) {
1236 *--out = static_cast<Char>('0' + value);
1237 return {out, end};
1238 }
1239 out -= 2;
1240 copy2(out, digits2(static_cast<size_t>(value)));
1241 return {out, end};
1242}
1243
1244template <typename Char, typename UInt, typename Iterator,
1246FMT_CONSTEXPR inline auto format_decimal(Iterator out, UInt value, int size)
1248 // Buffer is large enough to hold all digits (digits10 + 1).
1249 Char buffer[digits10<UInt>() + 1];
1250 auto end = format_decimal(buffer, value, size).end;
1251 return {out, detail::copy_str_noinline<Char>(buffer, end, out)};
1252}
1253
1254template <unsigned BASE_BITS, typename Char, typename UInt>
1255FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits,
1256 bool upper = false) -> Char* {
1257 buffer += num_digits;
1258 Char* end = buffer;
1259 do {
1260 const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1261 unsigned digit = static_cast<unsigned>(value & ((1 << BASE_BITS) - 1));
1262 *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
1263 : digits[digit]);
1264 } while ((value >>= BASE_BITS) != 0);
1265 return end;
1266}
1267
1268template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1269inline auto format_uint(It out, UInt value, int num_digits, bool upper = false)
1270 -> It {
1271 if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1272 format_uint<BASE_BITS>(ptr, value, num_digits, upper);
1273 return out;
1274 }
1275 // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
1276 char buffer[num_bits<UInt>() / BASE_BITS + 1];
1277 format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1278 return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out);
1279}
1280
1281// A converter from UTF-8 to UTF-16.
1283 private:
1285
1286 public:
1287 FMT_API explicit utf8_to_utf16(string_view s);
1288 operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; }
1289 auto size() const -> size_t { return buffer_.size() - 1; }
1290 auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1291 auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1292};
1293
1294namespace dragonbox {
1295
1296// Type-specific information that Dragonbox uses.
1297template <typename T, typename Enable = void> struct float_info;
1298
1299template <> struct float_info<float> {
1301 static const int exponent_bits = 8;
1302 static const int kappa = 1;
1303 static const int big_divisor = 100;
1304 static const int small_divisor = 10;
1305 static const int min_k = -31;
1306 static const int max_k = 46;
1307 static const int shorter_interval_tie_lower_threshold = -35;
1308 static const int shorter_interval_tie_upper_threshold = -35;
1309};
1310
1311template <> struct float_info<double> {
1313 static const int exponent_bits = 11;
1314 static const int kappa = 2;
1315 static const int big_divisor = 1000;
1316 static const int small_divisor = 100;
1317 static const int min_k = -292;
1318 static const int max_k = 326;
1319 static const int shorter_interval_tie_lower_threshold = -77;
1320 static const int shorter_interval_tie_upper_threshold = -77;
1321};
1322
1323// An 80- or 128-bit floating point number.
1324template <typename T>
1325struct float_info<T, enable_if_t<std::numeric_limits<T>::digits == 64 ||
1326 std::numeric_limits<T>::digits == 113 ||
1327 is_float128<T>::value>> {
1329 static const int exponent_bits = 15;
1330};
1331
1332// A double-double floating point number.
1333template <typename T>
1334struct float_info<T, enable_if_t<is_double_double<T>::value>> {
1336};
1337
1338template <typename T> struct decimal_fp {
1342};
1343
1344template <typename T> FMT_API auto to_decimal(T x) noexcept -> decimal_fp<T>;
1345} // namespace dragonbox
1346
1347// Returns true iff Float has the implicit bit which is not stored.
1348template <typename Float> constexpr bool has_implicit_bit() {
1349 // An 80-bit FP number has a 64-bit significand an no implicit bit.
1350 return std::numeric_limits<Float>::digits != 64;
1351}
1352
1353// Returns the number of significand bits stored in Float. The implicit bit is
1354// not counted since it is not stored.
1355template <typename Float> constexpr int num_significand_bits() {
1356 // std::numeric_limits may not support __float128.
1357 return is_float128<Float>() ? 112
1358 : (std::numeric_limits<Float>::digits -
1359 (has_implicit_bit<Float>() ? 1 : 0));
1360}
1361
1362template <typename Float>
1363constexpr auto exponent_mask() ->
1365 using uint = typename dragonbox::float_info<Float>::carrier_uint;
1366 return ((uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1367 << num_significand_bits<Float>();
1368}
1369template <typename Float> constexpr auto exponent_bias() -> int {
1370 // std::numeric_limits may not support __float128.
1371 return is_float128<Float>() ? 16383
1372 : std::numeric_limits<Float>::max_exponent - 1;
1373}
1374
1375// Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1376template <typename Char, typename It>
1377FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It {
1378 FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1379 if (exp < 0) {
1380 *it++ = static_cast<Char>('-');
1381 exp = -exp;
1382 } else {
1383 *it++ = static_cast<Char>('+');
1384 }
1385 if (exp >= 100) {
1386 const char* top = digits2(to_unsigned(exp / 100));
1387 if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
1388 *it++ = static_cast<Char>(top[1]);
1389 exp %= 100;
1390 }
1391 const char* d = digits2(to_unsigned(exp));
1392 *it++ = static_cast<Char>(d[0]);
1393 *it++ = static_cast<Char>(d[1]);
1394 return it;
1395}
1396
1397// A floating-point number f * pow(2, e) where F is an unsigned type.
1398template <typename F> struct basic_fp {
1400 int e;
1401
1402 static constexpr const int num_significand_bits =
1403 static_cast<int>(sizeof(F) * num_bits<unsigned char>());
1404
1405 constexpr basic_fp() : f(0), e(0) {}
1406 constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
1407
1408 // Constructs fp from an IEEE754 floating-point number.
1409 template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
1410
1411 // Assigns n to this and return true iff predecessor is closer than successor.
1412 template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
1413 FMT_CONSTEXPR auto assign(Float n) -> bool {
1414 static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1415 // Assume Float is in the format [sign][exponent][significand].
1416 using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1417 const auto num_float_significand_bits =
1418 detail::num_significand_bits<Float>();
1419 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1420 const auto significand_mask = implicit_bit - 1;
1421 auto u = bit_cast<carrier_uint>(n);
1422 f = static_cast<F>(u & significand_mask);
1423 auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1424 num_float_significand_bits);
1425 // The predecessor is closer if n is a normalized power of 2 (f == 0)
1426 // other than the smallest normalized number (biased_e > 1).
1427 auto is_predecessor_closer = f == 0 && biased_e > 1;
1428 if (biased_e == 0)
1429 biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
1430 else if (has_implicit_bit<Float>())
1431 f += static_cast<F>(implicit_bit);
1432 e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1433 if (!has_implicit_bit<Float>()) ++e;
1434 return is_predecessor_closer;
1435 }
1436
1437 template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
1438 FMT_CONSTEXPR auto assign(Float n) -> bool {
1439 static_assert(std::numeric_limits<double>::is_iec559, "unsupported FP");
1440 return assign(static_cast<double>(n));
1441 }
1442};
1443
1445
1446// Normalizes the value converted from double and multiplied by (1 << SHIFT).
1447template <int SHIFT = 0, typename F>
1449 // Handle subnormals.
1450 const auto implicit_bit = F(1) << num_significand_bits<double>();
1451 const auto shifted_implicit_bit = implicit_bit << SHIFT;
1452 while ((value.f & shifted_implicit_bit) == 0) {
1453 value.f <<= 1;
1454 --value.e;
1455 }
1456 // Subtract 1 to account for hidden bit.
1457 const auto offset = basic_fp<F>::num_significand_bits -
1458 num_significand_bits<double>() - SHIFT - 1;
1459 value.f <<= offset;
1460 value.e -= offset;
1461 return value;
1462}
1463
1464// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
1466#if FMT_USE_INT128
1467 auto product = static_cast<__uint128_t>(lhs) * rhs;
1468 auto f = static_cast<uint64_t>(product >> 64);
1469 return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1470#else
1471 // Multiply 32-bit parts of significands.
1472 uint64_t mask = (1ULL << 32) - 1;
1473 uint64_t a = lhs >> 32, b = lhs & mask;
1474 uint64_t c = rhs >> 32, d = rhs & mask;
1475 uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
1476 // Compute mid 64-bit of result and round.
1477 uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1478 return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1479#endif
1480}
1481
1483 return {multiply(x.f, y.f), x.e + y.e + 64};
1484}
1485
1486template <typename T = void> struct basic_data {
1487 // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
1488 // These are generated by support/compute-powers.py.
1489 static constexpr uint64_t pow10_significands[87] = {
1490 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
1491 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
1492 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
1493 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
1494 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
1495 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
1496 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
1497 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
1498 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
1499 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
1500 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
1501 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
1502 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
1503 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
1504 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
1505 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
1506 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
1507 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
1508 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
1509 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
1510 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
1511 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
1512 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
1513 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
1514 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
1515 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
1516 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
1517 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
1518 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
1519 };
1520
1521#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1522# pragma GCC diagnostic push
1523# pragma GCC diagnostic ignored "-Wnarrowing"
1524#endif
1525 // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
1526 // to significands above.
1527 static constexpr int16_t pow10_exponents[87] = {
1528 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
1529 -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
1530 -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
1531 -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
1532 -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
1533 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
1534 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
1535 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
1536#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1537# pragma GCC diagnostic pop
1538#endif
1539
1540 static constexpr uint64_t power_of_10_64[20] = {
1541 1, FMT_POWERS_OF_10(1ULL), FMT_POWERS_OF_10(1000000000ULL),
1542 10000000000000000000ULL};
1543};
1544
1545#if FMT_CPLUSPLUS < 201703L
1546template <typename T> constexpr uint64_t basic_data<T>::pow10_significands[];
1547template <typename T> constexpr int16_t basic_data<T>::pow10_exponents[];
1548template <typename T> constexpr uint64_t basic_data<T>::power_of_10_64[];
1549#endif
1550
1551// This is a struct rather than an alias to avoid shadowing warnings in gcc.
1552struct data : basic_data<> {};
1553
1554// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
1555// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
1556FMT_CONSTEXPR inline fp get_cached_power(int min_exponent,
1557 int& pow10_exponent) {
1558 const int shift = 32;
1559 // log10(2) = 0x0.4d104d427de7fbcc...
1560 const int64_t significand = 0x4d104d427de7fbcc;
1561 int index = static_cast<int>(
1562 ((min_exponent + fp::num_significand_bits - 1) * (significand >> shift) +
1563 ((int64_t(1) << shift) - 1)) // ceil
1564 >> 32 // arithmetic shift
1565 );
1566 // Decimal exponent of the first (smallest) cached power of 10.
1567 const int first_dec_exp = -348;
1568 // Difference between 2 consecutive decimal exponents in cached powers of 10.
1569 const int dec_exp_step = 8;
1570 index = (index - first_dec_exp - 1) / dec_exp_step + 1;
1571 pow10_exponent = first_dec_exp + index * dec_exp_step;
1572 // Using *(x + index) instead of x[index] avoids an issue with some compilers
1573 // using the EDG frontend (e.g. nvhpc/22.3 in C++17 mode).
1574 return {*(data::pow10_significands + index),
1576}
1577
1578#ifndef _MSC_VER
1579# define FMT_SNPRINTF snprintf
1580#else
1581FMT_API auto fmt_snprintf(char* buf, size_t size, const char* fmt, ...) -> int;
1582# define FMT_SNPRINTF fmt_snprintf
1583#endif // _MSC_VER
1584
1585// Formats a floating-point number with snprintf using the hexfloat format.
1586template <typename T>
1587auto snprintf_float(T value, int precision, float_specs specs,
1588 buffer<char>& buf) -> int {
1589 // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
1590 FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer");
1591 FMT_ASSERT(specs.format == float_format::hex, "");
1592 static_assert(!std::is_same<T, float>::value, "");
1593
1594 // Build the format string.
1595 char format[7]; // The longest format is "%#.*Le".
1596 char* format_ptr = format;
1597 *format_ptr++ = '%';
1598 if (specs.showpoint) *format_ptr++ = '#';
1599 if (precision >= 0) {
1600 *format_ptr++ = '.';
1601 *format_ptr++ = '*';
1602 }
1603 if (std::is_same<T, long double>()) *format_ptr++ = 'L';
1604 *format_ptr++ = specs.upper ? 'A' : 'a';
1605 *format_ptr = '\0';
1606
1607 // Format using snprintf.
1608 auto offset = buf.size();
1609 for (;;) {
1610 auto begin = buf.data() + offset;
1611 auto capacity = buf.capacity() - offset;
1612 abort_fuzzing_if(precision > 100000);
1613 // Suppress the warning about a nonliteral format string.
1614 // Cannot use auto because of a bug in MinGW (#1532).
1615 int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
1616 int result = precision >= 0
1617 ? snprintf_ptr(begin, capacity, format, precision, value)
1618 : snprintf_ptr(begin, capacity, format, value);
1619 if (result < 0) {
1620 // The buffer will grow exponentially.
1621 buf.try_reserve(buf.capacity() + 1);
1622 continue;
1623 }
1624 auto size = to_unsigned(result);
1625 // Size equal to capacity means that the last character was truncated.
1626 if (size < capacity) {
1627 buf.try_resize(size + offset);
1628 return 0;
1629 }
1630 buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'.
1631 }
1632}
1633
1634template <typename T>
1636 conditional_t<std::is_same<T, float>::value || sizeof(T) == sizeof(double),
1637 double, T>;
1638
1639template <typename T>
1641 return static_cast<convert_float_result<T>>(value);
1642}
1643
1644template <typename OutputIt, typename Char>
1645FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
1646 const fill_t<Char>& fill) -> OutputIt {
1647 auto fill_size = fill.size();
1648 if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
1649 auto data = fill.data();
1650 for (size_t i = 0; i < n; ++i)
1651 it = copy_str<Char>(data, data + fill_size, it);
1652 return it;
1653}
1654
1655// Writes the output of f, padded according to format specifications in specs.
1656// size: output size in code units.
1657// width: output display width in (terminal) column positions.
1658template <align::type align = align::left, typename OutputIt, typename Char,
1659 typename F>
1660FMT_CONSTEXPR auto write_padded(OutputIt out,
1661 const basic_format_specs<Char>& specs,
1662 size_t size, size_t width, F&& f) -> OutputIt {
1663 static_assert(align == align::left || align == align::right, "");
1664 unsigned spec_width = to_unsigned(specs.width);
1665 size_t padding = spec_width > width ? spec_width - width : 0;
1666 // Shifts are encoded as string literals because static constexpr is not
1667 // supported in constexpr functions.
1668 auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1669 size_t left_padding = padding >> shifts[specs.align];
1670 size_t right_padding = padding - left_padding;
1671 auto it = reserve(out, size + padding * specs.fill.size());
1672 if (left_padding != 0) it = fill(it, left_padding, specs.fill);
1673 it = f(it);
1674 if (right_padding != 0) it = fill(it, right_padding, specs.fill);
1675 return base_iterator(out, it);
1676}
1677
1678template <align::type align = align::left, typename OutputIt, typename Char,
1679 typename F>
1680constexpr auto write_padded(OutputIt out, const basic_format_specs<Char>& specs,
1681 size_t size, F&& f) -> OutputIt {
1682 return write_padded<align>(out, specs, size, size, f);
1683}
1684
1685template <align::type align = align::left, typename Char, typename OutputIt>
1687 const basic_format_specs<Char>& specs)
1688 -> OutputIt {
1689 return write_padded<align>(
1690 out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1691 const char* data = bytes.data();
1692 return copy_str<Char>(data, data + bytes.size(), it);
1693 });
1694}
1695
1696template <typename Char, typename OutputIt, typename UIntPtr>
1697auto write_ptr(OutputIt out, UIntPtr value,
1698 const basic_format_specs<Char>* specs) -> OutputIt {
1699 int num_digits = count_digits<4>(value);
1700 auto size = to_unsigned(num_digits) + size_t(2);
1701 auto write = [=](reserve_iterator<OutputIt> it) {
1702 *it++ = static_cast<Char>('0');
1703 *it++ = static_cast<Char>('x');
1704 return format_uint<4, Char>(it, value, num_digits);
1705 };
1706 return specs ? write_padded<align::right>(out, *specs, size, write)
1707 : base_iterator(out, write(reserve(out, size)));
1708}
1709
1710// Returns true iff the code point cp is printable.
1712
1713inline auto needs_escape(uint32_t cp) -> bool {
1714 return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' ||
1715 !is_printable(cp);
1716}
1717
1718template <typename Char> struct find_escape_result {
1719 const Char* begin;
1720 const Char* end;
1722};
1723
1724template <typename Char>
1727 std::make_unsigned<Char>,
1729
1730template <typename Char>
1731auto find_escape(const Char* begin, const Char* end)
1733 for (; begin != end; ++begin) {
1734 uint32_t cp = static_cast<make_unsigned_char<Char>>(*begin);
1735 if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue;
1736 if (needs_escape(cp)) return {begin, begin + 1, cp};
1737 }
1738 return {begin, nullptr, 0};
1739}
1740
1741inline auto find_escape(const char* begin, const char* end)
1743 if (!is_utf8()) return find_escape<char>(begin, end);
1744 auto result = find_escape_result<char>{end, nullptr, 0};
1746 [&](uint32_t cp, string_view sv) {
1747 if (needs_escape(cp)) {
1748 result = {sv.begin(), sv.end(), cp};
1749 return false;
1750 }
1751 return true;
1752 });
1753 return result;
1754}
1755
1756#define FMT_STRING_IMPL(s, base, explicit) \
1757 [] { \
1758 /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
1759 /* Use a macro-like name to avoid shadowing warnings. */ \
1760 struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
1761 using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t<decltype(s[0])>; \
1762 FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
1763 operator fmt::basic_string_view<char_type>() const { \
1764 return fmt::detail_exported::compile_string_to_view<char_type>(s); \
1765 } \
1766 }; \
1767 return FMT_COMPILE_STRING(); \
1768 }()
1769
1770/**
1771 \rst
1772 Constructs a compile-time format string from a string literal *s*.
1773
1774 **Example**::
1775
1776 // A compile-time error because 'd' is an invalid specifier for strings.
1777 std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
1778 \endrst
1779 */
1780#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
1781
1782template <size_t width, typename Char, typename OutputIt>
1783auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {
1784 *out++ = static_cast<Char>('\\');
1785 *out++ = static_cast<Char>(prefix);
1786 Char buf[width];
1787 fill_n(buf, width, static_cast<Char>('0'));
1788 format_uint<4>(buf, cp, width);
1789 return copy_str<Char>(buf, buf + width, out);
1790}
1791
1792template <typename OutputIt, typename Char>
1793auto write_escaped_cp(OutputIt out, const find_escape_result<Char>& escape)
1794 -> OutputIt {
1795 auto c = static_cast<Char>(escape.cp);
1796 switch (escape.cp) {
1797 case '\n':
1798 *out++ = static_cast<Char>('\\');
1799 c = static_cast<Char>('n');
1800 break;
1801 case '\r':
1802 *out++ = static_cast<Char>('\\');
1803 c = static_cast<Char>('r');
1804 break;
1805 case '\t':
1806 *out++ = static_cast<Char>('\\');
1807 c = static_cast<Char>('t');
1808 break;
1809 case '"':
1811 case '\'':
1813 case '\\':
1814 *out++ = static_cast<Char>('\\');
1815 break;
1816 default:
1817 if (is_utf8()) {
1818 if (escape.cp < 0x100) {
1819 return write_codepoint<2, Char>(out, 'x', escape.cp);
1820 }
1821 if (escape.cp < 0x10000) {
1822 return write_codepoint<4, Char>(out, 'u', escape.cp);
1823 }
1824 if (escape.cp < 0x110000) {
1825 return write_codepoint<8, Char>(out, 'U', escape.cp);
1826 }
1827 }
1828 for (Char escape_char : basic_string_view<Char>(
1829 escape.begin, to_unsigned(escape.end - escape.begin))) {
1830 out = write_codepoint<2, Char>(out, 'x',
1831 static_cast<uint32_t>(escape_char) & 0xFF);
1832 }
1833 return out;
1834 }
1835 *out++ = c;
1836 return out;
1837}
1838
1839template <typename Char, typename OutputIt>
1841 -> OutputIt {
1842 *out++ = static_cast<Char>('"');
1843 auto begin = str.begin(), end = str.end();
1844 do {
1845 auto escape = find_escape(begin, end);
1846 out = copy_str<Char>(begin, escape.begin, out);
1847 begin = escape.end;
1848 if (!begin) break;
1849 out = write_escaped_cp<OutputIt, Char>(out, escape);
1850 } while (begin != end);
1851 *out++ = static_cast<Char>('"');
1852 return out;
1853}
1854
1855template <typename Char, typename OutputIt>
1856auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
1857 *out++ = static_cast<Char>('\'');
1858 if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('"')) ||
1859 v == static_cast<Char>('\'')) {
1860 out = write_escaped_cp(
1861 out, find_escape_result<Char>{&v, &v + 1, static_cast<uint32_t>(v)});
1862 } else {
1863 *out++ = v;
1864 }
1865 *out++ = static_cast<Char>('\'');
1866 return out;
1867}
1868
1869template <typename Char, typename OutputIt>
1870FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1871 const basic_format_specs<Char>& specs)
1872 -> OutputIt {
1873 bool is_debug = specs.type == presentation_type::debug;
1874 return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1875 if (is_debug) return write_escaped_char(it, value);
1876 *it++ = value;
1877 return it;
1878 });
1879}
1880template <typename Char, typename OutputIt>
1881FMT_CONSTEXPR auto write(OutputIt out, Char value,
1882 const basic_format_specs<Char>& specs,
1883 locale_ref loc = {}) -> OutputIt {
1884 return check_char_specs(specs)
1885 ? write_char(out, value, specs)
1886 : write(out, static_cast<int>(value), specs, loc);
1887}
1888
1889// Data for write_int that doesn't depend on output iterator type. It is used to
1890// avoid template code bloat.
1891template <typename Char> struct write_int_data {
1892 size_t size;
1893 size_t padding;
1894
1895 FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
1896 const basic_format_specs<Char>& specs)
1897 : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
1898 if (specs.align == align::numeric) {
1899 auto width = to_unsigned(specs.width);
1900 if (width > size) {
1901 padding = width - size;
1902 size = width;
1903 }
1904 } else if (specs.precision > num_digits) {
1905 size = (prefix >> 24) + to_unsigned(specs.precision);
1906 padding = to_unsigned(specs.precision - num_digits);
1907 }
1908 }
1909};
1910
1911// Writes an integer in the format
1912// <left-padding><prefix><numeric-padding><digits><right-padding>
1913// where <digits> are written by write_digits(it).
1914// prefix contains chars in three lower bytes and the size in the fourth byte.
1915template <typename OutputIt, typename Char, typename W>
1916FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
1917 unsigned prefix,
1918 const basic_format_specs<Char>& specs,
1919 W write_digits) -> OutputIt {
1920 // Slightly faster check for specs.width == 0 && specs.precision == -1.
1921 if ((specs.width | (specs.precision + 1)) == 0) {
1922 auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
1923 if (prefix != 0) {
1924 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1925 *it++ = static_cast<Char>(p & 0xff);
1926 }
1927 return base_iterator(out, write_digits(it));
1928 }
1929 auto data = write_int_data<Char>(num_digits, prefix, specs);
1930 return write_padded<align::right>(
1931 out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
1932 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1933 *it++ = static_cast<Char>(p & 0xff);
1934 it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
1935 return write_digits(it);
1936 });
1937}
1938
1939template <typename Char> class digit_grouping {
1940 private:
1942
1943 struct next_state {
1944 std::string::const_iterator group;
1945 int pos;
1946 };
1947 next_state initial_state() const { return {sep_.grouping.begin(), 0}; }
1948
1949 // Returns the next digit group separator position.
1950 int next(next_state& state) const {
1951 if (!sep_.thousands_sep) return max_value<int>();
1952 if (state.group == sep_.grouping.end())
1953 return state.pos += sep_.grouping.back();
1954 if (*state.group <= 0 || *state.group == max_value<char>())
1955 return max_value<int>();
1956 state.pos += *state.group++;
1957 return state.pos;
1958 }
1959
1960 public:
1961 explicit digit_grouping(locale_ref loc, bool localized = true) {
1962 if (localized)
1963 sep_ = thousands_sep<Char>(loc);
1964 else
1965 sep_.thousands_sep = Char();
1966 }
1967 explicit digit_grouping(thousands_sep_result<Char> sep) : sep_(sep) {}
1968
1969 Char separator() const { return sep_.thousands_sep; }
1970
1971 int count_separators(int num_digits) const {
1972 int count = 0;
1973 auto state = initial_state();
1974 while (num_digits > next(state)) ++count;
1975 return count;
1976 }
1977
1978 // Applies grouping to digits and write the output to out.
1979 template <typename Out, typename C>
1980 Out apply(Out out, basic_string_view<C> digits) const {
1981 auto num_digits = static_cast<int>(digits.size());
1982 auto separators = basic_memory_buffer<int>();
1983 separators.push_back(0);
1984 auto state = initial_state();
1985 while (int i = next(state)) {
1986 if (i >= num_digits) break;
1987 separators.push_back(i);
1988 }
1989 for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);
1990 i < num_digits; ++i) {
1991 if (num_digits - i == separators[sep_index]) {
1992 *out++ = separator();
1993 --sep_index;
1994 }
1995 *out++ = static_cast<Char>(digits[to_unsigned(i)]);
1996 }
1997 return out;
1998 }
1999};
2000
2001template <typename OutputIt, typename UInt, typename Char>
2002auto write_int_localized(OutputIt out, UInt value, unsigned prefix,
2003 const basic_format_specs<Char>& specs,
2004 const digit_grouping<Char>& grouping) -> OutputIt {
2005 static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
2006 int num_digits = count_digits(value);
2007 char digits[40];
2008 format_decimal(digits, value, num_digits);
2009 unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
2010 grouping.count_separators(num_digits));
2011 return write_padded<align::right>(
2012 out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
2013 if (prefix != 0) {
2014 char sign = static_cast<char>(prefix);
2015 *it++ = static_cast<Char>(sign);
2016 }
2017 return grouping.apply(it, string_view(digits, to_unsigned(num_digits)));
2018 });
2019}
2020
2021template <typename OutputIt, typename UInt, typename Char>
2022auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
2023 const basic_format_specs<Char>& specs, locale_ref loc)
2024 -> bool {
2025 auto grouping = digit_grouping<Char>(loc);
2026 out = write_int_localized(out, value, prefix, specs, grouping);
2027 return true;
2028}
2029
2030FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
2031 prefix |= prefix != 0 ? value << 8 : value;
2032 prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
2033}
2034
2035template <typename UInt> struct write_int_arg {
2037 unsigned prefix;
2038};
2039
2040template <typename T>
2043 auto prefix = 0u;
2044 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2045 if (is_negative(value)) {
2046 prefix = 0x01000000 | '-';
2047 abs_value = 0 - abs_value;
2048 } else {
2049 constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
2050 0x1000000u | ' '};
2051 prefix = prefixes[sign];
2052 }
2053 return {abs_value, prefix};
2054}
2055
2056template <typename Char, typename OutputIt, typename T>
2058 const basic_format_specs<Char>& specs,
2059 locale_ref loc) -> OutputIt {
2060 static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2061 auto abs_value = arg.abs_value;
2062 auto prefix = arg.prefix;
2063 switch (specs.type) {
2066 if (specs.localized &&
2067 write_int_localized(out, static_cast<uint64_or_128_t<T>>(abs_value),
2068 prefix, specs, loc)) {
2069 return out;
2070 }
2071 auto num_digits = count_digits(abs_value);
2072 return write_int(
2073 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2074 return format_decimal<Char>(it, abs_value, num_digits).end;
2075 });
2076 }
2079 bool upper = specs.type == presentation_type::hex_upper;
2080 if (specs.alt)
2081 prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
2082 int num_digits = count_digits<4>(abs_value);
2083 return write_int(
2084 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2085 return format_uint<4, Char>(it, abs_value, num_digits, upper);
2086 });
2087 }
2090 bool upper = specs.type == presentation_type::bin_upper;
2091 if (specs.alt)
2092 prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
2093 int num_digits = count_digits<1>(abs_value);
2094 return write_int(out, num_digits, prefix, specs,
2095 [=](reserve_iterator<OutputIt> it) {
2096 return format_uint<1, Char>(it, abs_value, num_digits);
2097 });
2098 }
2100 int num_digits = count_digits<3>(abs_value);
2101 // Octal prefix '0' is counted as a digit, so only add it if precision
2102 // is not greater than the number of digits.
2103 if (specs.alt && specs.precision <= num_digits && abs_value != 0)
2104 prefix_append(prefix, '0');
2105 return write_int(out, num_digits, prefix, specs,
2106 [=](reserve_iterator<OutputIt> it) {
2107 return format_uint<3, Char>(it, abs_value, num_digits);
2108 });
2109 }
2111 return write_char(out, static_cast<Char>(abs_value), specs);
2112 default:
2113 throw_format_error("invalid type specifier");
2114 }
2115 return out;
2116}
2117template <typename Char, typename OutputIt, typename T>
2119 OutputIt out, write_int_arg<T> arg, const basic_format_specs<Char>& specs,
2120 locale_ref loc) -> OutputIt {
2121 return write_int(out, arg, specs, loc);
2122}
2123template <typename Char, typename OutputIt, typename T,
2125 !std::is_same<T, bool>::value &&
2126 std::is_same<OutputIt, buffer_appender<Char>>::value)>
2128 const basic_format_specs<Char>& specs,
2129 locale_ref loc) -> OutputIt {
2130 return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
2131 loc);
2132}
2133// An inlined version of write used in format string compilation.
2134template <typename Char, typename OutputIt, typename T,
2136 !std::is_same<T, bool>::value &&
2137 !std::is_same<OutputIt, buffer_appender<Char>>::value)>
2138FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2139 const basic_format_specs<Char>& specs,
2140 locale_ref loc) -> OutputIt {
2141 return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
2142}
2143
2144// An output iterator that counts the number of objects written to it and
2145// discards them.
2147 private:
2148 size_t count_;
2149
2150 public:
2151 using iterator_category = std::output_iterator_tag;
2152 using difference_type = std::ptrdiff_t;
2153 using pointer = void;
2154 using reference = void;
2156
2157 struct value_type {
2158 template <typename T> FMT_CONSTEXPR void operator=(const T&) {}
2159 };
2160
2162
2163 FMT_CONSTEXPR size_t count() const { return count_; }
2164
2166 ++count_;
2167 return *this;
2168 }
2170 auto it = *this;
2171 ++*this;
2172 return it;
2173 }
2174
2176 difference_type n) {
2177 it.count_ += static_cast<size_t>(n);
2178 return it;
2179 }
2180
2181 FMT_CONSTEXPR value_type operator*() const { return {}; }
2182};
2183
2184template <typename Char, typename OutputIt>
2186 const basic_format_specs<Char>& specs) -> OutputIt {
2187 auto data = s.data();
2188 auto size = s.size();
2189 if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
2191 bool is_debug = specs.type == presentation_type::debug;
2192 size_t width = 0;
2193 if (specs.width != 0) {
2194 if (is_debug)
2196 else
2198 }
2199 return write_padded(out, specs, size, width,
2200 [=](reserve_iterator<OutputIt> it) {
2201 if (is_debug) return write_escaped_string(it, s);
2202 return copy_str<Char>(data, data + size, it);
2203 });
2204}
2205template <typename Char, typename OutputIt>
2206FMT_CONSTEXPR auto write(OutputIt out,
2209 -> OutputIt {
2211 return write(out, s, specs);
2212}
2213template <typename Char, typename OutputIt>
2214FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
2216 -> OutputIt {
2217 return check_cstring_type_spec(specs.type)
2218 ? write(out, basic_string_view<Char>(s), specs, {})
2219 : write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
2220}
2221
2222template <typename Char, typename OutputIt, typename T,
2224 !std::is_same<T, bool>::value &&
2225 !std::is_same<T, Char>::value)>
2226FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2227 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2228 bool negative = is_negative(value);
2229 // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2230 if (negative) abs_value = ~abs_value + 1;
2231 int num_digits = count_digits(abs_value);
2232 auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2233 auto it = reserve(out, size);
2234 if (auto ptr = to_pointer<Char>(it, size)) {
2235 if (negative) *ptr++ = static_cast<Char>('-');
2236 format_decimal<Char>(ptr, abs_value, num_digits);
2237 return out;
2238 }
2239 if (negative) *it++ = static_cast<Char>('-');
2240 it = format_decimal<Char>(it, abs_value, num_digits).end;
2241 return base_iterator(out, it);
2242}
2243
2244template <typename Char, typename OutputIt>
2245FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
2247 const float_specs& fspecs) -> OutputIt {
2248 auto str =
2249 isnan ? (fspecs.upper ? "NAN" : "nan") : (fspecs.upper ? "INF" : "inf");
2250 constexpr size_t str_size = 3;
2251 auto sign = fspecs.sign;
2252 auto size = str_size + (sign ? 1 : 0);
2253 // Replace '0'-padding with space for non-finite values.
2254 const bool is_zero_fill =
2255 specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
2256 if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
2257 return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
2258 if (sign) *it++ = detail::sign<Char>(sign);
2259 return copy_str<Char>(str, str + str_size, it);
2260 });
2261}
2262
2263// A decimal floating-point number significand * pow(10, exp).
2265 const char* significand;
2268};
2269
2270constexpr auto get_significand_size(const big_decimal_fp& f) -> int {
2271 return f.significand_size;
2272}
2273template <typename T>
2275 return count_digits(f.significand);
2276}
2277
2278template <typename Char, typename OutputIt>
2279constexpr auto write_significand(OutputIt out, const char* significand,
2280 int significand_size) -> OutputIt {
2281 return copy_str<Char>(significand, significand + significand_size, out);
2282}
2283template <typename Char, typename OutputIt, typename UInt>
2284inline auto write_significand(OutputIt out, UInt significand,
2285 int significand_size) -> OutputIt {
2286 return format_decimal<Char>(out, significand, significand_size).end;
2287}
2288template <typename Char, typename OutputIt, typename T, typename Grouping>
2289FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2290 int significand_size, int exponent,
2291 const Grouping& grouping) -> OutputIt {
2292 if (!grouping.separator()) {
2293 out = write_significand<Char>(out, significand, significand_size);
2294 return detail::fill_n(out, exponent, static_cast<Char>('0'));
2295 }
2296 auto buffer = memory_buffer();
2297 write_significand<char>(appender(buffer), significand, significand_size);
2298 detail::fill_n(appender(buffer), exponent, '0');
2299 return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2300}
2301
2302template <typename Char, typename UInt,
2303 FMT_ENABLE_IF(std::is_integral<UInt>::value)>
2304inline auto write_significand(Char* out, UInt significand, int significand_size,
2305 int integral_size, Char decimal_point) -> Char* {
2306 if (!decimal_point)
2307 return format_decimal(out, significand, significand_size).end;
2308 out += significand_size + 1;
2309 Char* end = out;
2310 int floating_size = significand_size - integral_size;
2311 for (int i = floating_size / 2; i > 0; --i) {
2312 out -= 2;
2313 copy2(out, digits2(static_cast<std::size_t>(significand % 100)));
2314 significand /= 100;
2315 }
2316 if (floating_size % 2 != 0) {
2317 *--out = static_cast<Char>('0' + significand % 10);
2318 significand /= 10;
2319 }
2320 *--out = decimal_point;
2321 format_decimal(out - integral_size, significand, integral_size);
2322 return end;
2323}
2324
2325template <typename OutputIt, typename UInt, typename Char,
2327inline auto write_significand(OutputIt out, UInt significand,
2328 int significand_size, int integral_size,
2329 Char decimal_point) -> OutputIt {
2330 // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2331 Char buffer[digits10<UInt>() + 2];
2332 auto end = write_significand(buffer, significand, significand_size,
2333 integral_size, decimal_point);
2334 return detail::copy_str_noinline<Char>(buffer, end, out);
2335}
2336
2337template <typename OutputIt, typename Char>
2338FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,
2339 int significand_size, int integral_size,
2340 Char decimal_point) -> OutputIt {
2341 out = detail::copy_str_noinline<Char>(significand,
2342 significand + integral_size, out);
2343 if (!decimal_point) return out;
2344 *out++ = decimal_point;
2345 return detail::copy_str_noinline<Char>(significand + integral_size,
2346 significand + significand_size, out);
2347}
2348
2349template <typename OutputIt, typename Char, typename T, typename Grouping>
2350FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2351 int significand_size, int integral_size,
2352 Char decimal_point,
2353 const Grouping& grouping) -> OutputIt {
2354 if (!grouping.separator()) {
2355 return write_significand(out, significand, significand_size, integral_size,
2357 }
2360 significand_size, integral_size, decimal_point);
2361 grouping.apply(
2362 out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2363 return detail::copy_str_noinline<Char>(buffer.data() + integral_size,
2364 buffer.end(), out);
2365}
2366
2367template <typename OutputIt, typename DecimalFP, typename Char,
2368 typename Grouping = digit_grouping<Char>>
2369FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
2370 const basic_format_specs<Char>& specs,
2371 float_specs fspecs, locale_ref loc)
2372 -> OutputIt {
2373 auto significand = f.significand;
2374 int significand_size = get_significand_size(f);
2375 const Char zero = static_cast<Char>('0');
2376 auto sign = fspecs.sign;
2377 size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
2378 using iterator = reserve_iterator<OutputIt>;
2379
2380 Char decimal_point =
2381 fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>('.');
2382
2383 int output_exp = f.exponent + significand_size - 1;
2384 auto use_exp_format = [=]() {
2385 if (fspecs.format == float_format::exp) return true;
2386 if (fspecs.format != float_format::general) return false;
2387 // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
2388 // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
2389 const int exp_lower = -4, exp_upper = 16;
2390 return output_exp < exp_lower ||
2391 output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
2392 };
2393 if (use_exp_format()) {
2394 int num_zeros = 0;
2395 if (fspecs.showpoint) {
2396 num_zeros = fspecs.precision - significand_size;
2397 if (num_zeros < 0) num_zeros = 0;
2398 size += to_unsigned(num_zeros);
2399 } else if (significand_size == 1) {
2400 decimal_point = Char();
2401 }
2402 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2403 int exp_digits = 2;
2404 if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2405
2406 size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
2407 char exp_char = fspecs.upper ? 'E' : 'e';
2408 auto write = [=](iterator it) {
2409 if (sign) *it++ = detail::sign<Char>(sign);
2410 // Insert a decimal point after the first digit and add an exponent.
2411 it = write_significand(it, significand, significand_size, 1,
2413 if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
2414 *it++ = static_cast<Char>(exp_char);
2415 return write_exponent<Char>(output_exp, it);
2416 };
2417 return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
2418 : base_iterator(out, write(reserve(out, size)));
2419 }
2420
2421 int exp = f.exponent + significand_size;
2422 if (f.exponent >= 0) {
2423 // 1234e5 -> 123400000[.0+]
2424 size += to_unsigned(f.exponent);
2425 int num_zeros = fspecs.precision - exp;
2426 abort_fuzzing_if(num_zeros > 5000);
2427 if (fspecs.showpoint) {
2428 ++size;
2429 if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1;
2430 if (num_zeros > 0) size += to_unsigned(num_zeros);
2431 }
2432 auto grouping = Grouping(loc, fspecs.locale);
2433 size += to_unsigned(grouping.count_separators(exp));
2434 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2435 if (sign) *it++ = detail::sign<Char>(sign);
2436 it = write_significand<Char>(it, significand, significand_size,
2437 f.exponent, grouping);
2438 if (!fspecs.showpoint) return it;
2439 *it++ = decimal_point;
2440 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2441 });
2442 } else if (exp > 0) {
2443 // 1234e-2 -> 12.34[0+]
2444 int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
2445 size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
2446 auto grouping = Grouping(loc, fspecs.locale);
2447 size += to_unsigned(grouping.count_separators(significand_size));
2448 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2449 if (sign) *it++ = detail::sign<Char>(sign);
2450 it = write_significand(it, significand, significand_size, exp,
2451 decimal_point, grouping);
2452 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2453 });
2454 }
2455 // 1234e-6 -> 0.001234
2456 int num_zeros = -exp;
2457 if (significand_size == 0 && fspecs.precision >= 0 &&
2458 fspecs.precision < num_zeros) {
2459 num_zeros = fspecs.precision;
2460 }
2461 bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
2462 size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
2463 return write_padded<align::right>(out, specs, size, [&](iterator it) {
2464 if (sign) *it++ = detail::sign<Char>(sign);
2465 *it++ = zero;
2466 if (!pointy) return it;
2467 *it++ = decimal_point;
2468 it = detail::fill_n(it, num_zeros, zero);
2469 return write_significand<Char>(it, significand, significand_size);
2470 });
2471}
2472
2473template <typename Char> class fallback_digit_grouping {
2474 public:
2476
2477 constexpr Char separator() const { return Char(); }
2478
2479 constexpr int count_separators(int) const { return 0; }
2480
2481 template <typename Out, typename C>
2482 constexpr Out apply(Out out, basic_string_view<C>) const {
2483 return out;
2484 }
2485};
2486
2487template <typename OutputIt, typename DecimalFP, typename Char>
2488FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,
2489 const basic_format_specs<Char>& specs,
2490 float_specs fspecs, locale_ref loc)
2491 -> OutputIt {
2492 if (is_constant_evaluated()) {
2493 return do_write_float<OutputIt, DecimalFP, Char,
2494 fallback_digit_grouping<Char>>(out, f, specs, fspecs,
2495 loc);
2496 } else {
2497 return do_write_float(out, f, specs, fspecs, loc);
2498 }
2499}
2500
2501template <typename T> constexpr bool isnan(T value) {
2502 return !(value >= value); // std::isnan doesn't support __float128.
2503}
2504
2505template <typename T, typename Enable = void>
2506struct has_isfinite : std::false_type {};
2507
2508template <typename T>
2509struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
2510 : std::true_type {};
2511
2512template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&&
2513 has_isfinite<T>::value)>
2515 constexpr T inf = T(std::numeric_limits<double>::infinity());
2517 return !detail::isnan(value) && value != inf && value != -inf;
2518 return std::isfinite(value);
2519}
2520template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
2522 T inf = T(std::numeric_limits<double>::infinity());
2523 // std::isfinite doesn't support __float128.
2524 return !detail::isnan(value) && value != inf && value != -inf;
2525}
2526
2527template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
2529 if (is_constant_evaluated()) {
2530#ifdef __cpp_if_constexpr
2531 if constexpr (std::numeric_limits<double>::is_iec559) {
2532 auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2533 return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2534 }
2535#endif
2536 }
2537 return std::signbit(static_cast<double>(value));
2538}
2539
2541
2542// Given the divisor (normally a power of 10), the remainder = v % divisor for
2543// some number v and the error, returns whether v should be rounded up, down, or
2544// whether the rounding direction can't be determined due to error.
2545// error should be less than divisor / 2.
2547 uint64_t remainder,
2548 uint64_t error) {
2549 FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow.
2550 FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow.
2551 FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow.
2552 // Round down if (remainder + error) * 2 <= divisor.
2553 if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
2554 return round_direction::down;
2555 // Round up if (remainder - error) * 2 >= divisor.
2556 if (remainder >= error &&
2557 remainder - error >= divisor - (remainder - error)) {
2558 return round_direction::up;
2559 }
2561}
2562
2563namespace digits {
2565 more, // Generate more digits.
2566 done, // Done generating digits.
2567 error // Digit generation cancelled due to an error.
2569}
2570
2572 char* buf;
2573 int size;
2576 bool fixed;
2577
2579 uint64_t remainder, uint64_t error,
2580 bool integral) {
2581 FMT_ASSERT(remainder < divisor, "");
2582 buf[size++] = digit;
2583 if (!integral && error >= remainder) return digits::error;
2584 if (size < precision) return digits::more;
2585 if (!integral) {
2586 // Check if error * 2 < divisor with overflow prevention.
2587 // The check is not needed for the integral part because error = 1
2588 // and divisor > (1 << 32) there.
2589 if (error >= divisor || error >= divisor - error) return digits::error;
2590 } else {
2591 FMT_ASSERT(error == 1 && divisor > 2, "");
2592 }
2593 auto dir = get_round_direction(divisor, remainder, error);
2594 if (dir != round_direction::up)
2596 ++buf[size - 1];
2597 for (int i = size - 1; i > 0 && buf[i] > '9'; --i) {
2598 buf[i] = '0';
2599 ++buf[i - 1];
2600 }
2601 if (buf[0] > '9') {
2602 buf[0] = '1';
2603 if (fixed)
2604 buf[size++] = '0';
2605 else
2606 ++exp10;
2607 }
2608 return digits::done;
2609 }
2610};
2611
2612inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {
2613 // Adjust fixed precision by exponent because it is relative to decimal
2614 // point.
2615 if (exp10 > 0 && precision > max_value<int>() - exp10)
2616 FMT_THROW(format_error("number is too big"));
2617 precision += exp10;
2618}
2619
2620// Generates output using the Grisu digit-gen algorithm.
2621// error: the size of the region (lower, upper) outside of which numbers
2622// definitely do not round to value (Delta in Grisu3).
2624 int& exp,
2625 gen_digits_handler& handler)
2626 -> digits::result {
2627 const fp one(1ULL << -value.e, value.e);
2628 // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be
2629 // zero because it contains a product of two 64-bit numbers with MSB set (due
2630 // to normalization) - 1, shifted right by at most 60 bits.
2631 auto integral = static_cast<uint32_t>(value.f >> -one.e);
2632 FMT_ASSERT(integral != 0, "");
2633 FMT_ASSERT(integral == value.f >> -one.e, "");
2634 // The fractional part of scaled value (p2 in Grisu) c = value % one.
2635 uint64_t fractional = value.f & (one.f - 1);
2636 exp = count_digits(integral); // kappa in Grisu.
2637 // Non-fixed formats require at least one digit and no precision adjustment.
2638 if (handler.fixed) {
2639 adjust_precision(handler.precision, exp + handler.exp10);
2640 // Check if precision is satisfied just by leading zeros, e.g.
2641 // format("{:.2f}", 0.001) gives "0.00" without generating any digits.
2642 if (handler.precision <= 0) {
2643 if (handler.precision < 0) return digits::done;
2644 // Divide by 10 to prevent overflow.
2645 uint64_t divisor = data::power_of_10_64[exp - 1] << -one.e;
2646 auto dir = get_round_direction(divisor, value.f / 10, error * 10);
2647 if (dir == round_direction::unknown) return digits::error;
2648 handler.buf[handler.size++] = dir == round_direction::up ? '1' : '0';
2649 return digits::done;
2650 }
2651 }
2652 // Generate digits for the integral part. This can produce up to 10 digits.
2653 do {
2654 uint32_t digit = 0;
2655 auto divmod_integral = [&](uint32_t divisor) {
2656 digit = integral / divisor;
2657 integral %= divisor;
2658 };
2659 // This optimization by Milo Yip reduces the number of integer divisions by
2660 // one per iteration.
2661 switch (exp) {
2662 case 10:
2663 divmod_integral(1000000000);
2664 break;
2665 case 9:
2666 divmod_integral(100000000);
2667 break;
2668 case 8:
2669 divmod_integral(10000000);
2670 break;
2671 case 7:
2672 divmod_integral(1000000);
2673 break;
2674 case 6:
2675 divmod_integral(100000);
2676 break;
2677 case 5:
2678 divmod_integral(10000);
2679 break;
2680 case 4:
2681 divmod_integral(1000);
2682 break;
2683 case 3:
2684 divmod_integral(100);
2685 break;
2686 case 2:
2687 divmod_integral(10);
2688 break;
2689 case 1:
2690 digit = integral;
2691 integral = 0;
2692 break;
2693 default:
2694 FMT_ASSERT(false, "invalid number of digits");
2695 }
2696 --exp;
2697 auto remainder = (static_cast<uint64_t>(integral) << -one.e) + fractional;
2698 auto result = handler.on_digit(static_cast<char>('0' + digit),
2699 data::power_of_10_64[exp] << -one.e,
2700 remainder, error, true);
2701 if (result != digits::more) return result;
2702 } while (exp > 0);
2703 // Generate digits for the fractional part.
2704 for (;;) {
2705 fractional *= 10;
2706 error *= 10;
2707 char digit = static_cast<char>('0' + (fractional >> -one.e));
2708 fractional &= one.f - 1;
2709 --exp;
2710 auto result = handler.on_digit(digit, one.f, fractional, error, false);
2711 if (result != digits::more) return result;
2712 }
2713}
2714
2715class bigint {
2716 private:
2717 // A bigint is stored as an array of bigits (big digits), with bigit at index
2718 // 0 being the least significant one.
2719 using bigit = uint32_t;
2720 using double_bigit = uint64_t;
2721 enum { bigits_capacity = 32 };
2723 int exp_;
2724
2725 FMT_CONSTEXPR20 bigit operator[](int index) const {
2726 return bigits_[to_unsigned(index)];
2727 }
2728 FMT_CONSTEXPR20 bigit& operator[](int index) {
2729 return bigits_[to_unsigned(index)];
2730 }
2731
2732 static constexpr const int bigit_bits = num_bits<bigit>();
2733
2734 friend struct formatter<bigint>;
2735
2736 FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit& borrow) {
2737 auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
2738 (*this)[index] = static_cast<bigit>(result);
2739 borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
2740 }
2741
2742 FMT_CONSTEXPR20 void remove_leading_zeros() {
2743 int num_bigits = static_cast<int>(bigits_.size()) - 1;
2744 while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
2745 bigits_.resize(to_unsigned(num_bigits + 1));
2746 }
2747
2748 // Computes *this -= other assuming aligned bigints and *this >= other.
2749 FMT_CONSTEXPR20 void subtract_aligned(const bigint& other) {
2750 FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
2751 FMT_ASSERT(compare(*this, other) >= 0, "");
2752 bigit borrow = 0;
2753 int i = other.exp_ - exp_;
2754 for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
2755 subtract_bigits(i, other.bigits_[j], borrow);
2756 while (borrow > 0) subtract_bigits(i, 0, borrow);
2757 remove_leading_zeros();
2758 }
2759
2761 const double_bigit wide_value = value;
2762 bigit carry = 0;
2763 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2764 double_bigit result = bigits_[i] * wide_value + carry;
2765 bigits_[i] = static_cast<bigit>(result);
2766 carry = static_cast<bigit>(result >> bigit_bits);
2767 }
2768 if (carry != 0) bigits_.push_back(carry);
2769 }
2770
2771 template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2772 std::is_same<UInt, uint128_t>::value)>
2773 FMT_CONSTEXPR20 void multiply(UInt value) {
2774 using half_uint =
2776 const int shift = num_bits<half_uint>() - bigit_bits;
2777 const UInt lower = static_cast<half_uint>(value);
2778 const UInt upper = value >> num_bits<half_uint>();
2779 UInt carry = 0;
2780 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2781 UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
2782 carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
2783 (carry >> bigit_bits);
2784 bigits_[i] = static_cast<bigit>(result);
2785 }
2786 while (carry != 0) {
2787 bigits_.push_back(static_cast<bigit>(carry));
2788 carry >>= bigit_bits;
2789 }
2790 }
2791
2792 template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2793 std::is_same<UInt, uint128_t>::value)>
2794 FMT_CONSTEXPR20 void assign(UInt n) {
2795 size_t num_bigits = 0;
2796 do {
2797 bigits_[num_bigits++] = static_cast<bigit>(n);
2798 n >>= bigit_bits;
2799 } while (n != 0);
2800 bigits_.resize(num_bigits);
2801 exp_ = 0;
2802 }
2803
2804 public:
2806 explicit bigint(uint64_t n) { assign(n); }
2807
2808 bigint(const bigint&) = delete;
2809 void operator=(const bigint&) = delete;
2810
2811 FMT_CONSTEXPR20 void assign(const bigint& other) {
2812 auto size = other.bigits_.size();
2813 bigits_.resize(size);
2814 auto data = other.bigits_.data();
2815#if FMT_GCC_VERSION && FMT_GCC_VERSION >= 1300
2816# pragma GCC diagnostic push
2817# pragma GCC diagnostic ignored "-Warray-bounds"
2818#endif
2819 std::copy(data, data + size, make_checked(bigits_.data(), size));
2820#if FMT_GCC_VERSION && FMT_GCC_VERSION >= 1300
2821# pragma GCC diagnostic pop
2822#endif
2823 exp_ = other.exp_;
2824 }
2825
2826 template <typename Int> FMT_CONSTEXPR20 void operator=(Int n) {
2827 FMT_ASSERT(n > 0, "");
2828 assign(uint64_or_128_t<Int>(n));
2829 }
2830
2832 return static_cast<int>(bigits_.size()) + exp_;
2833 }
2834
2836 FMT_ASSERT(shift >= 0, "");
2837 exp_ += shift / bigit_bits;
2838 shift %= bigit_bits;
2839 if (shift == 0) return *this;
2840 bigit carry = 0;
2841 for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2842 bigit c = bigits_[i] >> (bigit_bits - shift);
2843 bigits_[i] = (bigits_[i] << shift) + carry;
2844 carry = c;
2845 }
2846 if (carry != 0) bigits_.push_back(carry);
2847 return *this;
2848 }
2849
2850 template <typename Int> FMT_CONSTEXPR20 bigint& operator*=(Int value) {
2851 FMT_ASSERT(value > 0, "");
2853 return *this;
2854 }
2855
2856 friend FMT_CONSTEXPR20 int compare(const bigint& lhs, const bigint& rhs) {
2857 int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
2858 if (num_lhs_bigits != num_rhs_bigits)
2859 return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
2860 int i = static_cast<int>(lhs.bigits_.size()) - 1;
2861 int j = static_cast<int>(rhs.bigits_.size()) - 1;
2862 int end = i - j;
2863 if (end < 0) end = 0;
2864 for (; i >= end; --i, --j) {
2865 bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
2866 if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
2867 }
2868 if (i != j) return i > j ? 1 : -1;
2869 return 0;
2870 }
2871
2872 // Returns compare(lhs1 + lhs2, rhs).
2873 friend FMT_CONSTEXPR20 int add_compare(const bigint& lhs1, const bigint& lhs2,
2874 const bigint& rhs) {
2875 auto minimum = [](int a, int b) { return a < b ? a : b; };
2876 auto maximum = [](int a, int b) { return a > b ? a : b; };
2877 int max_lhs_bigits = maximum(lhs1.num_bigits(), lhs2.num_bigits());
2878 int num_rhs_bigits = rhs.num_bigits();
2879 if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
2880 if (max_lhs_bigits > num_rhs_bigits) return 1;
2881 auto get_bigit = [](const bigint& n, int i) -> bigit {
2882 return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
2883 };
2884 double_bigit borrow = 0;
2885 int min_exp = minimum(minimum(lhs1.exp_, lhs2.exp_), rhs.exp_);
2886 for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
2887 double_bigit sum =
2888 static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
2889 bigit rhs_bigit = get_bigit(rhs, i);
2890 if (sum > rhs_bigit + borrow) return 1;
2891 borrow = rhs_bigit + borrow - sum;
2892 if (borrow > 1) return -1;
2893 borrow <<= bigit_bits;
2894 }
2895 return borrow != 0 ? -1 : 0;
2896 }
2897
2898 // Assigns pow(10, exp) to this bigint.
2900 FMT_ASSERT(exp >= 0, "");
2901 if (exp == 0) return *this = 1;
2902 // Find the top bit.
2903 int bitmask = 1;
2904 while (exp >= bitmask) bitmask <<= 1;
2905 bitmask >>= 1;
2906 // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
2907 // repeated squaring and multiplication.
2908 *this = 5;
2909 bitmask >>= 1;
2910 while (bitmask != 0) {
2911 square();
2912 if ((exp & bitmask) != 0) *this *= 5;
2913 bitmask >>= 1;
2914 }
2915 *this <<= exp; // Multiply by pow(2, exp) by shifting.
2916 }
2917
2919 int num_bigits = static_cast<int>(bigits_.size());
2920 int num_result_bigits = 2 * num_bigits;
2921 basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
2922 bigits_.resize(to_unsigned(num_result_bigits));
2923 auto sum = uint128_t();
2924 for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
2925 // Compute bigit at position bigit_index of the result by adding
2926 // cross-product terms n[i] * n[j] such that i + j == bigit_index.
2927 for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
2928 // Most terms are multiplied twice which can be optimized in the future.
2929 sum += static_cast<double_bigit>(n[i]) * n[j];
2930 }
2931 (*this)[bigit_index] = static_cast<bigit>(sum);
2932 sum >>= num_bits<bigit>(); // Compute the carry.
2933 }
2934 // Do the same for the top half.
2935 for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
2936 ++bigit_index) {
2937 for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
2938 sum += static_cast<double_bigit>(n[i++]) * n[j--];
2939 (*this)[bigit_index] = static_cast<bigit>(sum);
2940 sum >>= num_bits<bigit>();
2941 }
2942 remove_leading_zeros();
2943 exp_ *= 2;
2944 }
2945
2946 // If this bigint has a bigger exponent than other, adds trailing zero to make
2947 // exponents equal. This simplifies some operations such as subtraction.
2948 FMT_CONSTEXPR20 void align(const bigint& other) {
2949 int exp_difference = exp_ - other.exp_;
2950 if (exp_difference <= 0) return;
2951 int num_bigits = static_cast<int>(bigits_.size());
2952 bigits_.resize(to_unsigned(num_bigits + exp_difference));
2953 for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
2954 bigits_[j] = bigits_[i];
2955 std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
2956 exp_ -= exp_difference;
2957 }
2958
2959 // Divides this bignum by divisor, assigning the remainder to this and
2960 // returning the quotient.
2962 FMT_ASSERT(this != &divisor, "");
2963 if (compare(*this, divisor) < 0) return 0;
2964 FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
2965 align(divisor);
2966 int quotient = 0;
2967 do {
2968 subtract_aligned(divisor);
2969 ++quotient;
2970 } while (compare(*this, divisor) >= 0);
2971 return quotient;
2972 }
2973};
2974
2975// format_dragon flags.
2978 fixup = 2, // Run fixup to correct exp10 which can be off by one.
2980};
2981
2982// Formats a floating-point number using a variation of the Fixed-Precision
2983// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
2984// https://fmt.dev/papers/p372-steele.pdf.
2986 unsigned flags, int num_digits,
2987 buffer<char>& buf, int& exp10) {
2988 bigint numerator; // 2 * R in (FPP)^2.
2989 bigint denominator; // 2 * S in (FPP)^2.
2990 // lower and upper are differences between value and corresponding boundaries.
2991 bigint lower; // (M^- in (FPP)^2).
2992 bigint upper_store; // upper's value if different from lower.
2993 bigint* upper = nullptr; // (M^+ in (FPP)^2).
2994 // Shift numerator and denominator by an extra bit or two (if lower boundary
2995 // is closer) to make lower and upper integers. This eliminates multiplication
2996 // by 2 during later computations.
2997 bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0;
2998 int shift = is_predecessor_closer ? 2 : 1;
2999 if (value.e >= 0) {
3000 numerator = value.f;
3001 numerator <<= value.e + shift;
3002 lower = 1;
3003 lower <<= value.e;
3004 if (is_predecessor_closer) {
3005 upper_store = 1;
3006 upper_store <<= value.e + 1;
3007 upper = &upper_store;
3008 }
3009 denominator.assign_pow10(exp10);
3010 denominator <<= shift;
3011 } else if (exp10 < 0) {
3012 numerator.assign_pow10(-exp10);
3013 lower.assign(numerator);
3014 if (is_predecessor_closer) {
3015 upper_store.assign(numerator);
3016 upper_store <<= 1;
3017 upper = &upper_store;
3018 }
3019 numerator *= value.f;
3020 numerator <<= shift;
3021 denominator = 1;
3022 denominator <<= shift - value.e;
3023 } else {
3024 numerator = value.f;
3025 numerator <<= shift;
3026 denominator.assign_pow10(exp10);
3027 denominator <<= shift - value.e;
3028 lower = 1;
3029 if (is_predecessor_closer) {
3030 upper_store = 1ULL << 1;
3031 upper = &upper_store;
3032 }
3033 }
3034 int even = static_cast<int>((value.f & 1) == 0);
3035 if (!upper) upper = &lower;
3036 if ((flags & dragon::fixup) != 0) {
3037 if (add_compare(numerator, *upper, denominator) + even <= 0) {
3038 --exp10;
3039 numerator *= 10;
3040 if (num_digits < 0) {
3041 lower *= 10;
3042 if (upper != &lower) *upper *= 10;
3043 }
3044 }
3045 if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1);
3046 }
3047 // Invariant: value == (numerator / denominator) * pow(10, exp10).
3048 if (num_digits < 0) {
3049 // Generate the shortest representation.
3050 num_digits = 0;
3051 char* data = buf.data();
3052 for (;;) {
3053 int digit = numerator.divmod_assign(denominator);
3054 bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower.
3055 // numerator + upper >[=] pow10:
3056 bool high = add_compare(numerator, *upper, denominator) + even > 0;
3057 data[num_digits++] = static_cast<char>('0' + digit);
3058 if (low || high) {
3059 if (!low) {
3060 ++data[num_digits - 1];
3061 } else if (high) {
3062 int result = add_compare(numerator, numerator, denominator);
3063 // Round half to even.
3064 if (result > 0 || (result == 0 && (digit % 2) != 0))
3065 ++data[num_digits - 1];
3066 }
3067 buf.try_resize(to_unsigned(num_digits));
3068 exp10 -= num_digits - 1;
3069 return;
3070 }
3071 numerator *= 10;
3072 lower *= 10;
3073 if (upper != &lower) *upper *= 10;
3074 }
3075 }
3076 // Generate the given number of digits.
3077 exp10 -= num_digits - 1;
3078 if (num_digits == 0) {
3079 denominator *= 10;
3080 auto digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
3081 buf.push_back(digit);
3082 return;
3083 }
3084 buf.try_resize(to_unsigned(num_digits));
3085 for (int i = 0; i < num_digits - 1; ++i) {
3086 int digit = numerator.divmod_assign(denominator);
3087 buf[i] = static_cast<char>('0' + digit);
3088 numerator *= 10;
3089 }
3090 int digit = numerator.divmod_assign(denominator);
3091 auto result = add_compare(numerator, numerator, denominator);
3092 if (result > 0 || (result == 0 && (digit % 2) != 0)) {
3093 if (digit == 9) {
3094 const auto overflow = '0' + 10;
3095 buf[num_digits - 1] = overflow;
3096 // Propagate the carry.
3097 for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
3098 buf[i] = '0';
3099 ++buf[i - 1];
3100 }
3101 if (buf[0] == overflow) {
3102 buf[0] = '1';
3103 ++exp10;
3104 }
3105 return;
3106 }
3107 ++digit;
3108 }
3109 buf[num_digits - 1] = static_cast<char>('0' + digit);
3110}
3111
3112template <typename Float>
3113FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
3114 buffer<char>& buf) -> int {
3115 // float is passed as double to reduce the number of instantiations.
3116 static_assert(!std::is_same<Float, float>::value, "");
3117 FMT_ASSERT(value >= 0, "value is negative");
3118 auto converted_value = convert_float(value);
3119
3120 const bool fixed = specs.format == float_format::fixed;
3121 if (value <= 0) { // <= instead of == to silence a warning.
3122 if (precision <= 0 || !fixed) {
3123 buf.push_back('0');
3124 return 0;
3125 }
3126 buf.try_resize(to_unsigned(precision));
3127 fill_n(buf.data(), precision, '0');
3128 return -precision;
3129 }
3130
3131 int exp = 0;
3132 bool use_dragon = true;
3133 unsigned dragon_flags = 0;
3134 if (!is_fast_float<Float>()) {
3135 const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10)
3136 using info = dragonbox::float_info<decltype(converted_value)>;
3137 const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3138 // Compute exp, an approximate power of 10, such that
3139 // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3140 // This is based on log10(value) == log2(value) / log2(10) and approximation
3141 // of log2(value) by e + num_fraction_bits idea from double-conversion.
3142 exp = static_cast<int>(
3143 std::ceil((f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10));
3144 dragon_flags = dragon::fixup;
3145 } else if (!is_constant_evaluated() && precision < 0) {
3146 // Use Dragonbox for the shortest format.
3147 if (specs.binary32) {
3148 auto dec = dragonbox::to_decimal(static_cast<float>(value));
3149 write<char>(buffer_appender<char>(buf), dec.significand);
3150 return dec.exponent;
3151 }
3152 auto dec = dragonbox::to_decimal(static_cast<double>(value));
3153 write<char>(buffer_appender<char>(buf), dec.significand);
3154 return dec.exponent;
3155 } else {
3156 // Use Grisu + Dragon4 for the given precision:
3157 // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf.
3158 const int min_exp = -60; // alpha in Grisu.
3159 int cached_exp10 = 0; // K in Grisu.
3160 fp normalized = normalize(fp(converted_value));
3161 const auto cached_pow = get_cached_power(
3162 min_exp - (normalized.e + fp::num_significand_bits), cached_exp10);
3163 normalized = normalized * cached_pow;
3164 gen_digits_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
3165 if (grisu_gen_digits(normalized, 1, exp, handler) != digits::error &&
3167 exp += handler.exp10;
3168 buf.try_resize(to_unsigned(handler.size));
3169 use_dragon = false;
3170 } else {
3171 exp += handler.size - cached_exp10 - 1;
3172 precision = handler.precision;
3173 }
3174 }
3175 if (use_dragon) {
3176 auto f = basic_fp<uint128_t>();
3177 bool is_predecessor_closer = specs.binary32
3178 ? f.assign(static_cast<float>(value))
3179 : f.assign(converted_value);
3180 if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3181 if (fixed) dragon_flags |= dragon::fixed;
3182 // Limit precision to the maximum possible number of significant digits in
3183 // an IEEE754 double because we don't need to generate zeros.
3184 const int max_double_digits = 767;
3185 if (precision > max_double_digits) precision = max_double_digits;
3186 format_dragon(f, dragon_flags, precision, buf, exp);
3187 }
3188 if (!fixed && !specs.showpoint) {
3189 // Remove trailing zeros.
3190 auto num_digits = buf.size();
3191 while (num_digits > 0 && buf[num_digits - 1] == '0') {
3192 --num_digits;
3193 ++exp;
3194 }
3195 buf.try_resize(num_digits);
3196 }
3197 return exp;
3198}
3199
3200template <typename Char, typename OutputIt, typename T,
3201 FMT_ENABLE_IF(is_floating_point<T>::value)>
3202FMT_CONSTEXPR20 auto write(OutputIt out, T value,
3203 basic_format_specs<Char> specs, locale_ref loc = {})
3204 -> OutputIt {
3206 float_specs fspecs = parse_float_type_spec(specs);
3207 fspecs.sign = specs.sign;
3208 if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit.
3209 fspecs.sign = sign::minus;
3210 value = -value;
3211 } else if (fspecs.sign == sign::minus) {
3212 fspecs.sign = sign::none;
3213 }
3214
3215 if (!detail::isfinite(value))
3216 return write_nonfinite(out, detail::isnan(value), specs, fspecs);
3217
3218 if (specs.align == align::numeric && fspecs.sign) {
3219 auto it = reserve(out, 1);
3220 *it++ = detail::sign<Char>(fspecs.sign);
3221 out = base_iterator(out, it);
3222 fspecs.sign = sign::none;
3223 if (specs.width != 0) --specs.width;
3224 }
3225
3227 if (fspecs.format == float_format::hex) {
3228 if (fspecs.sign) buffer.push_back(detail::sign<char>(fspecs.sign));
3230 return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
3231 specs);
3232 }
3233 int precision = specs.precision >= 0 || specs.type == presentation_type::none
3234 ? specs.precision
3235 : 6;
3236 if (fspecs.format == float_format::exp) {
3237 if (precision == max_value<int>())
3238 throw_format_error("number is too big");
3239 else
3240 ++precision;
3241 } else if (fspecs.format != float_format::fixed && precision == 0) {
3242 precision = 1;
3243 }
3244 if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
3245 int exp = format_float(convert_float(value), precision, fspecs, buffer);
3246 fspecs.precision = precision;
3247 auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3248 return write_float(out, f, specs, fspecs, loc);
3249}
3250
3251template <typename Char, typename OutputIt, typename T,
3252 FMT_ENABLE_IF(is_fast_float<T>::value)>
3253FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3255 return write(out, value, basic_format_specs<Char>());
3257
3258 auto fspecs = float_specs();
3259 if (detail::signbit(value)) {
3260 fspecs.sign = sign::minus;
3261 value = -value;
3262 }
3263
3264 constexpr auto specs = basic_format_specs<Char>();
3265 using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
3266 using uint = typename dragonbox::float_info<floaty>::carrier_uint;
3267 uint mask = exponent_mask<floaty>();
3268 if ((bit_cast<uint>(value) & mask) == mask)
3269 return write_nonfinite(out, std::isnan(value), specs, fspecs);
3270
3271 auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
3272 return write_float(out, dec, specs, fspecs, {});
3273}
3274
3275template <typename Char, typename OutputIt, typename T,
3276 FMT_ENABLE_IF(is_floating_point<T>::value &&
3277 !is_fast_float<T>::value)>
3278inline auto write(OutputIt out, T value) -> OutputIt {
3279 return write(out, value, basic_format_specs<Char>());
3280}
3281
3282template <typename Char, typename OutputIt>
3284 locale_ref = {}) -> OutputIt {
3285 FMT_ASSERT(false, "");
3286 return out;
3287}
3288
3289template <typename Char, typename OutputIt>
3291 -> OutputIt {
3292 auto it = reserve(out, value.size());
3293 it = copy_str_noinline<Char>(value.begin(), value.end(), it);
3294 return base_iterator(out, it);
3295}
3296
3297template <typename Char, typename OutputIt, typename T,
3299constexpr auto write(OutputIt out, const T& value) -> OutputIt {
3300 return write<Char>(out, to_string_view(value));
3301}
3302
3303// FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
3304template <
3305 typename Char, typename OutputIt, typename T,
3306 bool check =
3307 std::is_enum<T>::value && !std::is_same<T, Char>::value &&
3310 FMT_ENABLE_IF(check)>
3311FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
3312 return write<Char>(out, static_cast<underlying_t<T>>(value));
3313}
3314
3315template <typename Char, typename OutputIt, typename T,
3316 FMT_ENABLE_IF(std::is_same<T, bool>::value)>
3317FMT_CONSTEXPR auto write(OutputIt out, T value,
3318 const basic_format_specs<Char>& specs = {},
3319 locale_ref = {}) -> OutputIt {
3320 return specs.type != presentation_type::none &&
3322 ? write(out, value ? 1 : 0, specs, {})
3323 : write_bytes(out, value ? "true" : "false", specs);
3324}
3325
3326template <typename Char, typename OutputIt>
3327FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
3328 auto it = reserve(out, 1);
3329 *it++ = value;
3330 return base_iterator(out, it);
3331}
3332
3333template <typename Char, typename OutputIt>
3334FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
3335 -> OutputIt {
3336 if (!value) {
3337 throw_format_error("string pointer is null");
3338 } else {
3339 out = write(out, basic_string_view<Char>(value));
3340 }
3341 return out;
3342}
3343
3344template <typename Char, typename OutputIt, typename T,
3345 FMT_ENABLE_IF(std::is_same<T, void>::value)>
3346auto write(OutputIt out, const T* value,
3347 const basic_format_specs<Char>& specs = {}, locale_ref = {})
3348 -> OutputIt {
3350 return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
3351}
3352
3353// A write overload that handles implicit conversions.
3354template <typename Char, typename OutputIt, typename T,
3355 typename Context = basic_format_context<OutputIt, Char>>
3356FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> enable_if_t<
3357 std::is_class<T>::value && !is_string<T>::value &&
3358 !is_floating_point<T>::value && !std::is_same<T, Char>::value &&
3359 !std::is_same<const T&,
3360 decltype(arg_mapper<Context>().map(value))>::value,
3361 OutputIt> {
3362 return write<Char>(out, arg_mapper<Context>().map(value));
3363}
3364
3365template <typename Char, typename OutputIt, typename T,
3366 typename Context = basic_format_context<OutputIt, Char>>
3367FMT_CONSTEXPR auto write(OutputIt out, const T& value)
3369 OutputIt> {
3370 using formatter_type =
3372 typename Context::template formatter_type<T>,
3374 auto ctx = Context(out, {}, {});
3375 return formatter_type().format(value, ctx);
3376}
3377
3378// An argument visitor that formats the argument and writes it via the output
3379// iterator. It's a class and not a generic lambda for compatibility with C++11.
3380template <typename Char> struct default_arg_formatter {
3383
3387
3388 template <typename T> auto operator()(T value) -> iterator {
3389 return write<Char>(out, value);
3390 }
3393 context format_ctx(out, args, loc);
3394 h.format(parse_ctx, format_ctx);
3395 return format_ctx.out();
3396 }
3397};
3398
3399template <typename Char> struct arg_formatter {
3402
3406
3407 template <typename T>
3409 return detail::write(out, value, specs, locale);
3410 }
3412 // User-defined types are handled separately because they require access
3413 // to the parse context.
3414 return out;
3415 }
3416};
3417
3418template <typename Char> struct custom_formatter {
3421
3423 typename basic_format_arg<buffer_context<Char>>::handle h) const {
3424 h.format(parse_ctx, ctx);
3425 }
3426 template <typename T> void operator()(T) const {}
3427};
3428
3429template <typename T>
3431 bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
3432 !std::is_same<T, char>::value &&
3433 !std::is_same<T, wchar_t>::value>;
3434
3435template <typename ErrorHandler> class width_checker {
3436 public:
3437 explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}
3438
3439 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3440 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3441 if (is_negative(value)) handler_.on_error("negative width");
3442 return static_cast<unsigned long long>(value);
3443 }
3444
3445 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3446 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3447 handler_.on_error("width is not integer");
3448 return 0;
3449 }
3450
3451 private:
3452 ErrorHandler& handler_;
3453};
3454
3455template <typename ErrorHandler> class precision_checker {
3456 public:
3457 explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}
3458
3459 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3460 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3461 if (is_negative(value)) handler_.on_error("negative precision");
3462 return static_cast<unsigned long long>(value);
3463 }
3464
3465 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3466 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3467 handler_.on_error("precision is not integer");
3468 return 0;
3469 }
3470
3471 private:
3472 ErrorHandler& handler_;
3473};
3474
3475template <template <typename> class Handler, typename FormatArg,
3476 typename ErrorHandler>
3477FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int {
3478 unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg);
3479 if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big");
3480 return static_cast<int>(value);
3481}
3482
3483template <typename Context, typename ID>
3484FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) ->
3485 typename Context::format_arg {
3486 auto arg = ctx.arg(id);
3487 if (!arg) ctx.on_error("argument not found");
3488 return arg;
3489}
3490
3491// The standard format specifier handler with checking.
3492template <typename Char> class specs_handler : public specs_setter<Char> {
3493 private:
3494 basic_format_parse_context<Char>& parse_context_;
3495 buffer_context<Char>& context_;
3496
3497 // This is only needed for compatibility with gcc 4.4.
3499
3501 return detail::get_arg(context_, parse_context_.next_arg_id());
3502 }
3503
3504 FMT_CONSTEXPR auto get_arg(int arg_id) -> format_arg {
3505 parse_context_.check_arg_id(arg_id);
3506 return detail::get_arg(context_, arg_id);
3507 }
3508
3510 parse_context_.check_arg_id(arg_id);
3511 return detail::get_arg(context_, arg_id);
3512 }
3513
3514 public:
3518 : specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {}
3519
3520 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
3521 this->specs_.width = get_dynamic_spec<width_checker>(
3522 get_arg(arg_id), context_.error_handler());
3523 }
3524
3525 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
3526 this->specs_.precision = get_dynamic_spec<precision_checker>(
3527 get_arg(arg_id), context_.error_handler());
3528 }
3529
3530 void on_error(const char* message) { context_.on_error(message); }
3531};
3532
3533template <template <typename> class Handler, typename Context>
3536 Context& ctx) {
3537 switch (ref.kind) {
3538 case arg_id_kind::none:
3539 break;
3540 case arg_id_kind::index:
3541 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.index),
3542 ctx.error_handler());
3543 break;
3544 case arg_id_kind::name:
3545 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
3546 ctx.error_handler());
3547 break;
3548 }
3549}
3550
3551#if FMT_USE_USER_DEFINED_LITERALS
3552template <typename Char> struct udl_formatter {
3554
3555 template <typename... T>
3556 auto operator()(T&&... args) const -> std::basic_string<Char> {
3557 return vformat(str, fmt::make_format_args<buffer_context<Char>>(args...));
3558 }
3559};
3560
3561# if FMT_USE_NONTYPE_TEMPLATE_ARGS
3562template <typename T, typename Char, size_t N,
3563 fmt::detail_exported::fixed_string<Char, N> Str>
3564struct statically_named_arg : view {
3565 static constexpr auto name = Str.data;
3566
3567 const T& value;
3568 statically_named_arg(const T& v) : value(v) {}
3569};
3570
3571template <typename T, typename Char, size_t N,
3572 fmt::detail_exported::fixed_string<Char, N> Str>
3573struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
3574
3575template <typename T, typename Char, size_t N,
3576 fmt::detail_exported::fixed_string<Char, N> Str>
3577struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
3578 : std::true_type {};
3579
3580template <typename Char, size_t N,
3581 fmt::detail_exported::fixed_string<Char, N> Str>
3582struct udl_arg {
3583 template <typename T> auto operator=(T&& value) const {
3584 return statically_named_arg<T, Char, N, Str>(std::forward<T>(value));
3585 }
3586};
3587# else
3588template <typename Char> struct udl_arg {
3589 const Char* str;
3590
3591 template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
3592 return {str, std::forward<T>(value)};
3593 }
3594};
3595# endif
3596#endif // FMT_USE_USER_DEFINED_LITERALS
3597
3598template <typename Locale, typename Char>
3599auto vformat(const Locale& loc, basic_string_view<Char> format_str,
3601 -> std::basic_string<Char> {
3603 detail::vformat_to(buffer, format_str, args, detail::locale_ref(loc));
3604 return {buffer.data(), buffer.size()};
3605}
3606
3607using format_func = void (*)(detail::buffer<char>&, int, const char*);
3608
3609FMT_API void format_error_code(buffer<char>& out, int error_code,
3610 string_view message) noexcept;
3611
3612FMT_API void report_error(format_func func, int error_code,
3613 const char* message) noexcept;
3615
3616FMT_API auto vsystem_error(int error_code, string_view format_str,
3618
3619/**
3620 \rst
3621 Constructs :class:`std::system_error` with a message formatted with
3622 ``fmt::format(fmt, args...)``.
3623 *error_code* is a system error code as given by ``errno``.
3624
3625 **Example**::
3626
3627 // This throws std::system_error with the description
3628 // cannot open file 'madeup': No such file or directory
3629 // or similar (system message may vary).
3630 const char* filename = "madeup";
3631 std::FILE* file = std::fopen(filename, "r");
3632 if (!file)
3633 throw fmt::system_error(errno, "cannot open file '{}'", filename);
3634 \endrst
3635*/
3636template <typename... T>
3637auto system_error(int error_code, format_string<T...> fmt, T&&... args)
3639 return vsystem_error(error_code, fmt, fmt::make_format_args(args...));
3640}
3641
3642/**
3643 \rst
3644 Formats an error message for an error returned by an operating system or a
3645 language runtime, for example a file opening error, and writes it to *out*.
3646 The format is the same as the one used by ``std::system_error(ec, message)``
3647 where ``ec`` is ``std::error_code(error_code, std::generic_category()})``.
3648 It is implementation-defined but normally looks like:
3649
3650 .. parsed-literal::
3651 *<message>*: *<system-message>*
3652
3653 where *<message>* is the passed message and *<system-message>* is the system
3654 message corresponding to the error code.
3655 *error_code* is a system error code as given by ``errno``.
3656 \endrst
3657 */
3658FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
3659 const char* message) noexcept;
3660
3661// Reports a system error without throwing an exception.
3662// Can be used to report errors from destructors.
3663FMT_API void report_system_error(int error_code, const char* message) noexcept;
3664
3665/** Fast integer formatter. */
3667 private:
3668 // Buffer should be large enough to hold all digits (digits10 + 1),
3669 // a sign and a null character.
3670 enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
3671 mutable char buffer_[buffer_size];
3672 char* str_;
3673
3674 template <typename UInt> auto format_unsigned(UInt value) -> char* {
3675 auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
3676 return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
3677 }
3678
3679 template <typename Int> auto format_signed(Int value) -> char* {
3680 auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
3681 bool negative = value < 0;
3682 if (negative) abs_value = 0 - abs_value;
3683 auto begin = format_unsigned(abs_value);
3684 if (negative) *--begin = '-';
3685 return begin;
3686 }
3687
3688 public:
3689 explicit format_int(int value) : str_(format_signed(value)) {}
3690 explicit format_int(long value) : str_(format_signed(value)) {}
3691 explicit format_int(long long value) : str_(format_signed(value)) {}
3692 explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
3693 explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
3694 explicit format_int(unsigned long long value)
3695 : str_(format_unsigned(value)) {}
3696
3697 /** Returns the number of characters written to the output buffer. */
3698 auto size() const -> size_t {
3699 return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
3700 }
3701
3702 /**
3703 Returns a pointer to the output buffer content. No terminating null
3704 character is appended.
3705 */
3706 auto data() const -> const char* { return str_; }
3707
3708 /**
3709 Returns a pointer to the output buffer content with terminating null
3710 character appended.
3711 */
3712 auto c_str() const -> const char* {
3713 buffer_[buffer_size - 1] = '\0';
3714 return str_;
3715 }
3716
3717 /**
3718 \rst
3719 Returns the content of the output buffer as an ``std::string``.
3720 \endrst
3721 */
3722 auto str() const -> std::string { return std::string(str_, size()); }
3723};
3724
3725template <typename T, typename Char>
3726template <typename FormatContext>
3728formatter<T, Char,
3730 detail::type::custom_type>>::format(const T& val,
3731 FormatContext& ctx)
3732 const -> decltype(ctx.out()) {
3733 if (specs_.width_ref.kind != detail::arg_id_kind::none ||
3734 specs_.precision_ref.kind != detail::arg_id_kind::none) {
3735 auto specs = specs_;
3736 detail::handle_dynamic_spec<detail::width_checker>(specs.width,
3737 specs.width_ref, ctx);
3738 detail::handle_dynamic_spec<detail::precision_checker>(
3739 specs.precision, specs.precision_ref, ctx);
3740 return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
3741 }
3742 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
3743}
3744
3745template <typename Char>
3747 template <typename FormatContext>
3748 auto format(void* val, FormatContext& ctx) const -> decltype(ctx.out()) {
3749 return formatter<const void*, Char>::format(val, ctx);
3750 }
3751};
3752
3753template <typename Char, size_t N>
3754struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
3755 template <typename FormatContext>
3756 FMT_CONSTEXPR auto format(const Char* val, FormatContext& ctx) const
3757 -> decltype(ctx.out()) {
3758 return formatter<basic_string_view<Char>, Char>::format(val, ctx);
3759 }
3760};
3761
3762// A formatter for types known only at run time such as variant alternatives.
3763//
3764// Usage:
3765// using variant = std::variant<int, std::string>;
3766// template <>
3767// struct formatter<variant>: dynamic_formatter<> {
3768// auto format(const variant& v, format_context& ctx) {
3769// return visit([&](const auto& val) {
3770// return dynamic_formatter<>::format(val, ctx);
3771// }, v);
3772// }
3773// };
3774template <typename Char = char> class dynamic_formatter {
3775 private:
3776 detail::dynamic_format_specs<Char> specs_;
3777 const Char* format_str_;
3778
3779 struct null_handler : detail::error_handler {
3780 void on_align(align_t) {}
3781 void on_sign(sign_t) {}
3782 void on_hash() {}
3783 };
3784
3785 template <typename Context> void handle_specs(Context& ctx) {
3786 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
3787 specs_.width_ref, ctx);
3788 detail::handle_dynamic_spec<detail::precision_checker>(
3789 specs_.precision, specs_.precision_ref, ctx);
3790 }
3791
3792 public:
3793 template <typename ParseContext>
3794 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3795 format_str_ = ctx.begin();
3796 // Checks are deferred to formatting time when the argument type is known.
3797 detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
3798 return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
3799 }
3800
3801 template <typename T, typename FormatContext>
3802 auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3803 handle_specs(ctx);
3804 detail::specs_checker<null_handler> checker(
3805 null_handler(), detail::mapped_type_constant<T, FormatContext>::value);
3806 checker.on_align(specs_.align);
3807 if (specs_.sign != sign::none) checker.on_sign(specs_.sign);
3808 if (specs_.alt) checker.on_hash();
3809 if (specs_.precision >= 0) checker.end_precision();
3810 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
3811 }
3812};
3813
3814/**
3815 \rst
3816 Converts ``p`` to ``const void*`` for pointer formatting.
3817
3818 **Example**::
3819
3820 auto s = fmt::format("{}", fmt::ptr(p));
3821 \endrst
3822 */
3823template <typename T> auto ptr(T p) -> const void* {
3824 static_assert(std::is_pointer<T>::value, "");
3825 return detail::bit_cast<const void*>(p);
3826}
3827template <typename T> auto ptr(const std::unique_ptr<T>& p) -> const void* {
3828 return p.get();
3829}
3830template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
3831 return p.get();
3832}
3833
3834/**
3835 \rst
3836 Converts ``e`` to the underlying type.
3837
3838 **Example**::
3839
3840 enum class color { red, green, blue };
3841 auto s = fmt::format("{}", fmt::underlying(color::red));
3842 \endrst
3843 */
3844template <typename Enum>
3845constexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {
3846 return static_cast<underlying_t<Enum>>(e);
3847}
3848
3849namespace enums {
3850template <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
3851constexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {
3852 return static_cast<underlying_t<Enum>>(e);
3853}
3854} // namespace enums
3855
3856class bytes {
3857 private:
3859 friend struct formatter<bytes>;
3860
3861 public:
3862 explicit bytes(string_view data) : data_(data) {}
3863};
3864
3865template <> struct formatter<bytes> {
3866 private:
3867 detail::dynamic_format_specs<char> specs_;
3868
3869 public:
3870 template <typename ParseContext>
3871 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3872 using handler_type = detail::dynamic_specs_handler<ParseContext>;
3873 detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
3874 detail::type::string_type);
3875 auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
3876 detail::check_string_type_spec(specs_.type, ctx.error_handler());
3877 return it;
3878 }
3879
3880 template <typename FormatContext>
3881 auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
3882 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
3883 specs_.width_ref, ctx);
3884 detail::handle_dynamic_spec<detail::precision_checker>(
3885 specs_.precision, specs_.precision_ref, ctx);
3886 return detail::write_bytes(ctx.out(), b.data_, specs_);
3887 }
3888};
3889
3890// group_digits_view is not derived from view because it copies the argument.
3891template <typename T> struct group_digits_view { T value; };
3892
3893/**
3894 \rst
3895 Returns a view that formats an integer value using ',' as a locale-independent
3896 thousands separator.
3897
3898 **Example**::
3899
3900 fmt::print("{}", fmt::group_digits(12345));
3901 // Output: "12,345"
3902 \endrst
3903 */
3904template <typename T> auto group_digits(T value) -> group_digits_view<T> {
3905 return {value};
3906}
3907
3908template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
3909 private:
3910 detail::dynamic_format_specs<char> specs_;
3911
3912 public:
3913 template <typename ParseContext>
3914 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3915 using handler_type = detail::dynamic_specs_handler<ParseContext>;
3916 detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
3917 detail::type::int_type);
3918 auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
3919 detail::check_string_type_spec(specs_.type, ctx.error_handler());
3920 return it;
3921 }
3922
3923 template <typename FormatContext>
3924 auto format(group_digits_view<T> t, FormatContext& ctx)
3925 -> decltype(ctx.out()) {
3926 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
3927 specs_.width_ref, ctx);
3928 detail::handle_dynamic_spec<detail::precision_checker>(
3929 specs_.precision, specs_.precision_ref, ctx);
3931 ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_,
3932 detail::digit_grouping<char>({"\3", ','}));
3933 }
3934};
3935
3936template <typename It, typename Sentinel, typename Char = char>
3937struct join_view : detail::view {
3939 Sentinel end;
3941
3943 : begin(b), end(e), sep(s) {}
3944};
3945
3946template <typename It, typename Sentinel, typename Char>
3947struct formatter<join_view<It, Sentinel, Char>, Char> {
3948 private:
3949 using value_type =
3950#ifdef __cpp_lib_ranges
3951 std::iter_value_t<It>;
3952#else
3953 typename std::iterator_traits<It>::value_type;
3954#endif
3956 using mapper = detail::arg_mapper<context>;
3957
3958 template <typename T, FMT_ENABLE_IF(has_formatter<T, context>::value)>
3959 static auto map(const T& value) -> const T& {
3960 return value;
3961 }
3962 template <typename T, FMT_ENABLE_IF(!has_formatter<T, context>::value)>
3963 static auto map(const T& value) -> decltype(mapper().map(value)) {
3964 return mapper().map(value);
3965 }
3966
3967 using formatter_type =
3969 formatter<remove_cvref_t<decltype(map(
3970 std::declval<const value_type&>()))>,
3971 Char>,
3972 detail::fallback_formatter<value_type, Char>>;
3973
3974 formatter_type value_formatter_;
3975
3976 public:
3977 template <typename ParseContext>
3978 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3979 return value_formatter_.parse(ctx);
3980 }
3981
3982 template <typename FormatContext>
3984 FormatContext& ctx) const -> decltype(ctx.out()) {
3985 auto it = value.begin;
3986 auto out = ctx.out();
3987 if (it != value.end) {
3988 out = value_formatter_.format(map(*it), ctx);
3989 ++it;
3990 while (it != value.end) {
3991 out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
3992 ctx.advance_to(out);
3993 out = value_formatter_.format(map(*it), ctx);
3994 ++it;
3995 }
3996 }
3997 return out;
3998 }
3999};
4000
4001/**
4002 Returns a view that formats the iterator range `[begin, end)` with elements
4003 separated by `sep`.
4004 */
4005template <typename It, typename Sentinel>
4006auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
4007 return {begin, end, sep};
4008}
4009
4010/**
4011 \rst
4012 Returns a view that formats `range` with elements separated by `sep`.
4013
4014 **Example**::
4015
4016 std::vector<int> v = {1, 2, 3};
4017 fmt::print("{}", fmt::join(v, ", "));
4018 // Output: "1, 2, 3"
4019
4020 ``fmt::join`` applies passed format specifiers to the range elements::
4021
4022 fmt::print("{:02}", fmt::join(v, ", "));
4023 // Output: "01, 02, 03"
4024 \endrst
4025 */
4026template <typename Range>
4027auto join(Range&& range, string_view sep)
4029 return join(std::begin(range), std::end(range), sep);
4030}
4031
4032/**
4033 \rst
4034 Converts *value* to ``std::string`` using the default format for type *T*.
4035
4036 **Example**::
4037
4038 #include <fmt/format.h>
4039
4040 std::string answer = fmt::to_string(42);
4041 \endrst
4042 */
4043template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
4044inline auto to_string(const T& value) -> std::string {
4045 auto result = std::string();
4046 detail::write<char>(std::back_inserter(result), value);
4047 return result;
4048}
4049
4050template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
4051FMT_NODISCARD inline auto to_string(T value) -> std::string {
4052 // The buffer should be large enough to store the number including the sign
4053 // or "false" for bool.
4054 constexpr int max_size = detail::digits10<T>() + 2;
4055 char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
4056 char* begin = buffer;
4057 return std::string(begin, detail::write<char>(begin, value));
4058}
4059
4060template <typename Char, size_t SIZE>
4062 -> std::basic_string<Char> {
4063 auto size = buf.size();
4064 detail::assume(size < std::basic_string<Char>().max_size());
4065 return std::basic_string<Char>(buf.data(), size);
4066}
4067
4069
4070template <typename Char>
4074 locale_ref loc) {
4075 // workaround for msvc bug regarding name-lookup in module
4076 // link names into function scope
4077 using detail::arg_formatter;
4079 using detail::custom_formatter;
4080 using detail::default_arg_formatter;
4081 using detail::get_arg;
4082 using detail::locale_ref;
4084 using detail::specs_checker;
4085 using detail::specs_handler;
4086 using detail::to_unsigned;
4087 using detail::type;
4088 using detail::write;
4089 auto out = buffer_appender<Char>(buf);
4090 if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
4091 auto arg = args.get(0);
4092 if (!arg) error_handler().on_error("argument not found");
4094 return;
4095 }
4096
4097 struct format_handler : error_handler {
4099 buffer_context<Char> context;
4100
4101 format_handler(buffer_appender<Char> p_out, basic_string_view<Char> str,
4103 locale_ref p_loc)
4104 : parse_context(str), context(p_out, p_args, p_loc) {}
4105
4106 void on_text(const Char* begin, const Char* end) {
4107 auto text = basic_string_view<Char>(begin, to_unsigned(end - begin));
4108 context.advance_to(write<Char>(context.out(), text));
4109 }
4110
4111 FMT_CONSTEXPR auto on_arg_id() -> int {
4112 return parse_context.next_arg_id();
4113 }
4114 FMT_CONSTEXPR auto on_arg_id(int id) -> int {
4115 return parse_context.check_arg_id(id), id;
4116 }
4117 FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
4118 int arg_id = context.arg_id(id);
4119 if (arg_id < 0) on_error("argument not found");
4120 return arg_id;
4121 }
4122
4123 FMT_INLINE void on_replacement_field(int id, const Char*) {
4124 auto arg = get_arg(context, id);
4126 default_arg_formatter<Char>{context.out(), context.args(),
4127 context.locale()},
4128 arg));
4129 }
4130
4131 auto on_format_specs(int id, const Char* begin, const Char* end)
4132 -> const Char* {
4133 auto arg = get_arg(context, id);
4134 if (arg.type() == type::custom_type) {
4135 parse_context.advance_to(parse_context.begin() +
4136 (begin - &*parse_context.begin()));
4137 visit_format_arg(custom_formatter<Char>{parse_context, context}, arg);
4138 return parse_context.begin();
4139 }
4140 auto specs = basic_format_specs<Char>();
4142 specs_handler<Char>(specs, parse_context, context), arg.type());
4143 begin = parse_format_specs(begin, end, handler);
4144 if (begin == end || *begin != '}')
4145 on_error("missing '}' in format string");
4146 auto f = arg_formatter<Char>{context.out(), specs, context.locale()};
4147 context.advance_to(visit_format_arg(f, arg));
4148 return begin;
4149 }
4150 };
4151 detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
4152}
4153
4154#ifndef FMT_HEADER_ONLY
4159extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
4160extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
4161#endif // FMT_HEADER_ONLY
4162
4164
4165#if FMT_USE_USER_DEFINED_LITERALS
4166inline namespace literals {
4167/**
4168 \rst
4169 User-defined literal equivalent of :func:`fmt::arg`.
4170
4171 **Example**::
4172
4173 using namespace fmt::literals;
4174 fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
4175 \endrst
4176 */
4177# if FMT_USE_NONTYPE_TEMPLATE_ARGS
4178template <detail_exported::fixed_string Str> constexpr auto operator""_a() {
4179 using char_t = remove_cvref_t<decltype(Str.data[0])>;
4180 return detail::udl_arg<char_t, sizeof(Str.data) / sizeof(char_t), Str>();
4181}
4182# else
4183constexpr auto operator"" _a(const char* s, size_t) -> detail::udl_arg<char> {
4184 return {s};
4185}
4186# endif
4187} // namespace literals
4188#endif // FMT_USE_USER_DEFINED_LITERALS
4189
4190template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4191inline auto vformat(const Locale& loc, string_view fmt, format_args args)
4192 -> std::string {
4193 return detail::vformat(loc, fmt, args);
4194}
4195
4196template <typename Locale, typename... T,
4197 FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4198inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
4199 -> std::string {
4200 return vformat(loc, string_view(fmt), fmt::make_format_args(args...));
4201}
4202
4203template <typename OutputIt, typename Locale,
4204 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
4205 detail::is_locale<Locale>::value)>
4206auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
4207 format_args args) -> OutputIt {
4208 using detail::get_buffer;
4209 auto&& buf = get_buffer<char>(out);
4210 detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
4211 return detail::get_iterator(buf);
4212}
4213
4214template <typename OutputIt, typename Locale, typename... T,
4215 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
4216 detail::is_locale<Locale>::value)>
4217FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
4218 format_string<T...> fmt, T&&... args) -> OutputIt {
4219 return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
4220}
4221
4224
4225#ifdef FMT_HEADER_ONLY
4226# define FMT_FUNC inline
4227# include "format-inl.h"
4228#else
4229# define FMT_FUNC
4230#endif
4231
4232#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:128
Definition: core.h:1543
Definition: core.h:1588
Definition: core.h:1562
\rst A view of a collection of formatting arguments.
Definition: core.h:1955
Definition: core.h:1795
FMT_CONSTEXPR auto locale() -> detail::locale_ref
Definition: core.h:1845
FMT_CONSTEXPR auto out() -> iterator
Definition: core.h:1838
FMT_CONSTEXPR auto arg_id(basic_string_view< char_type > name) -> int
Definition: core.h:1827
void on_error(const char *message)
Definition: core.h:1835
FMT_CONSTEXPR auto error_handler() -> detail::error_handler
Definition: core.h:1834
auto args() const -> const basic_format_args< basic_format_context > &
Definition: core.h:1830
void advance_to(iterator it)
Definition: core.h:1841
\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:3147
\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:2715
friend FMT_CONSTEXPR20 int compare(const bigint &lhs, const bigint &rhs)
Definition: format.h:2856
FMT_CONSTEXPR20 void assign_pow10(int exp)
Definition: format.h:2899
FMT_CONSTEXPR20 bigint()
Definition: format.h:2805
bigint(const bigint &)=delete
FMT_CONSTEXPR20 void assign(const bigint &other)
Definition: format.h:2811
FMT_CONSTEXPR20 void square()
Definition: format.h:2918
friend FMT_CONSTEXPR20 int add_compare(const bigint &lhs1, const bigint &lhs2, const bigint &rhs)
Definition: format.h:2873
FMT_NOINLINE FMT_CONSTEXPR20 bigint & operator<<=(int shift)
Definition: format.h:2835
FMT_CONSTEXPR20 int divmod_assign(const bigint &divisor)
Definition: format.h:2961
bigint(uint64_t n)
Definition: format.h:2806
FMT_CONSTEXPR20 bigint & operator*=(Int value)
Definition: format.h:2850
FMT_CONSTEXPR20 int num_bigits() const
Definition: format.h:2831
void operator=(const bigint &)=delete
FMT_CONSTEXPR20 void align(const bigint &other)
Definition: format.h:2948
FMT_CONSTEXPR20 void operator=(Int n)
Definition: format.h:2826
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:3856
bytes(string_view data)
Definition: format.h:3862
Definition: format.h:2146
std::ptrdiff_t difference_type
Definition: format.h:2152
void pointer
Definition: format.h:2153
FMT_CONSTEXPR value_type operator*() const
Definition: format.h:2181
FMT_CONSTEXPR size_t count() const
Definition: format.h:2163
FMT_CONSTEXPR friend counting_iterator operator+(counting_iterator it, difference_type n)
Definition: format.h:2175
std::output_iterator_tag iterator_category
Definition: format.h:2151
FMT_CONSTEXPR counting_iterator & operator++()
Definition: format.h:2165
FMT_UNCHECKED_ITERATOR(counting_iterator)
void reference
Definition: format.h:2154
FMT_CONSTEXPR counting_iterator operator++(int)
Definition: format.h:2169
FMT_CONSTEXPR counting_iterator()
Definition: format.h:2161
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:1939
Out apply(Out out, basic_string_view< C > digits) const
Definition: format.h:1980
digit_grouping(thousands_sep_result< Char > sep)
Definition: format.h:1967
digit_grouping(locale_ref loc, bool localized=true)
Definition: format.h:1961
int count_separators(int num_digits) const
Definition: format.h:1971
Char separator() const
Definition: format.h:1969
Definition: format.h:3774
auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3802
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3794
Definition: format.h:2473
constexpr fallback_digit_grouping(locale_ref, bool)
Definition: format.h:2475
constexpr Char separator() const
Definition: format.h:2477
constexpr int count_separators(int) const
Definition: format.h:2479
constexpr Out apply(Out out, basic_string_view< C >) const
Definition: format.h:2482
A formatting error such as invalid format string.
Definition: format.h:957
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:959
format_error(const std::string &message)
Definition: format.h:960
Fast integer formatter.
Definition: format.h:3666
format_int(unsigned long long value)
Definition: format.h:3694
auto str() const -> std::string
\rst Returns the content of the output buffer as an std::string.
Definition: format.h:3722
auto size() const -> size_t
Returns the number of characters written to the output buffer.
Definition: format.h:3698
format_int(int value)
Definition: format.h:3689
format_int(long value)
Definition: format.h:3690
format_int(long long value)
Definition: format.h:3691
auto c_str() const -> const char *
Returns a pointer to the output buffer content with terminating null character appended.
Definition: format.h:3712
auto data() const -> const char *
Returns a pointer to the output buffer content.
Definition: format.h:3706
format_int(unsigned value)
Definition: format.h:3692
format_int(unsigned long value)
Definition: format.h:3693
Definition: core.h:1710
Definition: format.h:3455
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition: format.h:3466
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
Definition: format.h:3457
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition: format.h:3460
Definition: core.h:2867
Definition: format.h:3492
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition: format.h:3520
void on_error(const char *message)
Definition: format.h:3530
FMT_CONSTEXPR specs_handler(basic_format_specs< Char > &specs, basic_format_parse_context< Char > &parse_ctx, buffer_context< Char > &ctx)
Definition: format.h:3515
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition: format.h:3525
Definition: core.h:2204
Definition: format.h:1282
auto str() const -> std::wstring
Definition: format.h:1291
auto size() const -> size_t
Definition: format.h:1289
auto c_str() const -> const wchar_t *
Definition: format.h:1290
Definition: core.h:1240
Definition: format.h:3435
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition: format.h:3446
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition: format.h:3440
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
Definition: format.h:3437
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:2568
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:2307
align::type align_t
Definition: core.h:2084
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> bool
Definition: core.h:2765
#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:2851
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:1923
#define FMT_CONSTEXPR
Definition: core.h:106
FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type, ErrorHandler &&eh)
Definition: core.h:2859
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:1854
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:2841
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:2088
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:2797
FMT_INLINE FMT_CONSTEXPR20 auto grisu_gen_digits(fp value, uint64_t error, int &exp, gen_digits_handler &handler) -> digits::result
Definition: format.h:2623
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:3637
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:2118
constexpr auto digits10() noexcept -> int
Definition: format.h:1162
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:1731
round_direction
Definition: format.h:2540
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:3433
constexpr bool isnan(T value)
Definition: format.h:2501
auto decimal_point(locale_ref loc) -> Char
Definition: format.h:1187
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:2488
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:4217
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const basic_format_specs< Char > &specs) -> OutputIt
Definition: format.h:1686
auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt
Definition: format.h:1783
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:1728
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:1101
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:4006
auto write_escaped_cp(OutputIt out, const find_escape_result< Char > &escape) -> OutputIt
Definition: format.h:1793
FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It
Definition: format.h:1377
FMT_CONSTEXPR auto count_digits_fallback(T n) -> int
Definition: format.h:1058
FMT_CONSTEXPR20 FMT_INLINE void copy2(Char *dst, const char *src)
Definition: format.h:1204
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:3607
dragon
Definition: format.h:2976
@ predecessor_closer
Definition: format.h:2977
@ fixup
Definition: format.h:2978
@ fixed
Definition: format.h:2979
FMT_CONSTEXPR20 void format_dragon(basic_fp< uint128_t > value, unsigned flags, int num_digits, buffer< char > &buf, int &exp10)
Definition: format.h:2985
#define FMT_MSC_DEFAULT
Definition: format.h:77
FMT_CONSTEXPR fp operator*(fp x, fp y)
Definition: format.h:1482
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_opt >::value > is_signed
Definition: format.h:1004
auto snprintf_float(T value, int precision, float_specs specs, buffer< char > &buf) -> int
Definition: format.h:1587
constexpr Char sign(Sign s)
Definition: format.h:1051
FMT_CONSTEXPR auto write_char(OutputIt out, Char value, const basic_format_specs< Char > &specs) -> OutputIt
Definition: format.h:1870
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:3534
constexpr auto convert_float(T value) -> convert_float_result< T >
Definition: format.h:1640
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:1033
constexpr auto is_negative(T value) -> bool
Definition: format.h:1009
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:2002
FMT_CONSTEXPR20 auto format_decimal(Char *out, UInt value, int size) -> format_decimal_result< Char * >
Definition: format.h:1222
FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int
Definition: format.h:3477
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:1031
constexpr auto exponent_mask() -> typename dragonbox::float_info< Float >::carrier_uint
Definition: format.h:1363
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:1660
auto write_escaped_string(OutputIt out, basic_string_view< Char > str) -> OutputIt
Definition: format.h:1840
constexpr auto exponent_bias() -> int
Definition: format.h:1369
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:3599
conditional_t< std::is_same< T, float >::value||sizeof(T)==sizeof(double), double, T > convert_float_result
Definition: format.h:1637
constexpr bool has_implicit_bit()
Definition: format.h:1348
constexpr const char * digits2(size_t value)
Definition: format.h:1041
FMT_CONSTEXPR void prefix_append(unsigned &prefix, unsigned value)
Definition: format.h:2030
#define FMT_SNPRINTF
Definition: format.h:1579
FMT_INLINE FMT_CONSTEXPR bool signbit(T value)
Definition: format.h:2528
auto to_string(const T &value) -> std::string
\rst Converts value to std::string using the default format for type T.
Definition: format.h:4044
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1645
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:1916
basic_memory_buffer< char > memory_buffer
Definition: format.h:942
constexpr int num_significand_bits()
Definition: format.h:1355
auto write_escaped_char(OutputIt out, Char v) -> OutputIt
Definition: format.h:1856
constexpr auto write_significand(OutputIt out, const char *significand, int significand_size) -> OutputIt
Definition: format.h:2279
constexpr auto digits10< int128_opt >() noexcept -> int
Definition: format.h:1165
auto format(const Locale &loc, format_string< T... > fmt, T &&... args) -> std::string
Definition: format.h:4198
auto write_ptr(OutputIt out, UIntPtr value, const basic_format_specs< Char > *specs) -> OutputIt
Definition: format.h:1697
#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:2245
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:2369
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:3904
FMT_CONSTEXPR round_direction get_round_direction(uint64_t divisor, uint64_t remainder, uint64_t error)
Definition: format.h:2546
auto thousands_sep(locale_ref loc) -> thousands_sep_result< Char >
Definition: format.h:1176
auto needs_escape(uint32_t cp) -> bool
Definition: format.h:1713
constexpr auto underlying(Enum e) noexcept -> underlying_t< Enum >
\rst Converts e to the underlying type.
Definition: format.h:3845
auto equal2(const Char *lhs, const char *rhs) -> bool
Definition: format.h:1195
FMT_CONSTEXPR auto is_supported_floating_point(T) -> bool
Definition: format.h:1018
#define FMT_THROW(x)
Definition: format.h:95
FMT_CONSTEXPR auto get_arg(Context &ctx, ID id) -> typename Context::format_arg
Definition: format.h:3484
auto ptr(T p) -> const void *
\rst Converts p to const void* for pointer formatting.
Definition: format.h:3823
basic_fp< unsigned long long > fp
Definition: format.h:1444
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:2041
FMT_API auto is_printable(uint32_t cp) -> bool
FMT_CONSTEXPR fp get_cached_power(int min_exponent, int &pow10_exponent)
Definition: format.h:1556
FMT_CONSTEXPR auto write(OutputIt out, Char value, const basic_format_specs< Char > &specs, locale_ref loc={}) -> OutputIt
Definition: format.h:1881
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:4071
FMT_CONSTEXPR20 void adjust_precision(int &precision, int exp10)
Definition: format.h:2612
#define FMT_REDUCE_INT_INSTANTIATIONS
Definition: format.h:137
FMT_CONSTEXPR basic_fp< F > normalize(basic_fp< F > value)
Definition: format.h:1448
FMT_CONSTEXPR auto format_uint(Char *buffer, UInt value, int num_digits, bool upper=false) -> Char *
Definition: format.h:1255
#define FMT_POWERS_OF_10(factor)
Definition: format.h:1035
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:3113
FMT_CONSTEXPR uint64_t multiply(uint64_t lhs, uint64_t rhs)
Definition: format.h:1465
constexpr auto get_significand_size(const big_decimal_fp &f) -> int
Definition: format.h:2270
constexpr auto digits10< uint128_t >() noexcept -> int
Definition: format.h:1166
FMT_CONSTEXPR20 bool isfinite(T value)
Definition: format.h:2514
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:2080
uint32_t divisor
Definition: format-inl.h:236
Definition: format.h:969
constexpr auto compile_string_to_view(detail::std_string_view< Char > s) -> basic_string_view< Char >
Definition: format.h:989
Definition: format-inl.h:32
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:2563
result
Definition: format.h:2564
@ done
Definition: format.h:2566
@ error
Definition: format.h:2567
@ more
Definition: format.h:2565
Definition: format.h:1294
FMT_API auto to_decimal(T x) noexcept -> decimal_fp< T >
Definition: format.h:3849
constexpr auto format_as(Enum e) noexcept -> underlying_t< Enum >
Definition: format.h:3851
Definition: xchar.h:50
Definition: core.h:2085
Definition: BFloat16.h:88
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:3399
FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator
Definition: format.h:3408
const basic_format_specs< Char > & specs
Definition: format.h:3404
auto operator()(typename basic_format_arg< context >::handle) -> iterator
Definition: format.h:3411
locale_ref locale
Definition: format.h:3405
iterator out
Definition: format.h:3403
buffer_appender< Char > iterator
Definition: format.h:3400
Definition: core.h:1345
FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int
Definition: core.h:1348
Definition: core.h:2168
union arg_ref::value val
arg_id_kind kind
Definition: core.h:2182
Definition: core.h:2201
Definition: format.h:1486
static constexpr uint64_t pow10_significands[87]
Definition: format.h:1489
static constexpr uint64_t power_of_10_64[20]
Definition: format.h:1540
static constexpr int16_t pow10_exponents[87]
Definition: format.h:1527
Definition: core.h:2141
presentation_type type
Definition: core.h:2144
sign_t sign
Definition: core.h:2146
detail::fill_t< Char > fill
Definition: core.h:2149
align_t align
Definition: core.h:2145
bool alt
Definition: core.h:2147
int precision
Definition: core.h:2143
int width
Definition: core.h:2142
bool localized
Definition: core.h:2148
Definition: format.h:1398
int e
Definition: format.h:1400
FMT_CONSTEXPR auto assign(Float n) -> bool
Definition: format.h:1413
constexpr basic_fp()
Definition: format.h:1405
F f
Definition: format.h:1399
FMT_CONSTEXPR basic_fp(Float n)
Definition: format.h:1409
static constexpr const int num_significand_bits
Definition: format.h:1402
constexpr basic_fp(uint64_t f_val, int e_val)
Definition: format.h:1406
Definition: format.h:2264
int significand_size
Definition: format.h:2266
int exponent
Definition: format.h:2267
const char * significand
Definition: format.h:2265
Definition: format.h:2157
FMT_CONSTEXPR void operator=(const T &)
Definition: format.h:2158
Definition: format.h:3418
void operator()(T) const
Definition: format.h:3426
void operator()(typename basic_format_arg< buffer_context< Char > >::handle h) const
Definition: format.h:3422
buffer_context< Char > & ctx
Definition: format.h:3420
basic_format_parse_context< Char > & parse_ctx
Definition: format.h:3419
Definition: format.h:1552
Definition: format.h:3380
iterator out
Definition: format.h:3384
basic_format_args< context > args
Definition: format.h:3385
auto operator()(T value) -> iterator
Definition: format.h:3388
locale_ref loc
Definition: format.h:3386
auto operator()(typename basic_format_arg< context >::handle h) -> iterator
Definition: format.h:3391
buffer_appender< Char > iterator
Definition: format.h:3381
Definition: format.h:252
static constexpr CharT value[sizeof...(C)]
Definition: format.h:253
Definition: format.h:1338
int exponent
Definition: format.h:1341
typename float_info< T >::carrier_uint significand_type
Definition: format.h:1339
significand_type significand
Definition: format.h:1340
uint64_t carrier_uint
Definition: format.h:1312
uint32_t carrier_uint
Definition: format.h:1300
Definition: format.h:1297
Definition: core.h:632
FMT_NORETURN void on_error(const char *message)
Definition: core.h:637
Definition: core.h:1123
Definition: core.h:2093
Definition: format.h:1718
const Char * end
Definition: format.h:1720
uint32_t cp
Definition: format.h:1721
const Char * begin
Definition: format.h:1719
Definition: core.h:2786
float_format format
Definition: core.h:2788
int precision
Definition: core.h:2787
sign_t sign
Definition: core.h:2789
bool binary32
Definition: core.h:2792
Definition: format.h:1213
Iterator end
Definition: format.h:1215
Iterator begin
Definition: format.h:1214
FMT_CONSTEXPR auto format(const Char *val, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:3756
auto format(bytes b, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3881
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3871
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3914
auto format(group_digits_view< T > t, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3924
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3978
auto format(const join_view< It, Sentinel, Char > &value, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:3983
auto format(void *val, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:3748
Definition: core.h:791
Definition: format.h:2571
bool fixed
Definition: format.h:2576
FMT_CONSTEXPR digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, uint64_t error, bool integral)
Definition: format.h:2578
int exp10
Definition: format.h:2575
int size
Definition: format.h:2573
int precision
Definition: format.h:2574
char * buf
Definition: format.h:2572
Definition: format.h:3891
T value
Definition: format.h:3891
Definition: format.h:2506
Definition: core.h:803
Definition: format.h:997
Definition: core.h:1179
Definition: core.h:1180
Definition: core.h:566
Definition: format.h:3937
It begin
Definition: format.h:3938
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition: format.h:3942
Sentinel end
Definition: format.h:3939
basic_string_view< Char > sep
Definition: format.h:3940
Definition: core.h:325
Definition: core.h:1138
Definition: format.h:1168
std::string grouping
Definition: format.h:1169
Char thousands_sep
Definition: format.h:1170
Definition: core.h:600
Definition: core.h:308
Definition: core.h:1136
Definition: format.h:2035
UInt abs_value
Definition: format.h:2036
unsigned prefix
Definition: format.h:2037
Definition: format.h:1891
FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, const basic_format_specs< Char > &specs)
Definition: format.h:1895
size_t padding
Definition: format.h:1893
size_t size
Definition: format.h:1892
int index
Definition: core.h:2187
basic_string_view< Char > name
Definition: core.h:2188