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