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