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