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