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 <initializer_list> // std::initializer_list
40 #include <limits> // std::numeric_limits
41 #include <memory> // std::uninitialized_copy
42 #include <stdexcept> // std::runtime_error
43 #include <system_error> // std::system_error
44 
45 #ifdef __cpp_lib_bit_cast
46 # include <bit> // std::bit_cast
47 #endif
48 
49 #include "core.h"
50 
51 #if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L
52 # define FMT_INLINE_VARIABLE inline
53 #else
54 # define FMT_INLINE_VARIABLE
55 #endif
56 
57 #if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
58 # define FMT_FALLTHROUGH [[fallthrough]]
59 #elif defined(__clang__)
60 # define FMT_FALLTHROUGH [[clang::fallthrough]]
61 #elif FMT_GCC_VERSION >= 700 && \
62  (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
63 # define FMT_FALLTHROUGH [[gnu::fallthrough]]
64 #else
65 # define FMT_FALLTHROUGH
66 #endif
67 
68 #ifndef FMT_DEPRECATED
69 # if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VERSION >= 1900
70 # define FMT_DEPRECATED [[deprecated]]
71 # else
72 # if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
73 # define FMT_DEPRECATED __attribute__((deprecated))
74 # elif FMT_MSC_VERSION
75 # define FMT_DEPRECATED __declspec(deprecated)
76 # else
77 # define FMT_DEPRECATED /* deprecated */
78 # endif
79 # endif
80 #endif
81 
82 #ifndef FMT_NO_UNIQUE_ADDRESS
83 # if FMT_CPLUSPLUS >= 202002L
84 # if FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
85 # define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
86 // VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485)
87 # elif (FMT_MSC_VERSION >= 1929) && !FMT_CLANG_VERSION
88 # define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
89 # endif
90 # endif
91 #endif
92 #ifndef FMT_NO_UNIQUE_ADDRESS
93 # define FMT_NO_UNIQUE_ADDRESS
94 #endif
95 
96 // Visibility when compiled as a shared library/object.
97 #if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
98 # define FMT_SO_VISIBILITY(value) FMT_VISIBILITY(value)
99 #else
100 # define FMT_SO_VISIBILITY(value)
101 #endif
102 
103 #ifdef __has_builtin
104 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
105 #else
106 # define FMT_HAS_BUILTIN(x) 0
107 #endif
108 
109 #if FMT_GCC_VERSION || FMT_CLANG_VERSION
110 # define FMT_NOINLINE __attribute__((noinline))
111 #else
112 # define FMT_NOINLINE
113 #endif
114 
115 #ifndef FMT_THROW
116 # if FMT_EXCEPTIONS
117 # if FMT_MSC_VERSION || defined(__NVCC__)
119 namespace detail {
120 template <typename Exception> inline void do_throw(const Exception& x) {
121  // Silence unreachable code warnings in MSVC and NVCC because these
122  // are nearly impossible to fix in a generic code.
123  volatile bool b = true;
124  if (b) throw x;
125 }
126 } // namespace detail
128 # define FMT_THROW(x) detail::do_throw(x)
129 # else
130 # define FMT_THROW(x) throw x
131 # endif
132 # else
133 # define FMT_THROW(x) \
134  ::fmt::detail::assert_fail(__FILE__, __LINE__, (x).what())
135 # endif
136 #endif
137 
138 #if FMT_EXCEPTIONS
139 # define FMT_TRY try
140 # define FMT_CATCH(x) catch (x)
141 #else
142 # define FMT_TRY if (true)
143 # define FMT_CATCH(x) if (false)
144 #endif
145 
146 #ifndef FMT_MAYBE_UNUSED
147 # if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
148 # define FMT_MAYBE_UNUSED [[maybe_unused]]
149 # else
150 # define FMT_MAYBE_UNUSED
151 # endif
152 #endif
153 
154 #ifndef FMT_USE_USER_DEFINED_LITERALS
155 // EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
156 //
157 // GCC before 4.9 requires a space in `operator"" _a` which is invalid in later
158 // compiler versions.
159 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 409 || \
160  FMT_MSC_VERSION >= 1900) && \
161  (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480)
162 # define FMT_USE_USER_DEFINED_LITERALS 1
163 # else
164 # define FMT_USE_USER_DEFINED_LITERALS 0
165 # endif
166 #endif
167 
168 // Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
169 // integer formatter template instantiations to just one by only using the
170 // largest integer type. This results in a reduction in binary size but will
171 // cause a decrease in integer formatting performance.
172 #if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
173 # define FMT_REDUCE_INT_INSTANTIATIONS 0
174 #endif
175 
176 // __builtin_clz is broken in clang with Microsoft CodeGen:
177 // https://github.com/fmtlib/fmt/issues/519.
178 #if !FMT_MSC_VERSION
179 # if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
180 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
181 # endif
182 # if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
183 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
184 # endif
185 #endif
186 
187 // __builtin_ctz is broken in Intel Compiler Classic on Windows:
188 // https://github.com/fmtlib/fmt/issues/2510.
189 #ifndef __ICL
190 # if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION || \
191  defined(__NVCOMPILER)
192 # define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
193 # endif
194 # if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || \
195  FMT_ICC_VERSION || defined(__NVCOMPILER)
196 # define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
197 # endif
198 #endif
199 
200 #if FMT_MSC_VERSION
201 # include <intrin.h> // _BitScanReverse[64], _BitScanForward[64], _umul128
202 #endif
203 
204 // Some compilers masquerade as both MSVC and GCC-likes or otherwise support
205 // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
206 // MSVC intrinsics if the clz and clzll builtins are not available.
207 #if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) && \
208  !defined(FMT_BUILTIN_CTZLL)
210 namespace detail {
211 // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
212 # if !defined(__clang__)
213 # pragma intrinsic(_BitScanForward)
214 # pragma intrinsic(_BitScanReverse)
215 # if defined(_WIN64)
216 # pragma intrinsic(_BitScanForward64)
217 # pragma intrinsic(_BitScanReverse64)
218 # endif
219 # endif
220 
221 inline auto clz(uint32_t x) -> int {
222  unsigned long r = 0;
223  _BitScanReverse(&r, x);
224  FMT_ASSERT(x != 0, "");
225  // Static analysis complains about using uninitialized data
226  // "r", but the only way that can happen is if "x" is 0,
227  // which the callers guarantee to not happen.
228  FMT_MSC_WARNING(suppress : 6102)
229  return 31 ^ static_cast<int>(r);
230 }
231 # define FMT_BUILTIN_CLZ(n) detail::clz(n)
232 
233 inline auto clzll(uint64_t x) -> int {
234  unsigned long r = 0;
235 # ifdef _WIN64
236  _BitScanReverse64(&r, x);
237 # else
238  // Scan the high 32 bits.
239  if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
240  return 63 ^ static_cast<int>(r + 32);
241  // Scan the low 32 bits.
242  _BitScanReverse(&r, static_cast<uint32_t>(x));
243 # endif
244  FMT_ASSERT(x != 0, "");
245  FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
246  return 63 ^ static_cast<int>(r);
247 }
248 # define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
249 
250 inline auto ctz(uint32_t x) -> int {
251  unsigned long r = 0;
252  _BitScanForward(&r, x);
253  FMT_ASSERT(x != 0, "");
254  FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
255  return static_cast<int>(r);
256 }
257 # define FMT_BUILTIN_CTZ(n) detail::ctz(n)
258 
259 inline auto ctzll(uint64_t x) -> int {
260  unsigned long r = 0;
261  FMT_ASSERT(x != 0, "");
262  FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
263 # ifdef _WIN64
264  _BitScanForward64(&r, x);
265 # else
266  // Scan the low 32 bits.
267  if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r);
268  // Scan the high 32 bits.
269  _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
270  r += 32;
271 # endif
272  return static_cast<int>(r);
273 }
274 # define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
275 } // namespace detail
277 #endif
278 
280 namespace detail {
281 
282 FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) {
283  ignore_unused(condition);
284 #ifdef FMT_FUZZ
285  if (condition) throw std::runtime_error("fuzzing limit reached");
286 #endif
287 }
288 
289 template <typename CharT, CharT... C> struct string_literal {
290  static constexpr CharT value[sizeof...(C)] = {C...};
291  constexpr operator basic_string_view<CharT>() const {
292  return {value, sizeof...(C)};
293  }
294 };
295 
296 #if FMT_CPLUSPLUS < 201703L
297 template <typename CharT, CharT... C>
298 constexpr CharT string_literal<CharT, C...>::value[sizeof...(C)];
299 #endif
300 
301 // Implementation of std::bit_cast for pre-C++20.
302 template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>
303 FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
304 #ifdef __cpp_lib_bit_cast
305  if (is_constant_evaluated()) return std::bit_cast<To>(from);
306 #endif
307  auto to = To();
308  // The cast suppresses a bogus -Wclass-memaccess on GCC.
309  std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
310  return to;
311 }
312 
313 inline auto is_big_endian() -> bool {
314 #ifdef _WIN32
315  return false;
316 #elif defined(__BIG_ENDIAN__)
317  return true;
318 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
319  return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
320 #else
321  struct bytes {
322  char data[sizeof(int)];
323  };
324  return bit_cast<bytes>(1).data[0] == 0;
325 #endif
326 }
327 
329  private:
330  uint64_t lo_, hi_;
331 
332  public:
333  constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}
334  constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}
335 
336  constexpr auto high() const noexcept -> uint64_t { return hi_; }
337  constexpr auto low() const noexcept -> uint64_t { return lo_; }
338 
339  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
340  constexpr explicit operator T() const {
341  return static_cast<T>(lo_);
342  }
343 
344  friend constexpr auto operator==(const uint128_fallback& lhs,
345  const uint128_fallback& rhs) -> bool {
346  return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
347  }
348  friend constexpr auto operator!=(const uint128_fallback& lhs,
349  const uint128_fallback& rhs) -> bool {
350  return !(lhs == rhs);
351  }
352  friend constexpr auto operator>(const uint128_fallback& lhs,
353  const uint128_fallback& rhs) -> bool {
354  return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;
355  }
356  friend constexpr auto operator|(const uint128_fallback& lhs,
357  const uint128_fallback& rhs)
358  -> uint128_fallback {
359  return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};
360  }
361  friend constexpr auto operator&(const uint128_fallback& lhs,
362  const uint128_fallback& rhs)
363  -> uint128_fallback {
364  return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
365  }
366  friend constexpr auto operator~(const uint128_fallback& n)
367  -> uint128_fallback {
368  return {~n.hi_, ~n.lo_};
369  }
370  friend auto operator+(const uint128_fallback& lhs,
371  const uint128_fallback& rhs) -> uint128_fallback {
372  auto result = uint128_fallback(lhs);
373  result += rhs;
374  return result;
375  }
376  friend auto operator*(const uint128_fallback& lhs, uint32_t rhs)
377  -> uint128_fallback {
378  FMT_ASSERT(lhs.hi_ == 0, "");
379  uint64_t hi = (lhs.lo_ >> 32) * rhs;
380  uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;
381  uint64_t new_lo = (hi << 32) + lo;
382  return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};
383  }
384  friend auto operator-(const uint128_fallback& lhs, uint64_t rhs)
385  -> uint128_fallback {
386  return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};
387  }
388  FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback {
389  if (shift == 64) return {0, hi_};
390  if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64);
391  return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
392  }
393  FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback {
394  if (shift == 64) return {lo_, 0};
395  if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64);
396  return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
397  }
399  return *this = *this >> shift;
400  }
402  uint64_t new_lo = lo_ + n.lo_;
403  uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0);
404  FMT_ASSERT(new_hi >= hi_, "");
405  lo_ = new_lo;
406  hi_ = new_hi;
407  }
409  lo_ &= n.lo_;
410  hi_ &= n.hi_;
411  }
412 
413  FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback& {
414  if (is_constant_evaluated()) {
415  lo_ += n;
416  hi_ += (lo_ < n ? 1 : 0);
417  return *this;
418  }
419 #if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)
420  unsigned long long carry;
421  lo_ = __builtin_addcll(lo_, n, 0, &carry);
422  hi_ += carry;
423 #elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)
424  unsigned long long result;
425  auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result);
426  lo_ = result;
427  hi_ += carry;
428 #elif defined(_MSC_VER) && defined(_M_X64)
429  auto carry = _addcarry_u64(0, lo_, n, &lo_);
430  _addcarry_u64(carry, hi_, 0, &hi_);
431 #else
432  lo_ += n;
433  hi_ += (lo_ < n ? 1 : 0);
434 #endif
435  return *this;
436  }
437 };
438 
440 
441 #ifdef UINTPTR_MAX
442 using uintptr_t = ::uintptr_t;
443 #else
445 #endif
446 
447 // Returns the largest possible value for type T. Same as
448 // std::numeric_limits<T>::max() but shorter and not affected by the max macro.
449 template <typename T> constexpr auto max_value() -> T {
450  return (std::numeric_limits<T>::max)();
451 }
452 template <typename T> constexpr auto num_bits() -> int {
453  return std::numeric_limits<T>::digits;
454 }
455 // std::numeric_limits<T>::digits may return 0 for 128-bit ints.
456 template <> constexpr auto num_bits<int128_opt>() -> int { return 128; }
457 template <> constexpr auto num_bits<uint128_t>() -> int { return 128; }
458 
459 // A heterogeneous bit_cast used for converting 96-bit long double to uint128_t
460 // and 128-bit pointers to uint128_fallback.
461 template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) > sizeof(From))>
462 inline auto bit_cast(const From& from) -> To {
463  constexpr auto size = static_cast<int>(sizeof(From) / sizeof(unsigned));
464  struct data_t {
465  unsigned value[static_cast<unsigned>(size)];
466  } data = bit_cast<data_t>(from);
467  auto result = To();
468  if (const_check(is_big_endian())) {
469  for (int i = 0; i < size; ++i)
470  result = (result << num_bits<unsigned>()) | data.value[i];
471  } else {
472  for (int i = size - 1; i >= 0; --i)
473  result = (result << num_bits<unsigned>()) | data.value[i];
474  }
475  return result;
476 }
477 
478 template <typename UInt>
479 FMT_CONSTEXPR20 inline auto countl_zero_fallback(UInt n) -> int {
480  int lz = 0;
481  constexpr UInt msb_mask = static_cast<UInt>(1) << (num_bits<UInt>() - 1);
482  for (; (n & msb_mask) == 0; n <<= 1) lz++;
483  return lz;
484 }
485 
486 FMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int {
487 #ifdef FMT_BUILTIN_CLZ
488  if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n);
489 #endif
490  return countl_zero_fallback(n);
491 }
492 
493 FMT_CONSTEXPR20 inline auto countl_zero(uint64_t n) -> int {
494 #ifdef FMT_BUILTIN_CLZLL
495  if (!is_constant_evaluated()) return FMT_BUILTIN_CLZLL(n);
496 #endif
497  return countl_zero_fallback(n);
498 }
499 
500 FMT_INLINE void assume(bool condition) {
501  (void)condition;
502 #if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
503  __builtin_assume(condition);
504 #elif FMT_GCC_VERSION
505  if (!condition) __builtin_unreachable();
506 #endif
507 }
508 
509 // An approximation of iterator_t for pre-C++20 systems.
510 template <typename T>
511 using iterator_t = decltype(std::begin(std::declval<T&>()));
512 template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>()));
513 
514 // A workaround for std::string not having mutable data() until C++17.
515 template <typename Char>
516 inline auto get_data(std::basic_string<Char>& s) -> Char* {
517  return &s[0];
518 }
519 template <typename Container>
520 inline auto get_data(Container& c) -> typename Container::value_type* {
521  return c.data();
522 }
523 
524 // Attempts to reserve space for n extra characters in the output range.
525 // Returns a pointer to the reserved range or a reference to it.
526 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
527 #if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
528 __attribute__((no_sanitize("undefined")))
529 #endif
530 inline auto
531 reserve(std::back_insert_iterator<Container> it, size_t n) ->
532  typename Container::value_type* {
533  Container& c = get_container(it);
534  size_t size = c.size();
535  c.resize(size + n);
536  return get_data(c) + size;
537 }
538 
539 template <typename T>
540 inline auto reserve(buffer_appender<T> it, size_t n) -> buffer_appender<T> {
541  buffer<T>& buf = get_container(it);
542  buf.try_reserve(buf.size() + n);
543  return it;
544 }
545 
546 template <typename Iterator>
547 constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
548  return it;
549 }
550 
551 template <typename OutputIt>
552 using reserve_iterator =
554 
555 template <typename T, typename OutputIt>
556 constexpr auto to_pointer(OutputIt, size_t) -> T* {
557  return nullptr;
558 }
559 template <typename T> auto to_pointer(buffer_appender<T> it, size_t n) -> T* {
560  buffer<T>& buf = get_container(it);
561  auto size = buf.size();
562  if (buf.capacity() < size + n) return nullptr;
563  buf.try_resize(size + n);
564  return buf.data() + size;
565 }
566 
567 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
568 inline auto base_iterator(std::back_insert_iterator<Container> it,
569  typename Container::value_type*)
570  -> std::back_insert_iterator<Container> {
571  return it;
572 }
573 
574 template <typename Iterator>
575 constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
576  return it;
577 }
578 
579 // <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
580 // instead (#1998).
581 template <typename OutputIt, typename Size, typename T>
582 FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
583  -> OutputIt {
584  for (Size i = 0; i < count; ++i) *out++ = value;
585  return out;
586 }
587 template <typename T, typename Size>
588 FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
589  if (is_constant_evaluated()) {
590  return fill_n<T*, Size, T>(out, count, value);
591  }
592  std::memset(out, value, to_unsigned(count));
593  return out + count;
594 }
595 
596 #ifdef __cpp_char8_t
597 using char8_type = char8_t;
598 #else
599 enum char8_type : unsigned char {};
600 #endif
601 
602 template <typename OutChar, typename InputIt, typename OutputIt>
603 FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end,
604  OutputIt out) -> OutputIt {
605  return copy_str<OutChar>(begin, end, out);
606 }
607 
608 // A public domain branchless UTF-8 decoder by Christopher Wellons:
609 // https://github.com/skeeto/branchless-utf8
610 /* Decode the next character, c, from s, reporting errors in e.
611  *
612  * Since this is a branchless decoder, four bytes will be read from the
613  * buffer regardless of the actual length of the next character. This
614  * means the buffer _must_ have at least three bytes of zero padding
615  * following the end of the data stream.
616  *
617  * Errors are reported in e, which will be non-zero if the parsed
618  * character was somehow invalid: invalid byte sequence, non-canonical
619  * encoding, or a surrogate half.
620  *
621  * The function returns a pointer to the next character. When an error
622  * occurs, this pointer will be a guess that depends on the particular
623  * error, but it will always advance at least one byte.
624  */
625 FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
626  -> const char* {
627  constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
628  constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
629  constexpr const int shiftc[] = {0, 18, 12, 6, 0};
630  constexpr const int shifte[] = {0, 6, 4, 2, 0};
631 
632  int len = "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4"
633  [static_cast<unsigned char>(*s) >> 3];
634  // Compute the pointer to the next character early so that the next
635  // iteration can start working on the next character. Neither Clang
636  // nor GCC figure out this reordering on their own.
637  const char* next = s + len + !len;
638 
639  using uchar = unsigned char;
640 
641  // Assume a four-byte character and load four bytes. Unused bits are
642  // shifted out.
643  *c = uint32_t(uchar(s[0]) & masks[len]) << 18;
644  *c |= uint32_t(uchar(s[1]) & 0x3f) << 12;
645  *c |= uint32_t(uchar(s[2]) & 0x3f) << 6;
646  *c |= uint32_t(uchar(s[3]) & 0x3f) << 0;
647  *c >>= shiftc[len];
648 
649  // Accumulate the various error conditions.
650  *e = (*c < mins[len]) << 6; // non-canonical encoding
651  *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half?
652  *e |= (*c > 0x10FFFF) << 8; // out of range?
653  *e |= (uchar(s[1]) & 0xc0) >> 2;
654  *e |= (uchar(s[2]) & 0xc0) >> 4;
655  *e |= uchar(s[3]) >> 6;
656  *e ^= 0x2a; // top two bits of each tail byte correct?
657  *e >>= shifte[len];
658 
659  return next;
660 }
661 
662 constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point = ~uint32_t();
663 
664 // Invokes f(cp, sv) for every code point cp in s with sv being the string view
665 // corresponding to the code point. cp is invalid_code_point on error.
666 template <typename F>
668  auto decode = [f](const char* buf_ptr, const char* ptr) {
669  auto cp = uint32_t();
670  auto error = 0;
671  auto end = utf8_decode(buf_ptr, &cp, &error);
672  bool result = f(error ? invalid_code_point : cp,
673  string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));
674  return result ? (error ? buf_ptr + 1 : end) : nullptr;
675  };
676  auto p = s.data();
677  const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars.
678  if (s.size() >= block_size) {
679  for (auto end = p + s.size() - block_size + 1; p < end;) {
680  p = decode(p, p);
681  if (!p) return;
682  }
683  }
684  if (auto num_chars_left = s.data() + s.size() - p) {
685  char buf[2 * block_size - 1] = {};
686  copy_str<char>(p, p + num_chars_left, buf);
687  const char* buf_ptr = buf;
688  do {
689  auto end = decode(buf_ptr, p);
690  if (!end) return;
691  p += end - buf_ptr;
692  buf_ptr = end;
693  } while (buf_ptr - buf < num_chars_left);
694  }
695 }
696 
697 template <typename Char>
698 inline auto compute_width(basic_string_view<Char> s) -> size_t {
699  return s.size();
700 }
701 
702 // Computes approximate display width of a UTF-8 string.
703 FMT_CONSTEXPR inline auto compute_width(string_view s) -> size_t {
704  size_t num_code_points = 0;
705  // It is not a lambda for compatibility with C++14.
706  struct count_code_points {
707  size_t* count;
708  FMT_CONSTEXPR auto operator()(uint32_t cp, string_view) const -> bool {
710  1 +
711  (cp >= 0x1100 &&
712  (cp <= 0x115f || // Hangul Jamo init. consonants
713  cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET
714  cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET
715  // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:
716  (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
717  (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables
718  (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs
719  (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms
720  (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms
721  (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms
722  (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms
723  (cp >= 0x20000 && cp <= 0x2fffd) || // CJK
724  (cp >= 0x30000 && cp <= 0x3fffd) ||
725  // Miscellaneous Symbols and Pictographs + Emoticons:
726  (cp >= 0x1f300 && cp <= 0x1f64f) ||
727  // Supplemental Symbols and Pictographs:
728  (cp >= 0x1f900 && cp <= 0x1f9ff))));
729  return true;
730  }
731  };
732  // We could avoid branches by using utf8_decode directly.
733  for_each_codepoint(s, count_code_points{&num_code_points});
734  return num_code_points;
735 }
736 
738  return compute_width(
739  string_view(reinterpret_cast<const char*>(s.data()), s.size()));
740 }
741 
742 template <typename Char>
743 inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
744  size_t size = s.size();
745  return n < size ? n : size;
746 }
747 
748 // Calculates the index of the nth code point in a UTF-8 string.
749 inline auto code_point_index(string_view s, size_t n) -> size_t {
750  size_t result = s.size();
751  const char* begin = s.begin();
752  for_each_codepoint(s, [begin, &n, &result](uint32_t, string_view sv) {
753  if (n != 0) {
754  --n;
755  return true;
756  }
757  result = to_unsigned(sv.begin() - begin);
758  return false;
759  });
760  return result;
761 }
762 
764  -> size_t {
765  return code_point_index(
766  string_view(reinterpret_cast<const char*>(s.data()), s.size()), n);
767 }
768 
769 template <typename T> struct is_integral : std::is_integral<T> {};
770 template <> struct is_integral<int128_opt> : std::true_type {};
771 template <> struct is_integral<uint128_t> : std::true_type {};
772 
773 template <typename T>
774 using is_signed =
776  std::is_same<T, int128_opt>::value>;
777 
778 template <typename T>
779 using is_integer =
780  bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
781  !std::is_same<T, char>::value &&
782  !std::is_same<T, wchar_t>::value>;
783 
784 #ifndef FMT_USE_FLOAT
785 # define FMT_USE_FLOAT 1
786 #endif
787 #ifndef FMT_USE_DOUBLE
788 # define FMT_USE_DOUBLE 1
789 #endif
790 #ifndef FMT_USE_LONG_DOUBLE
791 # define FMT_USE_LONG_DOUBLE 1
792 #endif
793 
794 #ifndef FMT_USE_FLOAT128
795 # ifdef __clang__
796 // Clang emulates GCC, so it has to appear early.
797 # if FMT_HAS_INCLUDE(<quadmath.h>)
798 # define FMT_USE_FLOAT128 1
799 # endif
800 # elif defined(__GNUC__)
801 // GNU C++:
802 # if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__)
803 # define FMT_USE_FLOAT128 1
804 # endif
805 # endif
806 # ifndef FMT_USE_FLOAT128
807 # define FMT_USE_FLOAT128 0
808 # endif
809 #endif
810 
811 #if FMT_USE_FLOAT128
812 using float128 = __float128;
813 #else
814 using float128 = void;
815 #endif
816 template <typename T> using is_float128 = std::is_same<T, float128>;
817 
818 template <typename T>
819 using is_floating_point =
821 
822 template <typename T, bool = std::is_floating_point<T>::value>
823 struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&
824  sizeof(T) <= sizeof(double)> {};
825 template <typename T> struct is_fast_float<T, false> : std::false_type {};
826 
827 template <typename T>
828 using is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;
829 
830 #ifndef FMT_USE_FULL_CACHE_DRAGONBOX
831 # define FMT_USE_FULL_CACHE_DRAGONBOX 0
832 #endif
833 
834 template <typename T>
835 template <typename U>
836 void buffer<T>::append(const U* begin, const U* end) {
837  while (begin != end) {
838  auto count = to_unsigned(end - begin);
839  try_reserve(size_ + count);
840  auto free_cap = capacity_ - size_;
841  if (free_cap < count) count = free_cap;
842  std::uninitialized_copy_n(begin, count, ptr_ + size_);
843  size_ += count;
844  begin += count;
845  }
846 }
847 
848 template <typename T, typename Enable = void>
849 struct is_locale : std::false_type {};
850 template <typename T>
851 struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {};
852 } // namespace detail
853 
854 FMT_BEGIN_EXPORT
855 
856 // The number of characters to store in the basic_memory_buffer object itself
857 // to avoid dynamic memory allocation.
858 enum { inline_buffer_size = 500 };
859 
881 template <typename T, size_t SIZE = inline_buffer_size,
882  typename Allocator = std::allocator<T>>
883 class basic_memory_buffer final : public detail::buffer<T> {
884  private:
885  T store_[SIZE];
886 
887  // Don't inherit from Allocator to avoid generating type_info for it.
888  FMT_NO_UNIQUE_ADDRESS Allocator alloc_;
889 
890  // Deallocate memory allocated by the buffer.
891  FMT_CONSTEXPR20 void deallocate() {
892  T* data = this->data();
893  if (data != store_) alloc_.deallocate(data, this->capacity());
894  }
895 
896  protected:
897  FMT_CONSTEXPR20 void grow(size_t size) override {
899  const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
900  size_t old_capacity = this->capacity();
901  size_t new_capacity = old_capacity + old_capacity / 2;
902  if (size > new_capacity)
903  new_capacity = size;
904  else if (new_capacity > max_size)
905  new_capacity = size > max_size ? size : max_size;
906  T* old_data = this->data();
907  T* new_data =
908  std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
909  // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
910  detail::assume(this->size() <= new_capacity);
911  // The following code doesn't throw, so the raw pointer above doesn't leak.
912  std::uninitialized_copy_n(old_data, this->size(), new_data);
913  this->set(new_data, new_capacity);
914  // deallocate must not throw according to the standard, but even if it does,
915  // the buffer already uses the new storage and will deallocate it in
916  // destructor.
917  if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
918  }
919 
920  public:
921  using value_type = T;
922  using const_reference = const T&;
923 
925  const Allocator& alloc = Allocator())
926  : alloc_(alloc) {
927  this->set(store_, SIZE);
928  if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
929  }
931 
932  private:
933  // Move data from other to this buffer.
935  alloc_ = std::move(other.alloc_);
936  T* data = other.data();
937  size_t size = other.size(), capacity = other.capacity();
938  if (data == other.store_) {
939  this->set(store_, capacity);
940  detail::copy_str<T>(other.store_, other.store_ + size, store_);
941  } else {
942  this->set(data, capacity);
943  // Set pointer to the inline array so that delete is not called
944  // when deallocating.
945  other.set(other.store_, 0);
946  other.clear();
947  }
948  this->resize(size);
949  }
950 
951  public:
959  move(other);
960  }
961 
967  auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& {
968  FMT_ASSERT(this != &other, "");
969  deallocate();
970  move(other);
971  return *this;
972  }
973 
974  // Returns a copy of the allocator associated with this buffer.
975  auto get_allocator() const -> Allocator { return alloc_; }
976 
981  FMT_CONSTEXPR20 void resize(size_t count) { this->try_resize(count); }
982 
984  void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
985 
987  template <typename ContiguousRange>
988  void append(const ContiguousRange& range) {
989  append(range.data(), range.data() + range.size());
990  }
991 };
992 
994 
995 template <typename T, size_t SIZE, typename Allocator>
996 struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
997 };
998 
1000 namespace detail {
1001 FMT_API auto write_console(int fd, string_view text) -> bool;
1002 FMT_API auto write_console(std::FILE* f, string_view text) -> bool;
1003 FMT_API void print(std::FILE*, string_view);
1004 } // namespace detail
1005 
1007 
1008 // Suppress a misleading warning in older versions of clang.
1009 #if FMT_CLANG_VERSION
1010 # pragma clang diagnostic ignored "-Wweak-vtables"
1011 #endif
1012 
1014 class FMT_SO_VISIBILITY("default") format_error : public std::runtime_error {
1015  public:
1016  using std::runtime_error::runtime_error;
1017 };
1018 
1019 namespace detail_exported {
1020 #if FMT_USE_NONTYPE_TEMPLATE_ARGS
1021 template <typename Char, size_t N> struct fixed_string {
1022  constexpr fixed_string(const Char (&str)[N]) {
1023  detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str),
1024  str + N, data);
1025  }
1026  Char data[N] = {};
1027 };
1028 #endif
1029 
1030 // Converts a compile-time string to basic_string_view.
1031 template <typename Char, size_t N>
1032 constexpr auto compile_string_to_view(const Char (&s)[N])
1034  // Remove trailing NUL character if needed. Won't be present if this is used
1035  // with a raw character array (i.e. not defined as a string).
1036  return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
1037 }
1038 template <typename Char>
1041  return {s.data(), s.size()};
1042 }
1043 } // namespace detail_exported
1044 
1045 class loc_value {
1046  private:
1048 
1049  public:
1050  template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>
1052 
1053  template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>
1055 
1056  template <typename Visitor> auto visit(Visitor&& vis) -> decltype(vis(0)) {
1057  return visit_format_arg(vis, value_);
1058  }
1059 };
1060 
1061 // A locale facet that formats values in UTF-8.
1062 // It is parameterized on the locale to avoid the heavy <locale> include.
1063 template <typename Locale> class format_facet : public Locale::facet {
1064  private:
1065  std::string separator_;
1066  std::string grouping_;
1067  std::string decimal_point_;
1068 
1069  protected:
1070  virtual auto do_put(appender out, loc_value val,
1071  const format_specs<>& specs) const -> bool;
1072 
1073  public:
1074  static FMT_API typename Locale::id id;
1075 
1076  explicit format_facet(Locale& loc);
1077  explicit format_facet(string_view sep = "",
1078  std::initializer_list<unsigned char> g = {3},
1079  std::string decimal_point = ".")
1080  : separator_(sep.data(), sep.size()),
1081  grouping_(g.begin(), g.end()),
1083 
1084  auto put(appender out, loc_value val, const format_specs<>& specs) const
1085  -> bool {
1086  return do_put(out, val, specs);
1087  }
1088 };
1089 
1090 namespace detail {
1091 
1092 // Returns true if value is negative, false otherwise.
1093 // Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
1094 template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
1095 constexpr auto is_negative(T value) -> bool {
1096  return value < 0;
1097 }
1098 template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
1099 constexpr auto is_negative(T) -> bool {
1100  return false;
1101 }
1102 
1103 template <typename T>
1105  if (std::is_same<T, float>()) return FMT_USE_FLOAT;
1106  if (std::is_same<T, double>()) return FMT_USE_DOUBLE;
1107  if (std::is_same<T, long double>()) return FMT_USE_LONG_DOUBLE;
1108  return true;
1109 }
1110 
1111 // Smallest of uint32_t, uint64_t, uint128_t that is large enough to
1112 // represent all values of an integral type T.
1113 template <typename T>
1114 using uint32_or_64_or_128_t =
1116  uint32_t,
1117  conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
1118 template <typename T>
1120 
1121 #define FMT_POWERS_OF_10(factor) \
1122  factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \
1123  (factor) * 100000, (factor) * 1000000, (factor) * 10000000, \
1124  (factor) * 100000000, (factor) * 1000000000
1125 
1126 // Converts value in the range [0, 100) to a string.
1127 constexpr auto digits2(size_t value) -> const char* {
1128  // GCC generates slightly better code when value is pointer-size.
1129  return &"0001020304050607080910111213141516171819"
1130  "2021222324252627282930313233343536373839"
1131  "4041424344454647484950515253545556575859"
1132  "6061626364656667686970717273747576777879"
1133  "8081828384858687888990919293949596979899"[value * 2];
1134 }
1135 
1136 // Sign is a template parameter to workaround a bug in gcc 4.8.
1137 template <typename Char, typename Sign> constexpr auto sign(Sign s) -> Char {
1138 #if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604
1139  static_assert(std::is_same<Sign, sign_t>::value, "");
1140 #endif
1141  return static_cast<Char>("\0-+ "[s]);
1142 }
1143 
1144 template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
1145  int count = 1;
1146  for (;;) {
1147  // Integer division is slow so do it for a group of four digits instead
1148  // of for every digit. The idea comes from the talk by Alexandrescu
1149  // "Three Optimization Tips for C++". See speed-test for a comparison.
1150  if (n < 10) return count;
1151  if (n < 100) return count + 1;
1152  if (n < 1000) return count + 2;
1153  if (n < 10000) return count + 3;
1154  n /= 10000u;
1155  count += 4;
1156  }
1157 }
1158 #if FMT_USE_INT128
1159 FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int {
1160  return count_digits_fallback(n);
1161 }
1162 #endif
1163 
1164 #ifdef FMT_BUILTIN_CLZLL
1165 // It is a separate function rather than a part of count_digits to workaround
1166 // the lack of static constexpr in constexpr functions.
1167 inline auto do_count_digits(uint64_t n) -> int {
1168  // This has comparable performance to the version by Kendall Willets
1169  // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)
1170  // but uses smaller tables.
1171  // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
1172  static constexpr uint8_t bsr2log10[] = {
1173  1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
1174  6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
1175  10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1176  15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1177  auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
1178  static constexpr const uint64_t zero_or_powers_of_10[] = {
1179  0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
1180  10000000000000000000ULL};
1181  return t - (n < zero_or_powers_of_10[t]);
1182 }
1183 #endif
1184 
1185 // Returns the number of decimal digits in n. Leading zeros are not counted
1186 // except for n == 0 in which case count_digits returns 1.
1187 FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {
1188 #ifdef FMT_BUILTIN_CLZLL
1189  if (!is_constant_evaluated()) {
1190  return do_count_digits(n);
1191  }
1192 #endif
1193  return count_digits_fallback(n);
1194 }
1195 
1196 // Counts the number of digits in n. BITS = log2(radix).
1197 template <int BITS, typename UInt>
1198 FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1199 #ifdef FMT_BUILTIN_CLZ
1200  if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1201  return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1202 #endif
1203  // Lambda avoids unreachable code warnings from NVHPC.
1204  return [](UInt m) {
1205  int num_digits = 0;
1206  do {
1207  ++num_digits;
1208  } while ((m >>= BITS) != 0);
1209  return num_digits;
1210  }(n);
1211 }
1212 
1213 #ifdef FMT_BUILTIN_CLZ
1214 // It is a separate function rather than a part of count_digits to workaround
1215 // the lack of static constexpr in constexpr functions.
1216 FMT_INLINE auto do_count_digits(uint32_t n) -> int {
1217 // An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
1218 // This increments the upper 32 bits (log10(T) - 1) when >= T is added.
1219 # define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)
1220  static constexpr uint64_t table[] = {
1221  FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8
1222  FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64
1223  FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512
1224  FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096
1225  FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k
1226  FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k
1227  FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k
1228  FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M
1229  FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M
1230  FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M
1231  FMT_INC(1000000000), FMT_INC(1000000000) // 4B
1232  };
1233  auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
1234  return static_cast<int>((n + inc) >> 32);
1235 }
1236 #endif
1237 
1238 // Optional version of count_digits for better performance on 32-bit platforms.
1239 FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {
1240 #ifdef FMT_BUILTIN_CLZ
1241  if (!is_constant_evaluated()) {
1242  return do_count_digits(n);
1243  }
1244 #endif
1245  return count_digits_fallback(n);
1246 }
1247 
1248 template <typename Int> constexpr auto digits10() noexcept -> int {
1250 }
1251 template <> constexpr auto digits10<int128_opt>() noexcept -> int { return 38; }
1252 template <> constexpr auto digits10<uint128_t>() noexcept -> int { return 38; }
1253 
1254 template <typename Char> struct thousands_sep_result {
1255  std::string grouping;
1257 };
1258 
1259 template <typename Char>
1261 template <typename Char>
1263  auto result = thousands_sep_impl<char>(loc);
1264  return {result.grouping, Char(result.thousands_sep)};
1265 }
1266 template <>
1268  return thousands_sep_impl<wchar_t>(loc);
1269 }
1270 
1271 template <typename Char>
1272 FMT_API auto decimal_point_impl(locale_ref loc) -> Char;
1273 template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1274  return Char(decimal_point_impl<char>(loc));
1275 }
1276 template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1277  return decimal_point_impl<wchar_t>(loc);
1278 }
1279 
1280 // Compares two characters for equality.
1281 template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1282  return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1283 }
1284 inline auto equal2(const char* lhs, const char* rhs) -> bool {
1285  return memcmp(lhs, rhs, 2) == 0;
1286 }
1287 
1288 // Copies two characters from src to dst.
1289 template <typename Char>
1290 FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) {
1291  if (!is_constant_evaluated() && sizeof(Char) == sizeof(char)) {
1292  memcpy(dst, src, 2);
1293  return;
1294  }
1295  *dst++ = static_cast<Char>(*src++);
1296  *dst = static_cast<Char>(*src);
1297 }
1298 
1299 template <typename Iterator> struct format_decimal_result {
1300  Iterator begin;
1301  Iterator end;
1302 };
1303 
1304 // Formats a decimal unsigned integer value writing into out pointing to a
1305 // buffer of specified size. The caller must ensure that the buffer is large
1306 // enough.
1307 template <typename Char, typename UInt>
1308 FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
1310  FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1311  out += size;
1312  Char* end = out;
1313  while (value >= 100) {
1314  // Integer division is slow so do it for a group of two digits instead
1315  // of for every digit. The idea comes from the talk by Alexandrescu
1316  // "Three Optimization Tips for C++". See speed-test for a comparison.
1317  out -= 2;
1318  copy2(out, digits2(static_cast<size_t>(value % 100)));
1319  value /= 100;
1320  }
1321  if (value < 10) {
1322  *--out = static_cast<Char>('0' + value);
1323  return {out, end};
1324  }
1325  out -= 2;
1326  copy2(out, digits2(static_cast<size_t>(value)));
1327  return {out, end};
1328 }
1329 
1330 template <typename Char, typename UInt, typename Iterator,
1331  FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)>
1332 FMT_CONSTEXPR inline auto format_decimal(Iterator out, UInt value, int size)
1334  // Buffer is large enough to hold all digits (digits10 + 1).
1335  Char buffer[digits10<UInt>() + 1] = {};
1336  auto end = format_decimal(buffer, value, size).end;
1337  return {out, detail::copy_str_noinline<Char>(buffer, end, out)};
1338 }
1339 
1340 template <unsigned BASE_BITS, typename Char, typename UInt>
1341 FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits,
1342  bool upper = false) -> Char* {
1343  buffer += num_digits;
1344  Char* end = buffer;
1345  do {
1346  const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1347  unsigned digit = static_cast<unsigned>(value & ((1 << BASE_BITS) - 1));
1348  *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
1349  : digits[digit]);
1350  } while ((value >>= BASE_BITS) != 0);
1351  return end;
1352 }
1353 
1354 template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1355 FMT_CONSTEXPR inline auto format_uint(It out, UInt value, int num_digits,
1356  bool upper = false) -> It {
1357  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1358  format_uint<BASE_BITS>(ptr, value, num_digits, upper);
1359  return out;
1360  }
1361  // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
1362  char buffer[num_bits<UInt>() / BASE_BITS + 1] = {};
1363  format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1364  return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out);
1365 }
1366 
1367 // A converter from UTF-8 to UTF-16.
1369  private:
1371 
1372  public:
1373  FMT_API explicit utf8_to_utf16(string_view s);
1374  operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; }
1375  auto size() const -> size_t { return buffer_.size() - 1; }
1376  auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1377  auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1378 };
1379 
1381 
1382 // A converter from UTF-16/UTF-32 (host endian) to UTF-8.
1383 template <typename WChar, typename Buffer = memory_buffer> class to_utf8 {
1384  private:
1385  Buffer buffer_;
1386 
1387  public:
1388  to_utf8() {}
1391  static_assert(sizeof(WChar) == 2 || sizeof(WChar) == 4,
1392  "Expect utf16 or utf32");
1393  if (!convert(s, policy))
1394  FMT_THROW(std::runtime_error(sizeof(WChar) == 2 ? "invalid utf16"
1395  : "invalid utf32"));
1396  }
1397  operator string_view() const { return string_view(&buffer_[0], size()); }
1398  auto size() const -> size_t { return buffer_.size() - 1; }
1399  auto c_str() const -> const char* { return &buffer_[0]; }
1400  auto str() const -> std::string { return std::string(&buffer_[0], size()); }
1401 
1402  // Performs conversion returning a bool instead of throwing exception on
1403  // conversion error. This method may still throw in case of memory allocation
1404  // error.
1407  -> bool {
1408  if (!convert(buffer_, s, policy)) return false;
1409  buffer_.push_back(0);
1410  return true;
1411  }
1412  static auto convert(Buffer& buf, basic_string_view<WChar> s,
1414  -> bool {
1415  for (auto p = s.begin(); p != s.end(); ++p) {
1416  uint32_t c = static_cast<uint32_t>(*p);
1417  if (sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) {
1418  // Handle a surrogate pair.
1419  ++p;
1420  if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) {
1421  if (policy == to_utf8_error_policy::abort) return false;
1422  buf.append(string_view("\xEF\xBF\xBD"));
1423  --p;
1424  } else {
1425  c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00;
1426  }
1427  } else if (c < 0x80) {
1428  buf.push_back(static_cast<char>(c));
1429  } else if (c < 0x800) {
1430  buf.push_back(static_cast<char>(0xc0 | (c >> 6)));
1431  buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1432  } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) {
1433  buf.push_back(static_cast<char>(0xe0 | (c >> 12)));
1434  buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1435  buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1436  } else if (c >= 0x10000 && c <= 0x10ffff) {
1437  buf.push_back(static_cast<char>(0xf0 | (c >> 18)));
1438  buf.push_back(static_cast<char>(0x80 | ((c & 0x3ffff) >> 12)));
1439  buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1440  buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1441  } else {
1442  return false;
1443  }
1444  }
1445  return true;
1446  }
1447 };
1448 
1449 // Computes 128-bit result of multiplication of two 64-bit unsigned integers.
1450 inline auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback {
1451 #if FMT_USE_INT128
1452  auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1453  return {static_cast<uint64_t>(p >> 64), static_cast<uint64_t>(p)};
1454 #elif defined(_MSC_VER) && defined(_M_X64)
1455  auto hi = uint64_t();
1456  auto lo = _umul128(x, y, &hi);
1457  return {hi, lo};
1458 #else
1459  const uint64_t mask = static_cast<uint64_t>(max_value<uint32_t>());
1460 
1461  uint64_t a = x >> 32;
1462  uint64_t b = x & mask;
1463  uint64_t c = y >> 32;
1464  uint64_t d = y & mask;
1465 
1466  uint64_t ac = a * c;
1467  uint64_t bc = b * c;
1468  uint64_t ad = a * d;
1469  uint64_t bd = b * d;
1470 
1471  uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask);
1472 
1473  return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
1474  (intermediate << 32) + (bd & mask)};
1475 #endif
1476 }
1477 
1478 namespace dragonbox {
1479 // Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from
1480 // https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1.
1481 inline auto floor_log10_pow2(int e) noexcept -> int {
1482  FMT_ASSERT(e <= 2620 && e >= -2620, "too large exponent");
1483  static_assert((-1 >> 1) == -1, "right shift is not arithmetic");
1484  return (e * 315653) >> 20;
1485 }
1486 
1487 inline auto floor_log2_pow10(int e) noexcept -> int {
1488  FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent");
1489  return (e * 1741647) >> 19;
1490 }
1491 
1492 // Computes upper 64 bits of multiplication of two 64-bit unsigned integers.
1493 inline auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t {
1494 #if FMT_USE_INT128
1495  auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1496  return static_cast<uint64_t>(p >> 64);
1497 #elif defined(_MSC_VER) && defined(_M_X64)
1498  return __umulh(x, y);
1499 #else
1500  return umul128(x, y).high();
1501 #endif
1502 }
1503 
1504 // Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a
1505 // 128-bit unsigned integer.
1506 inline auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept
1507  -> uint128_fallback {
1508  uint128_fallback r = umul128(x, y.high());
1509  r += umul128_upper64(x, y.low());
1510  return r;
1511 }
1512 
1513 FMT_API auto get_cached_power(int k) noexcept -> uint128_fallback;
1514 
1515 // Type-specific information that Dragonbox uses.
1516 template <typename T, typename Enable = void> struct float_info;
1517 
1518 template <> struct float_info<float> {
1519  using carrier_uint = uint32_t;
1520  static const int exponent_bits = 8;
1521  static const int kappa = 1;
1522  static const int big_divisor = 100;
1523  static const int small_divisor = 10;
1524  static const int min_k = -31;
1525  static const int max_k = 46;
1526  static const int shorter_interval_tie_lower_threshold = -35;
1527  static const int shorter_interval_tie_upper_threshold = -35;
1528 };
1529 
1530 template <> struct float_info<double> {
1531  using carrier_uint = uint64_t;
1532  static const int exponent_bits = 11;
1533  static const int kappa = 2;
1534  static const int big_divisor = 1000;
1535  static const int small_divisor = 100;
1536  static const int min_k = -292;
1537  static const int max_k = 341;
1538  static const int shorter_interval_tie_lower_threshold = -77;
1539  static const int shorter_interval_tie_upper_threshold = -77;
1540 };
1541 
1542 // An 80- or 128-bit floating point number.
1543 template <typename T>
1544 struct float_info<T, enable_if_t<std::numeric_limits<T>::digits == 64 ||
1545  std::numeric_limits<T>::digits == 113 ||
1546  is_float128<T>::value>> {
1548  static const int exponent_bits = 15;
1549 };
1550 
1551 // A double-double floating point number.
1552 template <typename T>
1553 struct float_info<T, enable_if_t<is_double_double<T>::value>> {
1555 };
1556 
1557 template <typename T> struct decimal_fp {
1561 };
1562 
1563 template <typename T> FMT_API auto to_decimal(T x) noexcept -> decimal_fp<T>;
1564 } // namespace dragonbox
1565 
1566 // Returns true iff Float has the implicit bit which is not stored.
1567 template <typename Float> constexpr auto has_implicit_bit() -> bool {
1568  // An 80-bit FP number has a 64-bit significand an no implicit bit.
1569  return std::numeric_limits<Float>::digits != 64;
1570 }
1571 
1572 // Returns the number of significand bits stored in Float. The implicit bit is
1573 // not counted since it is not stored.
1574 template <typename Float> constexpr auto num_significand_bits() -> int {
1575  // std::numeric_limits may not support __float128.
1576  return is_float128<Float>() ? 112
1577  : (std::numeric_limits<Float>::digits -
1578  (has_implicit_bit<Float>() ? 1 : 0));
1579 }
1580 
1581 template <typename Float>
1582 constexpr auto exponent_mask() ->
1584  using float_uint = typename dragonbox::float_info<Float>::carrier_uint;
1585  return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1586  << num_significand_bits<Float>();
1587 }
1588 template <typename Float> constexpr auto exponent_bias() -> int {
1589  // std::numeric_limits may not support __float128.
1590  return is_float128<Float>() ? 16383
1591  : std::numeric_limits<Float>::max_exponent - 1;
1592 }
1593 
1594 // Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1595 template <typename Char, typename It>
1596 FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It {
1597  FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1598  if (exp < 0) {
1599  *it++ = static_cast<Char>('-');
1600  exp = -exp;
1601  } else {
1602  *it++ = static_cast<Char>('+');
1603  }
1604  if (exp >= 100) {
1605  const char* top = digits2(to_unsigned(exp / 100));
1606  if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
1607  *it++ = static_cast<Char>(top[1]);
1608  exp %= 100;
1609  }
1610  const char* d = digits2(to_unsigned(exp));
1611  *it++ = static_cast<Char>(d[0]);
1612  *it++ = static_cast<Char>(d[1]);
1613  return it;
1614 }
1615 
1616 // A floating-point number f * pow(2, e) where F is an unsigned type.
1617 template <typename F> struct basic_fp {
1618  F f;
1619  int e;
1620 
1621  static constexpr const int num_significand_bits =
1622  static_cast<int>(sizeof(F) * num_bits<unsigned char>());
1623 
1624  constexpr basic_fp() : f(0), e(0) {}
1625  constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
1626 
1627  // Constructs fp from an IEEE754 floating-point number.
1628  template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
1629 
1630  // Assigns n to this and return true iff predecessor is closer than successor.
1631  template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
1632  FMT_CONSTEXPR auto assign(Float n) -> bool {
1633  static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1634  // Assume Float is in the format [sign][exponent][significand].
1635  using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1636  const auto num_float_significand_bits =
1637  detail::num_significand_bits<Float>();
1638  const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1639  const auto significand_mask = implicit_bit - 1;
1640  auto u = bit_cast<carrier_uint>(n);
1641  f = static_cast<F>(u & significand_mask);
1642  auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1643  num_float_significand_bits);
1644  // The predecessor is closer if n is a normalized power of 2 (f == 0)
1645  // other than the smallest normalized number (biased_e > 1).
1646  auto is_predecessor_closer = f == 0 && biased_e > 1;
1647  if (biased_e == 0)
1648  biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
1649  else if (has_implicit_bit<Float>())
1650  f += static_cast<F>(implicit_bit);
1651  e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1652  if (!has_implicit_bit<Float>()) ++e;
1653  return is_predecessor_closer;
1654  }
1655 
1656  template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
1657  FMT_CONSTEXPR auto assign(Float n) -> bool {
1658  static_assert(std::numeric_limits<double>::is_iec559, "unsupported FP");
1659  return assign(static_cast<double>(n));
1660  }
1661 };
1662 
1664 
1665 // Normalizes the value converted from double and multiplied by (1 << SHIFT).
1666 template <int SHIFT = 0, typename F>
1668  // Handle subnormals.
1669  const auto implicit_bit = F(1) << num_significand_bits<double>();
1670  const auto shifted_implicit_bit = implicit_bit << SHIFT;
1671  while ((value.f & shifted_implicit_bit) == 0) {
1672  value.f <<= 1;
1673  --value.e;
1674  }
1675  // Subtract 1 to account for hidden bit.
1676  const auto offset = basic_fp<F>::num_significand_bits -
1677  num_significand_bits<double>() - SHIFT - 1;
1678  value.f <<= offset;
1679  value.e -= offset;
1680  return value;
1681 }
1682 
1683 // Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
1684 FMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t {
1685 #if FMT_USE_INT128
1686  auto product = static_cast<__uint128_t>(lhs) * rhs;
1687  auto f = static_cast<uint64_t>(product >> 64);
1688  return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1689 #else
1690  // Multiply 32-bit parts of significands.
1691  uint64_t mask = (1ULL << 32) - 1;
1692  uint64_t a = lhs >> 32, b = lhs & mask;
1693  uint64_t c = rhs >> 32, d = rhs & mask;
1694  uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
1695  // Compute mid 64-bit of result and round.
1696  uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1697  return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1698 #endif
1699 }
1700 
1701 FMT_CONSTEXPR inline auto operator*(fp x, fp y) -> fp {
1702  return {multiply(x.f, y.f), x.e + y.e + 64};
1703 }
1704 
1705 template <typename T, bool doublish = num_bits<T>() == num_bits<double>()>
1706 using convert_float_result =
1708 
1709 template <typename T>
1711  return static_cast<convert_float_result<T>>(value);
1712 }
1713 
1714 template <typename OutputIt, typename Char>
1715 FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
1716  const fill_t<Char>& fill) -> OutputIt {
1717  auto fill_size = fill.size();
1718  if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
1719  auto data = fill.data();
1720  for (size_t i = 0; i < n; ++i)
1721  it = copy_str<Char>(data, data + fill_size, it);
1722  return it;
1723 }
1724 
1725 // Writes the output of f, padded according to format specifications in specs.
1726 // size: output size in code units.
1727 // width: output display width in (terminal) column positions.
1728 template <align::type align = align::left, typename OutputIt, typename Char,
1729  typename F>
1730 FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs<Char>& specs,
1731  size_t size, size_t width, F&& f) -> OutputIt {
1732  static_assert(align == align::left || align == align::right, "");
1733  unsigned spec_width = to_unsigned(specs.width);
1734  size_t padding = spec_width > width ? spec_width - width : 0;
1735  // Shifts are encoded as string literals because static constexpr is not
1736  // supported in constexpr functions.
1737  auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1738  size_t left_padding = padding >> shifts[specs.align];
1739  size_t right_padding = padding - left_padding;
1740  auto it = reserve(out, size + padding * specs.fill.size());
1741  if (left_padding != 0) it = fill(it, left_padding, specs.fill);
1742  it = f(it);
1743  if (right_padding != 0) it = fill(it, right_padding, specs.fill);
1744  return base_iterator(out, it);
1745 }
1746 
1747 template <align::type align = align::left, typename OutputIt, typename Char,
1748  typename F>
1749 constexpr auto write_padded(OutputIt out, const format_specs<Char>& specs,
1750  size_t size, F&& f) -> OutputIt {
1751  return write_padded<align>(out, specs, size, size, f);
1752 }
1753 
1754 template <align::type align = align::left, typename Char, typename OutputIt>
1756  const format_specs<Char>& specs) -> OutputIt {
1757  return write_padded<align>(
1758  out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1759  const char* data = bytes.data();
1760  return copy_str<Char>(data, data + bytes.size(), it);
1761  });
1762 }
1763 
1764 template <typename Char, typename OutputIt, typename UIntPtr>
1765 auto write_ptr(OutputIt out, UIntPtr value, const format_specs<Char>* specs)
1766  -> OutputIt {
1767  int num_digits = count_digits<4>(value);
1768  auto size = to_unsigned(num_digits) + size_t(2);
1769  auto write = [=](reserve_iterator<OutputIt> it) {
1770  *it++ = static_cast<Char>('0');
1771  *it++ = static_cast<Char>('x');
1772  return format_uint<4, Char>(it, value, num_digits);
1773  };
1774  return specs ? write_padded<align::right>(out, *specs, size, write)
1775  : base_iterator(out, write(reserve(out, size)));
1776 }
1777 
1778 // Returns true iff the code point cp is printable.
1779 FMT_API auto is_printable(uint32_t cp) -> bool;
1780 
1781 inline auto needs_escape(uint32_t cp) -> bool {
1782  return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' ||
1783  !is_printable(cp);
1784 }
1785 
1786 template <typename Char> struct find_escape_result {
1787  const Char* begin;
1788  const Char* end;
1789  uint32_t cp;
1790 };
1791 
1792 template <typename Char>
1793 using make_unsigned_char =
1795  std::make_unsigned<Char>,
1797 
1798 template <typename Char>
1799 auto find_escape(const Char* begin, const Char* end)
1801  for (; begin != end; ++begin) {
1802  uint32_t cp = static_cast<make_unsigned_char<Char>>(*begin);
1803  if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue;
1804  if (needs_escape(cp)) return {begin, begin + 1, cp};
1805  }
1806  return {begin, nullptr, 0};
1807 }
1808 
1809 inline auto find_escape(const char* begin, const char* end)
1811  if (!is_utf8()) return find_escape<char>(begin, end);
1812  auto result = find_escape_result<char>{end, nullptr, 0};
1813  for_each_codepoint(string_view(begin, to_unsigned(end - begin)),
1814  [&](uint32_t cp, string_view sv) {
1815  if (needs_escape(cp)) {
1816  result = {sv.begin(), sv.end(), cp};
1817  return false;
1818  }
1819  return true;
1820  });
1821  return result;
1822 }
1823 
1824 #define FMT_STRING_IMPL(s, base, explicit) \
1825  [] { \
1826  /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
1827  /* Use a macro-like name to avoid shadowing warnings. */ \
1828  struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base { \
1829  using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t<decltype(s[0])>; \
1830  FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
1831  operator fmt::basic_string_view<char_type>() const { \
1832  return fmt::detail_exported::compile_string_to_view<char_type>(s); \
1833  } \
1834  }; \
1835  return FMT_COMPILE_STRING(); \
1836  }()
1837 
1848 #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
1849 
1850 template <size_t width, typename Char, typename OutputIt>
1851 auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {
1852  *out++ = static_cast<Char>('\\');
1853  *out++ = static_cast<Char>(prefix);
1854  Char buf[width];
1855  fill_n(buf, width, static_cast<Char>('0'));
1856  format_uint<4>(buf, cp, width);
1857  return copy_str<Char>(buf, buf + width, out);
1858 }
1859 
1860 template <typename OutputIt, typename Char>
1862  -> OutputIt {
1863  auto c = static_cast<Char>(escape.cp);
1864  switch (escape.cp) {
1865  case '\n':
1866  *out++ = static_cast<Char>('\\');
1867  c = static_cast<Char>('n');
1868  break;
1869  case '\r':
1870  *out++ = static_cast<Char>('\\');
1871  c = static_cast<Char>('r');
1872  break;
1873  case '\t':
1874  *out++ = static_cast<Char>('\\');
1875  c = static_cast<Char>('t');
1876  break;
1877  case '"':
1879  case '\'':
1881  case '\\':
1882  *out++ = static_cast<Char>('\\');
1883  break;
1884  default:
1885  if (escape.cp < 0x100) {
1886  return write_codepoint<2, Char>(out, 'x', escape.cp);
1887  }
1888  if (escape.cp < 0x10000) {
1889  return write_codepoint<4, Char>(out, 'u', escape.cp);
1890  }
1891  if (escape.cp < 0x110000) {
1892  return write_codepoint<8, Char>(out, 'U', escape.cp);
1893  }
1894  for (Char escape_char : basic_string_view<Char>(
1895  escape.begin, to_unsigned(escape.end - escape.begin))) {
1896  out = write_codepoint<2, Char>(out, 'x',
1897  static_cast<uint32_t>(escape_char) & 0xFF);
1898  }
1899  return out;
1900  }
1901  *out++ = c;
1902  return out;
1903 }
1904 
1905 template <typename Char, typename OutputIt>
1907  -> OutputIt {
1908  *out++ = static_cast<Char>('"');
1909  auto begin = str.begin(), end = str.end();
1910  do {
1911  auto escape = find_escape(begin, end);
1912  out = copy_str<Char>(begin, escape.begin, out);
1913  begin = escape.end;
1914  if (!begin) break;
1915  out = write_escaped_cp<OutputIt, Char>(out, escape);
1916  } while (begin != end);
1917  *out++ = static_cast<Char>('"');
1918  return out;
1919 }
1920 
1921 template <typename Char, typename OutputIt>
1922 auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
1923  Char v_array[1] = {v};
1924  *out++ = static_cast<Char>('\'');
1925  if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('"')) ||
1926  v == static_cast<Char>('\'')) {
1927  out = write_escaped_cp(out,
1928  find_escape_result<Char>{v_array, v_array + 1,
1929  static_cast<uint32_t>(v)});
1930  } else {
1931  *out++ = v;
1932  }
1933  *out++ = static_cast<Char>('\'');
1934  return out;
1935 }
1936 
1937 template <typename Char, typename OutputIt>
1938 FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1939  const format_specs<Char>& specs) -> OutputIt {
1940  bool is_debug = specs.type == presentation_type::debug;
1941  return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1942  if (is_debug) return write_escaped_char(it, value);
1943  *it++ = value;
1944  return it;
1945  });
1946 }
1947 template <typename Char, typename OutputIt>
1948 FMT_CONSTEXPR auto write(OutputIt out, Char value,
1949  const format_specs<Char>& specs, locale_ref loc = {})
1950  -> OutputIt {
1951  // char is formatted as unsigned char for consistency across platforms.
1952  using unsigned_type =
1953  conditional_t<std::is_same<Char, char>::value, unsigned char, unsigned>;
1954  return check_char_specs(specs)
1955  ? write_char(out, value, specs)
1956  : write(out, static_cast<unsigned_type>(value), specs, loc);
1957 }
1958 
1959 // Data for write_int that doesn't depend on output iterator type. It is used to
1960 // avoid template code bloat.
1961 template <typename Char> struct write_int_data {
1962  size_t size;
1963  size_t padding;
1964 
1965  FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
1966  const format_specs<Char>& specs)
1967  : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
1968  if (specs.align == align::numeric) {
1969  auto width = to_unsigned(specs.width);
1970  if (width > size) {
1971  padding = width - size;
1972  size = width;
1973  }
1974  } else if (specs.precision > num_digits) {
1975  size = (prefix >> 24) + to_unsigned(specs.precision);
1976  padding = to_unsigned(specs.precision - num_digits);
1977  }
1978  }
1979 };
1980 
1981 // Writes an integer in the format
1982 // <left-padding><prefix><numeric-padding><digits><right-padding>
1983 // where <digits> are written by write_digits(it).
1984 // prefix contains chars in three lower bytes and the size in the fourth byte.
1985 template <typename OutputIt, typename Char, typename W>
1986 FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
1987  unsigned prefix,
1988  const format_specs<Char>& specs,
1989  W write_digits) -> OutputIt {
1990  // Slightly faster check for specs.width == 0 && specs.precision == -1.
1991  if ((specs.width | (specs.precision + 1)) == 0) {
1992  auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
1993  if (prefix != 0) {
1994  for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1995  *it++ = static_cast<Char>(p & 0xff);
1996  }
1997  return base_iterator(out, write_digits(it));
1998  }
1999  auto data = write_int_data<Char>(num_digits, prefix, specs);
2000  return write_padded<align::right>(
2001  out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
2002  for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2003  *it++ = static_cast<Char>(p & 0xff);
2004  it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
2005  return write_digits(it);
2006  });
2007 }
2008 
2009 template <typename Char> class digit_grouping {
2010  private:
2011  std::string grouping_;
2012  std::basic_string<Char> thousands_sep_;
2013 
2014  struct next_state {
2015  std::string::const_iterator group;
2016  int pos;
2017  };
2018  auto initial_state() const -> next_state { return {grouping_.begin(), 0}; }
2019 
2020  // Returns the next digit group separator position.
2021  auto next(next_state& state) const -> int {
2022  if (thousands_sep_.empty()) return max_value<int>();
2023  if (state.group == grouping_.end()) return state.pos += grouping_.back();
2024  if (*state.group <= 0 || *state.group == max_value<char>())
2025  return max_value<int>();
2026  state.pos += *state.group++;
2027  return state.pos;
2028  }
2029 
2030  public:
2031  explicit digit_grouping(locale_ref loc, bool localized = true) {
2032  if (!localized) return;
2033  auto sep = thousands_sep<Char>(loc);
2034  grouping_ = sep.grouping;
2035  if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep);
2036  }
2037  digit_grouping(std::string grouping, std::basic_string<Char> sep)
2038  : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {}
2039 
2040  auto has_separator() const -> bool { return !thousands_sep_.empty(); }
2041 
2042  auto count_separators(int num_digits) const -> int {
2043  int count = 0;
2044  auto state = initial_state();
2045  while (num_digits > next(state)) ++count;
2046  return count;
2047  }
2048 
2049  // Applies grouping to digits and write the output to out.
2050  template <typename Out, typename C>
2051  auto apply(Out out, basic_string_view<C> digits) const -> Out {
2052  auto num_digits = static_cast<int>(digits.size());
2053  auto separators = basic_memory_buffer<int>();
2054  separators.push_back(0);
2055  auto state = initial_state();
2056  while (int i = next(state)) {
2057  if (i >= num_digits) break;
2058  separators.push_back(i);
2059  }
2060  for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);
2061  i < num_digits; ++i) {
2062  if (num_digits - i == separators[sep_index]) {
2063  out =
2064  copy_str<Char>(thousands_sep_.data(),
2065  thousands_sep_.data() + thousands_sep_.size(), out);
2066  --sep_index;
2067  }
2068  *out++ = static_cast<Char>(digits[to_unsigned(i)]);
2069  }
2070  return out;
2071  }
2072 };
2073 
2074 FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
2075  prefix |= prefix != 0 ? value << 8 : value;
2076  prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
2077 }
2078 
2079 // Writes a decimal integer with digit grouping.
2080 template <typename OutputIt, typename UInt, typename Char>
2081 auto write_int(OutputIt out, UInt value, unsigned prefix,
2082  const format_specs<Char>& specs,
2083  const digit_grouping<Char>& grouping) -> OutputIt {
2084  static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
2085  int num_digits = 0;
2086  auto buffer = memory_buffer();
2087  switch (specs.type) {
2089  case presentation_type::dec: {
2090  num_digits = count_digits(value);
2091  format_decimal<char>(appender(buffer), value, num_digits);
2092  break;
2093  }
2096  bool upper = specs.type == presentation_type::hex_upper;
2097  if (specs.alt)
2098  prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
2099  num_digits = count_digits<4>(value);
2100  format_uint<4, char>(appender(buffer), value, num_digits, upper);
2101  break;
2102  }
2105  bool upper = specs.type == presentation_type::bin_upper;
2106  if (specs.alt)
2107  prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
2108  num_digits = count_digits<1>(value);
2109  format_uint<1, char>(appender(buffer), value, num_digits);
2110  break;
2111  }
2112  case presentation_type::oct: {
2113  num_digits = count_digits<3>(value);
2114  // Octal prefix '0' is counted as a digit, so only add it if precision
2115  // is not greater than the number of digits.
2116  if (specs.alt && specs.precision <= num_digits && value != 0)
2117  prefix_append(prefix, '0');
2118  format_uint<3, char>(appender(buffer), value, num_digits);
2119  break;
2120  }
2122  return write_char(out, static_cast<Char>(value), specs);
2123  default:
2124  throw_format_error("invalid format specifier");
2125  }
2126 
2127  unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) +
2128  to_unsigned(grouping.count_separators(num_digits));
2129  return write_padded<align::right>(
2130  out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
2131  for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2132  *it++ = static_cast<Char>(p & 0xff);
2133  return grouping.apply(it, string_view(buffer.data(), buffer.size()));
2134  });
2135 }
2136 
2137 // Writes a localized value.
2138 FMT_API auto write_loc(appender out, loc_value value,
2139  const format_specs<>& specs, locale_ref loc) -> bool;
2140 template <typename OutputIt, typename Char>
2141 inline auto write_loc(OutputIt, loc_value, const format_specs<Char>&,
2142  locale_ref) -> bool {
2143  return false;
2144 }
2145 
2146 template <typename UInt> struct write_int_arg {
2148  unsigned prefix;
2149 };
2150 
2151 template <typename T>
2154  auto prefix = 0u;
2155  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2156  if (is_negative(value)) {
2157  prefix = 0x01000000 | '-';
2158  abs_value = 0 - abs_value;
2159  } else {
2160  constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
2161  0x1000000u | ' '};
2162  prefix = prefixes[sign];
2163  }
2164  return {abs_value, prefix};
2165 }
2166 
2167 template <typename Char = char> struct loc_writer {
2170  std::basic_string<Char> sep;
2171  std::string grouping;
2172  std::basic_string<Char> decimal_point;
2173 
2174  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2175  auto operator()(T value) -> bool {
2176  auto arg = make_write_int_arg(value, specs.sign);
2177  write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2179  return true;
2180  }
2181 
2182  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2183  auto operator()(T) -> bool {
2184  return false;
2185  }
2186 };
2187 
2188 template <typename Char, typename OutputIt, typename T>
2190  const format_specs<Char>& specs,
2191  locale_ref) -> OutputIt {
2192  static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2193  auto abs_value = arg.abs_value;
2194  auto prefix = arg.prefix;
2195  switch (specs.type) {
2197  case presentation_type::dec: {
2198  auto num_digits = count_digits(abs_value);
2199  return write_int(
2200  out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2201  return format_decimal<Char>(it, abs_value, num_digits).end;
2202  });
2203  }
2206  bool upper = specs.type == presentation_type::hex_upper;
2207  if (specs.alt)
2208  prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
2209  int num_digits = count_digits<4>(abs_value);
2210  return write_int(
2211  out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2212  return format_uint<4, Char>(it, abs_value, num_digits, upper);
2213  });
2214  }
2217  bool upper = specs.type == presentation_type::bin_upper;
2218  if (specs.alt)
2219  prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
2220  int num_digits = count_digits<1>(abs_value);
2221  return write_int(out, num_digits, prefix, specs,
2222  [=](reserve_iterator<OutputIt> it) {
2223  return format_uint<1, Char>(it, abs_value, num_digits);
2224  });
2225  }
2226  case presentation_type::oct: {
2227  int num_digits = count_digits<3>(abs_value);
2228  // Octal prefix '0' is counted as a digit, so only add it if precision
2229  // is not greater than the number of digits.
2230  if (specs.alt && specs.precision <= num_digits && abs_value != 0)
2231  prefix_append(prefix, '0');
2232  return write_int(out, num_digits, prefix, specs,
2233  [=](reserve_iterator<OutputIt> it) {
2234  return format_uint<3, Char>(it, abs_value, num_digits);
2235  });
2236  }
2238  return write_char(out, static_cast<Char>(abs_value), specs);
2239  default:
2240  throw_format_error("invalid format specifier");
2241  }
2242  return out;
2243 }
2244 template <typename Char, typename OutputIt, typename T>
2246  OutputIt out, write_int_arg<T> arg, const format_specs<Char>& specs,
2247  locale_ref loc) -> OutputIt {
2248  return write_int(out, arg, specs, loc);
2249 }
2250 template <typename Char, typename OutputIt, typename T,
2251  FMT_ENABLE_IF(is_integral<T>::value &&
2252  !std::is_same<T, bool>::value &&
2253  std::is_same<OutputIt, buffer_appender<Char>>::value)>
2254 FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2255  const format_specs<Char>& specs,
2256  locale_ref loc) -> OutputIt {
2257  if (specs.localized && write_loc(out, value, specs, loc)) return out;
2258  return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
2259  loc);
2260 }
2261 // An inlined version of write used in format string compilation.
2262 template <typename Char, typename OutputIt, typename T,
2263  FMT_ENABLE_IF(is_integral<T>::value &&
2264  !std::is_same<T, bool>::value &&
2265  !std::is_same<OutputIt, buffer_appender<Char>>::value)>
2266 FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2267  const format_specs<Char>& specs,
2268  locale_ref loc) -> OutputIt {
2269  if (specs.localized && write_loc(out, value, specs, loc)) return out;
2270  return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
2271 }
2272 
2273 // An output iterator that counts the number of objects written to it and
2274 // discards them.
2276  private:
2277  size_t count_;
2278 
2279  public:
2280  using iterator_category = std::output_iterator_tag;
2281  using difference_type = std::ptrdiff_t;
2282  using pointer = void;
2283  using reference = void;
2285 
2286  struct value_type {
2287  template <typename T> FMT_CONSTEXPR void operator=(const T&) {}
2288  };
2289 
2291 
2292  FMT_CONSTEXPR auto count() const -> size_t { return count_; }
2293 
2295  ++count_;
2296  return *this;
2297  }
2299  auto it = *this;
2300  ++*this;
2301  return it;
2302  }
2303 
2305  -> counting_iterator {
2306  it.count_ += static_cast<size_t>(n);
2307  return it;
2308  }
2309 
2310  FMT_CONSTEXPR auto operator*() const -> value_type { return {}; }
2311 };
2312 
2313 template <typename Char, typename OutputIt>
2315  const format_specs<Char>& specs) -> OutputIt {
2316  auto data = s.data();
2317  auto size = s.size();
2318  if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
2320  bool is_debug = specs.type == presentation_type::debug;
2321  size_t width = 0;
2322  if (specs.width != 0) {
2323  if (is_debug)
2325  else
2327  }
2328  return write_padded(out, specs, size, width,
2329  [=](reserve_iterator<OutputIt> it) {
2330  if (is_debug) return write_escaped_string(it, s);
2331  return copy_str<Char>(data, data + size, it);
2332  });
2333 }
2334 template <typename Char, typename OutputIt>
2335 FMT_CONSTEXPR auto write(OutputIt out,
2337  const format_specs<Char>& specs, locale_ref)
2338  -> OutputIt {
2339  return write(out, s, specs);
2340 }
2341 template <typename Char, typename OutputIt>
2342 FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
2343  const format_specs<Char>& specs, locale_ref)
2344  -> OutputIt {
2345  if (specs.type == presentation_type::pointer)
2346  return write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
2347  if (!s) throw_format_error("string pointer is null");
2348  return write(out, basic_string_view<Char>(s), specs, {});
2349 }
2350 
2351 template <typename Char, typename OutputIt, typename T,
2352  FMT_ENABLE_IF(is_integral<T>::value &&
2353  !std::is_same<T, bool>::value &&
2354  !std::is_same<T, Char>::value)>
2355 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2356  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2357  bool negative = is_negative(value);
2358  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2359  if (negative) abs_value = ~abs_value + 1;
2360  int num_digits = count_digits(abs_value);
2361  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2362  auto it = reserve(out, size);
2363  if (auto ptr = to_pointer<Char>(it, size)) {
2364  if (negative) *ptr++ = static_cast<Char>('-');
2365  format_decimal<Char>(ptr, abs_value, num_digits);
2366  return out;
2367  }
2368  if (negative) *it++ = static_cast<Char>('-');
2369  it = format_decimal<Char>(it, abs_value, num_digits).end;
2370  return base_iterator(out, it);
2371 }
2372 
2373 // DEPRECATED!
2374 template <typename Char>
2375 FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
2376  format_specs<Char>& specs) -> const Char* {
2377  FMT_ASSERT(begin != end, "");
2378  auto align = align::none;
2379  auto p = begin + code_point_length(begin);
2380  if (end - p <= 0) p = begin;
2381  for (;;) {
2382  switch (to_ascii(*p)) {
2383  case '<':
2384  align = align::left;
2385  break;
2386  case '>':
2387  align = align::right;
2388  break;
2389  case '^':
2390  align = align::center;
2391  break;
2392  }
2393  if (align != align::none) {
2394  if (p != begin) {
2395  auto c = *begin;
2396  if (c == '}') return begin;
2397  if (c == '{') {
2398  throw_format_error("invalid fill character '{'");
2399  return begin;
2400  }
2401  specs.fill = {begin, to_unsigned(p - begin)};
2402  begin = p + 1;
2403  } else {
2404  ++begin;
2405  }
2406  break;
2407  } else if (p == begin) {
2408  break;
2409  }
2410  p = begin;
2411  }
2412  specs.align = align;
2413  return begin;
2414 }
2415 
2416 // A floating-point presentation format.
2417 enum class float_format : unsigned char {
2418  general, // General: exponent notation or fixed point based on magnitude.
2419  exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3.
2420  fixed, // Fixed point with the default precision of 6, e.g. 0.0012.
2421  hex
2422 };
2423 
2424 struct float_specs {
2428  bool upper : 1;
2429  bool locale : 1;
2430  bool binary32 : 1;
2431  bool showpoint : 1;
2432 };
2433 
2434 template <typename Char>
2436  -> float_specs {
2437  auto result = float_specs();
2438  result.showpoint = specs.alt;
2439  result.locale = specs.localized;
2440  switch (specs.type) {
2442  result.format = float_format::general;
2443  break;
2445  result.upper = true;
2448  result.format = float_format::general;
2449  break;
2451  result.upper = true;
2454  result.format = float_format::exp;
2455  result.showpoint |= specs.precision != 0;
2456  break;
2458  result.upper = true;
2461  result.format = float_format::fixed;
2462  result.showpoint |= specs.precision != 0;
2463  break;
2465  result.upper = true;
2468  result.format = float_format::hex;
2469  break;
2470  default:
2471  throw_format_error("invalid format specifier");
2472  break;
2473  }
2474  return result;
2475 }
2476 
2477 template <typename Char, typename OutputIt>
2478 FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
2479  format_specs<Char> specs,
2480  const float_specs& fspecs) -> OutputIt {
2481  auto str =
2482  isnan ? (fspecs.upper ? "NAN" : "nan") : (fspecs.upper ? "INF" : "inf");
2483  constexpr size_t str_size = 3;
2484  auto sign = fspecs.sign;
2485  auto size = str_size + (sign ? 1 : 0);
2486  // Replace '0'-padding with space for non-finite values.
2487  const bool is_zero_fill =
2488  specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
2489  if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
2490  return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
2491  if (sign) *it++ = detail::sign<Char>(sign);
2492  return copy_str<Char>(str, str + str_size, it);
2493  });
2494 }
2495 
2496 // A decimal floating-point number significand * pow(10, exp).
2498  const char* significand;
2501 };
2502 
2503 constexpr auto get_significand_size(const big_decimal_fp& f) -> int {
2504  return f.significand_size;
2505 }
2506 template <typename T>
2507 inline auto get_significand_size(const dragonbox::decimal_fp<T>& f) -> int {
2508  return count_digits(f.significand);
2509 }
2510 
2511 template <typename Char, typename OutputIt>
2512 constexpr auto write_significand(OutputIt out, const char* significand,
2513  int significand_size) -> OutputIt {
2514  return copy_str<Char>(significand, significand + significand_size, out);
2515 }
2516 template <typename Char, typename OutputIt, typename UInt>
2517 inline auto write_significand(OutputIt out, UInt significand,
2518  int significand_size) -> OutputIt {
2519  return format_decimal<Char>(out, significand, significand_size).end;
2520 }
2521 template <typename Char, typename OutputIt, typename T, typename Grouping>
2522 FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2523  int significand_size, int exponent,
2524  const Grouping& grouping) -> OutputIt {
2525  if (!grouping.has_separator()) {
2526  out = write_significand<Char>(out, significand, significand_size);
2527  return detail::fill_n(out, exponent, static_cast<Char>('0'));
2528  }
2529  auto buffer = memory_buffer();
2530  write_significand<char>(appender(buffer), significand, significand_size);
2531  detail::fill_n(appender(buffer), exponent, '0');
2532  return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2533 }
2534 
2535 template <typename Char, typename UInt,
2536  FMT_ENABLE_IF(std::is_integral<UInt>::value)>
2537 inline auto write_significand(Char* out, UInt significand, int significand_size,
2538  int integral_size, Char decimal_point) -> Char* {
2539  if (!decimal_point)
2540  return format_decimal(out, significand, significand_size).end;
2541  out += significand_size + 1;
2542  Char* end = out;
2543  int floating_size = significand_size - integral_size;
2544  for (int i = floating_size / 2; i > 0; --i) {
2545  out -= 2;
2546  copy2(out, digits2(static_cast<std::size_t>(significand % 100)));
2547  significand /= 100;
2548  }
2549  if (floating_size % 2 != 0) {
2550  *--out = static_cast<Char>('0' + significand % 10);
2551  significand /= 10;
2552  }
2553  *--out = decimal_point;
2554  format_decimal(out - integral_size, significand, integral_size);
2555  return end;
2556 }
2557 
2558 template <typename OutputIt, typename UInt, typename Char,
2559  FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
2560 inline auto write_significand(OutputIt out, UInt significand,
2561  int significand_size, int integral_size,
2562  Char decimal_point) -> OutputIt {
2563  // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2564  Char buffer[digits10<UInt>() + 2];
2565  auto end = write_significand(buffer, significand, significand_size,
2566  integral_size, decimal_point);
2567  return detail::copy_str_noinline<Char>(buffer, end, out);
2568 }
2569 
2570 template <typename OutputIt, typename Char>
2571 FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,
2572  int significand_size, int integral_size,
2573  Char decimal_point) -> OutputIt {
2574  out = detail::copy_str_noinline<Char>(significand,
2575  significand + integral_size, out);
2576  if (!decimal_point) return out;
2577  *out++ = decimal_point;
2578  return detail::copy_str_noinline<Char>(significand + integral_size,
2579  significand + significand_size, out);
2580 }
2581 
2582 template <typename OutputIt, typename Char, typename T, typename Grouping>
2583 FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2584  int significand_size, int integral_size,
2585  Char decimal_point,
2586  const Grouping& grouping) -> OutputIt {
2587  if (!grouping.has_separator()) {
2588  return write_significand(out, significand, significand_size, integral_size,
2589  decimal_point);
2590  }
2593  significand_size, integral_size, decimal_point);
2594  grouping.apply(
2595  out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2596  return detail::copy_str_noinline<Char>(buffer.data() + integral_size,
2597  buffer.end(), out);
2598 }
2599 
2600 template <typename OutputIt, typename DecimalFP, typename Char,
2601  typename Grouping = digit_grouping<Char>>
2602 FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
2603  const format_specs<Char>& specs,
2604  float_specs fspecs, locale_ref loc)
2605  -> OutputIt {
2606  auto significand = f.significand;
2607  int significand_size = get_significand_size(f);
2608  const Char zero = static_cast<Char>('0');
2609  auto sign = fspecs.sign;
2610  size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
2611  using iterator = reserve_iterator<OutputIt>;
2612 
2613  Char decimal_point =
2614  fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>('.');
2615 
2616  int output_exp = f.exponent + significand_size - 1;
2617  auto use_exp_format = [=]() {
2618  if (fspecs.format == float_format::exp) return true;
2619  if (fspecs.format != float_format::general) return false;
2620  // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
2621  // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
2622  const int exp_lower = -4, exp_upper = 16;
2623  return output_exp < exp_lower ||
2624  output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
2625  };
2626  if (use_exp_format()) {
2627  int num_zeros = 0;
2628  if (fspecs.showpoint) {
2629  num_zeros = fspecs.precision - significand_size;
2630  if (num_zeros < 0) num_zeros = 0;
2631  size += to_unsigned(num_zeros);
2632  } else if (significand_size == 1) {
2633  decimal_point = Char();
2634  }
2635  auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2636  int exp_digits = 2;
2637  if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2638 
2639  size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
2640  char exp_char = fspecs.upper ? 'E' : 'e';
2641  auto write = [=](iterator it) {
2642  if (sign) *it++ = detail::sign<Char>(sign);
2643  // Insert a decimal point after the first digit and add an exponent.
2644  it = write_significand(it, significand, significand_size, 1,
2645  decimal_point);
2646  if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
2647  *it++ = static_cast<Char>(exp_char);
2648  return write_exponent<Char>(output_exp, it);
2649  };
2650  return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
2651  : base_iterator(out, write(reserve(out, size)));
2652  }
2653 
2654  int exp = f.exponent + significand_size;
2655  if (f.exponent >= 0) {
2656  // 1234e5 -> 123400000[.0+]
2657  size += to_unsigned(f.exponent);
2658  int num_zeros = fspecs.precision - exp;
2659  abort_fuzzing_if(num_zeros > 5000);
2660  if (fspecs.showpoint) {
2661  ++size;
2662  if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 0;
2663  if (num_zeros > 0) size += to_unsigned(num_zeros);
2664  }
2665  auto grouping = Grouping(loc, fspecs.locale);
2666  size += to_unsigned(grouping.count_separators(exp));
2667  return write_padded<align::right>(out, specs, size, [&](iterator it) {
2668  if (sign) *it++ = detail::sign<Char>(sign);
2669  it = write_significand<Char>(it, significand, significand_size,
2670  f.exponent, grouping);
2671  if (!fspecs.showpoint) return it;
2672  *it++ = decimal_point;
2673  return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2674  });
2675  } else if (exp > 0) {
2676  // 1234e-2 -> 12.34[0+]
2677  int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
2678  size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
2679  auto grouping = Grouping(loc, fspecs.locale);
2680  size += to_unsigned(grouping.count_separators(exp));
2681  return write_padded<align::right>(out, specs, size, [&](iterator it) {
2682  if (sign) *it++ = detail::sign<Char>(sign);
2683  it = write_significand(it, significand, significand_size, exp,
2684  decimal_point, grouping);
2685  return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
2686  });
2687  }
2688  // 1234e-6 -> 0.001234
2689  int num_zeros = -exp;
2690  if (significand_size == 0 && fspecs.precision >= 0 &&
2691  fspecs.precision < num_zeros) {
2692  num_zeros = fspecs.precision;
2693  }
2694  bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
2695  size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
2696  return write_padded<align::right>(out, specs, size, [&](iterator it) {
2697  if (sign) *it++ = detail::sign<Char>(sign);
2698  *it++ = zero;
2699  if (!pointy) return it;
2700  *it++ = decimal_point;
2701  it = detail::fill_n(it, num_zeros, zero);
2702  return write_significand<Char>(it, significand, significand_size);
2703  });
2704 }
2705 
2706 template <typename Char> class fallback_digit_grouping {
2707  public:
2709 
2710  constexpr auto has_separator() const -> bool { return false; }
2711 
2712  constexpr auto count_separators(int) const -> int { return 0; }
2713 
2714  template <typename Out, typename C>
2715  constexpr auto apply(Out out, basic_string_view<C>) const -> Out {
2716  return out;
2717  }
2718 };
2719 
2720 template <typename OutputIt, typename DecimalFP, typename Char>
2721 FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,
2722  const format_specs<Char>& specs,
2723  float_specs fspecs, locale_ref loc)
2724  -> OutputIt {
2725  if (is_constant_evaluated()) {
2726  return do_write_float<OutputIt, DecimalFP, Char,
2727  fallback_digit_grouping<Char>>(out, f, specs, fspecs,
2728  loc);
2729  } else {
2730  return do_write_float(out, f, specs, fspecs, loc);
2731  }
2732 }
2733 
2734 template <typename T> constexpr auto isnan(T value) -> bool {
2735  return !(value >= value); // std::isnan doesn't support __float128.
2736 }
2737 
2738 template <typename T, typename Enable = void>
2740 
2741 template <typename T>
2742 struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
2743  : std::true_type {};
2744 
2745 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&&
2746  has_isfinite<T>::value)>
2747 FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
2748  constexpr T inf = T(std::numeric_limits<double>::infinity());
2749  if (is_constant_evaluated())
2750  return !detail::isnan(value) && value < inf && value > -inf;
2751  return std::isfinite(value);
2752 }
2753 template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
2754 FMT_CONSTEXPR auto isfinite(T value) -> bool {
2755  T inf = T(std::numeric_limits<double>::infinity());
2756  // std::isfinite doesn't support __float128.
2757  return !detail::isnan(value) && value < inf && value > -inf;
2758 }
2759 
2760 template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
2762  if (is_constant_evaluated()) {
2763 #ifdef __cpp_if_constexpr
2764  if constexpr (std::numeric_limits<double>::is_iec559) {
2765  auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2766  return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2767  }
2768 #endif
2769  }
2770  return std::signbit(static_cast<double>(value));
2771 }
2772 
2773 inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {
2774  // Adjust fixed precision by exponent because it is relative to decimal
2775  // point.
2776  if (exp10 > 0 && precision > max_value<int>() - exp10)
2777  FMT_THROW(format_error("number is too big"));
2778  precision += exp10;
2779 }
2780 
2781 class bigint {
2782  private:
2783  // A bigint is stored as an array of bigits (big digits), with bigit at index
2784  // 0 being the least significant one.
2785  using bigit = uint32_t;
2786  using double_bigit = uint64_t;
2787  enum { bigits_capacity = 32 };
2789  int exp_;
2790 
2791  FMT_CONSTEXPR20 auto operator[](int index) const -> bigit {
2792  return bigits_[to_unsigned(index)];
2793  }
2794  FMT_CONSTEXPR20 auto operator[](int index) -> bigit& {
2795  return bigits_[to_unsigned(index)];
2796  }
2797 
2798  static constexpr const int bigit_bits = num_bits<bigit>();
2799 
2800  friend struct formatter<bigint>;
2801 
2802  FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit& borrow) {
2803  auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
2804  (*this)[index] = static_cast<bigit>(result);
2805  borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
2806  }
2807 
2809  int num_bigits = static_cast<int>(bigits_.size()) - 1;
2810  while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
2812  }
2813 
2814  // Computes *this -= other assuming aligned bigints and *this >= other.
2816  FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
2817  FMT_ASSERT(compare(*this, other) >= 0, "");
2818  bigit borrow = 0;
2819  int i = other.exp_ - exp_;
2820  for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
2821  subtract_bigits(i, other.bigits_[j], borrow);
2822  while (borrow > 0) subtract_bigits(i, 0, borrow);
2824  }
2825 
2826  FMT_CONSTEXPR20 void multiply(uint32_t value) {
2827  const double_bigit wide_value = value;
2828  bigit carry = 0;
2829  for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2830  double_bigit result = bigits_[i] * wide_value + carry;
2831  bigits_[i] = static_cast<bigit>(result);
2832  carry = static_cast<bigit>(result >> bigit_bits);
2833  }
2834  if (carry != 0) bigits_.push_back(carry);
2835  }
2836 
2837  template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2838  std::is_same<UInt, uint128_t>::value)>
2840  using half_uint =
2842  const int shift = num_bits<half_uint>() - bigit_bits;
2843  const UInt lower = static_cast<half_uint>(value);
2844  const UInt upper = value >> num_bits<half_uint>();
2845  UInt carry = 0;
2846  for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2847  UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
2848  carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
2849  (carry >> bigit_bits);
2850  bigits_[i] = static_cast<bigit>(result);
2851  }
2852  while (carry != 0) {
2853  bigits_.push_back(static_cast<bigit>(carry));
2854  carry >>= bigit_bits;
2855  }
2856  }
2857 
2858  template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2859  std::is_same<UInt, uint128_t>::value)>
2860  FMT_CONSTEXPR20 void assign(UInt n) {
2861  size_t num_bigits = 0;
2862  do {
2863  bigits_[num_bigits++] = static_cast<bigit>(n);
2864  n >>= bigit_bits;
2865  } while (n != 0);
2867  exp_ = 0;
2868  }
2869 
2870  public:
2872  explicit bigint(uint64_t n) { assign(n); }
2873 
2874  bigint(const bigint&) = delete;
2875  void operator=(const bigint&) = delete;
2876 
2877  FMT_CONSTEXPR20 void assign(const bigint& other) {
2878  auto size = other.bigits_.size();
2879  bigits_.resize(size);
2880  auto data = other.bigits_.data();
2881  copy_str<bigit>(data, data + size, bigits_.data());
2882  exp_ = other.exp_;
2883  }
2884 
2885  template <typename Int> FMT_CONSTEXPR20 void operator=(Int n) {
2886  FMT_ASSERT(n > 0, "");
2888  }
2889 
2890  FMT_CONSTEXPR20 auto num_bigits() const -> int {
2891  return static_cast<int>(bigits_.size()) + exp_;
2892  }
2893 
2895  FMT_ASSERT(shift >= 0, "");
2896  exp_ += shift / bigit_bits;
2897  shift %= bigit_bits;
2898  if (shift == 0) return *this;
2899  bigit carry = 0;
2900  for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2901  bigit c = bigits_[i] >> (bigit_bits - shift);
2902  bigits_[i] = (bigits_[i] << shift) + carry;
2903  carry = c;
2904  }
2905  if (carry != 0) bigits_.push_back(carry);
2906  return *this;
2907  }
2908 
2909  template <typename Int>
2911  FMT_ASSERT(value > 0, "");
2913  return *this;
2914  }
2915 
2916  friend FMT_CONSTEXPR20 auto compare(const bigint& lhs, const bigint& rhs)
2917  -> int {
2918  int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
2919  if (num_lhs_bigits != num_rhs_bigits)
2920  return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
2921  int i = static_cast<int>(lhs.bigits_.size()) - 1;
2922  int j = static_cast<int>(rhs.bigits_.size()) - 1;
2923  int end = i - j;
2924  if (end < 0) end = 0;
2925  for (; i >= end; --i, --j) {
2926  bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
2927  if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
2928  }
2929  if (i != j) return i > j ? 1 : -1;
2930  return 0;
2931  }
2932 
2933  // Returns compare(lhs1 + lhs2, rhs).
2934  friend FMT_CONSTEXPR20 auto add_compare(const bigint& lhs1,
2935  const bigint& lhs2, const bigint& rhs)
2936  -> int {
2937  auto minimum = [](int a, int b) { return a < b ? a : b; };
2938  auto maximum = [](int a, int b) { return a > b ? a : b; };
2939  int max_lhs_bigits = maximum(lhs1.num_bigits(), lhs2.num_bigits());
2940  int num_rhs_bigits = rhs.num_bigits();
2941  if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
2942  if (max_lhs_bigits > num_rhs_bigits) return 1;
2943  auto get_bigit = [](const bigint& n, int i) -> bigit {
2944  return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
2945  };
2946  double_bigit borrow = 0;
2947  int min_exp = minimum(minimum(lhs1.exp_, lhs2.exp_), rhs.exp_);
2948  for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
2949  double_bigit sum =
2950  static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
2951  bigit rhs_bigit = get_bigit(rhs, i);
2952  if (sum > rhs_bigit + borrow) return 1;
2953  borrow = rhs_bigit + borrow - sum;
2954  if (borrow > 1) return -1;
2955  borrow <<= bigit_bits;
2956  }
2957  return borrow != 0 ? -1 : 0;
2958  }
2959 
2960  // Assigns pow(10, exp) to this bigint.
2962  FMT_ASSERT(exp >= 0, "");
2963  if (exp == 0) return *this = 1;
2964  // Find the top bit.
2965  int bitmask = 1;
2966  while (exp >= bitmask) bitmask <<= 1;
2967  bitmask >>= 1;
2968  // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
2969  // repeated squaring and multiplication.
2970  *this = 5;
2971  bitmask >>= 1;
2972  while (bitmask != 0) {
2973  square();
2974  if ((exp & bitmask) != 0) *this *= 5;
2975  bitmask >>= 1;
2976  }
2977  *this <<= exp; // Multiply by pow(2, exp) by shifting.
2978  }
2979 
2981  int num_bigits = static_cast<int>(bigits_.size());
2982  int num_result_bigits = 2 * num_bigits;
2984  bigits_.resize(to_unsigned(num_result_bigits));
2985  auto sum = uint128_t();
2986  for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
2987  // Compute bigit at position bigit_index of the result by adding
2988  // cross-product terms n[i] * n[j] such that i + j == bigit_index.
2989  for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
2990  // Most terms are multiplied twice which can be optimized in the future.
2991  sum += static_cast<double_bigit>(n[i]) * n[j];
2992  }
2993  (*this)[bigit_index] = static_cast<bigit>(sum);
2994  sum >>= num_bits<bigit>(); // Compute the carry.
2995  }
2996  // Do the same for the top half.
2997  for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
2998  ++bigit_index) {
2999  for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
3000  sum += static_cast<double_bigit>(n[i++]) * n[j--];
3001  (*this)[bigit_index] = static_cast<bigit>(sum);
3002  sum >>= num_bits<bigit>();
3003  }
3005  exp_ *= 2;
3006  }
3007 
3008  // If this bigint has a bigger exponent than other, adds trailing zero to make
3009  // exponents equal. This simplifies some operations such as subtraction.
3010  FMT_CONSTEXPR20 void align(const bigint& other) {
3011  int exp_difference = exp_ - other.exp_;
3012  if (exp_difference <= 0) return;
3013  int num_bigits = static_cast<int>(bigits_.size());
3014  bigits_.resize(to_unsigned(num_bigits + exp_difference));
3015  for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
3016  bigits_[j] = bigits_[i];
3017  std::uninitialized_fill_n(bigits_.data(), exp_difference, 0u);
3018  exp_ -= exp_difference;
3019  }
3020 
3021  // Divides this bignum by divisor, assigning the remainder to this and
3022  // returning the quotient.
3024  FMT_ASSERT(this != &divisor, "");
3025  if (compare(*this, divisor) < 0) return 0;
3026  FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
3027  align(divisor);
3028  int quotient = 0;
3029  do {
3031  ++quotient;
3032  } while (compare(*this, divisor) >= 0);
3033  return quotient;
3034  }
3035 };
3036 
3037 // format_dragon flags.
3038 enum dragon {
3040  fixup = 2, // Run fixup to correct exp10 which can be off by one.
3041  fixed = 4,
3042 };
3043 
3044 // Formats a floating-point number using a variation of the Fixed-Precision
3045 // Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
3046 // https://fmt.dev/papers/p372-steele.pdf.
3048  unsigned flags, int num_digits,
3049  buffer<char>& buf, int& exp10) {
3050  bigint numerator; // 2 * R in (FPP)^2.
3051  bigint denominator; // 2 * S in (FPP)^2.
3052  // lower and upper are differences between value and corresponding boundaries.
3053  bigint lower; // (M^- in (FPP)^2).
3054  bigint upper_store; // upper's value if different from lower.
3055  bigint* upper = nullptr; // (M^+ in (FPP)^2).
3056  // Shift numerator and denominator by an extra bit or two (if lower boundary
3057  // is closer) to make lower and upper integers. This eliminates multiplication
3058  // by 2 during later computations.
3059  bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0;
3060  int shift = is_predecessor_closer ? 2 : 1;
3061  if (value.e >= 0) {
3062  numerator = value.f;
3063  numerator <<= value.e + shift;
3064  lower = 1;
3065  lower <<= value.e;
3066  if (is_predecessor_closer) {
3067  upper_store = 1;
3068  upper_store <<= value.e + 1;
3069  upper = &upper_store;
3070  }
3071  denominator.assign_pow10(exp10);
3072  denominator <<= shift;
3073  } else if (exp10 < 0) {
3074  numerator.assign_pow10(-exp10);
3075  lower.assign(numerator);
3076  if (is_predecessor_closer) {
3077  upper_store.assign(numerator);
3078  upper_store <<= 1;
3079  upper = &upper_store;
3080  }
3081  numerator *= value.f;
3082  numerator <<= shift;
3083  denominator = 1;
3084  denominator <<= shift - value.e;
3085  } else {
3086  numerator = value.f;
3087  numerator <<= shift;
3088  denominator.assign_pow10(exp10);
3089  denominator <<= shift - value.e;
3090  lower = 1;
3091  if (is_predecessor_closer) {
3092  upper_store = 1ULL << 1;
3093  upper = &upper_store;
3094  }
3095  }
3096  int even = static_cast<int>((value.f & 1) == 0);
3097  if (!upper) upper = &lower;
3098  bool shortest = num_digits < 0;
3099  if ((flags & dragon::fixup) != 0) {
3100  if (add_compare(numerator, *upper, denominator) + even <= 0) {
3101  --exp10;
3102  numerator *= 10;
3103  if (num_digits < 0) {
3104  lower *= 10;
3105  if (upper != &lower) *upper *= 10;
3106  }
3107  }
3108  if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1);
3109  }
3110  // Invariant: value == (numerator / denominator) * pow(10, exp10).
3111  if (shortest) {
3112  // Generate the shortest representation.
3113  num_digits = 0;
3114  char* data = buf.data();
3115  for (;;) {
3116  int digit = numerator.divmod_assign(denominator);
3117  bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower.
3118  // numerator + upper >[=] pow10:
3119  bool high = add_compare(numerator, *upper, denominator) + even > 0;
3120  data[num_digits++] = static_cast<char>('0' + digit);
3121  if (low || high) {
3122  if (!low) {
3123  ++data[num_digits - 1];
3124  } else if (high) {
3125  int result = add_compare(numerator, numerator, denominator);
3126  // Round half to even.
3127  if (result > 0 || (result == 0 && (digit % 2) != 0))
3128  ++data[num_digits - 1];
3129  }
3130  buf.try_resize(to_unsigned(num_digits));
3131  exp10 -= num_digits - 1;
3132  return;
3133  }
3134  numerator *= 10;
3135  lower *= 10;
3136  if (upper != &lower) *upper *= 10;
3137  }
3138  }
3139  // Generate the given number of digits.
3140  exp10 -= num_digits - 1;
3141  if (num_digits <= 0) {
3142  denominator *= 10;
3143  auto digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
3144  buf.push_back(digit);
3145  return;
3146  }
3147  buf.try_resize(to_unsigned(num_digits));
3148  for (int i = 0; i < num_digits - 1; ++i) {
3149  int digit = numerator.divmod_assign(denominator);
3150  buf[i] = static_cast<char>('0' + digit);
3151  numerator *= 10;
3152  }
3153  int digit = numerator.divmod_assign(denominator);
3154  auto result = add_compare(numerator, numerator, denominator);
3155  if (result > 0 || (result == 0 && (digit % 2) != 0)) {
3156  if (digit == 9) {
3157  const auto overflow = '0' + 10;
3158  buf[num_digits - 1] = overflow;
3159  // Propagate the carry.
3160  for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
3161  buf[i] = '0';
3162  ++buf[i - 1];
3163  }
3164  if (buf[0] == overflow) {
3165  buf[0] = '1';
3166  if ((flags & dragon::fixed) != 0)
3167  buf.push_back('0');
3168  else
3169  ++exp10;
3170  }
3171  return;
3172  }
3173  ++digit;
3174  }
3175  buf[num_digits - 1] = static_cast<char>('0' + digit);
3176 }
3177 
3178 // Formats a floating-point number using the hexfloat format.
3179 template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
3180 FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision,
3181  float_specs specs, buffer<char>& buf) {
3182  // float is passed as double to reduce the number of instantiations and to
3183  // simplify implementation.
3184  static_assert(!std::is_same<Float, float>::value, "");
3185 
3186  using info = dragonbox::float_info<Float>;
3187 
3188  // Assume Float is in the format [sign][exponent][significand].
3189  using carrier_uint = typename info::carrier_uint;
3190 
3191  constexpr auto num_float_significand_bits =
3192  detail::num_significand_bits<Float>();
3193 
3195  f.e += num_float_significand_bits;
3196  if (!has_implicit_bit<Float>()) --f.e;
3197 
3198  constexpr auto num_fraction_bits =
3199  num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3200  constexpr auto num_xdigits = (num_fraction_bits + 3) / 4;
3201 
3202  constexpr auto leading_shift = ((num_xdigits - 1) * 4);
3203  const auto leading_mask = carrier_uint(0xF) << leading_shift;
3204  const auto leading_xdigit =
3205  static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
3206  if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
3207 
3208  int print_xdigits = num_xdigits - 1;
3209  if (precision >= 0 && print_xdigits > precision) {
3210  const int shift = ((print_xdigits - precision - 1) * 4);
3211  const auto mask = carrier_uint(0xF) << shift;
3212  const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
3213 
3214  if (v >= 8) {
3215  const auto inc = carrier_uint(1) << (shift + 4);
3216  f.f += inc;
3217  f.f &= ~(inc - 1);
3218  }
3219 
3220  // Check long double overflow
3221  if (!has_implicit_bit<Float>()) {
3222  const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3223  if ((f.f & implicit_bit) == implicit_bit) {
3224  f.f >>= 4;
3225  f.e += 4;
3226  }
3227  }
3228 
3229  print_xdigits = precision;
3230  }
3231 
3232  char xdigits[num_bits<carrier_uint>() / 4];
3233  detail::fill_n(xdigits, sizeof(xdigits), '0');
3234  format_uint<4>(xdigits, f.f, num_xdigits, specs.upper);
3235 
3236  // Remove zero tail
3237  while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
3238 
3239  buf.push_back('0');
3240  buf.push_back(specs.upper ? 'X' : 'x');
3241  buf.push_back(xdigits[0]);
3242  if (specs.showpoint || print_xdigits > 0 || print_xdigits < precision)
3243  buf.push_back('.');
3244  buf.append(xdigits + 1, xdigits + 1 + print_xdigits);
3245  for (; print_xdigits < precision; ++print_xdigits) buf.push_back('0');
3246 
3247  buf.push_back(specs.upper ? 'P' : 'p');
3248 
3249  uint32_t abs_e;
3250  if (f.e < 0) {
3251  buf.push_back('-');
3252  abs_e = static_cast<uint32_t>(-f.e);
3253  } else {
3254  buf.push_back('+');
3255  abs_e = static_cast<uint32_t>(f.e);
3256  }
3257  format_decimal<char>(appender(buf), abs_e, detail::count_digits(abs_e));
3258 }
3259 
3260 template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
3261 FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision,
3262  float_specs specs, buffer<char>& buf) {
3263  format_hexfloat(static_cast<double>(value), precision, specs, buf);
3264 }
3265 
3266 constexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t {
3267  // For checking rounding thresholds.
3268  // The kth entry is chosen to be the smallest integer such that the
3269  // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k.
3270  // It is equal to ceil(2^31 + 2^32/10^(k + 1)).
3271  // These are stored in a string literal because we cannot have static arrays
3272  // in constexpr functions and non-static ones are poorly optimized.
3273  return U"\x9999999a\x828f5c29\x80418938\x80068db9\x8000a7c6\x800010c7"
3274  U"\x800001ae\x8000002b"[index];
3275 }
3276 
3277 template <typename Float>
3278 FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
3279  buffer<char>& buf) -> int {
3280  // float is passed as double to reduce the number of instantiations.
3281  static_assert(!std::is_same<Float, float>::value, "");
3282  FMT_ASSERT(value >= 0, "value is negative");
3283  auto converted_value = convert_float(value);
3284 
3285  const bool fixed = specs.format == float_format::fixed;
3286  if (value <= 0) { // <= instead of == to silence a warning.
3287  if (precision <= 0 || !fixed) {
3288  buf.push_back('0');
3289  return 0;
3290  }
3291  buf.try_resize(to_unsigned(precision));
3292  fill_n(buf.data(), precision, '0');
3293  return -precision;
3294  }
3295 
3296  int exp = 0;
3297  bool use_dragon = true;
3298  unsigned dragon_flags = 0;
3299  if (!is_fast_float<Float>() || is_constant_evaluated()) {
3300  const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10)
3301  using info = dragonbox::float_info<decltype(converted_value)>;
3302  const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3303  // Compute exp, an approximate power of 10, such that
3304  // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3305  // This is based on log10(value) == log2(value) / log2(10) and approximation
3306  // of log2(value) by e + num_fraction_bits idea from double-conversion.
3307  auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3308  exp = static_cast<int>(e);
3309  if (e > exp) ++exp; // Compute ceil.
3310  dragon_flags = dragon::fixup;
3311  } else if (precision < 0) {
3312  // Use Dragonbox for the shortest format.
3313  if (specs.binary32) {
3314  auto dec = dragonbox::to_decimal(static_cast<float>(value));
3315  write<char>(buffer_appender<char>(buf), dec.significand);
3316  return dec.exponent;
3317  }
3318  auto dec = dragonbox::to_decimal(static_cast<double>(value));
3319  write<char>(buffer_appender<char>(buf), dec.significand);
3320  return dec.exponent;
3321  } else {
3322  // Extract significand bits and exponent bits.
3323  using info = dragonbox::float_info<double>;
3324  auto br = bit_cast<uint64_t>(static_cast<double>(value));
3325 
3326  const uint64_t significand_mask =
3327  (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3328  uint64_t significand = (br & significand_mask);
3329  int exponent = static_cast<int>((br & exponent_mask<double>()) >>
3330  num_significand_bits<double>());
3331 
3332  if (exponent != 0) { // Check if normal.
3333  exponent -= exponent_bias<double>() + num_significand_bits<double>();
3334  significand |=
3335  (static_cast<uint64_t>(1) << num_significand_bits<double>());
3336  significand <<= 1;
3337  } else {
3338  // Normalize subnormal inputs.
3339  FMT_ASSERT(significand != 0, "zeros should not appear here");
3340  int shift = countl_zero(significand);
3341  FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3342  "");
3343  shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3344  exponent = (std::numeric_limits<double>::min_exponent -
3345  num_significand_bits<double>()) -
3346  shift;
3347  significand <<= shift;
3348  }
3349 
3350  // Compute the first several nonzero decimal significand digits.
3351  // We call the number we get the first segment.
3352  const int k = info::kappa - dragonbox::floor_log10_pow2(exponent);
3353  exp = -k;
3354  const int beta = exponent + dragonbox::floor_log2_pow10(k);
3355  uint64_t first_segment;
3356  bool has_more_segments;
3357  int digits_in_the_first_segment;
3358  {
3359  const auto r = dragonbox::umul192_upper128(
3360  significand << beta, dragonbox::get_cached_power(k));
3361  first_segment = r.high();
3362  has_more_segments = r.low() != 0;
3363 
3364  // The first segment can have 18 ~ 19 digits.
3365  if (first_segment >= 1000000000000000000ULL) {
3366  digits_in_the_first_segment = 19;
3367  } else {
3368  // When it is of 18-digits, we align it to 19-digits by adding a bogus
3369  // zero at the end.
3370  digits_in_the_first_segment = 18;
3371  first_segment *= 10;
3372  }
3373  }
3374 
3375  // Compute the actual number of decimal digits to print.
3376  if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment);
3377 
3378  // Use Dragon4 only when there might be not enough digits in the first
3379  // segment.
3380  if (digits_in_the_first_segment > precision) {
3381  use_dragon = false;
3382 
3383  if (precision <= 0) {
3384  exp += digits_in_the_first_segment;
3385 
3386  if (precision < 0) {
3387  // Nothing to do, since all we have are just leading zeros.
3388  buf.try_resize(0);
3389  } else {
3390  // We may need to round-up.
3391  buf.try_resize(1);
3392  if ((first_segment | static_cast<uint64_t>(has_more_segments)) >
3393  5000000000000000000ULL) {
3394  buf[0] = '1';
3395  } else {
3396  buf[0] = '0';
3397  }
3398  }
3399  } // precision <= 0
3400  else {
3401  exp += digits_in_the_first_segment - precision;
3402 
3403  // When precision > 0, we divide the first segment into three
3404  // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits
3405  // in 32-bits which usually allows faster calculation than in
3406  // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize
3407  // division-by-constant for large 64-bit divisors, we do it here
3408  // manually. The magic number 7922816251426433760 below is equal to
3409  // ceil(2^(64+32) / 10^10).
3410  const uint32_t first_subsegment = static_cast<uint32_t>(
3411  dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >>
3412  32);
3413  const uint64_t second_third_subsegments =
3414  first_segment - first_subsegment * 10000000000ULL;
3415 
3416  uint64_t prod;
3417  uint32_t digits;
3418  bool should_round_up;
3419  int number_of_digits_to_print = precision > 9 ? 9 : precision;
3420 
3421  // Print a 9-digits subsegment, either the first or the second.
3422  auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
3423  int number_of_digits_printed = 0;
3424 
3425  // If we want to print an odd number of digits from the subsegment,
3426  if ((number_of_digits_to_print & 1) != 0) {
3427  // Convert to 64-bit fixed-point fractional form with 1-digit
3428  // integer part. The magic number 720575941 is a good enough
3429  // approximation of 2^(32 + 24) / 10^8; see
3430  // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3431  // for details.
3432  prod = ((subsegment * static_cast<uint64_t>(720575941)) >> 24) + 1;
3433  digits = static_cast<uint32_t>(prod >> 32);
3434  *buffer = static_cast<char>('0' + digits);
3435  number_of_digits_printed++;
3436  }
3437  // If we want to print an even number of digits from the
3438  // first_subsegment,
3439  else {
3440  // Convert to 64-bit fixed-point fractional form with 2-digits
3441  // integer part. The magic number 450359963 is a good enough
3442  // approximation of 2^(32 + 20) / 10^7; see
3443  // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3444  // for details.
3445  prod = ((subsegment * static_cast<uint64_t>(450359963)) >> 20) + 1;
3446  digits = static_cast<uint32_t>(prod >> 32);
3447  copy2(buffer, digits2(digits));
3448  number_of_digits_printed += 2;
3449  }
3450 
3451  // Print all digit pairs.
3452  while (number_of_digits_printed < number_of_digits_to_print) {
3453  prod = static_cast<uint32_t>(prod) * static_cast<uint64_t>(100);
3454  digits = static_cast<uint32_t>(prod >> 32);
3455  copy2(buffer + number_of_digits_printed, digits2(digits));
3456  number_of_digits_printed += 2;
3457  }
3458  };
3459 
3460  // Print first subsegment.
3461  print_subsegment(first_subsegment, buf.data());
3462 
3463  // Perform rounding if the first subsegment is the last subsegment to
3464  // print.
3465  if (precision <= 9) {
3466  // Rounding inside the subsegment.
3467  // We round-up if:
3468  // - either the fractional part is strictly larger than 1/2, or
3469  // - the fractional part is exactly 1/2 and the last digit is odd.
3470  // We rely on the following observations:
3471  // - If fractional_part >= threshold, then the fractional part is
3472  // strictly larger than 1/2.
3473  // - If the MSB of fractional_part is set, then the fractional part
3474  // must be at least 1/2.
3475  // - When the MSB of fractional_part is set, either
3476  // second_third_subsegments being nonzero or has_more_segments
3477  // being true means there are further digits not printed, so the
3478  // fractional part is strictly larger than 1/2.
3479  if (precision < 9) {
3480  uint32_t fractional_part = static_cast<uint32_t>(prod);
3481  should_round_up =
3482  fractional_part >= fractional_part_rounding_thresholds(
3483  8 - number_of_digits_to_print) ||
3484  ((fractional_part >> 31) &
3485  ((digits & 1) | (second_third_subsegments != 0) |
3486  has_more_segments)) != 0;
3487  }
3488  // Rounding at the subsegment boundary.
3489  // In this case, the fractional part is at least 1/2 if and only if
3490  // second_third_subsegments >= 5000000000ULL, and is strictly larger
3491  // than 1/2 if we further have either second_third_subsegments >
3492  // 5000000000ULL or has_more_segments == true.
3493  else {
3494  should_round_up = second_third_subsegments > 5000000000ULL ||
3495  (second_third_subsegments == 5000000000ULL &&
3496  ((digits & 1) != 0 || has_more_segments));
3497  }
3498  }
3499  // Otherwise, print the second subsegment.
3500  else {
3501  // Compilers are not aware of how to leverage the maximum value of
3502  // second_third_subsegments to find out a better magic number which
3503  // allows us to eliminate an additional shift. 1844674407370955162 =
3504  // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))).
3505  const uint32_t second_subsegment =
3506  static_cast<uint32_t>(dragonbox::umul128_upper64(
3507  second_third_subsegments, 1844674407370955162ULL));
3508  const uint32_t third_subsegment =
3509  static_cast<uint32_t>(second_third_subsegments) -
3510  second_subsegment * 10;
3511 
3512  number_of_digits_to_print = precision - 9;
3513  print_subsegment(second_subsegment, buf.data() + 9);
3514 
3515  // Rounding inside the subsegment.
3516  if (precision < 18) {
3517  // The condition third_subsegment != 0 implies that the segment was
3518  // of 19 digits, so in this case the third segment should be
3519  // consisting of a genuine digit from the input.
3520  uint32_t fractional_part = static_cast<uint32_t>(prod);
3521  should_round_up =
3522  fractional_part >= fractional_part_rounding_thresholds(
3523  8 - number_of_digits_to_print) ||
3524  ((fractional_part >> 31) &
3525  ((digits & 1) | (third_subsegment != 0) |
3526  has_more_segments)) != 0;
3527  }
3528  // Rounding at the subsegment boundary.
3529  else {
3530  // In this case, the segment must be of 19 digits, thus
3531  // the third subsegment should be consisting of a genuine digit from
3532  // the input.
3533  should_round_up = third_subsegment > 5 ||
3534  (third_subsegment == 5 &&
3535  ((digits & 1) != 0 || has_more_segments));
3536  }
3537  }
3538 
3539  // Round-up if necessary.
3540  if (should_round_up) {
3541  ++buf[precision - 1];
3542  for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) {
3543  buf[i] = '0';
3544  ++buf[i - 1];
3545  }
3546  if (buf[0] > '9') {
3547  buf[0] = '1';
3548  if (fixed)
3549  buf[precision++] = '0';
3550  else
3551  ++exp;
3552  }
3553  }
3554  buf.try_resize(to_unsigned(precision));
3555  }
3556  } // if (digits_in_the_first_segment > precision)
3557  else {
3558  // Adjust the exponent for its use in Dragon4.
3559  exp += digits_in_the_first_segment - 1;
3560  }
3561  }
3562  if (use_dragon) {
3563  auto f = basic_fp<uint128_t>();
3564  bool is_predecessor_closer = specs.binary32
3565  ? f.assign(static_cast<float>(value))
3566  : f.assign(converted_value);
3567  if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3568  if (fixed) dragon_flags |= dragon::fixed;
3569  // Limit precision to the maximum possible number of significant digits in
3570  // an IEEE754 double because we don't need to generate zeros.
3571  const int max_double_digits = 767;
3572  if (precision > max_double_digits) precision = max_double_digits;
3573  format_dragon(f, dragon_flags, precision, buf, exp);
3574  }
3575  if (!fixed && !specs.showpoint) {
3576  // Remove trailing zeros.
3577  auto num_digits = buf.size();
3578  while (num_digits > 0 && buf[num_digits - 1] == '0') {
3579  --num_digits;
3580  ++exp;
3581  }
3582  buf.try_resize(num_digits);
3583  }
3584  return exp;
3585 }
3586 template <typename Char, typename OutputIt, typename T>
3587 FMT_CONSTEXPR20 auto write_float(OutputIt out, T value,
3588  format_specs<Char> specs, locale_ref loc)
3589  -> OutputIt {
3590  float_specs fspecs = parse_float_type_spec(specs);
3591  fspecs.sign = specs.sign;
3592  if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit.
3593  fspecs.sign = sign::minus;
3594  value = -value;
3595  } else if (fspecs.sign == sign::minus) {
3596  fspecs.sign = sign::none;
3597  }
3598 
3599  if (!detail::isfinite(value))
3600  return write_nonfinite(out, detail::isnan(value), specs, fspecs);
3601 
3602  if (specs.align == align::numeric && fspecs.sign) {
3603  auto it = reserve(out, 1);
3604  *it++ = detail::sign<Char>(fspecs.sign);
3605  out = base_iterator(out, it);
3606  fspecs.sign = sign::none;
3607  if (specs.width != 0) --specs.width;
3608  }
3609 
3611  if (fspecs.format == float_format::hex) {
3612  if (fspecs.sign) buffer.push_back(detail::sign<char>(fspecs.sign));
3613  format_hexfloat(convert_float(value), specs.precision, fspecs, buffer);
3614  return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
3615  specs);
3616  }
3617  int precision = specs.precision >= 0 || specs.type == presentation_type::none
3618  ? specs.precision
3619  : 6;
3620  if (fspecs.format == float_format::exp) {
3621  if (precision == max_value<int>())
3622  throw_format_error("number is too big");
3623  else
3624  ++precision;
3625  } else if (fspecs.format != float_format::fixed && precision == 0) {
3626  precision = 1;
3627  }
3628  if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
3629  int exp = format_float(convert_float(value), precision, fspecs, buffer);
3630  fspecs.precision = precision;
3631  auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3632  return write_float(out, f, specs, fspecs, loc);
3633 }
3634 
3635 template <typename Char, typename OutputIt, typename T,
3636  FMT_ENABLE_IF(is_floating_point<T>::value)>
3637 FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs<Char> specs,
3638  locale_ref loc = {}) -> OutputIt {
3639  if (const_check(!is_supported_floating_point(value))) return out;
3640  return specs.localized && write_loc(out, value, specs, loc)
3641  ? out
3642  : write_float(out, value, specs, loc);
3643 }
3644 
3645 template <typename Char, typename OutputIt, typename T,
3646  FMT_ENABLE_IF(is_fast_float<T>::value)>
3647 FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3648  if (is_constant_evaluated()) return write(out, value, format_specs<Char>());
3649  if (const_check(!is_supported_floating_point(value))) return out;
3650 
3651  auto fspecs = float_specs();
3652  if (detail::signbit(value)) {
3653  fspecs.sign = sign::minus;
3654  value = -value;
3655  }
3656 
3657  constexpr auto specs = format_specs<Char>();
3658  using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
3659  using floaty_uint = typename dragonbox::float_info<floaty>::carrier_uint;
3660  floaty_uint mask = exponent_mask<floaty>();
3661  if ((bit_cast<floaty_uint>(value) & mask) == mask)
3662  return write_nonfinite(out, std::isnan(value), specs, fspecs);
3663 
3664  auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
3665  return write_float(out, dec, specs, fspecs, {});
3666 }
3667 
3668 template <typename Char, typename OutputIt, typename T,
3669  FMT_ENABLE_IF(is_floating_point<T>::value &&
3670  !is_fast_float<T>::value)>
3671 inline auto write(OutputIt out, T value) -> OutputIt {
3672  return write(out, value, format_specs<Char>());
3673 }
3674 
3675 template <typename Char, typename OutputIt>
3676 auto write(OutputIt out, monostate, format_specs<Char> = {}, locale_ref = {})
3677  -> OutputIt {
3678  FMT_ASSERT(false, "");
3679  return out;
3680 }
3681 
3682 template <typename Char, typename OutputIt>
3684  -> OutputIt {
3685  auto it = reserve(out, value.size());
3686  it = copy_str_noinline<Char>(value.begin(), value.end(), it);
3687  return base_iterator(out, it);
3688 }
3689 
3690 template <typename Char, typename OutputIt, typename T,
3691  FMT_ENABLE_IF(is_string<T>::value)>
3692 constexpr auto write(OutputIt out, const T& value) -> OutputIt {
3693  return write<Char>(out, to_string_view(value));
3694 }
3695 
3696 // FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
3697 template <
3698  typename Char, typename OutputIt, typename T,
3699  bool check =
3700  std::is_enum<T>::value && !std::is_same<T, Char>::value &&
3701  mapped_type_constant<T, basic_format_context<OutputIt, Char>>::value !=
3704 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
3705  return write<Char>(out, static_cast<underlying_t<T>>(value));
3706 }
3707 
3708 template <typename Char, typename OutputIt, typename T,
3709  FMT_ENABLE_IF(std::is_same<T, bool>::value)>
3710 FMT_CONSTEXPR auto write(OutputIt out, T value,
3711  const format_specs<Char>& specs = {}, locale_ref = {})
3712  -> OutputIt {
3713  return specs.type != presentation_type::none &&
3715  ? write(out, value ? 1 : 0, specs, {})
3716  : write_bytes(out, value ? "true" : "false", specs);
3717 }
3718 
3719 template <typename Char, typename OutputIt>
3720 FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
3721  auto it = reserve(out, 1);
3722  *it++ = value;
3723  return base_iterator(out, it);
3724 }
3725 
3726 template <typename Char, typename OutputIt>
3727 FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
3728  -> OutputIt {
3729  if (value) return write(out, basic_string_view<Char>(value));
3730  throw_format_error("string pointer is null");
3731  return out;
3732 }
3733 
3734 template <typename Char, typename OutputIt, typename T,
3735  FMT_ENABLE_IF(std::is_same<T, void>::value)>
3736 auto write(OutputIt out, const T* value, const format_specs<Char>& specs = {},
3737  locale_ref = {}) -> OutputIt {
3738  return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
3739 }
3740 
3741 // A write overload that handles implicit conversions.
3742 template <typename Char, typename OutputIt, typename T,
3743  typename Context = basic_format_context<OutputIt, Char>>
3744 FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> enable_if_t<
3745  std::is_class<T>::value && !is_string<T>::value &&
3746  !is_floating_point<T>::value && !std::is_same<T, Char>::value &&
3747  !std::is_same<T, remove_cvref_t<decltype(arg_mapper<Context>().map(
3748  value))>>::value,
3749  OutputIt> {
3750  return write<Char>(out, arg_mapper<Context>().map(value));
3751 }
3752 
3753 template <typename Char, typename OutputIt, typename T,
3754  typename Context = basic_format_context<OutputIt, Char>>
3755 FMT_CONSTEXPR auto write(OutputIt out, const T& value)
3757  OutputIt> {
3758  auto formatter = typename Context::template formatter_type<T>();
3759  auto parse_ctx = typename Context::parse_context_type({});
3760  formatter.parse(parse_ctx);
3761  auto ctx = Context(out, {}, {});
3762  return formatter.format(value, ctx);
3763 }
3764 
3765 // An argument visitor that formats the argument and writes it via the output
3766 // iterator. It's a class and not a generic lambda for compatibility with C++11.
3767 template <typename Char> struct default_arg_formatter {
3770 
3774 
3775  template <typename T> auto operator()(T value) -> iterator {
3776  return write<Char>(out, value);
3777  }
3779  basic_format_parse_context<Char> parse_ctx({});
3780  context format_ctx(out, args, loc);
3781  h.format(parse_ctx, format_ctx);
3782  return format_ctx.out();
3783  }
3784 };
3785 
3786 template <typename Char> struct arg_formatter {
3789 
3793 
3794  template <typename T>
3796  return detail::write(out, value, specs, locale);
3797  }
3799  // User-defined types are handled separately because they require access
3800  // to the parse context.
3801  return out;
3802  }
3803 };
3804 
3806  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3807  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3808  if (is_negative(value)) throw_format_error("negative width");
3809  return static_cast<unsigned long long>(value);
3810  }
3811 
3812  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3813  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3814  throw_format_error("width is not integer");
3815  return 0;
3816  }
3817 };
3818 
3820  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3821  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3822  if (is_negative(value)) throw_format_error("negative precision");
3823  return static_cast<unsigned long long>(value);
3824  }
3825 
3826  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3827  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3828  throw_format_error("precision is not integer");
3829  return 0;
3830  }
3831 };
3832 
3833 template <typename Handler, typename FormatArg>
3834 FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg) -> int {
3835  unsigned long long value = visit_format_arg(Handler(), arg);
3836  if (value > to_unsigned(max_value<int>()))
3837  throw_format_error("number is too big");
3838  return static_cast<int>(value);
3839 }
3840 
3841 template <typename Context, typename ID>
3842 FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) -> decltype(ctx.arg(id)) {
3843  auto arg = ctx.arg(id);
3844  if (!arg) ctx.on_error("argument not found");
3845  return arg;
3846 }
3847 
3848 template <typename Handler, typename Context>
3851  Context& ctx) {
3852  switch (ref.kind) {
3853  case arg_id_kind::none:
3854  break;
3855  case arg_id_kind::index:
3856  value = detail::get_dynamic_spec<Handler>(get_arg(ctx, ref.val.index));
3857  break;
3858  case arg_id_kind::name:
3859  value = detail::get_dynamic_spec<Handler>(get_arg(ctx, ref.val.name));
3860  break;
3861  }
3862 }
3863 
3864 #if FMT_USE_USER_DEFINED_LITERALS
3865 # if FMT_USE_NONTYPE_TEMPLATE_ARGS
3866 template <typename T, typename Char, size_t N,
3867  fmt::detail_exported::fixed_string<Char, N> Str>
3868 struct statically_named_arg : view {
3869  static constexpr auto name = Str.data;
3870 
3871  const T& value;
3872  statically_named_arg(const T& v) : value(v) {}
3873 };
3874 
3875 template <typename T, typename Char, size_t N,
3876  fmt::detail_exported::fixed_string<Char, N> Str>
3877 struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
3878 
3879 template <typename T, typename Char, size_t N,
3880  fmt::detail_exported::fixed_string<Char, N> Str>
3881 struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
3882  : std::true_type {};
3883 
3884 template <typename Char, size_t N,
3885  fmt::detail_exported::fixed_string<Char, N> Str>
3886 struct udl_arg {
3887  template <typename T> auto operator=(T&& value) const {
3888  return statically_named_arg<T, Char, N, Str>(std::forward<T>(value));
3889  }
3890 };
3891 # else
3892 template <typename Char> struct udl_arg {
3893  const Char* str;
3894 
3895  template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
3896  return {str, std::forward<T>(value)};
3897  }
3898 };
3899 # endif
3900 #endif // FMT_USE_USER_DEFINED_LITERALS
3901 
3902 template <typename Locale, typename Char>
3903 auto vformat(const Locale& loc, basic_string_view<Char> fmt,
3905  -> std::basic_string<Char> {
3906  auto buf = basic_memory_buffer<Char>();
3907  detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
3908  return {buf.data(), buf.size()};
3909 }
3910 
3911 using format_func = void (*)(detail::buffer<char>&, int, const char*);
3912 
3914  string_view message) noexcept;
3915 
3917  const char* message) noexcept;
3918 } // namespace detail
3919 
3920 FMT_API auto vsystem_error(int error_code, string_view format_str,
3922 
3940 template <typename... T>
3942  -> std::system_error {
3944 }
3945 
3963  const char* message) noexcept;
3964 
3965 // Reports a system error without throwing an exception.
3966 // Can be used to report errors from destructors.
3967 FMT_API void report_system_error(int error_code, const char* message) noexcept;
3968 
3970 class format_int {
3971  private:
3972  // Buffer should be large enough to hold all digits (digits10 + 1),
3973  // a sign and a null character.
3975  mutable char buffer_[buffer_size];
3976  char* str_;
3977 
3978  template <typename UInt> auto format_unsigned(UInt value) -> char* {
3979  auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
3980  return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
3981  }
3982 
3983  template <typename Int> auto format_signed(Int value) -> char* {
3984  auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
3985  bool negative = value < 0;
3986  if (negative) abs_value = 0 - abs_value;
3987  auto begin = format_unsigned(abs_value);
3988  if (negative) *--begin = '-';
3989  return begin;
3990  }
3991 
3992  public:
3993  explicit format_int(int value) : str_(format_signed(value)) {}
3994  explicit format_int(long value) : str_(format_signed(value)) {}
3995  explicit format_int(long long value) : str_(format_signed(value)) {}
3996  explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
3997  explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
3998  explicit format_int(unsigned long long value)
3999  : str_(format_unsigned(value)) {}
4000 
4002  auto size() const -> size_t {
4003  return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
4004  }
4005 
4010  auto data() const -> const char* { return str_; }
4011 
4016  auto c_str() const -> const char* {
4017  buffer_[buffer_size - 1] = '\0';
4018  return str_;
4019  }
4020 
4026  auto str() const -> std::string { return std::string(str_, size()); }
4027 };
4028 
4029 template <typename T, typename Char>
4030 struct formatter<T, Char, enable_if_t<detail::has_format_as<T>::value>>
4031  : formatter<detail::format_as_t<T>, Char> {
4032  template <typename FormatContext>
4033  auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) {
4034  using base = formatter<detail::format_as_t<T>, Char>;
4035  return base::format(format_as(value), ctx);
4036  }
4037 };
4038 
4039 #define FMT_FORMAT_AS(Type, Base) \
4040  template <typename Char> \
4041  struct formatter<Type, Char> : formatter<Base, Char> {}
4042 
4043 FMT_FORMAT_AS(signed char, int);
4044 FMT_FORMAT_AS(unsigned char, unsigned);
4045 FMT_FORMAT_AS(short, int);
4046 FMT_FORMAT_AS(unsigned short, unsigned);
4048 FMT_FORMAT_AS(unsigned long, detail::ulong_type);
4049 FMT_FORMAT_AS(Char*, const Char*);
4050 FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
4051 FMT_FORMAT_AS(std::nullptr_t, const void*);
4053 FMT_FORMAT_AS(void*, const void*);
4054 
4055 template <typename Char, size_t N>
4056 struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {};
4057 
4067 template <typename T> auto ptr(T p) -> const void* {
4068  static_assert(std::is_pointer<T>::value, "");
4069  return detail::bit_cast<const void*>(p);
4070 }
4071 template <typename T, typename Deleter>
4072 auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
4073  return p.get();
4074 }
4075 template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
4076  return p.get();
4077 }
4078 
4089 template <typename Enum>
4090 constexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {
4091  return static_cast<underlying_t<Enum>>(e);
4092 }
4093 
4094 namespace enums {
4095 template <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
4096 constexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {
4097  return static_cast<underlying_t<Enum>>(e);
4098 }
4099 } // namespace enums
4100 
4101 class bytes {
4102  private:
4104  friend struct formatter<bytes>;
4105 
4106  public:
4107  explicit bytes(string_view data) : data_(data) {}
4108 };
4109 
4110 template <> struct formatter<bytes> {
4111  private:
4113 
4114  public:
4115  template <typename ParseContext>
4116  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const char* {
4117  return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
4119  }
4120 
4121  template <typename FormatContext>
4122  auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
4123  detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4124  specs_.width_ref, ctx);
4125  detail::handle_dynamic_spec<detail::precision_checker>(
4126  specs_.precision, specs_.precision_ref, ctx);
4127  return detail::write_bytes(ctx.out(), b.data_, specs_);
4128  }
4129 };
4130 
4131 // group_digits_view is not derived from view because it copies the argument.
4132 template <typename T> struct group_digits_view {
4134 };
4135 
4147 template <typename T> auto group_digits(T value) -> group_digits_view<T> {
4148  return {value};
4149 }
4150 
4151 template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
4152  private:
4154 
4155  public:
4156  template <typename ParseContext>
4157  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const char* {
4158  return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
4160  }
4161 
4162  template <typename FormatContext>
4163  auto format(group_digits_view<T> t, FormatContext& ctx)
4164  -> decltype(ctx.out()) {
4165  detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4166  specs_.width_ref, ctx);
4167  detail::handle_dynamic_spec<detail::precision_checker>(
4168  specs_.precision, specs_.precision_ref, ctx);
4169  return detail::write_int(
4170  ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_,
4171  detail::digit_grouping<char>("\3", ","));
4172  }
4173 };
4174 
4175 template <typename T> struct nested_view {
4177  const T* value;
4178 };
4179 
4180 template <typename T> struct formatter<nested_view<T>> {
4181  FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> const char* {
4182  return ctx.begin();
4183  }
4184  auto format(nested_view<T> view, format_context& ctx) const
4185  -> decltype(ctx.out()) {
4186  return view.fmt->format(*view.value, ctx);
4187  }
4188 };
4189 
4190 template <typename T> struct nested_formatter {
4191  private:
4192  int width_;
4196 
4197  public:
4198  constexpr nested_formatter() : width_(0), align_(align_t::none) {}
4199 
4200  FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> const char* {
4201  auto specs = detail::dynamic_format_specs<char>();
4202  auto it = parse_format_specs(ctx.begin(), ctx.end(), specs, ctx,
4204  width_ = specs.width;
4205  fill_ = specs.fill;
4206  align_ = specs.align;
4207  ctx.advance_to(it);
4208  return formatter_.parse(ctx);
4209  }
4210 
4211  template <typename F>
4212  auto write_padded(format_context& ctx, F write) const -> decltype(ctx.out()) {
4213  if (width_ == 0) return write(ctx.out());
4214  auto buf = memory_buffer();
4215  write(std::back_inserter(buf));
4216  auto specs = format_specs<>();
4217  specs.width = width_;
4218  specs.fill = fill_;
4219  specs.align = align_;
4220  return detail::write(ctx.out(), string_view(buf.data(), buf.size()), specs);
4221  }
4222 
4223  auto nested(const T& value) const -> nested_view<T> {
4224  return nested_view<T>{&formatter_, &value};
4225  }
4226 };
4227 
4228 // DEPRECATED! join_view will be moved to ranges.h.
4229 template <typename It, typename Sentinel, typename Char = char>
4231  It begin;
4232  Sentinel end;
4234 
4235  join_view(It b, Sentinel e, basic_string_view<Char> s)
4236  : begin(b), end(e), sep(s) {}
4237 };
4238 
4239 template <typename It, typename Sentinel, typename Char>
4240 struct formatter<join_view<It, Sentinel, Char>, Char> {
4241  private:
4242  using value_type =
4243 #ifdef __cpp_lib_ranges
4244  std::iter_value_t<It>;
4245 #else
4246  typename std::iterator_traits<It>::value_type;
4247 #endif
4249 
4250  public:
4251  template <typename ParseContext>
4252  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const Char* {
4253  return value_formatter_.parse(ctx);
4254  }
4255 
4256  template <typename FormatContext>
4258  FormatContext& ctx) const -> decltype(ctx.out()) {
4259  auto it = value.begin;
4260  auto out = ctx.out();
4261  if (it != value.end) {
4262  out = value_formatter_.format(*it, ctx);
4263  ++it;
4264  while (it != value.end) {
4265  out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
4266  ctx.advance_to(out);
4267  out = value_formatter_.format(*it, ctx);
4268  ++it;
4269  }
4270  }
4271  return out;
4272  }
4273 };
4274 
4279 template <typename It, typename Sentinel>
4280 auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
4281  return {begin, end, sep};
4282 }
4283 
4300 template <typename Range>
4301 auto join(Range&& range, string_view sep)
4303  return join(std::begin(range), std::end(range), sep);
4304 }
4305 
4317 template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
4318  !detail::has_format_as<T>::value)>
4319 inline auto to_string(const T& value) -> std::string {
4320  auto buffer = memory_buffer();
4321  detail::write<char>(appender(buffer), value);
4322  return {buffer.data(), buffer.size()};
4323 }
4324 
4325 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
4326 FMT_NODISCARD inline auto to_string(T value) -> std::string {
4327  // The buffer should be large enough to store the number including the sign
4328  // or "false" for bool.
4329  constexpr int max_size = detail::digits10<T>() + 2;
4330  char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
4331  char* begin = buffer;
4332  return std::string(begin, detail::write<char>(begin, value));
4333 }
4334 
4335 template <typename Char, size_t SIZE>
4337  -> std::basic_string<Char> {
4338  auto size = buf.size();
4339  detail::assume(size < std::basic_string<Char>().max_size());
4340  return std::basic_string<Char>(buf.data(), size);
4341 }
4342 
4343 template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
4344  detail::has_format_as<T>::value)>
4345 inline auto to_string(const T& value) -> std::string {
4346  return to_string(format_as(value));
4347 }
4348 
4350 
4351 namespace detail {
4352 
4353 template <typename Char>
4355  typename vformat_args<Char>::type args, locale_ref loc) {
4356  auto out = buffer_appender<Char>(buf);
4357  if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
4358  auto arg = args.get(0);
4359  if (!arg) throw_format_error("argument not found");
4361  return;
4362  }
4363 
4364  struct format_handler : error_handler {
4365  basic_format_parse_context<Char> parse_context;
4366  buffer_context<Char> context;
4367 
4368  format_handler(buffer_appender<Char> p_out, basic_string_view<Char> str,
4370  locale_ref p_loc)
4371  : parse_context(str), context(p_out, p_args, p_loc) {}
4372 
4373  void on_text(const Char* begin, const Char* end) {
4374  auto text = basic_string_view<Char>(begin, to_unsigned(end - begin));
4375  context.advance_to(write<Char>(context.out(), text));
4376  }
4377 
4378  FMT_CONSTEXPR auto on_arg_id() -> int {
4379  return parse_context.next_arg_id();
4380  }
4381  FMT_CONSTEXPR auto on_arg_id(int id) -> int {
4382  return parse_context.check_arg_id(id), id;
4383  }
4384  FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
4385  int arg_id = context.arg_id(id);
4386  if (arg_id < 0) throw_format_error("argument not found");
4387  return arg_id;
4388  }
4389 
4390  FMT_INLINE void on_replacement_field(int id, const Char*) {
4391  auto arg = get_arg(context, id);
4392  context.advance_to(visit_format_arg(
4393  default_arg_formatter<Char>{context.out(), context.args(),
4394  context.locale()},
4395  arg));
4396  }
4397 
4398  auto on_format_specs(int id, const Char* begin, const Char* end)
4399  -> const Char* {
4400  auto arg = get_arg(context, id);
4401  // Not using a visitor for custom types gives better codegen.
4402  if (arg.format_custom(begin, parse_context, context))
4403  return parse_context.begin();
4404  auto specs = detail::dynamic_format_specs<Char>();
4405  begin = parse_format_specs(begin, end, specs, parse_context, arg.type());
4406  detail::handle_dynamic_spec<detail::width_checker>(
4407  specs.width, specs.width_ref, context);
4408  detail::handle_dynamic_spec<detail::precision_checker>(
4409  specs.precision, specs.precision_ref, context);
4410  if (begin == end || *begin != '}')
4411  throw_format_error("missing '}' in format string");
4412  auto f = arg_formatter<Char>{context.out(), specs, context.locale()};
4413  context.advance_to(visit_format_arg(f, arg));
4414  return begin;
4415  }
4416  };
4417  detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
4418 }
4419 
4421 
4422 #ifndef FMT_HEADER_ONLY
4423 extern template FMT_API void vformat_to(buffer<char>&, string_view,
4424  typename vformat_args<>::type,
4425  locale_ref);
4426 extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
4427  -> thousands_sep_result<char>;
4428 extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
4429  -> thousands_sep_result<wchar_t>;
4430 extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
4431 extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
4432 #endif // FMT_HEADER_ONLY
4433 
4434 } // namespace detail
4435 
4436 #if FMT_USE_USER_DEFINED_LITERALS
4437 inline namespace literals {
4448 # if FMT_USE_NONTYPE_TEMPLATE_ARGS
4449 template <detail_exported::fixed_string Str> constexpr auto operator""_a() {
4450  using char_t = remove_cvref_t<decltype(Str.data[0])>;
4451  return detail::udl_arg<char_t, sizeof(Str.data) / sizeof(char_t), Str>();
4452 }
4453 # else
4454 constexpr auto operator""_a(const char* s, size_t) -> detail::udl_arg<char> {
4455  return {s};
4456 }
4457 # endif
4458 } // namespace literals
4459 #endif // FMT_USE_USER_DEFINED_LITERALS
4460 
4461 template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4462 inline auto vformat(const Locale& loc, string_view fmt, format_args args)
4463  -> std::string {
4464  return detail::vformat(loc, fmt, args);
4465 }
4466 
4467 template <typename Locale, typename... T,
4468  FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4469 inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
4470  -> std::string {
4471  return fmt::vformat(loc, string_view(fmt), fmt::make_format_args(args...));
4472 }
4473 
4474 template <typename OutputIt, typename Locale,
4476  detail::is_locale<Locale>::value)>
4477 auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
4478  format_args args) -> OutputIt {
4479  using detail::get_buffer;
4480  auto&& buf = get_buffer<char>(out);
4481  detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
4482  return detail::get_iterator(buf, out);
4483 }
4484 
4485 template <typename OutputIt, typename Locale, typename... T,
4487  detail::is_locale<Locale>::value)>
4488 FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
4489  format_string<T...> fmt, T&&... args) -> OutputIt {
4490  return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
4491 }
4492 
4493 template <typename Locale, typename... T,
4494  FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
4495 FMT_NODISCARD FMT_INLINE auto formatted_size(const Locale& loc,
4496  format_string<T...> fmt,
4497  T&&... args) -> size_t {
4498  auto buf = detail::counting_buffer<>();
4499  detail::vformat_to<char>(buf, fmt, fmt::make_format_args(args...),
4500  detail::locale_ref(loc));
4501  return buf.count();
4502 }
4503 
4505 
4506 template <typename T, typename Char>
4507 template <typename FormatContext>
4509 formatter<T, Char,
4512  FormatContext& ctx)
4513  const -> decltype(ctx.out()) {
4514  if (specs_.width_ref.kind == detail::arg_id_kind::none &&
4515  specs_.precision_ref.kind == detail::arg_id_kind::none) {
4516  return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
4517  }
4518  auto specs = specs_;
4519  detail::handle_dynamic_spec<detail::width_checker>(specs.width,
4520  specs.width_ref, ctx);
4521  detail::handle_dynamic_spec<detail::precision_checker>(
4522  specs.precision, specs.precision_ref, ctx);
4523  return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
4524 }
4525 
4527 
4528 #ifdef FMT_HEADER_ONLY
4529 # define FMT_FUNC inline
4530 # include "format-inl.h"
4531 #else
4532 # define FMT_FUNC
4533 #endif
4534 
4535 #endif // FMT_FORMAT_H_
formatted_size
FMT_NODISCARD FMT_INLINE auto formatted_size(const Locale &loc, format_string< T... > fmt, T &&... args) -> size_t
Definition: format.h:4495
detail::uint128_fallback::low
constexpr auto low() const noexcept -> uint64_t
Definition: format.h:337
detail::basic_fp::e
int e
Definition: format.h:1619
detail::bigint::exp_
int exp_
Definition: format.h:2789
detail::to_utf8_error_policy::replace
@ replace
detail::utf8_to_utf16
Definition: format.h:1368
detail::ignore_unused
FMT_CONSTEXPR void ignore_unused(const T &...)
Definition: core.h:319
detail::reserve_iterator
remove_reference_t< decltype(reserve(std::declval< OutputIt & >(), 0))> reserve_iterator
Definition: format.h:553
detail::digit_grouping::apply
auto apply(Out out, basic_string_view< C > digits) const -> Out
Definition: format.h:2051
detail::bigint::assign
FMT_CONSTEXPR20 void assign(UInt n)
Definition: format.h:2860
detail::write_significand
constexpr auto write_significand(OutputIt out, const char *significand, int significand_size) -> OutputIt
Definition: format.h:2512
formatter
Definition: core.h:1087
detail::uint128_fallback::hi_
uint64_t hi_
Definition: format.h:330
detail::basic_fp::basic_fp
FMT_CONSTEXPR basic_fp(Float n)
Definition: format.h:1628
left
lu_byte left
Definition: lparser.c:1226
detail::dynamic_format_specs::width_ref
arg_ref< Char > width_ref
Definition: core.h:2130
detail::fallback_digit_grouping::count_separators
constexpr auto count_separators(int) const -> int
Definition: format.h:2712
format_int::c_str
auto c_str() const -> const char *
Definition: format.h:4016
detail::isfinite
FMT_CONSTEXPR auto isfinite(T value) -> bool
Definition: format.h:2754
presentation_type::exp_upper
@ exp_upper
detail::code_point_index
auto code_point_index(basic_string_view< Char > s, size_t n) -> size_t
Definition: format.h:743
detail::buffer::clear
void clear()
Definition: core.h:867
detail::bigint::subtract_aligned
FMT_CONSTEXPR20 void subtract_aligned(const bigint &other)
Definition: format.h:2815
detail::operator*
FMT_CONSTEXPR auto operator*(fp x, fp y) -> fp
Definition: format.h:1701
format_specs::align
align_t align
Definition: core.h:2080
detail::do_write_float
FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP &f, const format_specs< Char > &specs, float_specs fspecs, locale_ref loc) -> OutputIt
Definition: format.h:2602
basic_memory_buffer::basic_memory_buffer
FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer &&other) noexcept
Definition: format.h:958
detail::loc_writer::decimal_point
std::basic_string< Char > decimal_point
Definition: format.h:2172
loc_value::loc_value
loc_value(T)
Definition: format.h:1054
detail::to_string_view
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:534
detail::float_specs::showpoint
bool showpoint
Definition: format.h:2431
basic_string_view::data
constexpr auto data() const noexcept -> const Char *
Definition: core.h:457
formatter< bytes >::parse
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> const char *
Definition: format.h:4116
sol::stack::top
int top(lua_State *L)
Definition: sol.hpp:11684
basic_memory_buffer::alloc_
FMT_NO_UNIQUE_ADDRESS Allocator alloc_
Definition: format.h:888
detail::num_bits
constexpr auto num_bits() -> int
Definition: format.h:452
detail::prefix_append
FMT_CONSTEXPR void prefix_append(unsigned &prefix, unsigned value)
Definition: format.h:2074
detail::write_escaped_string
auto write_escaped_string(OutputIt out, basic_string_view< Char > str) -> OutputIt
Definition: format.h:1906
detail::int128_opt
int128_opt
Definition: core.h:383
formatter< group_digits_view< T > >::specs_
detail::dynamic_format_specs specs_
Definition: format.h:4153
detail::state
state
Definition: core.h:2305
basic_format_context::advance_to
void advance_to(iterator it)
Definition: core.h:1783
detail::string_literal::value
static constexpr CharT value[sizeof...(C)]
Definition: format.h:290
detail::counting_buffer
Definition: core.h:1038
align
Definition: core.h:2016
detail::base_iterator
auto base_iterator(std::back_insert_iterator< Container > it, typename Container::value_type *) -> std::back_insert_iterator< Container >
Definition: format.h:568
detail::countl_zero_fallback
FMT_CONSTEXPR20 auto countl_zero_fallback(UInt n) -> int
Definition: format.h:479
detail::uint128_fallback
Definition: format.h:328
detail::bigint::bigint
bigint(uint64_t n)
Definition: format.h:2872
detail::bigint::compare
friend FMT_CONSTEXPR20 auto compare(const bigint &lhs, const bigint &rhs) -> int
Definition: format.h:2916
detail::type::string_type
@ string_type
basic_format_parse_context::next_arg_id
FMT_CONSTEXPR auto next_arg_id() -> int
Definition: core.h:711
bytes
Definition: format.h:4101
detail::make_arg
FMT_CONSTEXPR FMT_INLINE auto make_arg(T &val) -> value< Context >
Definition: core.h:1582
format_specs::width
int width
Definition: core.h:2077
detail::arg_ref::value::name
basic_string_view< Char > name
Definition: core.h:2121
nested_formatter::nested_formatter
constexpr nested_formatter()
Definition: format.h:4198
basic_memory_buffer
Definition: format.h:883
detail::uint128_fallback::operator!=
constexpr friend auto operator!=(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition: format.h:348
detail::digit_grouping::digit_grouping
digit_grouping(std::string grouping, std::basic_string< Char > sep)
Definition: format.h:2037
detail::arg_mapper
Definition: core.h:1355
detail::counting_iterator::operator*
FMT_CONSTEXPR auto operator*() const -> value_type
Definition: format.h:2310
detail::to_utf8_error_policy::abort
@ abort
detail::write_padded
FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs< Char > &specs, size_t size, size_t width, F &&f) -> OutputIt
Definition: format.h:1730
detail::bigint::remove_leading_zeros
FMT_CONSTEXPR20 void remove_leading_zeros()
Definition: format.h:2808
detail::make_unsigned_char
typename conditional_t< std::is_integral< Char >::value, std::make_unsigned< Char >, type_identity< uint32_t > >::type make_unsigned_char
Definition: format.h:1796
basic_format_context::arg_id
FMT_CONSTEXPR auto arg_id(basic_string_view< Char > name) -> int
Definition: core.h:1770
bitmask
#define bitmask(b)
Definition: lgc.h:63
basic_memory_buffer::store_
T store_[SIZE]
Definition: format.h:885
detail::num_bits< uint128_t >
constexpr auto num_bits< uint128_t >() -> int
Definition: format.h:457
detail::countl_zero
FMT_CONSTEXPR20 auto countl_zero(uint32_t n) -> int
Definition: format.h:486
udp_client.default
default
Definition: udp_client.py:10
detail::write
FMT_CONSTEXPR auto write(OutputIt out, const T &value) -> enable_if_t< std::is_class< T >::value &&!is_string< T >::value &&!is_floating_point< T >::value &&!std::is_same< T, Char >::value &&!std::is_same< T, remove_cvref_t< decltype(arg_mapper< Context >().map(value))>>::value, OutputIt >
Definition: format.h:3744
detail::dragonbox::float_info< float >::carrier_uint
uint32_t carrier_uint
Definition: format.h:1519
detail::uint128_t
conditional_t< FMT_USE_INT128, uint128_opt, uint128_fallback > uint128_t
Definition: format.h:439
remove_cvref_t
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition: core.h:280
FMT_FORMAT_AS
#define FMT_FORMAT_AS(Type, Base)
Definition: format.h:4039
detail::buffer
Definition: core.h:816
loc_value::value_
basic_format_arg< format_context > value_
Definition: format.h:1047
detail::bigint::operator[]
FMT_CONSTEXPR20 auto operator[](int index) -> bigit &
Definition: format.h:2794
basic_memory_buffer::operator=
auto operator=(basic_memory_buffer &&other) noexcept -> basic_memory_buffer &
Definition: format.h:967
FMT_MSC_WARNING
#define FMT_MSC_WARNING(...)
Definition: core.h:58
detail::get_data
auto get_data(std::basic_string< Char > &s) -> Char *
Definition: format.h:516
detail::count_digits_fallback
FMT_CONSTEXPR auto count_digits_fallback(T n) -> int
Definition: format.h:1144
detail::arg_formatter::operator()
FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator
Definition: format.h:3795
detail::bigint::align
FMT_CONSTEXPR20 void align(const bigint &other)
Definition: format.h:3010
basic_string_view::size
constexpr auto size() const noexcept -> size_t
Definition: core.h:460
detail::multiply
FMT_CONSTEXPR auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t
Definition: format.h:1684
detail::buffer::push_back
FMT_CONSTEXPR20 void push_back(const T &value)
Definition: core.h:884
detail::float_specs::precision
int precision
Definition: format.h:2425
detail::dragonbox::umul128_upper64
auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t
Definition: format.h:1493
detail::uint64_or_128_t
conditional_t< num_bits< T >()<=64, uint64_t, uint128_t > uint64_or_128_t
Definition: format.h:1119
nonstd::span_lite::size_t
span_CONFIG_SIZE_TYPE size_t
Definition: span.hpp:576
detail::default_arg_formatter::operator()
auto operator()(T value) -> iterator
Definition: format.h:3775
detail::arg_formatter::operator()
auto operator()(typename basic_format_arg< context >::handle) -> iterator
Definition: format.h:3798
detail::write_int_arg
Definition: format.h:2146
detail::width_checker
Definition: format.h:3805
format_int::format_int
format_int(long value)
Definition: format.h:3994
detail::loc_writer::operator()
auto operator()(T) -> bool
Definition: format.h:2183
FMT_POWERS_OF_10
#define FMT_POWERS_OF_10(factor)
Definition: format.h:1121
detail::fractional_part_rounding_thresholds
constexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t
Definition: format.h:3266
formatter< join_view< It, Sentinel, Char >, Char >::parse
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> const Char *
Definition: format.h:4252
detail::bigint::num_bigits
FMT_CONSTEXPR20 auto num_bigits() const -> int
Definition: format.h:2890
detail::buffer::end
FMT_INLINE auto end() noexcept -> T *
Definition: core.h:851
FMT_API
#define FMT_API
Definition: core.h:207
loc_value
Definition: format.h:1045
basic_string_view
Definition: core.h:415
visit_format_arg
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
Definition: core.h:1698
detail::buffer::size
constexpr auto size() const noexcept -> size_t
Definition: core.h:857
format_int::buffer_size
@ buffer_size
Definition: format.h:3974
s
XmlRpcServer s
detail::to_utf8::to_utf8
to_utf8()
Definition: format.h:1388
detail::exponent_mask
constexpr auto exponent_mask() -> typename dragonbox::float_info< Float >::carrier_uint
Definition: format.h:1582
prod
static int prod(const int *dims, int ndims)
Definition: kiss_fftndr.c:22
detail::uint128_fallback::operator>>
FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback
Definition: format.h:388
detail::uintptr_t
uint128_t uintptr_t
Definition: format.h:444
detail::counting_iterator::operator++
FMT_CONSTEXPR auto operator++(int) -> counting_iterator
Definition: format.h:2298
detail::digits10< uint128_t >
constexpr auto digits10< uint128_t >() noexcept -> int
Definition: format.h:1252
literals
Definition: xchar.h:71
vformat
auto vformat(const Locale &loc, string_view fmt, format_args args) -> std::string
Definition: format.h:4462
detail::dragonbox::float_info< double >
Definition: format.h:1530
format_int::str_
char * str_
Definition: format.h:3976
detail::to_utf8::convert
static auto convert(Buffer &buf, basic_string_view< WChar > s, to_utf8_error_policy policy=to_utf8_error_policy::abort) -> bool
Definition: format.h:1412
detail::thousands_sep_result::grouping
std::string grouping
Definition: format.h:1255
detail::float_format
float_format
Definition: format.h:2417
detail::bigint::add_compare
friend FMT_CONSTEXPR20 auto add_compare(const bigint &lhs1, const bigint &lhs2, const bigint &rhs) -> int
Definition: format.h:2934
formatter< bytes >::specs_
detail::dynamic_format_specs specs_
Definition: format.h:4112
detail::float_specs::format
float_format format
Definition: format.h:2426
group_digits_view::value
T value
Definition: format.h:4133
detail::is_integer
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:782
loc_value::visit
auto visit(Visitor &&vis) -> decltype(vis(0))
Definition: format.h:1056
detail::uint128_fallback::operator&
constexpr friend auto operator&(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition: format.h:361
format_specs
Definition: core.h:2076
detail::counting_iterator::difference_type
std::ptrdiff_t difference_type
Definition: format.h:2281
detail::loc_writer::grouping
std::string grouping
Definition: format.h:2171
format
auto format(const Locale &loc, format_string< T... > fmt, T &&... args) -> std::string
Definition: format.h:4469
detail::umul128
auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback
Definition: format.h:1450
detail::float_specs::upper
bool upper
Definition: format.h:2428
FMT_INLINE
#define FMT_INLINE
Definition: core.h:165
detail::write
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:419
detail::format_decimal_result::begin
Iterator begin
Definition: format.h:1300
right
lu_byte right
Definition: lparser.c:1227
basic_memory_buffer::move
FMT_CONSTEXPR20 void move(basic_memory_buffer &other)
Definition: format.h:934
detail::write_int_data::size
size_t size
Definition: format.h:1962
FMT_USE_FLOAT
#define FMT_USE_FLOAT
Definition: format.h:785
detail::basic_fp::assign
FMT_CONSTEXPR auto assign(Float n) -> bool
Definition: format.h:1632
detail::bigint::bigits_capacity
@ bigits_capacity
Definition: format.h:2787
detail::digit_grouping::next_state
Definition: format.h:2014
format_facet::grouping_
std::string grouping_
Definition: format.h:1066
detail::iterator_t
decltype(std::begin(std::declval< T & >())) iterator_t
Definition: format.h:511
detail::thousands_sep_impl
FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result< Char >
Definition: format-inl.h:94
detail::bigint
Definition: format.h:2781
detail::view
Definition: core.h:1154
detail::is_negative
constexpr auto is_negative(T value) -> bool
Definition: format.h:1095
group_digits_view
Definition: format.h:4132
detail::write_ptr
auto write_ptr(OutputIt out, UIntPtr value, const format_specs< Char > *specs) -> OutputIt
Definition: format.h:1765
detail::write_loc
FMT_FUNC auto write_loc(appender out, loc_value value, const format_specs<> &specs, locale_ref loc) -> bool
Definition: format-inl.h:115
arg
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1875
detail::loc_writer::out
buffer_appender< Char > out
Definition: format.h:2168
detail::format_float
FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs, buffer< char > &buf) -> int
Definition: format.h:3278
detail::dynamic_format_specs::precision_ref
arg_ref< Char > precision_ref
Definition: core.h:2131
detail::arg_ref
Definition: core.h:2101
detail::print
FMT_FUNC void print(std::FILE *f, string_view text)
Definition: format-inl.h:1463
detail::arg_formatter::locale
locale_ref locale
Definition: format.h:3792
detail::fixup
@ fixup
Definition: format.h:3040
nested_formatter::formatter_
formatter< T > formatter_
Definition: format.h:4195
detail::to_utf8::c_str
auto c_str() const -> const char *
Definition: format.h:1399
detail::arg_ref::val
union detail::arg_ref::value val
detail::get_significand_size
constexpr auto get_significand_size(const big_decimal_fp &f) -> int
Definition: format.h:2503
format_specs::sign
sign_t sign
Definition: core.h:2081
nonstd::span_lite::std11::false_type
integral_constant< bool, false > false_type
Definition: span.hpp:657
detail
Definition: args.h:19
detail::uint128_fallback::uint128_fallback
constexpr uint128_fallback(uint64_t hi, uint64_t lo)
Definition: format.h:333
nested_formatter::width_
int width_
Definition: format.h:4192
detail::convert_float
constexpr auto convert_float(T value) -> convert_float_result< T >
Definition: format.h:1710
detail::bigint::divmod_assign
FMT_CONSTEXPR20 auto divmod_assign(const bigint &divisor) -> int
Definition: format.h:3023
basic_format_parse_context::check_arg_id
FMT_CONSTEXPR void check_arg_id(int id)
Definition: core.h:726
detail::uint128_fallback::operator-
friend auto operator-(const uint128_fallback &lhs, uint64_t rhs) -> uint128_fallback
Definition: format.h:384
presentation_type::fixed_upper
@ fixed_upper
detail::max_value
constexpr auto max_value() -> T
Definition: format.h:449
detail::error_handler
Definition: core.h:650
detail::format_dragon
FMT_CONSTEXPR20 void format_dragon(basic_fp< uint128_t > value, unsigned flags, int num_digits, buffer< char > &buf, int &exp10)
Definition: format.h:3047
detail::format_uint
FMT_CONSTEXPR auto format_uint(Char *buffer, UInt value, int num_digits, bool upper=false) -> Char *
Definition: format.h:1341
detail::buffer::capacity
constexpr auto capacity() const noexcept -> size_t
Definition: core.h:860
nested_formatter::parse
FMT_CONSTEXPR auto parse(format_parse_context &ctx) -> const char *
Definition: format.h:4200
mqtt_test_proto.x
x
Definition: mqtt_test_proto.py:34
detail::counting_iterator::iterator_category
std::output_iterator_tag iterator_category
Definition: format.h:2280
detail::ulong_type
conditional_t< long_short, unsigned, unsigned long long > ulong_type
Definition: core.h:1336
detail::dragonbox::decimal_fp
Definition: format.h:1557
detail::normalize
FMT_CONSTEXPR auto normalize(basic_fp< F > value) -> basic_fp< F >
Definition: format.h:1667
detail::has_implicit_bit
constexpr auto has_implicit_bit() -> bool
Definition: format.h:1567
detail::type::custom_type
@ custom_type
presentation_type::bin_lower
@ bin_lower
detail::find_escape
auto find_escape(const Char *begin, const Char *end) -> find_escape_result< Char >
Definition: format.h:1799
nested_formatter::align_
align_t align_
Definition: format.h:4194
detail::float_format::exp
@ exp
detail_exported::compile_string_to_view
constexpr auto compile_string_to_view(const Char(&s)[N]) -> basic_string_view< Char >
Definition: format.h:1032
detail::digit_grouping
Definition: format.h:2009
detail::dragonbox::divisor
uint32_t divisor
Definition: format-inl.h:200
basic_format_arg
Definition: core.h:1080
presentation_type::hex_lower
@ hex_lower
detail::fallback_digit_grouping::apply
constexpr auto apply(Out out, basic_string_view< C >) const -> Out
Definition: format.h:2715
detail::counting_iterator::operator+
FMT_CONSTEXPR friend auto operator+(counting_iterator it, difference_type n) -> counting_iterator
Definition: format.h:2304
formatter< nested_view< T > >::parse
FMT_CONSTEXPR auto parse(format_parse_context &ctx) -> const char *
Definition: format.h:4181
detail::arg_ref::kind
arg_id_kind kind
Definition: core.h:2115
nonstd::span_lite::std11::true_type
integral_constant< bool, true > true_type
Definition: span.hpp:656
basic_memory_buffer::~basic_memory_buffer
FMT_CONSTEXPR20 ~basic_memory_buffer()
Definition: format.h:930
detail::counting_iterator::pointer
void pointer
Definition: format.h:2282
detail::dragon
dragon
Definition: format.h:3038
to_string
auto to_string(const T &value) -> std::string
Definition: format.h:4319
detail::dragonbox::float_info< double >::carrier_uint
uint64_t carrier_uint
Definition: format.h:1531
detail::float_format::hex
@ hex
detail::uint128_fallback::operator+=
FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback &
Definition: format.h:413
detail::state::width
@ width
detail::format_decimal
FMT_CONSTEXPR20 auto format_decimal(Char *out, UInt value, int size) -> format_decimal_result< Char * >
Definition: format.h:1308
detail::needs_escape
auto needs_escape(uint32_t cp) -> bool
Definition: format.h:1781
detail::digits2
constexpr auto digits2(size_t value) -> const char *
Definition: format.h:1127
detail::exponent_bias
constexpr auto exponent_bias() -> int
Definition: format.h:1588
detail::thousands_sep
auto thousands_sep(locale_ref loc) -> thousands_sep_result< Char >
Definition: format.h:1262
detail::predecessor_closer
@ predecessor_closer
Definition: format.h:3039
detail::to_utf8
Definition: format.h:1383
basic_memory_buffer::get_allocator
auto get_allocator() const -> Allocator
Definition: format.h:975
mqtt_test_proto.y
y
Definition: mqtt_test_proto.py:35
detail::digit_grouping::count_separators
auto count_separators(int num_digits) const -> int
Definition: format.h:2042
detail::get_iterator
FMT_INLINE auto get_iterator(Buf &buf, OutputIt) -> decltype(buf.out())
Definition: core.h:1146
f
f
basic_format_context::locale
FMT_CONSTEXPR auto locale() -> detail::locale_ref
Definition: core.h:1787
basic_format_args
Definition: core.h:1081
detail::digit_grouping::next_state::pos
int pos
Definition: format.h:2016
detail::digit_grouping::digit_grouping
digit_grouping(locale_ref loc, bool localized=true)
Definition: format.h:2031
detail::buffer_appender
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T > >> buffer_appender
Definition: core.h:1132
append
QCXXHighlighter::QCXXHighlighter(QTextDocument *document) m_highlightRule append)({ QRegularExpression(R"(#[a-zA-Z_]+)"), "Preprocessor" })
Definition: QCXXHighlighter.cpp:60
detail::buffer::append
void append(const U *begin, const U *end)
detail::uint128_fallback::operator==
constexpr friend auto operator==(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition: format.h:344
nlohmann::detail::escape
std::string escape(std::string s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2743
detail::check_char_specs
FMT_CONSTEXPR auto check_char_specs(const format_specs< Char > &specs) -> bool
Definition: core.h:2603
detail::default_arg_formatter::out
iterator out
Definition: format.h:3771
detail::digits10< int128_opt >
constexpr auto digits10< int128_opt >() noexcept -> int
Definition: format.h:1251
FMT_REDUCE_INT_INSTANTIATIONS
#define FMT_REDUCE_INT_INSTANTIATIONS
Definition: format.h:173
detail::default_arg_formatter::args
basic_format_args< context > args
Definition: format.h:3772
detail::dragonbox::umul192_upper128
auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept -> uint128_fallback
Definition: format.h:1506
nested_formatter::fill_
detail::fill_t< char > fill_
Definition: format.h:4193
detail::digit_grouping::next_state::group
std::string::const_iterator group
Definition: format.h:2015
detail::dragonbox::floor_log2_pow10
auto floor_log2_pow10(int e) noexcept -> int
Definition: format.h:1487
detail::fallback_digit_grouping
Definition: format.h:2706
basic_format_string
Definition: core.h:2768
detail::parse_align
FMT_CONSTEXPR auto parse_align(char c) -> align_t
Definition: core.h:2194
format_int::buffer_
char buffer_[buffer_size]
Definition: format.h:3975
basic_string_view::begin
constexpr auto begin() const noexcept -> iterator
Definition: core.h:462
underlying_t
typename std::underlying_type< T >::type underlying_t
Definition: core.h:286
detail::buffer::data
FMT_CONSTEXPR auto data() noexcept -> T *
Definition: core.h:863
detail::big_decimal_fp::significand_size
int significand_size
Definition: format.h:2499
detail::type::int_type
@ int_type
detail::float_specs::binary32
bool binary32
Definition: format.h:2430
detail::arg_formatter::specs
const format_specs< Char > & specs
Definition: format.h:3791
detail::fill
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1715
detail::format_decimal_result::end
Iterator end
Definition: format.h:1301
detail::counting_iterator::operator++
FMT_CONSTEXPR auto operator++() -> counting_iterator &
Definition: format.h:2294
detail::dragonbox::decimal_fp::exponent
int exponent
Definition: format.h:1560
presentation_type::hexfloat_lower
@ hexfloat_lower
formatter< group_digits_view< T > >::parse
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> const char *
Definition: format.h:4157
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
formatter< T, Char, enable_if_t< detail::has_format_as< T >::value > >::format
auto format(const T &value, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:4033
detail::bigint::multiply
FMT_CONSTEXPR20 void multiply(UInt value)
Definition: format.h:2839
vformat_to
auto vformat_to(OutputIt out, const Locale &loc, string_view fmt, format_args args) -> OutputIt
Definition: format.h:4477
detail::write_exponent
FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It
Definition: format.h:1596
detail::count
constexpr auto count() -> size_t
Definition: core.h:1222
detail::buffer< wchar_t >::const_reference
const wchar_t & const_reference
Definition: core.h:845
detail::thousands_sep_impl< wchar_t >
template FMT_API auto thousands_sep_impl< wchar_t >(locale_ref) -> thousands_sep_result< wchar_t >
FMT_ENABLE_IF
#define FMT_ENABLE_IF(...)
Definition: core.h:303
detail::write_int_data::write_int_data
FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, const format_specs< Char > &specs)
Definition: format.h:1965
basic_format_context::out
FMT_CONSTEXPR auto out() -> iterator
Definition: core.h:1780
detail::to_pointer
constexpr auto to_pointer(OutputIt, size_t) -> T *
Definition: format.h:556
detail::is_float128
std::is_same< T, float128 > is_float128
Definition: format.h:816
FMT_FALLTHROUGH
#define FMT_FALLTHROUGH
Definition: format.h:65
detail::parse_format_specs
FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char *begin, const Char *end, dynamic_format_specs< Char > &specs, basic_format_parse_context< Char > &ctx, type arg_type) -> const Char *
Definition: core.h:2309
detail::thousands_sep_result
Definition: format.h:1254
presentation_type::oct
@ oct
format_int::format_int
format_int(unsigned long value)
Definition: format.h:3997
detail::invalid_code_point
constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point
Definition: format.h:662
presentation_type::hexfloat_upper
@ hexfloat_upper
detail::loc_writer::specs
const format_specs< Char > & specs
Definition: format.h:2169
detail::to_utf8::buffer_
Buffer buffer_
Definition: format.h:1385
detail::write_float
FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP &f, const format_specs< Char > &specs, float_specs fspecs, locale_ref loc) -> OutputIt
Definition: format.h:2721
detail::copy2
FMT_CONSTEXPR20 FMT_INLINE void copy2(Char *dst, const char *src)
Definition: format.h:1290
basic_memory_buffer::append
void append(const ContiguousRange &range)
Definition: format.h:988
format_int::format_int
format_int(unsigned long long value)
Definition: format.h:3998
detail::bigint::assign
FMT_CONSTEXPR20 void assign(const bigint &other)
Definition: format.h:2877
join_view::begin
It begin
Definition: format.h:4231
detail::write_bytes
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const format_specs< Char > &specs) -> OutputIt
Definition: format.h:1755
detail::digit_grouping::initial_state
auto initial_state() const -> next_state
Definition: format.h:2018
appender
Definition: core.h:1100
detail::fixed
@ fixed
Definition: format.h:3041
detail::utf8_decode
FMT_CONSTEXPR auto utf8_decode(const char *s, uint32_t *c, int *e) -> const char *
Definition: format.h:625
detail::bigint::multiply
FMT_CONSTEXPR20 void multiply(uint32_t value)
Definition: format.h:2826
basic_memory_buffer::reserve
void reserve(size_t new_capacity)
Definition: format.h:984
detail::convert_float_result
conditional_t< std::is_same< T, float >::value||doublish, double, T > convert_float_result
Definition: format.h:1707
range_format::map
@ map
nested_formatter::nested
auto nested(const T &value) const -> nested_view< T >
Definition: format.h:4223
FMT_END_NAMESPACE
#define FMT_END_NAMESPACE
Definition: core.h:180
FMT_NODISCARD
#define FMT_NODISCARD
Definition: core.h:157
enums::format_as
constexpr auto format_as(Enum e) noexcept -> underlying_t< Enum >
Definition: format.h:4096
detail::long_type
conditional_t< long_short, int, long long > long_type
Definition: core.h:1335
formatter< bytes >::format
auto format(bytes b, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:4122
detail::to_utf8_error_policy
to_utf8_error_policy
Definition: format.h:1380
detail::utf8_to_utf16::size
auto size() const -> size_t
Definition: format.h:1375
detail::uint128_fallback::operator+=
FMT_CONSTEXPR void operator+=(uint128_fallback n)
Definition: format.h:401
check
static void check(LexState *ls, int c)
Definition: lparser.c:107
backward::details::move
const T & move(const T &v)
Definition: backward.hpp:394
detail::utf8_to_utf16::c_str
auto c_str() const -> const wchar_t *
Definition: format.h:1376
detail::utf8_to_utf16::utf8_to_utf16
FMT_API utf8_to_utf16(string_view s)
Definition: format-inl.h:1395
detail::reserve
auto reserve(std::back_insert_iterator< Container > it, size_t n) -> typename Container::value_type *
Definition: format.h:531
type_identity
Definition: core.h:281
format_facet::do_put
virtual auto do_put(appender out, loc_value val, const format_specs<> &specs) const -> bool
detail::counting_iterator
Definition: format.h:2275
bytes::data_
string_view data_
Definition: format.h:4103
detail_exported
Definition: format.h:1019
format_system_error
FMT_API void format_system_error(detail::buffer< char > &out, int error_code, const char *message) noexcept
Definition: format-inl.h:1410
detail::sign
constexpr auto sign(Sign s) -> Char
Definition: format.h:1137
detail::digit_grouping::grouping_
std::string grouping_
Definition: format.h:2011
FMT_END_EXPORT
#define FMT_END_EXPORT
Definition: core.h:188
detail::write_int_arg::prefix
unsigned prefix
Definition: format.h:2148
detail::parse_float_type_spec
FMT_CONSTEXPR auto parse_float_type_spec(const format_specs< Char > &specs) -> float_specs
Definition: format.h:2435
detail::write_nonfinite
FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan, format_specs< Char > specs, const float_specs &fspecs) -> OutputIt
Definition: format.h:2478
detail::uint128_opt
uint128_opt
Definition: core.h:384
detail::write_codepoint
auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt
Definition: format.h:1851
detail::fallback_digit_grouping::fallback_digit_grouping
constexpr fallback_digit_grouping(locale_ref, bool)
Definition: format.h:2708
presentation_type::general_upper
@ general_upper
format_specs::localized
bool localized
Definition: core.h:2083
presentation_type::chr
@ chr
detail::value
Definition: core.h:1257
report_system_error
FMT_API void report_system_error(int error_code, const char *message) noexcept
Definition: format-inl.h:1421
join_view::join_view
join_view(It b, Sentinel e, basic_string_view< Char > s)
Definition: format.h:4235
detail::fill_n
FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T &value) -> OutputIt
Definition: format.h:582
make_format_args
constexpr auto make_format_args(T &... args) -> format_arg_store< Context, remove_cvref_t< T >... >
Definition: core.h:1858
detail::utf8_to_utf16::buffer_
basic_memory_buffer< wchar_t > buffer_
Definition: format.h:1370
detail::fallback_digit_grouping::has_separator
constexpr auto has_separator() const -> bool
Definition: format.h:2710
detail::width_checker::operator()
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition: format.h:3807
detail::for_each_codepoint
FMT_CONSTEXPR void for_each_codepoint(string_view s, F f)
Definition: format.h:667
formatter< join_view< It, Sentinel, Char >, Char >::value_formatter_
formatter< remove_cvref_t< value_type >, Char > value_formatter_
Definition: format.h:4248
detail::num_significand_bits
constexpr auto num_significand_bits() -> int
Definition: format.h:1574
detail::is_output_iterator
Definition: core.h:1538
detail::loc_writer
Definition: format.h:2167
basic_memory_buffer::resize
FMT_CONSTEXPR20 void resize(size_t count)
Definition: format.h:981
d
d
detail::isfinite
auto isfinite(T) -> bool
Definition: chrono.h:1647
detail::write_int_data
Definition: format.h:1961
underlying
constexpr auto underlying(Enum e) noexcept -> underlying_t< Enum >
Definition: format.h:4090
enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:271
presentation_type::dec
@ dec
format_facet::format_facet
format_facet(Locale &loc)
Definition: format-inl.h:133
FMT_NOINLINE
#define FMT_NOINLINE
Definition: format.h:112
nlohmann::detail::void
j template void())
Definition: json.hpp:4061
format_facet::decimal_point_
std::string decimal_point_
Definition: format.h:1067
detail::equal2
auto equal2(const Char *lhs, const char *rhs) -> bool
Definition: format.h:1281
detail::is_big_endian
auto is_big_endian() -> bool
Definition: format.h:313
detail::write_int_arg::abs_value
UInt abs_value
Definition: format.h:2147
detail::dragonbox::floor_log10_pow2
auto floor_log10_pow2(int e) noexcept -> int
Definition: format.h:1481
type_identity_t
typename type_identity< T >::type type_identity_t
Definition: core.h:284
sign
Definition: core.h:2021
format_facet::id
static FMT_API Locale::id id
Definition: format.h:1074
detail::is_floating_point
bool_constant< std::is_floating_point< T >::value||is_float128< T >::value > is_floating_point
Definition: format.h:820
detail::counting_iterator::FMT_UNCHECKED_ITERATOR
FMT_UNCHECKED_ITERATOR(counting_iterator)
detail::set
constexpr auto set(type rhs) -> int
Definition: core.h:627
detail::counting_iterator::value_type::operator=
FMT_CONSTEXPR void operator=(const T &)
Definition: format.h:2287
FMT_CONSTEXPR_CHAR_TRAITS
#define FMT_CONSTEXPR_CHAR_TRAITS
Definition: core.h:132
detail::to_utf8::str
auto str() const -> std::string
Definition: format.h:1400
detail::is_supported_floating_point
FMT_CONSTEXPR auto is_supported_floating_point(T) -> bool
Definition: format.h:1104
detail::num_bits< int128_opt >
constexpr auto num_bits< int128_opt >() -> int
Definition: format.h:456
detail::arg_formatter::out
iterator out
Definition: format.h:3790
detail::loc_writer::sep
std::basic_string< Char > sep
Definition: format.h:2170
detail::bigint::bigit
uint32_t bigit
Definition: format.h:2785
group_digits
auto group_digits(T value) -> group_digits_view< T >
Definition: format.h:4147
is_contiguous
Definition: core.h:289
detail::bigint::bigit_bits
static constexpr const int bigit_bits
Definition: format.h:2798
format_specs::alt
bool alt
Definition: core.h:2082
nested_formatter
Definition: format.h:4190
detail::bigint::subtract_bigits
FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit &borrow)
Definition: format.h:2802
detail::uint128_fallback::lo_
uint64_t lo_
Definition: format.h:330
basic_format_arg::handle
Definition: core.h:1653
detail::digits10
constexpr auto digits10() noexcept -> int
Definition: format.h:1248
detail::thousands_sep_impl< char >
template FMT_API auto thousands_sep_impl< char >(locale_ref) -> thousands_sep_result< char >
detail::uint128_fallback::operator*
friend auto operator*(const uint128_fallback &lhs, uint32_t rhs) -> uint128_fallback
Definition: format.h:376
detail::has_isfinite
Definition: format.h:2739
presentation_type::general_lower
@ general_lower
memory_buffer
basic_memory_buffer< char > memory_buffer
Definition: format.h:993
detail::string_literal
Definition: format.h:289
detail::write_int
FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, unsigned prefix, const format_specs< Char > &specs, W write_digits) -> OutputIt
Definition: format.h:1986
FMT_SO_VISIBILITY
#define FMT_SO_VISIBILITY(value)
Definition: format.h:100
detail::utf8_to_utf16::str
auto str() const -> std::wstring
Definition: format.h:1377
string_view
basic_string_view< char > string_view
Definition: core.h:518
override
#define override
Definition: backward.hpp:387
format-inl.h
detail::basic_fp
Definition: format.h:1617
detail::type::none_type
@ none_type
format_int::format_signed
auto format_signed(Int value) -> char *
Definition: format.h:3983
nested_view::value
const T * value
Definition: format.h:4177
detail::std_string_view
Definition: core.h:366
format_int::format_int
format_int(int value)
Definition: format.h:3993
detail::float_specs::locale
bool locale
Definition: format.h:2429
format_int::format_int
format_int(long long value)
Definition: format.h:3995
basic_format_parse_context
Definition: core.h:674
detail::float128
void float128
Definition: format.h:814
sign_t
sign::type sign_t
Definition: core.h:2024
detail::buffer::try_resize
FMT_CONSTEXPR20 void try_resize(size_t count)
Definition: core.h:871
detail::vformat
auto vformat(const Locale &loc, basic_string_view< Char > fmt, basic_format_args< buffer_context< type_identity_t< Char >>> args) -> std::basic_string< Char >
Definition: format.h:3903
formatter< join_view< It, Sentinel, Char >, Char >::value_type
typename std::iterator_traits< It >::value_type value_type
Definition: format.h:4246
detail::to_utf8::convert
auto convert(basic_string_view< WChar > s, to_utf8_error_policy policy=to_utf8_error_policy::abort) -> bool
Definition: format.h:1405
detail::is_signed
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_opt >::value > is_signed
Definition: format.h:776
detail::uint32_or_64_or_128_t
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:1117
detail::digit_grouping::has_separator
auto has_separator() const -> bool
Definition: format.h:2040
detail::arg_id_kind::none
@ none
detail::pad_type::zero
@ zero
detail::width_checker::operator()
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition: format.h:3813
detail::write_escaped_char
auto write_escaped_char(OutputIt out, Char v) -> OutputIt
Definition: format.h:1922
detail::dragonbox::decimal_fp::significand
significand_type significand
Definition: format.h:1559
detail::adjust_precision
FMT_CONSTEXPR20 void adjust_precision(int &precision, int exp10)
Definition: format.h:2773
detail::decimal_point_impl
FMT_FUNC auto decimal_point_impl(locale_ref loc) -> Char
Definition: format-inl.h:101
detail::float_specs
Definition: format.h:2424
detail::is_constant_evaluated
constexpr FMT_INLINE auto is_constant_evaluated(bool default_value=false) noexcept -> bool
Definition: core.h:321
detail::bigint::assign_pow10
FMT_CONSTEXPR20 void assign_pow10(int exp)
Definition: format.h:2961
detail::dynamic_format_specs
Definition: core.h:2129
udp_client.int
int
Definition: udp_client.py:11
detail::dragonbox::float_info
Definition: format.h:1516
detail::bit_cast
FMT_CONSTEXPR20 auto bit_cast(const From &from) -> To
Definition: format.h:303
presentation_type::fixed_lower
@ fixed_lower
nested_view::fmt
const formatter< T > * fmt
Definition: format.h:4176
detail::bigint::operator*=
FMT_CONSTEXPR20 auto operator*=(Int value) -> bigint &
Definition: format.h:2910
FMT_ASSERT
#define FMT_ASSERT(condition, message)
Definition: core.h:353
detail::write_int_noinline
FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(OutputIt out, write_int_arg< T > arg, const format_specs< Char > &specs, locale_ref loc) -> OutputIt
Definition: format.h:2245
detail::assume
FMT_INLINE void assume(bool condition)
Definition: format.h:500
detail::find_escape_result::begin
const Char * begin
Definition: format.h:1787
detail::bigint::bigits_
basic_memory_buffer< bigit, bigits_capacity > bigits_
Definition: format.h:2788
detail::handle_dynamic_spec
FMT_CONSTEXPR void handle_dynamic_spec(int &value, arg_ref< typename Context::char_type > ref, Context &ctx)
Definition: format.h:3849
detail::arg_id_kind::index
@ index
formatter< join_view< It, Sentinel, Char >, Char >::format
auto format(const join_view< It, Sentinel, Char > &value, FormatContext &ctx) const -> decltype(ctx.out())
Definition: format.h:4257
detail::digit_grouping::next
auto next(next_state &state) const -> int
Definition: format.h:2021
presentation_type::none
@ none
join_view::sep
basic_string_view< Char > sep
Definition: format.h:4233
detail::to_utf8::size
auto size() const -> size_t
Definition: format.h:1398
detail::find_escape_result
Definition: format.h:1786
format_to
FMT_INLINE auto format_to(OutputIt out, const Locale &loc, format_string< T... > fmt, T &&... args) -> OutputIt
Definition: format.h:4488
basic_format_context::args
auto args() const -> const format_args &
Definition: core.h:1773
bool_constant
std::integral_constant< bool, B > bool_constant
Definition: core.h:274
detail::write_int_data::padding
size_t padding
Definition: format.h:1963
detail::arg_formatter
Definition: format.h:3786
presentation_type::hex_upper
@ hex_upper
detail::digit_grouping::thousands_sep_
std::basic_string< Char > thousands_sep_
Definition: format.h:2012
format_int::format_int
format_int(unsigned value)
Definition: format.h:3996
format_specs::fill
detail::fill_t< Char > fill
Definition: core.h:2084
system_error
auto system_error(int error_code, format_string< T... > fmt, T &&... args) -> std::system_error
Definition: format.h:3941
detail::uint128_fallback::operator|
constexpr friend auto operator|(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition: format.h:356
std
detail::arg_ref::value::index
int index
Definition: core.h:2120
format_int
Definition: format.h:3970
detail::float_format::general
@ general
basic_memory_buffer::basic_memory_buffer
FMT_CONSTEXPR20 basic_memory_buffer(const Allocator &alloc=Allocator())
Definition: format.h:924
detail::fill_t
Definition: core.h:2029
C
#define C(name, bit)
Definition: zstd.c:4811
digit
static int digit(int c)
Definition: lstrlib.c:1396
detail::counting_iterator::reference
void reference
Definition: format.h:2283
detail::vformat_args::type
basic_format_args< basic_format_context< std::back_insert_iterator< buffer< Char > >, Char > > type
Definition: core.h:2713
format_int::format_unsigned
auto format_unsigned(UInt value) -> char *
Definition: format.h:3978
detail::uint128_fallback::operator>
constexpr friend auto operator>(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
Definition: format.h:352
detail::default_arg_formatter
Definition: format.h:3767
detail::buffer::try_reserve
FMT_CONSTEXPR20 void try_reserve(size_t new_capacity)
Definition: core.h:880
format_specs::type
presentation_type type
Definition: core.h:2079
nested_formatter::write_padded
auto write_padded(format_context &ctx, F write) const -> decltype(ctx.out())
Definition: format.h:4212
join_view
Definition: format.h:4230
detail::vformat_to
void vformat_to(buffer< Char > &buf, const text_style &ts, basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char >>> args)
Definition: color.h:444
detail::dragonbox::get_cached_power
FMT_FUNC auto get_cached_power(int k) noexcept -> uint128_fallback
Definition: format-inl.h:1123
FMT_BEGIN_EXPORT
#define FMT_BEGIN_EXPORT
Definition: core.h:187
detail::report_error
FMT_FUNC void report_error(format_func func, int error_code, const char *message) noexcept
Definition: format-inl.h:66
core.h
detail::locale_ref
Definition: core.h:1553
detail::basic_fp::num_significand_bits
static constexpr const int num_significand_bits
Definition: format.h:1621
detail::uint128_fallback::operator~
constexpr friend auto operator~(const uint128_fallback &n) -> uint128_fallback
Definition: format.h:366
detail::code_point_length
FMT_CONSTEXPR auto code_point_length(const Char *begin) -> int
Definition: core.h:2146
presentation_type::string
@ string
detail::dragonbox::float_info< T, enable_if_t< is_double_double< T >::value > >::carrier_uint
detail::uint128_t carrier_uint
Definition: format.h:1554
detail::default_arg_formatter::iterator
buffer_appender< Char > iterator
Definition: format.h:3768
enums
Definition: format.h:4094
detail::bigint::bigint
FMT_CONSTEXPR20 bigint()
Definition: format.h:2871
mqtt_test.data
dictionary data
Definition: mqtt_test.py:22
sol::unicode::error_code
error_code
Definition: sol.hpp:13048
detail::default_arg_formatter::operator()
auto operator()(typename basic_format_arg< context >::handle h) -> iterator
Definition: format.h:3778
FMT_BEGIN_NAMESPACE
#define FMT_BEGIN_NAMESPACE
Definition: core.h:177
detail::write_char
FMT_CONSTEXPR auto write_char(OutputIt out, Char value, const format_specs< Char > &specs) -> OutputIt
Definition: format.h:1938
detail::get_arg
FMT_CONSTEXPR auto get_arg(Context &ctx, ID id) -> decltype(ctx.arg(id))
Definition: format.h:3842
detail::uint128_fallback::operator&=
FMT_CONSTEXPR void operator&=(uint128_fallback n)
Definition: format.h:408
FMT_USE_LONG_DOUBLE
#define FMT_USE_LONG_DOUBLE
Definition: format.h:791
detail::big_decimal_fp
Definition: format.h:2497
detail::counting_iterator::count
FMT_CONSTEXPR auto count() const -> size_t
Definition: format.h:2292
detail::find_escape_result::end
const Char * end
Definition: format.h:1788
detail::count_digits
FMT_CONSTEXPR20 auto count_digits(uint64_t n) -> int
Definition: format.h:1187
detail::buffer< wchar_t >::value_type
wchar_t value_type
Definition: core.h:844
detail::bigint::operator=
void operator=(const bigint &)=delete
detail::get_container
auto get_container(std::back_insert_iterator< Container > it) -> Container &
Definition: core.h:783
detail::precision_checker
Definition: format.h:3819
detail::basic_fp::basic_fp
constexpr basic_fp(uint64_t f_val, int e_val)
Definition: format.h:1625
detail::bigint::operator[]
FMT_CONSTEXPR20 auto operator[](int index) const -> bigit
Definition: format.h:2791
presentation_type::debug
@ debug
basic_string_view::end
constexpr auto end() const noexcept -> iterator
Definition: core.h:463
detail::arg_formatter::iterator
buffer_appender< Char > iterator
Definition: format.h:3787
detail::decimal_point
auto decimal_point(locale_ref loc) -> Char
Definition: format.h:1273
detail::get_dynamic_spec
FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg) -> int
Definition: format.h:3834
detail::get_buffer
auto get_buffer(OutputIt out) -> iterator_buffer< OutputIt, T >
Definition: core.h:1136
detail::arg_id_kind::name
@ name
format_facet::separator_
std::string separator_
Definition: format.h:1065
detail::is_integral
Definition: format.h:769
detail::default_arg_formatter::loc
locale_ref loc
Definition: format.h:3773
basic_format_context
Definition: core.h:1739
detail::find_escape_result::cp
uint32_t cp
Definition: format.h:1789
conditional_t
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:273
monostate
Definition: core.h:293
detail::is_string
Definition: core.h:564
detail::make_write_int_arg
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:2152
detail::uint128_fallback::uint128_fallback
constexpr uint128_fallback(uint64_t value=0)
Definition: format.h:334
presentation_type::pointer
@ pointer
detail::abort_fuzzing_if
FMT_CONSTEXPR void abort_fuzzing_if(bool condition)
Definition: format.h:282
remove_reference_t
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:276
detail::buffer::set
FMT_CONSTEXPR void set(T *buf_data, size_t buf_capacity) noexcept
Definition: core.h:834
detail::to_unsigned
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition: core.h:391
format_int::data
auto data() const -> const char *
Definition: format.h:4010
detail::big_decimal_fp::significand
const char * significand
Definition: format.h:2498
format_int::str
auto str() const -> std::string
Definition: format.h:4026
detail::basic_fp::f
F f
Definition: format.h:1618
format_facet
Definition: format.h:1063
presentation_type::exp_lower
@ exp_lower
detail::to_utf8::to_utf8
to_utf8(basic_string_view< WChar > s, to_utf8_error_policy policy=to_utf8_error_policy::abort)
Definition: format.h:1389
detail::is_utf8
FMT_CONSTEXPR auto is_utf8() -> bool
Definition: core.h:397
FMT_INLINE_VARIABLE
#define FMT_INLINE_VARIABLE
Definition: format.h:54
FMT_USE_DOUBLE
#define FMT_USE_DOUBLE
Definition: format.h:788
detail::format_func
void(*)(detail::buffer< char > &, int, const char *) format_func
Definition: format.h:3911
detail::uint128_fallback::operator<<
FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback
Definition: format.h:393
detail::basic_fp::basic_fp
constexpr basic_fp()
Definition: format.h:1624
detail::bigint::operator=
FMT_CONSTEXPR20 void operator=(Int n)
Definition: format.h:2885
detail::uint128_fallback::operator+
friend auto operator+(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
Definition: format.h:370
format_facet::format_facet
format_facet(string_view sep="", std::initializer_list< unsigned char > g={3}, std::string decimal_point=".")
Definition: format.h:1077
nested_view
Definition: format.h:4175
detail::type
type
Definition: core.h:573
next
#define next(ls)
Definition: llex.c:32
detail::precision_checker::operator()
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long
Definition: format.h:3821
detail::throw_format_error
FMT_NORETURN FMT_API void throw_format_error(const char *message)
Definition: format-inl.h:39
basic_format_parse_context::begin
constexpr auto begin() const noexcept -> iterator
Definition: core.h:693
detail::signbit
FMT_INLINE FMT_CONSTEXPR bool signbit(T value)
Definition: format.h:2761
bytes::bytes
bytes(string_view data)
Definition: format.h:4107
detail::write_console
FMT_FUNC auto write_console(int, string_view) -> bool
Definition: format-inl.h:1436
detail::format_error_code
FMT_FUNC void format_error_code(detail::buffer< char > &out, int error_code, string_view message) noexcept
Definition: format-inl.h:43
detail::counting_iterator::counting_iterator
FMT_CONSTEXPR counting_iterator()
Definition: format.h:2290
uchar
#define uchar(c)
Definition: lstrlib.c:40
ptr
auto ptr(T p) -> const void *
Definition: format.h:4067
dst
char * dst
Definition: lz4.h:792
detail::write_escaped_cp
auto write_escaped_cp(OutputIt out, const find_escape_result< Char > &escape) -> OutputIt
Definition: format.h:1861
detail::compute_width
auto compute_width(basic_string_view< Char > s) -> size_t
Definition: format.h:698
join_view::end
Sentinel end
Definition: format.h:4232
detail::decimal_point
auto decimal_point(locale_ref loc) -> wchar_t
Definition: format.h:1276
detail::counting_iterator::count_
size_t count_
Definition: format.h:2277
detail::precision_checker::operator()
FMT_CONSTEXPR auto operator()(T) -> unsigned long long
Definition: format.h:3827
detail::format_hexfloat
FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision, float_specs specs, buffer< char > &buf)
Definition: format.h:3180
detail::format_decimal_result
Definition: format.h:1299
char_t
typename detail::char_t_impl< S >::type char_t
Definition: core.h:664
detail::bigint::double_bigit
uint64_t double_bigit
Definition: format.h:2786
loc_value::loc_value
loc_value(T value)
Definition: format.h:1051
detail::const_check
constexpr FMT_INLINE auto const_check(T value) -> T
Definition: core.h:340
sol::table
table_core< false > table
Definition: forward.hpp:1126
join
auto join(It begin, Sentinel end, string_view sep) -> join_view< It, Sentinel >
Definition: format.h:4280
formatter< group_digits_view< T > >::format
auto format(group_digits_view< T > t, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:4163
format_facet::put
auto put(appender out, loc_value val, const format_specs<> &specs) const -> bool
Definition: format.h:1084
format_specs::precision
int precision
Definition: core.h:2078
FMT_CONSTEXPR20
#define FMT_CONSTEXPR20
Definition: core.h:116
detail::uint128_fallback::high
constexpr auto high() const noexcept -> uint64_t
Definition: format.h:336
detail::dragonbox::float_info< T, enable_if_t< std::numeric_limits< T >::digits==64||std::numeric_limits< T >::digits==113||is_float128< T >::value > >::carrier_uint
detail::uint128_t carrier_uint
Definition: format.h:1547
detail::char8_type
char8_type
Definition: format.h:599
detail::copy_str_noinline
FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition: format.h:603
detail::state::precision
@ precision
detail::big_decimal_fp::exponent
int exponent
Definition: format.h:2500
vsystem_error
FMT_API auto vsystem_error(int error_code, string_view format_str, format_args args) -> std::system_error
Definition: format-inl.h:147
detail::uint128_fallback::operator>>=
FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback &
Definition: format.h:398
detail::dragonbox::decimal_fp::significand_type
typename float_info< T >::carrier_uint significand_type
Definition: format.h:1558
formatter< nested_view< T > >::format
auto format(nested_view< T > view, format_context &ctx) const -> decltype(ctx.out())
Definition: format.h:4184
detail::dragonbox::to_decimal
auto to_decimal(T x) noexcept -> decimal_fp< T >
Definition: format-inl.h:1243
detail::isnan
constexpr auto isnan(T value) -> bool
Definition: format.h:2734
detail::bigint::square
FMT_CONSTEXPR20 void square()
Definition: format.h:2980
FMT_CONSTEXPR
#define FMT_CONSTEXPR
Definition: core.h:105
detail::bigint::operator<<=
FMT_NOINLINE FMT_CONSTEXPR20 auto operator<<=(int shift) -> bigint &
Definition: format.h:2894
presentation_type::bin_upper
@ bin_upper
FMT_THROW
#define FMT_THROW(x)
Definition: format.h:130
align_t
align::type align_t
Definition: core.h:2020
detail::float_specs::sign
sign_t sign
Definition: format.h:2427
detail::is_printable
auto is_printable(uint16_t x, const singleton *singletons, size_t singletons_size, const unsigned char *singleton_lowers, const unsigned char *normal, size_t normal_size) -> bool
Definition: format-inl.h:1492
format_int::size
auto size() const -> size_t
Definition: format.h:4002
detail::sentinel_t
decltype(std::end(std::declval< T & >())) sentinel_t
Definition: format.h:512
detail::loc_writer::operator()
auto operator()(T value) -> bool
Definition: format.h:2175
detail::counting_iterator::value_type
Definition: format.h:2286
detail::to_ascii
constexpr auto to_ascii(Char c) -> char
Definition: core.h:2136
udp_client.args
args
Definition: udp_client.py:12
detail::thousands_sep_result::thousands_sep
Char thousands_sep
Definition: format.h:1256


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:44