Coverage Report

Created: 2025-11-18 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fmt/include/fmt/format.h
Line
Count
Source
1
/*
2
  Formatting library for C++
3
4
  Copyright (c) 2012 - present, Victor Zverovich
5
6
  Permission is hereby granted, free of charge, to any person obtaining
7
  a copy of this software and associated documentation files (the
8
  "Software"), to deal in the Software without restriction, including
9
  without limitation the rights to use, copy, modify, merge, publish,
10
  distribute, sublicense, and/or sell copies of the Software, and to
11
  permit persons to whom the Software is furnished to do so, subject to
12
  the following conditions:
13
14
  The above copyright notice and this permission notice shall be
15
  included in all copies or substantial portions of the Software.
16
17
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25
  --- Optional exception to the license ---
26
27
  As an exception, if, as a result of your compiling your source code, portions
28
  of this Software are embedded into a machine-executable object form of such
29
  source code, you may redistribute such embedded portions in such object form
30
  without including the above copyright and permission notices.
31
 */
32
33
#ifndef FMT_FORMAT_H_
34
#define FMT_FORMAT_H_
35
36
#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
37
#  define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
38
#  define FMT_REMOVE_TRANSITIVE_INCLUDES
39
#endif
40
41
#include "base.h"
42
43
// libc++ supports string_view in pre-c++17.
44
#if FMT_HAS_INCLUDE(<string_view>) && \
45
    (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION))
46
#  define FMT_USE_STRING_VIEW
47
#endif
48
49
#ifndef FMT_MODULE
50
#  include <stdlib.h>  // malloc, free
51
52
#  include <cmath>    // std::signbit
53
#  include <cstddef>  // std::byte
54
#  include <cstdint>  // uint32_t
55
#  include <cstring>  // std::memcpy
56
#  include <limits>   // std::numeric_limits
57
#  include <new>      // std::bad_alloc
58
#  if defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI)
59
// Workaround for pre gcc 5 libstdc++.
60
#    include <memory>  // std::allocator_traits
61
#  endif
62
#  include <stdexcept>     // std::runtime_error
63
#  include <string>        // std::string
64
#  include <system_error>  // std::system_error
65
66
// Check FMT_CPLUSPLUS to avoid a warning in MSVC.
67
#  if FMT_HAS_INCLUDE(<bit>) && FMT_CPLUSPLUS > 201703L
68
#    include <bit>  // std::bit_cast
69
#  endif
70
71
#  if defined(FMT_USE_STRING_VIEW)
72
#    include <string_view>
73
#  endif
74
75
#  if FMT_MSC_VERSION
76
#    include <intrin.h>  // _BitScanReverse[64], _umul128
77
#  endif
78
#endif  // FMT_MODULE
79
80
#if defined(FMT_USE_NONTYPE_TEMPLATE_ARGS)
81
// Use the provided definition.
82
#elif defined(__NVCOMPILER)
83
#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
84
#elif FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L
85
#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
86
#elif defined(__cpp_nontype_template_args) && \
87
    __cpp_nontype_template_args >= 201911L
88
#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
89
#elif FMT_CLANG_VERSION >= 1200 && FMT_CPLUSPLUS >= 202002L
90
#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
91
#else
92
#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
93
#endif
94
95
#if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L
96
#  define FMT_INLINE_VARIABLE inline
97
#else
98
#  define FMT_INLINE_VARIABLE
99
#endif
100
101
// Check if RTTI is disabled.
102
#ifdef FMT_USE_RTTI
103
// Use the provided definition.
104
#elif defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || defined(_CPPRTTI) || \
105
    defined(__INTEL_RTTI__) || defined(__RTTI)
106
// __RTTI is for EDG compilers. _CPPRTTI is for MSVC.
107
#  define FMT_USE_RTTI 1
108
#else
109
#  define FMT_USE_RTTI 0
110
#endif
111
112
// Visibility when compiled as a shared library/object.
113
#if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
114
#  define FMT_SO_VISIBILITY(value) FMT_VISIBILITY(value)
115
#else
116
#  define FMT_SO_VISIBILITY(value)
117
#endif
118
119
#if FMT_GCC_VERSION || FMT_CLANG_VERSION
120
#  define FMT_NOINLINE __attribute__((noinline))
121
#else
122
#  define FMT_NOINLINE
123
#endif
124
125
#ifdef FMT_DEPRECATED
126
// Use the provided definition.
127
#elif FMT_HAS_CPP14_ATTRIBUTE(deprecated)
128
#  define FMT_DEPRECATED [[deprecated]]
129
#else
130
#  define FMT_DEPRECATED /* deprecated */
131
#endif
132
133
// Detect constexpr std::string.
134
#if !FMT_USE_CONSTEVAL
135
#  define FMT_USE_CONSTEXPR_STRING 0
136
#elif defined(__cpp_lib_constexpr_string) && \
137
    __cpp_lib_constexpr_string >= 201907L
138
#  if FMT_CLANG_VERSION && FMT_GLIBCXX_RELEASE
139
// clang + libstdc++ are able to work only starting with gcc13.3
140
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113294
141
#    if FMT_GLIBCXX_RELEASE < 13
142
#      define FMT_USE_CONSTEXPR_STRING 0
143
#    elif FMT_GLIBCXX_RELEASE == 13 && __GLIBCXX__ < 20240521
144
#      define FMT_USE_CONSTEXPR_STRING 0
145
#    else
146
#      define FMT_USE_CONSTEXPR_STRING 1
147
#    endif
148
#  else
149
#    define FMT_USE_CONSTEXPR_STRING 1
150
#  endif
151
#else
152
#  define FMT_USE_CONSTEXPR_STRING 0
153
#endif
154
#if FMT_USE_CONSTEXPR_STRING
155
#  define FMT_CONSTEXPR_STRING constexpr
156
#else
157
#  define FMT_CONSTEXPR_STRING
158
#endif
159
160
// GCC 4.9 doesn't support qualified names in specializations.
161
namespace std {
162
template <typename T> struct iterator_traits<fmt::basic_appender<T>> {
163
  using iterator_category = output_iterator_tag;
164
  using value_type = T;
165
  using difference_type =
166
      decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));
167
  using pointer = void;
168
  using reference = void;
169
};
170
}  // namespace std
171
172
#ifdef FMT_THROW
173
// Use the provided definition.
174
#elif FMT_USE_EXCEPTIONS
175
8.03k
#  define FMT_THROW(x) throw x
Unexecuted instantiation: fmt::v12::detail::fwrite_all(void const*, unsigned long, _IO_FILE*)::{lambda()#1}::operator()() const
Unexecuted instantiation: fmt::v12::detail::fwrite_all(void const*, unsigned long, _IO_FILE*)::{lambda()#1}::operator()() const::FMT_COMPILE_STRING::operator fmt::v12::basic_string_view<char>() const
176
#else
177
#  define FMT_THROW(x) ::fmt::assert_fail(__FILE__, __LINE__, (x).what())
178
#endif
179
180
#ifdef __clang_analyzer__
181
#  define FMT_CLANG_ANALYZER 1
182
#else
183
#  define FMT_CLANG_ANALYZER 0
184
#endif
185
186
// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
187
// integer formatter template instantiations to just one by only using the
188
// largest integer type. This results in a reduction in binary size but will
189
// cause a decrease in integer formatting performance.
190
#if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
191
#  define FMT_REDUCE_INT_INSTANTIATIONS 0
192
#endif
193
194
FMT_BEGIN_NAMESPACE
195
196
template <typename Char, typename Traits, typename Allocator>
197
struct is_contiguous<std::basic_string<Char, Traits, Allocator>>
198
    : std::true_type {};
199
200
namespace detail {
201
202
// __builtin_clz is broken in clang with Microsoft codegen:
203
// https://github.com/fmtlib/fmt/issues/519.
204
#if !FMT_MSC_VERSION
205
#  if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
206
53.1k
#    define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
207
#  endif
208
#  if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
209
113k
#    define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
210
#  endif
211
#endif
212
213
// Some compilers masquerade as both MSVC and GCC but otherwise support
214
// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
215
// MSVC intrinsics if the clz and clzll builtins are not available.
216
#if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL)
217
// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
218
#  ifndef __clang__
219
#    pragma intrinsic(_BitScanReverse)
220
#    ifdef _WIN64
221
#      pragma intrinsic(_BitScanReverse64)
222
#    endif
223
#  endif
224
225
inline auto clz(uint32_t x) -> int {
226
  FMT_ASSERT(x != 0, "");
227
  FMT_MSC_WARNING(suppress : 6102)  // Suppress a bogus static analysis warning.
228
  unsigned long r = 0;
229
  _BitScanReverse(&r, x);
230
  return 31 ^ static_cast<int>(r);
231
}
232
#  define FMT_BUILTIN_CLZ(n) detail::clz(n)
233
234
inline auto clzll(uint64_t x) -> int {
235
  FMT_ASSERT(x != 0, "");
236
  FMT_MSC_WARNING(suppress : 6102)  // Suppress a bogus static analysis warning.
237
  unsigned long r = 0;
238
#  ifdef _WIN64
239
  _BitScanReverse64(&r, x);
240
#  else
241
  // Scan the high 32 bits.
242
  if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
243
    return 63 ^ static_cast<int>(r + 32);
244
  // Scan the low 32 bits.
245
  _BitScanReverse(&r, static_cast<uint32_t>(x));
246
#  endif
247
  return 63 ^ static_cast<int>(r);
248
}
249
#  define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
250
#endif  // FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL)
251
252
51.5k
FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) {
253
51.5k
  ignore_unused(condition);
254
51.5k
#ifdef FMT_FUZZ
255
51.5k
  if (condition) throw std::runtime_error("fuzzing limit reached");
256
51.5k
#endif
257
51.5k
}
258
259
#if defined(FMT_USE_STRING_VIEW)
260
template <typename Char> using std_string_view = std::basic_string_view<Char>;
261
#else
262
template <typename Char> struct std_string_view {
263
  operator basic_string_view<Char>() const;
264
};
265
#endif
266
267
template <typename Char, Char... C> struct string_literal {
268
  static constexpr Char value[sizeof...(C)] = {C...};
269
6.23k
  constexpr operator basic_string_view<Char>() const {
270
6.23k
    return {value, sizeof...(C)};
271
6.23k
  }
272
};
273
#if FMT_CPLUSPLUS < 201703L
274
template <typename Char, Char... C>
275
constexpr Char string_literal<Char, C...>::value[sizeof...(C)];
276
#endif
277
278
// Implementation of std::bit_cast for pre-C++20.
279
template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>
280
77.6k
FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
281
#ifdef __cpp_lib_bit_cast
282
  if (is_constant_evaluated()) return std::bit_cast<To>(from);
283
#endif
284
77.6k
  auto to = To();
285
  // The cast suppresses a bogus -Wclass-memaccess on GCC.
286
77.6k
  std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
287
77.6k
  return to;
288
77.6k
}
_ZN3fmt3v126detail8bit_castIjfTnNSt3__19enable_ifIXeqstT_stT0_EiE4typeELi0EEES5_RKS6_
Line
Count
Source
280
20.4k
FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
281
#ifdef __cpp_lib_bit_cast
282
  if (is_constant_evaluated()) return std::bit_cast<To>(from);
283
#endif
284
20.4k
  auto to = To();
285
  // The cast suppresses a bogus -Wclass-memaccess on GCC.
286
20.4k
  std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
287
20.4k
  return to;
288
20.4k
}
_ZN3fmt3v126detail8bit_castIoeTnNSt3__19enable_ifIXeqstT_stT0_EiE4typeELi0EEES5_RKS6_
Line
Count
Source
280
24.6k
FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
281
#ifdef __cpp_lib_bit_cast
282
  if (is_constant_evaluated()) return std::bit_cast<To>(from);
283
#endif
284
24.6k
  auto to = To();
285
  // The cast suppresses a bogus -Wclass-memaccess on GCC.
286
24.6k
  std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
287
24.6k
  return to;
288
24.6k
}
Unexecuted instantiation: _ZN3fmt3v126detail8bit_castImPKvTnNSt3__19enable_ifIXeqstT_stT0_EiE4typeELi0EEES7_RKS8_
Unexecuted instantiation: _ZN3fmt3v126detail8bit_castImPKcTnNSt3__19enable_ifIXeqstT_stT0_EiE4typeELi0EEES7_RKS8_
_ZN3fmt3v126detail8bit_castImdTnNSt3__19enable_ifIXeqstT_stT0_EiE4typeELi0EEES5_RKS6_
Line
Count
Source
280
32.6k
FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
281
#ifdef __cpp_lib_bit_cast
282
  if (is_constant_evaluated()) return std::bit_cast<To>(from);
283
#endif
284
32.6k
  auto to = To();
285
  // The cast suppresses a bogus -Wclass-memaccess on GCC.
286
32.6k
  std::memcpy(static_cast<void*>(&to), &from, sizeof(to));
287
32.6k
  return to;
288
32.6k
}
289
290
6.59k
inline auto is_big_endian() -> bool {
291
#ifdef _WIN32
292
  return false;
293
#elif defined(__BIG_ENDIAN__)
294
  return true;
295
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
296
  return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
297
#else
298
  struct bytes {
299
    char data[sizeof(int)];
300
  };
301
  return bit_cast<bytes>(1).data[0] == 0;
302
#endif
303
6.59k
}
304
305
class uint128_fallback {
306
 private:
307
  uint64_t lo_, hi_;
308
309
 public:
310
100k
  constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}
311
0
  constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}
312
313
142k
  constexpr auto high() const noexcept -> uint64_t { return hi_; }
314
160k
  constexpr auto low() const noexcept -> uint64_t { return lo_; }
315
316
  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
317
  constexpr explicit operator T() const {
318
    return static_cast<T>(lo_);
319
  }
320
321
  friend constexpr auto operator==(const uint128_fallback& lhs,
322
0
                                   const uint128_fallback& rhs) -> bool {
323
0
    return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
324
0
  }
325
  friend constexpr auto operator!=(const uint128_fallback& lhs,
326
0
                                   const uint128_fallback& rhs) -> bool {
327
0
    return !(lhs == rhs);
328
0
  }
329
  friend constexpr auto operator>(const uint128_fallback& lhs,
330
0
                                  const uint128_fallback& rhs) -> bool {
331
0
    return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;
332
0
  }
333
  friend constexpr auto operator|(const uint128_fallback& lhs,
334
                                  const uint128_fallback& rhs)
335
0
      -> uint128_fallback {
336
0
    return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};
337
0
  }
338
  friend constexpr auto operator&(const uint128_fallback& lhs,
339
                                  const uint128_fallback& rhs)
340
0
      -> uint128_fallback {
341
0
    return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
342
0
  }
343
  friend constexpr auto operator~(const uint128_fallback& n)
344
0
      -> uint128_fallback {
345
0
    return {~n.hi_, ~n.lo_};
346
0
  }
347
  friend FMT_CONSTEXPR auto operator+(const uint128_fallback& lhs,
348
                                      const uint128_fallback& rhs)
349
0
      -> uint128_fallback {
350
0
    auto result = uint128_fallback(lhs);
351
0
    result += rhs;
352
0
    return result;
353
0
  }
354
  friend FMT_CONSTEXPR auto operator*(const uint128_fallback& lhs, uint32_t rhs)
355
0
      -> uint128_fallback {
356
0
    FMT_ASSERT(lhs.hi_ == 0, "");
357
0
    uint64_t hi = (lhs.lo_ >> 32) * rhs;
358
0
    uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;
359
0
    uint64_t new_lo = (hi << 32) + lo;
360
0
    return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};
361
0
  }
362
  friend constexpr auto operator-(const uint128_fallback& lhs, uint64_t rhs)
363
0
      -> uint128_fallback {
364
0
    return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};
365
0
  }
366
0
  FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback {
367
0
    if (shift == 64) return {0, hi_};
368
0
    if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64);
369
0
    return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
370
0
  }
371
0
  FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback {
372
0
    if (shift == 64) return {lo_, 0};
373
0
    if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64);
374
0
    return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
375
0
  }
376
0
  FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& {
377
0
    return *this = *this >> shift;
378
0
  }
379
0
  FMT_CONSTEXPR void operator+=(uint128_fallback n) {
380
0
    uint64_t new_lo = lo_ + n.lo_;
381
0
    uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0);
382
0
    FMT_ASSERT(new_hi >= hi_, "");
383
0
    lo_ = new_lo;
384
0
    hi_ = new_hi;
385
0
  }
386
0
  FMT_CONSTEXPR void operator&=(uint128_fallback n) {
387
0
    lo_ &= n.lo_;
388
0
    hi_ &= n.hi_;
389
0
  }
390
391
38.3k
  FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback& {
392
38.3k
    if (is_constant_evaluated()) {
393
0
      lo_ += n;
394
0
      hi_ += (lo_ < n ? 1 : 0);
395
0
      return *this;
396
0
    }
397
38.3k
#if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)
398
38.3k
    unsigned long long carry;
399
38.3k
    lo_ = __builtin_addcll(lo_, n, 0, &carry);
400
38.3k
    hi_ += carry;
401
#elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)
402
    unsigned long long result;
403
    auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result);
404
    lo_ = result;
405
    hi_ += carry;
406
#elif defined(_MSC_VER) && defined(_M_X64)
407
    auto carry = _addcarry_u64(0, lo_, n, &lo_);
408
    _addcarry_u64(carry, hi_, 0, &hi_);
409
#else
410
    lo_ += n;
411
    hi_ += (lo_ < n ? 1 : 0);
412
#endif
413
38.3k
    return *this;
414
38.3k
  }
415
};
416
417
using uint128_t = conditional_t<FMT_USE_INT128, uint128_opt, uint128_fallback>;
418
419
#ifdef UINTPTR_MAX
420
using uintptr_t = ::uintptr_t;
421
#else
422
using uintptr_t = uint128_t;
423
#endif
424
425
// Returns the largest possible value for type T. Same as
426
// std::numeric_limits<T>::max() but shorter and not affected by the max macro.
427
110k
template <typename T> constexpr auto max_value() -> T {
428
110k
  return (std::numeric_limits<T>::max)();
429
110k
}
unsigned long fmt::v12::detail::max_value<unsigned long>()
Line
Count
Source
427
54.9k
template <typename T> constexpr auto max_value() -> T {
428
54.9k
  return (std::numeric_limits<T>::max)();
429
54.9k
}
int fmt::v12::detail::max_value<int>()
Line
Count
Source
427
31.5k
template <typename T> constexpr auto max_value() -> T {
428
31.5k
  return (std::numeric_limits<T>::max)();
429
31.5k
}
Unexecuted instantiation: char fmt::v12::detail::max_value<char>()
Unexecuted instantiation: long long fmt::v12::detail::max_value<long long>()
unsigned int fmt::v12::detail::max_value<unsigned int>()
Line
Count
Source
427
23.7k
template <typename T> constexpr auto max_value() -> T {
428
23.7k
  return (std::numeric_limits<T>::max)();
429
23.7k
}
430
3.65M
template <typename T> constexpr auto num_bits() -> int {
431
3.65M
  return std::numeric_limits<T>::digits;
432
3.65M
}
Unexecuted instantiation: int fmt::v12::detail::num_bits<unsigned short>()
Unexecuted instantiation: int fmt::v12::detail::num_bits<unsigned char>()
Unexecuted instantiation: int fmt::v12::detail::num_bits<double>()
int fmt::v12::detail::num_bits<unsigned int>()
Line
Count
Source
430
3.64M
template <typename T> constexpr auto num_bits() -> int {
431
3.64M
  return std::numeric_limits<T>::digits;
432
3.64M
}
Unexecuted instantiation: int fmt::v12::detail::num_bits<int>()
int fmt::v12::detail::num_bits<unsigned long>()
Line
Count
Source
430
7.63k
template <typename T> constexpr auto num_bits() -> int {
431
7.63k
  return std::numeric_limits<T>::digits;
432
7.63k
}
Unexecuted instantiation: int fmt::v12::detail::num_bits<unsigned long long>()
Unexecuted instantiation: int fmt::v12::detail::num_bits<long long>()
Unexecuted instantiation: int fmt::v12::detail::num_bits<long>()
Unexecuted instantiation: int fmt::v12::detail::num_bits<float>()
Unexecuted instantiation: int fmt::v12::detail::num_bits<long double>()
433
// std::numeric_limits<T>::digits may return 0 for 128-bit ints.
434
0
template <> constexpr auto num_bits<int128_opt>() -> int { return 128; }
435
0
template <> constexpr auto num_bits<uint128_opt>() -> int { return 128; }
436
0
template <> constexpr auto num_bits<uint128_fallback>() -> int { return 128; }
437
438
// A heterogeneous bit_cast used for converting 96-bit long double to uint128_t
439
// and 128-bit pointers to uint128_fallback.
440
template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) > sizeof(From))>
441
inline auto bit_cast(const From& from) -> To {
442
  constexpr auto size = static_cast<int>(sizeof(From) / sizeof(unsigned short));
443
  struct data_t {
444
    unsigned short value[static_cast<unsigned>(size)];
445
  } data = bit_cast<data_t>(from);
446
  auto result = To();
447
  if (const_check(is_big_endian())) {
448
    for (int i = 0; i < size; ++i)
449
      result = (result << num_bits<unsigned short>()) | data.value[i];
450
  } else {
451
    for (int i = size - 1; i >= 0; --i)
452
      result = (result << num_bits<unsigned short>()) | data.value[i];
453
  }
454
  return result;
455
}
456
457
template <typename UInt>
458
0
FMT_CONSTEXPR20 inline auto countl_zero_fallback(UInt n) -> int {
459
0
  int lz = 0;
460
0
  constexpr UInt msb_mask = static_cast<UInt>(1) << (num_bits<UInt>() - 1);
461
0
  for (; (n & msb_mask) == 0; n <<= 1) lz++;
462
0
  return lz;
463
0
}
Unexecuted instantiation: int fmt::v12::detail::countl_zero_fallback<unsigned int>(unsigned int)
Unexecuted instantiation: int fmt::v12::detail::countl_zero_fallback<unsigned long>(unsigned long)
464
465
13.1k
FMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int {
466
13.1k
#ifdef FMT_BUILTIN_CLZ
467
13.1k
  if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n);
468
0
#endif
469
0
  return countl_zero_fallback(n);
470
13.1k
}
471
472
671
FMT_CONSTEXPR20 inline auto countl_zero(uint64_t n) -> int {
473
671
#ifdef FMT_BUILTIN_CLZLL
474
671
  if (!is_constant_evaluated()) return FMT_BUILTIN_CLZLL(n);
475
0
#endif
476
0
  return countl_zero_fallback(n);
477
671
}
478
479
42.2k
FMT_INLINE void assume(bool condition) {
480
42.2k
  (void)condition;
481
42.2k
#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
482
42.2k
  __builtin_assume(condition);
483
#elif FMT_GCC_VERSION
484
  if (!condition) __builtin_unreachable();
485
#endif
486
42.2k
}
487
488
// Attempts to reserve space for n extra characters in the output range.
489
// Returns a pointer to the reserved range or a reference to it.
490
template <typename OutputIt,
491
          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
492
                            is_contiguous<typename OutputIt::container>::value)>
493
#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
494
__attribute__((no_sanitize("undefined")))
495
#endif
496
FMT_CONSTEXPR20 inline auto
497
reserve(OutputIt it, size_t n) -> typename OutputIt::value_type* {
498
  auto& c = get_container(it);
499
  size_t size = c.size();
500
  c.resize(size + n);
501
  return &c[size];
502
}
503
504
template <typename T>
505
FMT_CONSTEXPR20 inline auto reserve(basic_appender<T> it, size_t n)
506
82.6k
    -> basic_appender<T> {
507
82.6k
  buffer<T>& buf = get_container(it);
508
82.6k
  buf.try_reserve(buf.size() + n);
509
82.6k
  return it;
510
82.6k
}
511
512
template <typename Iterator>
513
constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
514
  return it;
515
}
516
517
template <typename OutputIt>
518
using reserve_iterator =
519
    remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>;
520
521
template <typename T, typename OutputIt>
522
constexpr auto to_pointer(OutputIt, size_t) -> T* {
523
  return nullptr;
524
}
525
template <typename T> FMT_CONSTEXPR auto to_pointer(T*& ptr, size_t n) -> T* {
526
  T* begin = ptr;
527
  ptr += n;
528
  return begin;
529
}
530
template <typename T>
531
65.3k
FMT_CONSTEXPR20 auto to_pointer(basic_appender<T> it, size_t n) -> T* {
532
65.3k
  buffer<T>& buf = get_container(it);
533
65.3k
  buf.try_reserve(buf.size() + n);
534
65.3k
  auto size = buf.size();
535
65.3k
  if (buf.capacity() < size + n) return nullptr;
536
65.3k
  buf.try_resize(size + n);
537
65.3k
  return buf.data() + size;
538
65.3k
}
539
540
template <typename OutputIt,
541
          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
542
                            is_contiguous<typename OutputIt::container>::value)>
543
inline auto base_iterator(OutputIt it,
544
                          typename OutputIt::container_type::value_type*)
545
    -> OutputIt {
546
  return it;
547
}
548
549
template <typename Iterator>
550
77.3k
constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
551
77.3k
  return it;
552
77.3k
}
553
554
// <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
555
// instead (#1998).
556
template <typename OutputIt, typename Size, typename T>
557
FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
558
40.8k
    -> OutputIt {
559
2.45M
  for (Size i = 0; i < count; ++i) *out++ = value;
560
40.8k
  return out;
561
40.8k
}
fmt::v12::basic_appender<char> fmt::v12::detail::fill_n<fmt::v12::basic_appender<char>, int, char>(fmt::v12::basic_appender<char>, int, char const&)
Line
Count
Source
558
18.7k
    -> OutputIt {
559
134k
  for (Size i = 0; i < count; ++i) *out++ = value;
560
18.7k
  return out;
561
18.7k
}
fmt::v12::basic_appender<char> fmt::v12::detail::fill_n<fmt::v12::basic_appender<char>, unsigned long, char>(fmt::v12::basic_appender<char>, unsigned long, char const&)
Line
Count
Source
558
14.9k
    -> OutputIt {
559
1.73M
  for (Size i = 0; i < count; ++i) *out++ = value;
560
14.9k
  return out;
561
14.9k
}
Unexecuted instantiation: int* fmt::v12::detail::fill_n<int*, unsigned long, int>(int*, unsigned long, int const&)
Unexecuted instantiation: unsigned int* fmt::v12::detail::fill_n<unsigned int*, unsigned long, unsigned int>(unsigned int*, unsigned long, unsigned int const&)
unsigned int* fmt::v12::detail::fill_n<unsigned int*, unsigned int, unsigned int>(unsigned int*, unsigned int, unsigned int const&)
Line
Count
Source
558
3.07k
    -> OutputIt {
559
560k
  for (Size i = 0; i < count; ++i) *out++ = value;
560
3.07k
  return out;
561
3.07k
}
Unexecuted instantiation: char* fmt::v12::detail::fill_n<char*, unsigned long, char>(char*, unsigned long, char const&)
fmt::v12::basic_appender<char> fmt::v12::detail::fill_n<fmt::v12::basic_appender<char>, unsigned int, char>(fmt::v12::basic_appender<char>, unsigned int, char const&)
Line
Count
Source
558
4.09k
    -> OutputIt {
559
22.3k
  for (Size i = 0; i < count; ++i) *out++ = value;
560
4.09k
  return out;
561
4.09k
}
Unexecuted instantiation: wchar_t* fmt::v12::detail::fill_n<wchar_t*, unsigned long, wchar_t>(wchar_t*, unsigned long, wchar_t const&)
Unexecuted instantiation: char* fmt::v12::detail::fill_n<char*, int, char>(char*, int, char const&)
562
template <typename T, typename Size>
563
5.20k
FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
564
5.20k
  if (is_constant_evaluated()) return fill_n<T*, Size, T>(out, count, value);
565
5.20k
  static_assert(sizeof(T) == 1,
566
5.20k
                "sizeof(T) must be 1 to use char for initialization");
567
5.20k
  std::memset(out, value, to_unsigned(count));
568
5.20k
  return out + count;
569
5.20k
}
char* fmt::v12::detail::fill_n<char, unsigned long>(char*, unsigned long, char)
Line
Count
Source
563
4.73k
FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
564
4.73k
  if (is_constant_evaluated()) return fill_n<T*, Size, T>(out, count, value);
565
4.73k
  static_assert(sizeof(T) == 1,
566
4.73k
                "sizeof(T) must be 1 to use char for initialization");
567
4.73k
  std::memset(out, value, to_unsigned(count));
568
4.73k
  return out + count;
569
4.73k
}
char* fmt::v12::detail::fill_n<char, int>(char*, int, char)
Line
Count
Source
563
465
FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
564
465
  if (is_constant_evaluated()) return fill_n<T*, Size, T>(out, count, value);
565
465
  static_assert(sizeof(T) == 1,
566
465
                "sizeof(T) must be 1 to use char for initialization");
567
465
  std::memset(out, value, to_unsigned(count));
568
465
  return out + count;
569
465
}
570
571
template <typename OutChar, typename InputIt, typename OutputIt>
572
FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end,
573
200k
                                              OutputIt out) -> OutputIt {
574
200k
  return copy<OutChar>(begin, end, out);
575
200k
}
fmt::v12::basic_appender<char> fmt::v12::detail::copy_noinline<char, char*, fmt::v12::basic_appender<char> >(char*, char*, fmt::v12::basic_appender<char>)
Line
Count
Source
573
10.4k
                                              OutputIt out) -> OutputIt {
574
10.4k
  return copy<OutChar>(begin, end, out);
575
10.4k
}
fmt::v12::basic_appender<char> fmt::v12::detail::copy_noinline<char, char const*, fmt::v12::basic_appender<char> >(char const*, char const*, fmt::v12::basic_appender<char>)
Line
Count
Source
573
189k
                                              OutputIt out) -> OutputIt {
574
189k
  return copy<OutChar>(begin, end, out);
575
189k
}
576
577
// A public domain branchless UTF-8 decoder by Christopher Wellons:
578
// https://github.com/skeeto/branchless-utf8
579
/* Decode the next character, c, from s, reporting errors in e.
580
 *
581
 * Since this is a branchless decoder, four bytes will be read from the
582
 * buffer regardless of the actual length of the next character. This
583
 * means the buffer _must_ have at least three bytes of zero padding
584
 * following the end of the data stream.
585
 *
586
 * Errors are reported in e, which will be non-zero if the parsed
587
 * character was somehow invalid: invalid byte sequence, non-canonical
588
 * encoding, or a surrogate half.
589
 *
590
 * The function returns a pointer to the next character. When an error
591
 * occurs, this pointer will be a guess that depends on the particular
592
 * error, but it will always advance at least one byte.
593
 */
594
FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
595
88.4k
    -> const char* {
596
88.4k
  constexpr int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
597
88.4k
  constexpr uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
598
88.4k
  constexpr int shiftc[] = {0, 18, 12, 6, 0};
599
88.4k
  constexpr int shifte[] = {0, 6, 4, 2, 0};
600
601
88.4k
  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"
602
88.4k
      [static_cast<unsigned char>(*s) >> 3];
603
  // Compute the pointer to the next character early so that the next
604
  // iteration can start working on the next character. Neither Clang
605
  // nor GCC figure out this reordering on their own.
606
88.4k
  const char* next = s + len + !len;
607
608
88.4k
  using uchar = unsigned char;
609
610
  // Assume a four-byte character and load four bytes. Unused bits are
611
  // shifted out.
612
88.4k
  *c = uint32_t(uchar(s[0]) & masks[len]) << 18;
613
88.4k
  *c |= uint32_t(uchar(s[1]) & 0x3f) << 12;
614
88.4k
  *c |= uint32_t(uchar(s[2]) & 0x3f) << 6;
615
88.4k
  *c |= uint32_t(uchar(s[3]) & 0x3f) << 0;
616
88.4k
  *c >>= shiftc[len];
617
618
  // Accumulate the various error conditions.
619
88.4k
  *e = (*c < mins[len]) << 6;       // non-canonical encoding
620
88.4k
  *e |= ((*c >> 11) == 0x1b) << 7;  // surrogate half?
621
88.4k
  *e |= (*c > 0x10FFFF) << 8;       // out of range?
622
88.4k
  *e |= (uchar(s[1]) & 0xc0) >> 2;
623
88.4k
  *e |= (uchar(s[2]) & 0xc0) >> 4;
624
88.4k
  *e |= uchar(s[3]) >> 6;
625
88.4k
  *e ^= 0x2a;  // top two bits of each tail byte correct?
626
88.4k
  *e >>= shifte[len];
627
628
88.4k
  return next;
629
88.4k
}
630
631
constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point = ~uint32_t();
632
633
// Invokes f(cp, sv) for every code point cp in s with sv being the string view
634
// corresponding to the code point. cp is invalid_code_point on error.
635
template <typename F>
636
1.92k
FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) {
637
88.4k
  auto decode = [f](const char* buf_ptr, const char* ptr) {
638
88.4k
    auto cp = uint32_t();
639
88.4k
    auto error = 0;
640
88.4k
    auto end = utf8_decode(buf_ptr, &cp, &error);
641
88.4k
    bool result = f(error ? invalid_code_point : cp,
642
88.4k
                    string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));
643
88.4k
    return result ? (error ? buf_ptr + 1 : end) : nullptr;
644
88.4k
  };
Unexecuted instantiation: fmt::v12::detail::for_each_codepoint<fmt::v12::detail::find_escape(char const*, char const*)::{lambda(unsigned int, fmt::v12::basic_string_view<char>)#1}>(fmt::v12::basic_string_view<char>, fmt::v12::detail::find_escape(char const*, char const*)::{lambda(unsigned int, fmt::v12::basic_string_view<char>)#1})::{lambda(char const*, char const*)#1}::operator()(char const*, char const*) const
_ZZN3fmt3v126detail18for_each_codepointIZNS1_5writeIcNS0_14basic_appenderIcEETnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SB_NS0_17basic_string_viewIS8_EERKNS0_12format_specsEEUljNSC_IcEEE_EEvSH_S8_ENKUlPKcSK_E_clESK_SK_
Line
Count
Source
637
88.4k
  auto decode = [f](const char* buf_ptr, const char* ptr) {
638
88.4k
    auto cp = uint32_t();
639
88.4k
    auto error = 0;
640
88.4k
    auto end = utf8_decode(buf_ptr, &cp, &error);
641
88.4k
    bool result = f(error ? invalid_code_point : cp,
642
88.4k
                    string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));
643
88.4k
    return result ? (error ? buf_ptr + 1 : end) : nullptr;
644
88.4k
  };
Unexecuted instantiation: format.cc:fmt::v12::detail::for_each_codepoint<fmt::v12::detail::utf8_to_utf16::utf8_to_utf16(fmt::v12::basic_string_view<char>)::$_0>(fmt::v12::basic_string_view<char>, fmt::v12::detail::utf8_to_utf16::utf8_to_utf16(fmt::v12::basic_string_view<char>)::$_0)::{lambda(char const*, char const*)#1}::operator()(char const*, char const*) const
645
646
1.92k
  auto p = s.data();
647
1.92k
  const size_t block_size = 4;  // utf8_decode always reads blocks of 4 chars.
648
1.92k
  if (s.size() >= block_size) {
649
85.9k
    for (auto end = p + s.size() - block_size + 1; p < end;) {
650
84.2k
      p = decode(p, p);
651
84.2k
      if (!p) return;
652
84.2k
    }
653
1.71k
  }
654
1.92k
  auto num_chars_left = to_unsigned(s.data() + s.size() - p);
655
1.92k
  if (num_chars_left == 0) return;
656
657
  // Suppress bogus -Wstringop-overflow.
658
1.61k
  if (FMT_GCC_VERSION) num_chars_left &= 3;
659
1.61k
  char buf[2 * block_size - 1] = {};
660
1.61k
  copy<char>(p, p + num_chars_left, buf);
661
1.61k
  const char* buf_ptr = buf;
662
4.20k
  do {
663
4.20k
    auto end = decode(buf_ptr, p);
664
4.20k
    if (!end) return;
665
4.20k
    p += end - buf_ptr;
666
4.20k
    buf_ptr = end;
667
4.20k
  } while (buf_ptr < buf + num_chars_left);
668
1.61k
}
Unexecuted instantiation: void fmt::v12::detail::for_each_codepoint<fmt::v12::detail::find_escape(char const*, char const*)::{lambda(unsigned int, fmt::v12::basic_string_view<char>)#1}>(fmt::v12::basic_string_view<char>, fmt::v12::detail::find_escape(char const*, char const*)::{lambda(unsigned int, fmt::v12::basic_string_view<char>)#1})
_ZN3fmt3v126detail18for_each_codepointIZNS1_5writeIcNS0_14basic_appenderIcEETnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SB_NS0_17basic_string_viewIS8_EERKNS0_12format_specsEEUljNSC_IcEEE_EEvSH_S8_
Line
Count
Source
636
1.92k
FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) {
637
1.92k
  auto decode = [f](const char* buf_ptr, const char* ptr) {
638
1.92k
    auto cp = uint32_t();
639
1.92k
    auto error = 0;
640
1.92k
    auto end = utf8_decode(buf_ptr, &cp, &error);
641
1.92k
    bool result = f(error ? invalid_code_point : cp,
642
1.92k
                    string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));
643
1.92k
    return result ? (error ? buf_ptr + 1 : end) : nullptr;
644
1.92k
  };
645
646
1.92k
  auto p = s.data();
647
1.92k
  const size_t block_size = 4;  // utf8_decode always reads blocks of 4 chars.
648
1.92k
  if (s.size() >= block_size) {
649
85.9k
    for (auto end = p + s.size() - block_size + 1; p < end;) {
650
84.2k
      p = decode(p, p);
651
84.2k
      if (!p) return;
652
84.2k
    }
653
1.71k
  }
654
1.92k
  auto num_chars_left = to_unsigned(s.data() + s.size() - p);
655
1.92k
  if (num_chars_left == 0) return;
656
657
  // Suppress bogus -Wstringop-overflow.
658
1.61k
  if (FMT_GCC_VERSION) num_chars_left &= 3;
659
1.61k
  char buf[2 * block_size - 1] = {};
660
1.61k
  copy<char>(p, p + num_chars_left, buf);
661
1.61k
  const char* buf_ptr = buf;
662
4.20k
  do {
663
4.20k
    auto end = decode(buf_ptr, p);
664
4.20k
    if (!end) return;
665
4.20k
    p += end - buf_ptr;
666
4.20k
    buf_ptr = end;
667
4.20k
  } while (buf_ptr < buf + num_chars_left);
668
1.61k
}
Unexecuted instantiation: format.cc:void fmt::v12::detail::for_each_codepoint<fmt::v12::detail::utf8_to_utf16::utf8_to_utf16(fmt::v12::basic_string_view<char>)::$_0>(fmt::v12::basic_string_view<char>, fmt::v12::detail::utf8_to_utf16::utf8_to_utf16(fmt::v12::basic_string_view<char>)::$_0)
669
670
88.4k
FMT_CONSTEXPR inline auto display_width_of(uint32_t cp) noexcept -> size_t {
671
88.4k
  return to_unsigned(
672
88.4k
      1 + (cp >= 0x1100 &&
673
16.4k
           (cp <= 0x115f ||  // Hangul Jamo init. consonants
674
16.0k
            cp == 0x2329 ||  // LEFT-POINTING ANGLE BRACKET
675
15.8k
            cp == 0x232a ||  // RIGHT-POINTING ANGLE BRACKET
676
            // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:
677
15.6k
            (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
678
15.4k
            (cp >= 0xac00 && cp <= 0xd7a3) ||    // Hangul Syllables
679
15.1k
            (cp >= 0xf900 && cp <= 0xfaff) ||    // CJK Compatibility Ideographs
680
14.9k
            (cp >= 0xfe10 && cp <= 0xfe19) ||    // Vertical Forms
681
14.7k
            (cp >= 0xfe30 && cp <= 0xfe6f) ||    // CJK Compatibility Forms
682
14.4k
            (cp >= 0xff00 && cp <= 0xff60) ||    // Fullwidth Forms
683
13.7k
            (cp >= 0xffe0 && cp <= 0xffe6) ||    // Fullwidth Forms
684
13.5k
            (cp >= 0x20000 && cp <= 0x2fffd) ||  // CJK
685
12.8k
            (cp >= 0x30000 && cp <= 0x3fffd) ||
686
            // Miscellaneous Symbols and Pictographs + Emoticons:
687
12.5k
            (cp >= 0x1f300 && cp <= 0x1f64f) ||
688
            // Supplemental Symbols and Pictographs:
689
12.1k
            (cp >= 0x1f900 && cp <= 0x1f9ff))));
690
88.4k
}
691
692
template <typename T> struct is_integral : std::is_integral<T> {};
693
template <> struct is_integral<int128_opt> : std::true_type {};
694
template <> struct is_integral<uint128_t> : std::true_type {};
695
696
template <typename T>
697
using is_signed =
698
    std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
699
                                     std::is_same<T, int128_opt>::value>;
700
701
template <typename T>
702
using is_integer =
703
    bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
704
                  !std::is_same<T, char>::value &&
705
                  !std::is_same<T, wchar_t>::value>;
706
707
#if defined(FMT_USE_FLOAT128)
708
// Use the provided definition.
709
#elif FMT_CLANG_VERSION >= 309 && FMT_HAS_INCLUDE(<quadmath.h>)
710
#  define FMT_USE_FLOAT128 1
711
#elif FMT_GCC_VERSION && defined(_GLIBCXX_USE_FLOAT128) && \
712
    !defined(__STRICT_ANSI__)
713
#  define FMT_USE_FLOAT128 1
714
#else
715
#  define FMT_USE_FLOAT128 0
716
#endif
717
#if FMT_USE_FLOAT128
718
using float128 = __float128;
719
#else
720
struct float128 {};
721
#endif
722
723
template <typename T> using is_float128 = std::is_same<T, float128>;
724
725
template <typename T> struct is_floating_point : std::is_floating_point<T> {};
726
template <> struct is_floating_point<float128> : std::true_type {};
727
728
template <typename T, bool = is_floating_point<T>::value>
729
struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&
730
                                     sizeof(T) <= sizeof(double)> {};
731
template <typename T> struct is_fast_float<T, false> : std::false_type {};
732
733
template <typename T>
734
using fast_float_t = conditional_t<sizeof(T) == sizeof(double), double, float>;
735
736
template <typename T>
737
using is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;
738
739
#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
740
#  define FMT_USE_FULL_CACHE_DRAGONBOX 0
741
#endif
742
743
// An allocator that uses malloc/free to allow removing dependency on the C++
744
// standard libary runtime. std::decay is used for back_inserter to be found by
745
// ADL when applied to memory_buffer.
746
template <typename T> struct allocator : private std::decay<void> {
747
  using value_type = T;
748
749
42.2k
  auto allocate(size_t n) -> T* {
750
42.2k
    FMT_ASSERT(n <= max_value<size_t>() / sizeof(T), "");
751
42.2k
    T* p = static_cast<T*>(malloc(n * sizeof(T)));
752
42.2k
    if (!p) FMT_THROW(std::bad_alloc());
753
42.2k
    return p;
754
42.2k
  }
fmt::v12::detail::allocator<char>::allocate(unsigned long)
Line
Count
Source
749
8.88k
  auto allocate(size_t n) -> T* {
750
8.88k
    FMT_ASSERT(n <= max_value<size_t>() / sizeof(T), "");
751
8.88k
    T* p = static_cast<T*>(malloc(n * sizeof(T)));
752
8.88k
    if (!p) FMT_THROW(std::bad_alloc());
753
8.88k
    return p;
754
8.88k
  }
Unexecuted instantiation: fmt::v12::detail::allocator<int>::allocate(unsigned long)
fmt::v12::detail::allocator<unsigned int>::allocate(unsigned long)
Line
Count
Source
749
33.3k
  auto allocate(size_t n) -> T* {
750
33.3k
    FMT_ASSERT(n <= max_value<size_t>() / sizeof(T), "");
751
33.3k
    T* p = static_cast<T*>(malloc(n * sizeof(T)));
752
33.3k
    if (!p) FMT_THROW(std::bad_alloc());
753
33.3k
    return p;
754
33.3k
  }
Unexecuted instantiation: fmt::v12::detail::allocator<wchar_t>::allocate(unsigned long)
755
756
42.2k
  void deallocate(T* p, size_t) { free(p); }
fmt::v12::detail::allocator<char>::deallocate(char*, unsigned long)
Line
Count
Source
756
8.88k
  void deallocate(T* p, size_t) { free(p); }
Unexecuted instantiation: fmt::v12::detail::allocator<int>::deallocate(int*, unsigned long)
fmt::v12::detail::allocator<unsigned int>::deallocate(unsigned int*, unsigned long)
Line
Count
Source
756
33.3k
  void deallocate(T* p, size_t) { free(p); }
Unexecuted instantiation: fmt::v12::detail::allocator<wchar_t>::deallocate(wchar_t*, unsigned long)
757
758
91.5k
  constexpr friend auto operator==(allocator, allocator) noexcept -> bool {
759
91.5k
    return true;  // All instances of this allocator are equivalent.
760
91.5k
  }
fmt::v12::detail::operator==(fmt::v12::detail::allocator<unsigned int>, fmt::v12::detail::allocator<unsigned int>)
Line
Count
Source
758
91.5k
  constexpr friend auto operator==(allocator, allocator) noexcept -> bool {
759
91.5k
    return true;  // All instances of this allocator are equivalent.
760
91.5k
  }
Unexecuted instantiation: fmt::v12::detail::operator==(fmt::v12::detail::allocator<char>, fmt::v12::detail::allocator<char>)
Unexecuted instantiation: fmt::v12::detail::operator==(fmt::v12::detail::allocator<int>, fmt::v12::detail::allocator<int>)
761
  constexpr friend auto operator!=(allocator, allocator) noexcept -> bool {
762
    return false;
763
  }
764
};
765
766
template <typename Formatter>
767
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set)
768
    -> decltype(f.set_debug_format(set)) {
769
  f.set_debug_format(set);
770
}
771
template <typename Formatter>
772
FMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {}
773
774
}  // namespace detail
775
776
FMT_BEGIN_EXPORT
777
778
// The number of characters to store in the basic_memory_buffer object itself
779
// to avoid dynamic memory allocation.
780
enum { inline_buffer_size = 500 };
781
782
/**
783
 * A dynamically growing memory buffer for trivially copyable/constructible
784
 * types with the first `SIZE` elements stored in the object itself. Most
785
 * commonly used via the `memory_buffer` alias for `char`.
786
 *
787
 * **Example**:
788
 *
789
 *     auto out = fmt::memory_buffer();
790
 *     fmt::format_to(std::back_inserter(out), "The answer is {}.", 42);
791
 *
792
 * This will append "The answer is 42." to `out`. The buffer content can be
793
 * converted to `std::string` with `to_string(out)`.
794
 */
795
template <typename T, size_t SIZE = inline_buffer_size,
796
          typename Allocator = detail::allocator<T>>
797
class basic_memory_buffer : public detail::buffer<T> {
798
 private:
799
  T store_[SIZE];
800
801
  // Don't inherit from Allocator to avoid generating type_info for it.
802
  FMT_NO_UNIQUE_ADDRESS Allocator alloc_;
803
804
  // Deallocate memory allocated by the buffer.
805
203k
  FMT_CONSTEXPR20 void deallocate() {
806
203k
    T* data = this->data();
807
203k
    if (data != store_) alloc_.deallocate(data, this->capacity());
808
203k
  }
fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >::deallocate()
Line
Count
Source
805
49.4k
  FMT_CONSTEXPR20 void deallocate() {
806
49.4k
    T* data = this->data();
807
49.4k
    if (data != store_) alloc_.deallocate(data, this->capacity());
808
49.4k
  }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 128ul, fmt::v12::detail::allocator<char> >::deallocate()
fmt::v12::basic_memory_buffer<unsigned int, 32ul, fmt::v12::detail::allocator<unsigned int> >::deallocate()
Line
Count
Source
805
149k
  FMT_CONSTEXPR20 void deallocate() {
806
149k
    T* data = this->data();
807
149k
    if (data != store_) alloc_.deallocate(data, this->capacity());
808
149k
  }
fmt::v12::basic_memory_buffer<int, 500ul, fmt::v12::detail::allocator<int> >::deallocate()
Line
Count
Source
805
4.65k
  FMT_CONSTEXPR20 void deallocate() {
806
4.65k
    T* data = this->data();
807
4.65k
    if (data != store_) alloc_.deallocate(data, this->capacity());
808
4.65k
  }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<wchar_t, 500ul, fmt::v12::detail::allocator<wchar_t> >::deallocate()
809
810
43.5k
  static FMT_CONSTEXPR20 void grow(detail::buffer<T>& buf, size_t size) {
811
43.5k
    detail::abort_fuzzing_if(size > 5000);
812
43.5k
    auto& self = static_cast<basic_memory_buffer&>(buf);
813
43.5k
    const size_t max_size =
814
43.5k
        std::allocator_traits<Allocator>::max_size(self.alloc_);
815
43.5k
    size_t old_capacity = buf.capacity();
816
43.5k
    size_t new_capacity = old_capacity + old_capacity / 2;
817
43.5k
    if (size > new_capacity)
818
23.9k
      new_capacity = size;
819
19.5k
    else if (new_capacity > max_size)
820
0
      new_capacity = max_of(size, max_size);
821
43.5k
    T* old_data = buf.data();
822
43.5k
    T* new_data = self.alloc_.allocate(new_capacity);
823
    // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
824
43.5k
    detail::assume(buf.size() <= new_capacity);
825
    // The following code doesn't throw, so the raw pointer above doesn't leak.
826
43.5k
    memcpy(new_data, old_data, buf.size() * sizeof(T));
827
43.5k
    self.set(new_data, new_capacity);
828
    // deallocate must not throw according to the standard, but even if it does,
829
    // the buffer already uses the new storage and will deallocate it in
830
    // destructor.
831
43.5k
    if (old_data != self.store_) self.alloc_.deallocate(old_data, old_capacity);
832
43.5k
  }
fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >::grow(fmt::v12::detail::buffer<char>&, unsigned long)
Line
Count
Source
810
10.1k
  static FMT_CONSTEXPR20 void grow(detail::buffer<T>& buf, size_t size) {
811
10.1k
    detail::abort_fuzzing_if(size > 5000);
812
10.1k
    auto& self = static_cast<basic_memory_buffer&>(buf);
813
10.1k
    const size_t max_size =
814
10.1k
        std::allocator_traits<Allocator>::max_size(self.alloc_);
815
10.1k
    size_t old_capacity = buf.capacity();
816
10.1k
    size_t new_capacity = old_capacity + old_capacity / 2;
817
10.1k
    if (size > new_capacity)
818
2.76k
      new_capacity = size;
819
7.42k
    else if (new_capacity > max_size)
820
0
      new_capacity = max_of(size, max_size);
821
10.1k
    T* old_data = buf.data();
822
10.1k
    T* new_data = self.alloc_.allocate(new_capacity);
823
    // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
824
10.1k
    detail::assume(buf.size() <= new_capacity);
825
    // The following code doesn't throw, so the raw pointer above doesn't leak.
826
10.1k
    memcpy(new_data, old_data, buf.size() * sizeof(T));
827
10.1k
    self.set(new_data, new_capacity);
828
    // deallocate must not throw according to the standard, but even if it does,
829
    // the buffer already uses the new storage and will deallocate it in
830
    // destructor.
831
10.1k
    if (old_data != self.store_) self.alloc_.deallocate(old_data, old_capacity);
832
10.1k
  }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 128ul, fmt::v12::detail::allocator<char> >::grow(fmt::v12::detail::buffer<char>&, unsigned long)
Unexecuted instantiation: fmt::v12::basic_memory_buffer<int, 500ul, fmt::v12::detail::allocator<int> >::grow(fmt::v12::detail::buffer<int>&, unsigned long)
fmt::v12::basic_memory_buffer<unsigned int, 32ul, fmt::v12::detail::allocator<unsigned int> >::grow(fmt::v12::detail::buffer<unsigned int>&, unsigned long)
Line
Count
Source
810
33.3k
  static FMT_CONSTEXPR20 void grow(detail::buffer<T>& buf, size_t size) {
811
33.3k
    detail::abort_fuzzing_if(size > 5000);
812
33.3k
    auto& self = static_cast<basic_memory_buffer&>(buf);
813
33.3k
    const size_t max_size =
814
33.3k
        std::allocator_traits<Allocator>::max_size(self.alloc_);
815
33.3k
    size_t old_capacity = buf.capacity();
816
33.3k
    size_t new_capacity = old_capacity + old_capacity / 2;
817
33.3k
    if (size > new_capacity)
818
21.2k
      new_capacity = size;
819
12.1k
    else if (new_capacity > max_size)
820
0
      new_capacity = max_of(size, max_size);
821
33.3k
    T* old_data = buf.data();
822
33.3k
    T* new_data = self.alloc_.allocate(new_capacity);
823
    // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
824
33.3k
    detail::assume(buf.size() <= new_capacity);
825
    // The following code doesn't throw, so the raw pointer above doesn't leak.
826
33.3k
    memcpy(new_data, old_data, buf.size() * sizeof(T));
827
33.3k
    self.set(new_data, new_capacity);
828
    // deallocate must not throw according to the standard, but even if it does,
829
    // the buffer already uses the new storage and will deallocate it in
830
    // destructor.
831
33.3k
    if (old_data != self.store_) self.alloc_.deallocate(old_data, old_capacity);
832
33.3k
  }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<wchar_t, 500ul, fmt::v12::detail::allocator<wchar_t> >::grow(fmt::v12::detail::buffer<wchar_t>&, unsigned long)
833
834
 public:
835
  using value_type = T;
836
  using const_reference = const T&;
837
838
  FMT_CONSTEXPR explicit basic_memory_buffer(
839
      const Allocator& alloc = Allocator())
840
112k
      : detail::buffer<T>(grow), alloc_(alloc) {
841
112k
    this->set(store_, SIZE);
842
112k
    if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
843
112k
  }
fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >::basic_memory_buffer(fmt::v12::detail::allocator<char> const&)
Line
Count
Source
840
49.4k
      : detail::buffer<T>(grow), alloc_(alloc) {
841
49.4k
    this->set(store_, SIZE);
842
49.4k
    if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
843
49.4k
  }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 128ul, fmt::v12::detail::allocator<char> >::basic_memory_buffer(fmt::v12::detail::allocator<char> const&)
Unexecuted instantiation: fmt::v12::basic_memory_buffer<wchar_t, 500ul, fmt::v12::detail::allocator<wchar_t> >::basic_memory_buffer(fmt::v12::detail::allocator<wchar_t> const&)
fmt::v12::basic_memory_buffer<unsigned int, 32ul, fmt::v12::detail::allocator<unsigned int> >::basic_memory_buffer(fmt::v12::detail::allocator<unsigned int> const&)
Line
Count
Source
840
57.9k
      : detail::buffer<T>(grow), alloc_(alloc) {
841
57.9k
    this->set(store_, SIZE);
842
57.9k
    if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
843
57.9k
  }
fmt::v12::basic_memory_buffer<int, 500ul, fmt::v12::detail::allocator<int> >::basic_memory_buffer(fmt::v12::detail::allocator<int> const&)
Line
Count
Source
840
4.65k
      : detail::buffer<T>(grow), alloc_(alloc) {
841
4.65k
    this->set(store_, SIZE);
842
4.65k
    if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());
843
4.65k
  }
844
203k
  FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >::~basic_memory_buffer()
Line
Count
Source
844
49.4k
  FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 128ul, fmt::v12::detail::allocator<char> >::~basic_memory_buffer()
fmt::v12::basic_memory_buffer<unsigned int, 32ul, fmt::v12::detail::allocator<unsigned int> >::~basic_memory_buffer()
Line
Count
Source
844
149k
  FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
fmt::v12::basic_memory_buffer<int, 500ul, fmt::v12::detail::allocator<int> >::~basic_memory_buffer()
Line
Count
Source
844
4.65k
  FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<wchar_t, 500ul, fmt::v12::detail::allocator<wchar_t> >::~basic_memory_buffer()
845
846
 private:
847
  template <typename Alloc = Allocator,
848
            FMT_ENABLE_IF(std::allocator_traits<Alloc>::
849
                              propagate_on_container_move_assignment::value)>
850
  FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool {
851
    alloc_ = std::move(other.alloc_);
852
    return true;
853
  }
854
  // If the allocator does not propagate then copy the data from other.
855
  template <typename Alloc = Allocator,
856
            FMT_ENABLE_IF(!std::allocator_traits<Alloc>::
857
                              propagate_on_container_move_assignment::value)>
858
91.5k
  FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool {
859
91.5k
    T* data = other.data();
860
91.5k
    if (alloc_ == other.alloc_ || data == other.store_) return true;
861
0
    size_t size = other.size();
862
    // Perform copy operation, allocators are different.
863
0
    this->resize(size);
864
0
    detail::copy<T>(data, data + size, this->data());
865
0
    return false;
866
91.5k
  }
_ZN3fmt3v1219basic_memory_bufferIjLm32ENS0_6detail9allocatorIjEEE10move_allocIS4_TnNSt3__19enable_ifIXntsr3std16allocator_traitsIT_E38propagate_on_container_move_assignmentE5valueEiE4typeELi0EEEbRS5_
Line
Count
Source
858
91.5k
  FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool {
859
91.5k
    T* data = other.data();
860
91.5k
    if (alloc_ == other.alloc_ || data == other.store_) return true;
861
0
    size_t size = other.size();
862
    // Perform copy operation, allocators are different.
863
0
    this->resize(size);
864
0
    detail::copy<T>(data, data + size, this->data());
865
0
    return false;
866
91.5k
  }
Unexecuted instantiation: _ZN3fmt3v1219basic_memory_bufferIcLm500ENS0_6detail9allocatorIcEEE10move_allocIS4_TnNSt3__19enable_ifIXntsr3std16allocator_traitsIT_E38propagate_on_container_move_assignmentE5valueEiE4typeELi0EEEbRS5_
Unexecuted instantiation: _ZN3fmt3v1219basic_memory_bufferIcLm128ENS0_6detail9allocatorIcEEE10move_allocIS4_TnNSt3__19enable_ifIXntsr3std16allocator_traitsIT_E38propagate_on_container_move_assignmentE5valueEiE4typeELi0EEEbRS5_
Unexecuted instantiation: _ZN3fmt3v1219basic_memory_bufferIiLm500ENS0_6detail9allocatorIiEEE10move_allocIS4_TnNSt3__19enable_ifIXntsr3std16allocator_traitsIT_E38propagate_on_container_move_assignmentE5valueEiE4typeELi0EEEbRS5_
867
868
  // Move data from other to this buffer.
869
91.5k
  FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
870
91.5k
    T* data = other.data();
871
91.5k
    size_t size = other.size(), capacity = other.capacity();
872
91.5k
    if (!move_alloc(other)) return;
873
91.5k
    if (data == other.store_) {
874
76.6k
      this->set(store_, capacity);
875
76.6k
      detail::copy<T>(other.store_, other.store_ + size, store_);
876
76.6k
    } else {
877
14.9k
      this->set(data, capacity);
878
      // Set pointer to the inline array so that delete is not called
879
      // when deallocating.
880
14.9k
      other.set(other.store_, 0);
881
14.9k
      other.clear();
882
14.9k
    }
883
91.5k
    this->resize(size);
884
91.5k
  }
fmt::v12::basic_memory_buffer<unsigned int, 32ul, fmt::v12::detail::allocator<unsigned int> >::move(fmt::v12::basic_memory_buffer<unsigned int, 32ul, fmt::v12::detail::allocator<unsigned int> >&)
Line
Count
Source
869
91.5k
  FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
870
91.5k
    T* data = other.data();
871
91.5k
    size_t size = other.size(), capacity = other.capacity();
872
91.5k
    if (!move_alloc(other)) return;
873
91.5k
    if (data == other.store_) {
874
76.6k
      this->set(store_, capacity);
875
76.6k
      detail::copy<T>(other.store_, other.store_ + size, store_);
876
76.6k
    } else {
877
14.9k
      this->set(data, capacity);
878
      // Set pointer to the inline array so that delete is not called
879
      // when deallocating.
880
14.9k
      other.set(other.store_, 0);
881
14.9k
      other.clear();
882
14.9k
    }
883
91.5k
    this->resize(size);
884
91.5k
  }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >::move(fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >&)
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 128ul, fmt::v12::detail::allocator<char> >::move(fmt::v12::basic_memory_buffer<char, 128ul, fmt::v12::detail::allocator<char> >&)
Unexecuted instantiation: fmt::v12::basic_memory_buffer<int, 500ul, fmt::v12::detail::allocator<int> >::move(fmt::v12::basic_memory_buffer<int, 500ul, fmt::v12::detail::allocator<int> >&)
885
886
 public:
887
  /// Constructs a `basic_memory_buffer` object moving the content of the other
888
  /// object to it.
889
  FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) noexcept
890
91.5k
      : detail::buffer<T>(grow) {
891
91.5k
    move(other);
892
91.5k
  }
893
894
  /// Moves the content of the other `basic_memory_buffer` object to this one.
895
  auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& {
896
    FMT_ASSERT(this != &other, "");
897
    deallocate();
898
    move(other);
899
    return *this;
900
  }
901
902
  // Returns a copy of the allocator associated with this buffer.
903
  auto get_allocator() const -> Allocator { return alloc_; }
904
905
  /// Resizes the buffer to contain `count` elements. If T is a POD type new
906
  /// elements may not be initialized.
907
3.32M
  FMT_CONSTEXPR void resize(size_t count) { this->try_resize(count); }
fmt::v12::basic_memory_buffer<unsigned int, 32ul, fmt::v12::detail::allocator<unsigned int> >::resize(unsigned long)
Line
Count
Source
907
3.32M
  FMT_CONSTEXPR void resize(size_t count) { this->try_resize(count); }
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >::resize(unsigned long)
Unexecuted instantiation: fmt::v12::basic_memory_buffer<char, 128ul, fmt::v12::detail::allocator<char> >::resize(unsigned long)
Unexecuted instantiation: fmt::v12::basic_memory_buffer<int, 500ul, fmt::v12::detail::allocator<int> >::resize(unsigned long)
908
909
  /// Increases the buffer capacity to `new_capacity`.
910
  void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
911
912
  using detail::buffer<T>::append;
913
  template <typename ContiguousRange>
914
0
  FMT_CONSTEXPR20 void append(const ContiguousRange& range) {
915
0
    append(range.data(), range.data() + range.size());
916
0
  }
917
};
918
919
using memory_buffer = basic_memory_buffer<char>;
920
921
template <size_t SIZE>
922
FMT_NODISCARD auto to_string(const basic_memory_buffer<char, SIZE>& buf)
923
0
    -> std::string {
924
0
  auto size = buf.size();
925
0
  detail::assume(size < std::string().max_size());
926
0
  return {buf.data(), size};
927
0
}
928
929
// A writer to a buffered stream. It doesn't own the underlying stream.
930
class writer {
931
 private:
932
  detail::buffer<char>* buf_;
933
934
  // We cannot create a file buffer in advance because any write to a FILE may
935
  // invalidate it.
936
  FILE* file_;
937
938
 public:
939
0
  inline writer(FILE* f) : buf_(nullptr), file_(f) {}
940
0
  inline writer(detail::buffer<char>& buf) : buf_(&buf) {}
941
942
  /// Formats `args` according to specifications in `fmt` and writes the
943
  /// output to the file.
944
  template <typename... T> void print(format_string<T...> fmt, T&&... args) {
945
    if (buf_)
946
      fmt::format_to(appender(*buf_), fmt, std::forward<T>(args)...);
947
    else
948
      fmt::print(file_, fmt, std::forward<T>(args)...);
949
  }
950
};
951
952
class string_buffer {
953
 private:
954
  std::string str_;
955
  detail::container_buffer<std::string> buf_;
956
957
 public:
958
0
  inline string_buffer() : buf_(str_) {}
959
960
0
  inline operator writer() { return buf_; }
961
0
  inline auto str() -> std::string& { return str_; }
962
};
963
964
template <typename T, size_t SIZE, typename Allocator>
965
struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
966
};
967
968
// Suppress a misleading warning in older versions of clang.
969
FMT_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables")
970
971
/// An error reported from a formatting function.
972
class FMT_SO_VISIBILITY("default") format_error : public std::runtime_error {
973
 public:
974
  using std::runtime_error::runtime_error;
975
};
976
977
class loc_value;
978
979
FMT_END_EXPORT
980
namespace detail {
981
FMT_API auto write_console(int fd, string_view text) -> bool;
982
FMT_API void print(FILE*, string_view);
983
}  // namespace detail
984
985
namespace detail {
986
template <typename Char, size_t N> struct fixed_string {
987
  FMT_CONSTEXPR20 fixed_string(const Char (&s)[N]) {
988
    detail::copy<Char, const Char*, Char*>(static_cast<const Char*>(s), s + N,
989
                                           data);
990
  }
991
  Char data[N] = {};
992
};
993
994
// Converts a compile-time string to basic_string_view.
995
FMT_EXPORT template <typename Char, size_t N>
996
constexpr auto compile_string_to_view(const Char (&s)[N])
997
0
    -> basic_string_view<Char> {
998
  // Remove trailing NUL character if needed. Won't be present if this is used
999
  // with a raw character array (i.e. not defined as a string).
1000
0
  return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
1001
0
}
Unexecuted instantiation: fmt::v12::basic_string_view<char> fmt::v12::detail::compile_string_to_view<char, 8ul>(char const (&) [8ul])
Unexecuted instantiation: fmt::v12::basic_string_view<char> fmt::v12::detail::compile_string_to_view<char, 5ul>(char const (&) [5ul])
Unexecuted instantiation: fmt::v12::basic_string_view<char> fmt::v12::detail::compile_string_to_view<char, 21ul>(char const (&) [21ul])
Unexecuted instantiation: fmt::v12::basic_string_view<char> fmt::v12::detail::compile_string_to_view<char, 7ul>(char const (&) [7ul])
Unexecuted instantiation: fmt::v12::basic_string_view<char> fmt::v12::detail::compile_string_to_view<char, 4ul>(char const (&) [4ul])
Unexecuted instantiation: fmt::v12::basic_string_view<char> fmt::v12::detail::compile_string_to_view<char, 12ul>(char const (&) [12ul])
Unexecuted instantiation: fmt::v12::basic_string_view<char> fmt::v12::detail::compile_string_to_view<char, 14ul>(char const (&) [14ul])
1002
FMT_EXPORT template <typename Char>
1003
constexpr auto compile_string_to_view(basic_string_view<Char> s)
1004
    -> basic_string_view<Char> {
1005
  return s;
1006
}
1007
1008
// Returns true if value is negative, false otherwise.
1009
// Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
1010
template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
1011
14.0k
constexpr auto is_negative(T value) -> bool {
1012
14.0k
  return value < 0;
1013
14.0k
}
_ZN3fmt3v126detail11is_negativeIiTnNSt3__19enable_ifIXsr9is_signedIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
1011
7.12k
constexpr auto is_negative(T value) -> bool {
1012
7.12k
  return value < 0;
1013
7.12k
}
_ZN3fmt3v126detail11is_negativeIxTnNSt3__19enable_ifIXsr9is_signedIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
1011
6.88k
constexpr auto is_negative(T value) -> bool {
1012
6.88k
  return value < 0;
1013
6.88k
}
Unexecuted instantiation: _ZN3fmt3v126detail11is_negativeInTnNSt3__19enable_ifIXsr9is_signedIT_EE5valueEiE4typeELi0EEEbS5_
1014
template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
1015
8.42k
constexpr auto is_negative(T) -> bool {
1016
8.42k
  return false;
1017
8.42k
}
_ZN3fmt3v126detail11is_negativeIjTnNSt3__19enable_ifIXntsr9is_signedIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
1015
4.14k
constexpr auto is_negative(T) -> bool {
1016
4.14k
  return false;
1017
4.14k
}
_ZN3fmt3v126detail11is_negativeIyTnNSt3__19enable_ifIXntsr9is_signedIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
1015
3.87k
constexpr auto is_negative(T) -> bool {
1016
3.87k
  return false;
1017
3.87k
}
Unexecuted instantiation: _ZN3fmt3v126detail11is_negativeIoTnNSt3__19enable_ifIXntsr9is_signedIT_EE5valueEiE4typeELi0EEEbS5_
_ZN3fmt3v126detail11is_negativeIhTnNSt3__19enable_ifIXntsr9is_signedIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
1015
398
constexpr auto is_negative(T) -> bool {
1016
398
  return false;
1017
398
}
1018
1019
// Smallest of uint32_t, uint64_t, uint128_t that is large enough to
1020
// represent all values of an integral type T.
1021
template <typename T>
1022
using uint32_or_64_or_128_t =
1023
    conditional_t<num_bits<T>() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS,
1024
                  uint32_t,
1025
                  conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
1026
template <typename T>
1027
using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;
1028
1029
#define FMT_POWERS_OF_10(factor)                                  \
1030
225k
  factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \
1031
225k
      (factor) * 100000, (factor) * 1000000, (factor) * 10000000, \
1032
225k
      (factor) * 100000000, (factor) * 1000000000
1033
1034
// Converts value in the range [0, 100) to a string.
1035
// GCC generates slightly better code when value is pointer-size.
1036
482k
inline auto digits2(size_t value) -> const char* {
1037
  // Align data since unaligned access may be slower when crossing a
1038
  // hardware-specific boundary.
1039
482k
  alignas(2) static const char data[] =
1040
482k
      "0001020304050607080910111213141516171819"
1041
482k
      "2021222324252627282930313233343536373839"
1042
482k
      "4041424344454647484950515253545556575859"
1043
482k
      "6061626364656667686970717273747576777879"
1044
482k
      "8081828384858687888990919293949596979899";
1045
482k
  return &data[value * 2];
1046
482k
}
1047
1048
21.8k
template <typename Char> constexpr auto getsign(sign s) -> Char {
1049
21.8k
  return static_cast<char>(((' ' << 24) | ('+' << 16) | ('-' << 8)) >>
1050
21.8k
                           (static_cast<int>(s) * 8));
1051
21.8k
}
1052
1053
0
template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
1054
0
  int count = 1;
1055
0
  for (;;) {
1056
    // Integer division is slow so do it for a group of four digits instead
1057
    // of for every digit. The idea comes from the talk by Alexandrescu
1058
    // "Three Optimization Tips for C++". See speed-test for a comparison.
1059
0
    if (n < 10) return count;
1060
0
    if (n < 100) return count + 1;
1061
0
    if (n < 1000) return count + 2;
1062
0
    if (n < 10000) return count + 3;
1063
0
    n /= 10000u;
1064
0
    count += 4;
1065
0
  }
1066
0
}
Unexecuted instantiation: int fmt::v12::detail::count_digits_fallback<unsigned __int128>(unsigned __int128)
Unexecuted instantiation: int fmt::v12::detail::count_digits_fallback<unsigned long>(unsigned long)
Unexecuted instantiation: int fmt::v12::detail::count_digits_fallback<unsigned int>(unsigned int)
1067
#if FMT_USE_INT128
1068
0
FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int {
1069
0
  return count_digits_fallback(n);
1070
0
}
1071
#endif
1072
1073
#ifdef FMT_BUILTIN_CLZLL
1074
// It is a separate function rather than a part of count_digits to workaround
1075
// the lack of static constexpr in constexpr functions.
1076
112k
inline auto do_count_digits(uint64_t n) -> int {
1077
  // This has comparable performance to the version by Kendall Willets
1078
  // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)
1079
  // but uses smaller tables.
1080
  // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
1081
112k
  static constexpr uint8_t bsr2log10[] = {
1082
112k
      1,  1,  1,  2,  2,  2,  3,  3,  3,  4,  4,  4,  4,  5,  5,  5,
1083
112k
      6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9,  10, 10, 10,
1084
112k
      10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1085
112k
      15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1086
112k
  auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
1087
112k
  static constexpr uint64_t zero_or_powers_of_10[] = {
1088
112k
      0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
1089
112k
      10000000000000000000ULL};
1090
112k
  return t - (n < zero_or_powers_of_10[t]);
1091
112k
}
1092
#endif
1093
1094
// Returns the number of decimal digits in n. Leading zeros are not counted
1095
// except for n == 0 in which case count_digits returns 1.
1096
112k
FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {
1097
112k
#ifdef FMT_BUILTIN_CLZLL
1098
112k
  if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n);
1099
0
#endif
1100
0
  return count_digits_fallback(n);
1101
112k
}
1102
1103
// Counts the number of digits in n. BITS = log2(radix).
1104
template <int BITS, typename UInt>
1105
14.0k
FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1106
14.0k
#ifdef FMT_BUILTIN_CLZ
1107
14.0k
  if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1108
0
    return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1109
14.0k
#endif
1110
  // Lambda avoids unreachable code warnings from NVHPC.
1111
14.0k
  return [](UInt m) {
1112
14.0k
    int num_digits = 0;
1113
677k
    do {
1114
677k
      ++num_digits;
1115
677k
    } while ((m >>= BITS) != 0);
1116
14.0k
    return num_digits;
1117
14.0k
  }(n);
fmt::v12::detail::count_digits<1, unsigned __int128>(unsigned __int128)::{lambda(unsigned __int128)#1}::operator()(unsigned __int128) const
Line
Count
Source
1111
11.4k
  return [](UInt m) {
1112
11.4k
    int num_digits = 0;
1113
662k
    do {
1114
662k
      ++num_digits;
1115
662k
    } while ((m >>= BITS) != 0);
1116
11.4k
    return num_digits;
1117
11.4k
  }(n);
fmt::v12::detail::count_digits<4, unsigned long>(unsigned long)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Line
Count
Source
1111
903
  return [](UInt m) {
1112
903
    int num_digits = 0;
1113
2.57k
    do {
1114
2.57k
      ++num_digits;
1115
2.57k
    } while ((m >>= BITS) != 0);
1116
903
    return num_digits;
1117
903
  }(n);
fmt::v12::detail::count_digits<3, unsigned long>(unsigned long)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Line
Count
Source
1111
914
  return [](UInt m) {
1112
914
    int num_digits = 0;
1113
7.19k
    do {
1114
7.19k
      ++num_digits;
1115
7.19k
    } while ((m >>= BITS) != 0);
1116
914
    return num_digits;
1117
914
  }(n);
fmt::v12::detail::count_digits<1, unsigned long>(unsigned long)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Line
Count
Source
1111
812
  return [](UInt m) {
1112
812
    int num_digits = 0;
1113
5.10k
    do {
1114
5.10k
      ++num_digits;
1115
5.10k
    } while ((m >>= BITS) != 0);
1116
812
    return num_digits;
1117
812
  }(n);
Unexecuted instantiation: fmt::v12::detail::count_digits<4, unsigned __int128>(unsigned __int128)::{lambda(unsigned __int128)#1}::operator()(unsigned __int128) const
Unexecuted instantiation: fmt::v12::detail::count_digits<3, unsigned __int128>(unsigned __int128)::{lambda(unsigned __int128)#1}::operator()(unsigned __int128) const
1118
14.0k
}
int fmt::v12::detail::count_digits<1, unsigned __int128>(unsigned __int128)
Line
Count
Source
1105
11.4k
FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1106
11.4k
#ifdef FMT_BUILTIN_CLZ
1107
11.4k
  if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1108
0
    return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1109
11.4k
#endif
1110
  // Lambda avoids unreachable code warnings from NVHPC.
1111
11.4k
  return [](UInt m) {
1112
11.4k
    int num_digits = 0;
1113
11.4k
    do {
1114
11.4k
      ++num_digits;
1115
11.4k
    } while ((m >>= BITS) != 0);
1116
11.4k
    return num_digits;
1117
11.4k
  }(n);
1118
11.4k
}
int fmt::v12::detail::count_digits<4, unsigned long>(unsigned long)
Line
Count
Source
1105
903
FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1106
903
#ifdef FMT_BUILTIN_CLZ
1107
903
  if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1108
0
    return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1109
903
#endif
1110
  // Lambda avoids unreachable code warnings from NVHPC.
1111
903
  return [](UInt m) {
1112
903
    int num_digits = 0;
1113
903
    do {
1114
903
      ++num_digits;
1115
903
    } while ((m >>= BITS) != 0);
1116
903
    return num_digits;
1117
903
  }(n);
1118
903
}
int fmt::v12::detail::count_digits<3, unsigned long>(unsigned long)
Line
Count
Source
1105
914
FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1106
914
#ifdef FMT_BUILTIN_CLZ
1107
914
  if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1108
0
    return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1109
914
#endif
1110
  // Lambda avoids unreachable code warnings from NVHPC.
1111
914
  return [](UInt m) {
1112
914
    int num_digits = 0;
1113
914
    do {
1114
914
      ++num_digits;
1115
914
    } while ((m >>= BITS) != 0);
1116
914
    return num_digits;
1117
914
  }(n);
1118
914
}
int fmt::v12::detail::count_digits<1, unsigned long>(unsigned long)
Line
Count
Source
1105
812
FMT_CONSTEXPR auto count_digits(UInt n) -> int {
1106
812
#ifdef FMT_BUILTIN_CLZ
1107
812
  if (!is_constant_evaluated() && num_bits<UInt>() == 32)
1108
0
    return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
1109
812
#endif
1110
  // Lambda avoids unreachable code warnings from NVHPC.
1111
812
  return [](UInt m) {
1112
812
    int num_digits = 0;
1113
812
    do {
1114
812
      ++num_digits;
1115
812
    } while ((m >>= BITS) != 0);
1116
812
    return num_digits;
1117
812
  }(n);
1118
812
}
1119
1120
#ifdef FMT_BUILTIN_CLZ
1121
// It is a separate function rather than a part of count_digits to workaround
1122
// the lack of static constexpr in constexpr functions.
1123
39.9k
FMT_INLINE auto do_count_digits(uint32_t n) -> int {
1124
// An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
1125
// This increments the upper 32 bits (log10(T) - 1) when >= T is added.
1126
1.27M
#  define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)
1127
39.9k
  static constexpr uint64_t table[] = {
1128
39.9k
      FMT_INC(0),          FMT_INC(0),          FMT_INC(0),           // 8
1129
39.9k
      FMT_INC(10),         FMT_INC(10),         FMT_INC(10),          // 64
1130
39.9k
      FMT_INC(100),        FMT_INC(100),        FMT_INC(100),         // 512
1131
39.9k
      FMT_INC(1000),       FMT_INC(1000),       FMT_INC(1000),        // 4096
1132
39.9k
      FMT_INC(10000),      FMT_INC(10000),      FMT_INC(10000),       // 32k
1133
39.9k
      FMT_INC(100000),     FMT_INC(100000),     FMT_INC(100000),      // 256k
1134
39.9k
      FMT_INC(1000000),    FMT_INC(1000000),    FMT_INC(1000000),     // 2048k
1135
39.9k
      FMT_INC(10000000),   FMT_INC(10000000),   FMT_INC(10000000),    // 16M
1136
39.9k
      FMT_INC(100000000),  FMT_INC(100000000),  FMT_INC(100000000),   // 128M
1137
39.9k
      FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000),  // 1024M
1138
39.9k
      FMT_INC(1000000000), FMT_INC(1000000000)                        // 4B
1139
39.9k
  };
1140
39.9k
  auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
1141
39.9k
  return static_cast<int>((n + inc) >> 32);
1142
39.9k
}
1143
#endif
1144
1145
// Optional version of count_digits for better performance on 32-bit platforms.
1146
39.9k
FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {
1147
39.9k
#ifdef FMT_BUILTIN_CLZ
1148
39.9k
  if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n);
1149
0
#endif
1150
0
  return count_digits_fallback(n);
1151
39.9k
}
1152
1153
0
template <typename Int> constexpr auto digits10() noexcept -> int {
1154
0
  return std::numeric_limits<Int>::digits10;
1155
0
}
Unexecuted instantiation: int fmt::v12::detail::digits10<unsigned int>()
Unexecuted instantiation: int fmt::v12::detail::digits10<unsigned long>()
1156
0
template <> constexpr auto digits10<int128_opt>() noexcept -> int { return 38; }
1157
0
template <> constexpr auto digits10<uint128_t>() noexcept -> int { return 38; }
1158
1159
template <typename Char> struct thousands_sep_result {
1160
  std::string grouping;
1161
  Char thousands_sep;
1162
};
1163
1164
template <typename Char>
1165
FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>;
1166
template <typename Char>
1167
730
inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> {
1168
730
  auto result = thousands_sep_impl<char>(loc);
1169
730
  return {result.grouping, Char(result.thousands_sep)};
1170
730
}
1171
template <>
1172
0
inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<wchar_t> {
1173
0
  return thousands_sep_impl<wchar_t>(loc);
1174
0
}
1175
1176
template <typename Char>
1177
FMT_API auto decimal_point_impl(locale_ref loc) -> Char;
1178
786
template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1179
786
  return Char(decimal_point_impl<char>(loc));
1180
786
}
1181
0
template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1182
0
  return decimal_point_impl<wchar_t>(loc);
1183
0
}
1184
1185
#ifndef FMT_HEADER_ONLY
1186
FMT_BEGIN_EXPORT
1187
extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
1188
    -> thousands_sep_result<char>;
1189
extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
1190
    -> thousands_sep_result<wchar_t>;
1191
extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
1192
extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
1193
FMT_END_EXPORT
1194
#endif  // FMT_HEADER_ONLY
1195
1196
// Compares two characters for equality.
1197
template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1198
  return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1199
}
1200
2.03k
inline auto equal2(const char* lhs, const char* rhs) -> bool {
1201
2.03k
  return memcmp(lhs, rhs, 2) == 0;
1202
2.03k
}
1203
1204
// Writes a two-digit value to out.
1205
template <typename Char>
1206
330k
FMT_CONSTEXPR20 FMT_INLINE void write2digits(Char* out, size_t value) {
1207
330k
  if (!is_constant_evaluated() && std::is_same<Char, char>::value &&
1208
330k
      !FMT_OPTIMIZE_SIZE) {
1209
330k
    memcpy(out, digits2(value), 2);
1210
330k
    return;
1211
330k
  }
1212
0
  *out++ = static_cast<Char>('0' + value / 10);
1213
0
  *out = static_cast<Char>('0' + value % 10);
1214
0
}
1215
1216
// Formats a decimal unsigned integer value writing to out pointing to a buffer
1217
// of specified size. The caller must ensure that the buffer is large enough.
1218
template <typename Char, typename UInt>
1219
FMT_CONSTEXPR20 auto do_format_decimal(Char* out, UInt value, int size)
1220
79.3k
    -> Char* {
1221
79.3k
  FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1222
79.3k
  unsigned n = to_unsigned(size);
1223
310k
  while (value >= 100) {
1224
    // Integer division is slow so do it for a group of two digits instead
1225
    // of for every digit. The idea comes from the talk by Alexandrescu
1226
    // "Three Optimization Tips for C++". See speed-test for a comparison.
1227
231k
    n -= 2;
1228
231k
    write2digits(out + n, static_cast<unsigned>(value % 100));
1229
231k
    value /= 100;
1230
231k
  }
1231
79.3k
  if (value >= 10) {
1232
46.9k
    n -= 2;
1233
46.9k
    write2digits(out + n, static_cast<unsigned>(value));
1234
46.9k
  } else {
1235
32.4k
    out[--n] = static_cast<Char>('0' + value);
1236
32.4k
  }
1237
79.3k
  return out + n;
1238
79.3k
}
char* fmt::v12::detail::do_format_decimal<char, unsigned long>(char*, unsigned long, int)
Line
Count
Source
1220
57.9k
    -> Char* {
1221
57.9k
  FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1222
57.9k
  unsigned n = to_unsigned(size);
1223
259k
  while (value >= 100) {
1224
    // Integer division is slow so do it for a group of two digits instead
1225
    // of for every digit. The idea comes from the talk by Alexandrescu
1226
    // "Three Optimization Tips for C++". See speed-test for a comparison.
1227
201k
    n -= 2;
1228
201k
    write2digits(out + n, static_cast<unsigned>(value % 100));
1229
201k
    value /= 100;
1230
201k
  }
1231
57.9k
  if (value >= 10) {
1232
39.2k
    n -= 2;
1233
39.2k
    write2digits(out + n, static_cast<unsigned>(value));
1234
39.2k
  } else {
1235
18.6k
    out[--n] = static_cast<Char>('0' + value);
1236
18.6k
  }
1237
57.9k
  return out + n;
1238
57.9k
}
char* fmt::v12::detail::do_format_decimal<char, unsigned int>(char*, unsigned int, int)
Line
Count
Source
1220
21.3k
    -> Char* {
1221
21.3k
  FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1222
21.3k
  unsigned n = to_unsigned(size);
1223
50.7k
  while (value >= 100) {
1224
    // Integer division is slow so do it for a group of two digits instead
1225
    // of for every digit. The idea comes from the talk by Alexandrescu
1226
    // "Three Optimization Tips for C++". See speed-test for a comparison.
1227
29.3k
    n -= 2;
1228
29.3k
    write2digits(out + n, static_cast<unsigned>(value % 100));
1229
29.3k
    value /= 100;
1230
29.3k
  }
1231
21.3k
  if (value >= 10) {
1232
7.66k
    n -= 2;
1233
7.66k
    write2digits(out + n, static_cast<unsigned>(value));
1234
13.7k
  } else {
1235
13.7k
    out[--n] = static_cast<Char>('0' + value);
1236
13.7k
  }
1237
21.3k
  return out + n;
1238
21.3k
}
Unexecuted instantiation: char* fmt::v12::detail::do_format_decimal<char, unsigned __int128>(char*, unsigned __int128, int)
1239
1240
template <typename Char, typename UInt>
1241
FMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value,
1242
19.7k
                                             int num_digits) -> Char* {
1243
19.7k
  do_format_decimal(out, value, num_digits);
1244
19.7k
  return out + num_digits;
1245
19.7k
}
char* fmt::v12::detail::format_decimal<char, unsigned long>(char*, unsigned long, int)
Line
Count
Source
1242
10.1k
                                             int num_digits) -> Char* {
1243
10.1k
  do_format_decimal(out, value, num_digits);
1244
10.1k
  return out + num_digits;
1245
10.1k
}
char* fmt::v12::detail::format_decimal<char, unsigned int>(char*, unsigned int, int)
Line
Count
Source
1242
9.63k
                                             int num_digits) -> Char* {
1243
9.63k
  do_format_decimal(out, value, num_digits);
1244
9.63k
  return out + num_digits;
1245
9.63k
}
Unexecuted instantiation: char* fmt::v12::detail::format_decimal<char, unsigned __int128>(char*, unsigned __int128, int)
1246
1247
template <typename Char, typename UInt, typename OutputIt,
1248
          FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
1249
FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits)
1250
52.8k
    -> OutputIt {
1251
52.8k
  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1252
52.8k
    do_format_decimal(ptr, value, num_digits);
1253
52.8k
    return out;
1254
52.8k
  }
1255
  // Buffer is large enough to hold all digits (digits10 + 1).
1256
1
  char buffer[digits10<UInt>() + 1];
1257
1
  if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0');
1258
1
  do_format_decimal(buffer, value, num_digits);
1259
1
  return copy_noinline<Char>(buffer, buffer + num_digits, out);
1260
52.8k
}
_ZN3fmt3v126detail14format_decimalIcmNS0_14basic_appenderIcEETnNSt3__19enable_ifIXntsr3std10is_pointerINS5_9remove_cvINS5_16remove_referenceIT1_E4typeEE4typeEEE5valueEiE4typeELi0EEES9_S9_T0_i
Line
Count
Source
1250
44.3k
    -> OutputIt {
1251
44.3k
  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1252
44.3k
    do_format_decimal(ptr, value, num_digits);
1253
44.3k
    return out;
1254
44.3k
  }
1255
  // Buffer is large enough to hold all digits (digits10 + 1).
1256
1
  char buffer[digits10<UInt>() + 1];
1257
1
  if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0');
1258
1
  do_format_decimal(buffer, value, num_digits);
1259
1
  return copy_noinline<Char>(buffer, buffer + num_digits, out);
1260
44.3k
}
_ZN3fmt3v126detail14format_decimalIcjNS0_14basic_appenderIcEETnNSt3__19enable_ifIXntsr3std10is_pointerINS5_9remove_cvINS5_16remove_referenceIT1_E4typeEE4typeEEE5valueEiE4typeELi0EEES9_S9_T0_i
Line
Count
Source
1250
8.48k
    -> OutputIt {
1251
8.48k
  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1252
8.48k
    do_format_decimal(ptr, value, num_digits);
1253
8.48k
    return out;
1254
8.48k
  }
1255
  // Buffer is large enough to hold all digits (digits10 + 1).
1256
0
  char buffer[digits10<UInt>() + 1];
1257
0
  if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0');
1258
0
  do_format_decimal(buffer, value, num_digits);
1259
0
  return copy_noinline<Char>(buffer, buffer + num_digits, out);
1260
8.48k
}
Unexecuted instantiation: _ZN3fmt3v126detail14format_decimalIcoNS0_14basic_appenderIcEETnNSt3__19enable_ifIXntsr3std10is_pointerINS5_9remove_cvINS5_16remove_referenceIT1_E4typeEE4typeEEE5valueEiE4typeELi0EEES9_S9_T0_i
1261
1262
template <typename Char, typename UInt>
1263
FMT_CONSTEXPR auto do_format_base2e(int base_bits, Char* out, UInt value,
1264
12.6k
                                    int size, bool upper = false) -> Char* {
1265
12.6k
  out += size;
1266
156k
  do {
1267
156k
    const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1268
156k
    unsigned digit = static_cast<unsigned>(value & ((1u << base_bits) - 1));
1269
156k
    *--out = static_cast<Char>(base_bits < 4 ? static_cast<char>('0' + digit)
1270
156k
                                             : digits[digit]);
1271
156k
  } while ((value >>= base_bits) != 0);
1272
12.6k
  return out;
1273
12.6k
}
char* fmt::v12::detail::do_format_base2e<char, unsigned int>(int, char*, unsigned int, int, bool)
Line
Count
Source
1264
3.41k
                                    int size, bool upper = false) -> Char* {
1265
3.41k
  out += size;
1266
26.0k
  do {
1267
26.0k
    const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1268
26.0k
    unsigned digit = static_cast<unsigned>(value & ((1u << base_bits) - 1));
1269
26.0k
    *--out = static_cast<Char>(base_bits < 4 ? static_cast<char>('0' + digit)
1270
26.0k
                                             : digits[digit]);
1271
26.0k
  } while ((value >>= base_bits) != 0);
1272
3.41k
  return out;
1273
3.41k
}
char* fmt::v12::detail::do_format_base2e<char, unsigned __int128>(int, char*, unsigned __int128, int, bool)
Line
Count
Source
1264
1.71k
                                    int size, bool upper = false) -> Char* {
1265
1.71k
  out += size;
1266
20.8k
  do {
1267
20.8k
    const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1268
20.8k
    unsigned digit = static_cast<unsigned>(value & ((1u << base_bits) - 1));
1269
20.8k
    *--out = static_cast<Char>(base_bits < 4 ? static_cast<char>('0' + digit)
1270
20.8k
                                             : digits[digit]);
1271
20.8k
  } while ((value >>= base_bits) != 0);
1272
1.71k
  return out;
1273
1.71k
}
char* fmt::v12::detail::do_format_base2e<char, unsigned long>(int, char*, unsigned long, int, bool)
Line
Count
Source
1264
7.56k
                                    int size, bool upper = false) -> Char* {
1265
7.56k
  out += size;
1266
109k
  do {
1267
109k
    const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1268
109k
    unsigned digit = static_cast<unsigned>(value & ((1u << base_bits) - 1));
1269
109k
    *--out = static_cast<Char>(base_bits < 4 ? static_cast<char>('0' + digit)
1270
109k
                                             : digits[digit]);
1271
109k
  } while ((value >>= base_bits) != 0);
1272
7.56k
  return out;
1273
7.56k
}
1274
1275
// Formats an unsigned integer in the power of two base (binary, octal, hex).
1276
template <typename Char, typename UInt>
1277
FMT_CONSTEXPR auto format_base2e(int base_bits, Char* out, UInt value,
1278
7.36k
                                 int num_digits, bool upper = false) -> Char* {
1279
7.36k
  do_format_base2e(base_bits, out, value, num_digits, upper);
1280
7.36k
  return out + num_digits;
1281
7.36k
}
char* fmt::v12::detail::format_base2e<char, unsigned int>(int, char*, unsigned int, int, bool)
Line
Count
Source
1278
718
                                 int num_digits, bool upper = false) -> Char* {
1279
718
  do_format_base2e(base_bits, out, value, num_digits, upper);
1280
718
  return out + num_digits;
1281
718
}
char* fmt::v12::detail::format_base2e<char, unsigned __int128>(int, char*, unsigned __int128, int, bool)
Line
Count
Source
1278
1.71k
                                 int num_digits, bool upper = false) -> Char* {
1279
1.71k
  do_format_base2e(base_bits, out, value, num_digits, upper);
1280
1.71k
  return out + num_digits;
1281
1.71k
}
char* fmt::v12::detail::format_base2e<char, unsigned long>(int, char*, unsigned long, int, bool)
Line
Count
Source
1278
4.93k
                                 int num_digits, bool upper = false) -> Char* {
1279
4.93k
  do_format_base2e(base_bits, out, value, num_digits, upper);
1280
4.93k
  return out + num_digits;
1281
4.93k
}
1282
1283
template <typename Char, typename OutputIt, typename UInt,
1284
          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
1285
FMT_CONSTEXPR inline auto format_base2e(int base_bits, OutputIt out, UInt value,
1286
                                        int num_digits, bool upper = false)
1287
2.62k
    -> OutputIt {
1288
2.62k
  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1289
2.62k
    format_base2e(base_bits, ptr, value, num_digits, upper);
1290
2.62k
    return out;
1291
2.62k
  }
1292
  // Make buffer large enough for any base.
1293
0
  char buffer[num_bits<UInt>()];
1294
0
  if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0');
1295
0
  format_base2e(base_bits, buffer, value, num_digits, upper);
1296
0
  return detail::copy_noinline<Char>(buffer, buffer + num_digits, out);
1297
2.62k
}
_ZN3fmt3v126detail13format_base2eIcNS0_14basic_appenderIcEEmTnNSt3__19enable_ifIXsr23is_back_insert_iteratorIT0_EE5valueEiE4typeELi0EEES7_iS7_T1_ib
Line
Count
Source
1287
2.62k
    -> OutputIt {
1288
2.62k
  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1289
2.62k
    format_base2e(base_bits, ptr, value, num_digits, upper);
1290
2.62k
    return out;
1291
2.62k
  }
1292
  // Make buffer large enough for any base.
1293
0
  char buffer[num_bits<UInt>()];
1294
0
  if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0');
1295
0
  format_base2e(base_bits, buffer, value, num_digits, upper);
1296
0
  return detail::copy_noinline<Char>(buffer, buffer + num_digits, out);
1297
2.62k
}
Unexecuted instantiation: _ZN3fmt3v126detail13format_base2eIcNS0_14basic_appenderIcEEoTnNSt3__19enable_ifIXsr23is_back_insert_iteratorIT0_EE5valueEiE4typeELi0EEES7_iS7_T1_ib
1298
1299
// A converter from UTF-8 to UTF-16.
1300
class utf8_to_utf16 {
1301
 private:
1302
  basic_memory_buffer<wchar_t> buffer_;
1303
1304
 public:
1305
  FMT_API explicit utf8_to_utf16(string_view s);
1306
0
  inline operator basic_string_view<wchar_t>() const {
1307
0
    return {&buffer_[0], size()};
1308
0
  }
1309
0
  inline auto size() const -> size_t { return buffer_.size() - 1; }
1310
0
  inline auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1311
0
  inline auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1312
};
1313
1314
enum class to_utf8_error_policy { abort, replace, wtf };
1315
1316
0
inline void to_utf8_3bytes(buffer<char>& buf, uint32_t cp) {
1317
0
  buf.push_back(static_cast<char>(0xe0 | (cp >> 12)));
1318
0
  buf.push_back(static_cast<char>(0x80 | ((cp & 0xfff) >> 6)));
1319
0
  buf.push_back(static_cast<char>(0x80 | (cp & 0x3f)));
1320
0
}
1321
1322
// A converter from UTF-16/UTF-32 (host endian) to UTF-8.
1323
template <typename WChar, typename Buffer = memory_buffer> class to_utf8 {
1324
 private:
1325
  Buffer buffer_;
1326
1327
 public:
1328
0
  to_utf8() {}
1329
  explicit to_utf8(basic_string_view<WChar> s,
1330
                   to_utf8_error_policy policy = to_utf8_error_policy::abort) {
1331
    static_assert(sizeof(WChar) == 2 || sizeof(WChar) == 4,
1332
                  "expected utf16 or utf32");
1333
    if (!convert(s, policy)) {
1334
      FMT_THROW(std::runtime_error(sizeof(WChar) == 2 ? "invalid utf16"
1335
                                                      : "invalid utf32"));
1336
    }
1337
  }
1338
  operator string_view() const { return string_view(&buffer_[0], size()); }
1339
0
  auto size() const -> size_t { return buffer_.size() - 1; }
1340
0
  auto c_str() const -> const char* { return &buffer_[0]; }
1341
  auto str() const -> std::string { return std::string(&buffer_[0], size()); }
1342
1343
  // Performs conversion returning a bool instead of throwing exception on
1344
  // conversion error. This method may still throw in case of memory allocation
1345
  // error.
1346
  auto convert(basic_string_view<WChar> s,
1347
               to_utf8_error_policy policy = to_utf8_error_policy::abort)
1348
0
      -> bool {
1349
0
    if (!convert(buffer_, s, policy)) return false;
1350
0
    buffer_.push_back(0);
1351
0
    return true;
1352
0
  }
1353
  static auto convert(Buffer& buf, basic_string_view<WChar> s,
1354
                      to_utf8_error_policy policy = to_utf8_error_policy::abort)
1355
0
      -> bool {
1356
0
    for (auto p = s.begin(); p != s.end(); ++p) {
1357
0
      uint32_t c = static_cast<uint32_t>(*p);
1358
0
      if (sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) {
1359
        // Handle a surrogate pair.
1360
0
        ++p;
1361
0
        if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) {
1362
0
          switch (policy) {
1363
0
          case to_utf8_error_policy::abort:
1364
0
            return false;
1365
0
          case to_utf8_error_policy::replace:
1366
0
            buf.append(string_view("\xEF\xBF\xBD"));
1367
0
            break;
1368
0
          case to_utf8_error_policy::wtf:
1369
0
            to_utf8_3bytes(buf, c);
1370
0
            break;
1371
0
          }
1372
0
          --p;
1373
0
          continue;
1374
0
        }
1375
0
        c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00;
1376
0
      }
1377
0
      if (c < 0x80) {
1378
0
        buf.push_back(static_cast<char>(c));
1379
0
      } else if (c < 0x800) {
1380
0
        buf.push_back(static_cast<char>(0xc0 | (c >> 6)));
1381
0
        buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1382
0
      } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) {
1383
0
        to_utf8_3bytes(buf, c);
1384
0
      } else if (c >= 0x10000 && c <= 0x10ffff) {
1385
0
        buf.push_back(static_cast<char>(0xf0 | (c >> 18)));
1386
0
        buf.push_back(static_cast<char>(0x80 | ((c & 0x3ffff) >> 12)));
1387
0
        buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1388
0
        buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1389
0
      } else {
1390
0
        return false;
1391
0
      }
1392
0
    }
1393
0
    return true;
1394
0
  }
1395
};
1396
1397
// Computes 128-bit result of multiplication of two 64-bit unsigned integers.
1398
59.6k
FMT_INLINE auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback {
1399
59.6k
#if FMT_USE_INT128
1400
59.6k
  auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1401
59.6k
  return {static_cast<uint64_t>(p >> 64), static_cast<uint64_t>(p)};
1402
#elif defined(_MSC_VER) && defined(_M_X64)
1403
  auto hi = uint64_t();
1404
  auto lo = _umul128(x, y, &hi);
1405
  return {hi, lo};
1406
#else
1407
  const uint64_t mask = static_cast<uint64_t>(max_value<uint32_t>());
1408
1409
  uint64_t a = x >> 32;
1410
  uint64_t b = x & mask;
1411
  uint64_t c = y >> 32;
1412
  uint64_t d = y & mask;
1413
1414
  uint64_t ac = a * c;
1415
  uint64_t bc = b * c;
1416
  uint64_t ad = a * d;
1417
  uint64_t bd = b * d;
1418
1419
  uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask);
1420
1421
  return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
1422
          (intermediate << 32) + (bd & mask)};
1423
#endif
1424
59.6k
}
1425
1426
namespace dragonbox {
1427
// Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from
1428
// https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1.
1429
28.4k
inline auto floor_log10_pow2(int e) noexcept -> int {
1430
28.4k
  FMT_ASSERT(e <= 2620 && e >= -2620, "too large exponent");
1431
28.4k
  static_assert((-1 >> 1) == -1, "right shift is not arithmetic");
1432
28.4k
  return (e * 315653) >> 20;
1433
28.4k
}
1434
1435
72.3k
inline auto floor_log2_pow10(int e) noexcept -> int {
1436
72.3k
  FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent");
1437
72.3k
  return (e * 1741647) >> 19;
1438
72.3k
}
1439
1440
// Computes upper 64 bits of multiplication of two 64-bit unsigned integers.
1441
44.3k
inline auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t {
1442
44.3k
#if FMT_USE_INT128
1443
44.3k
  auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
1444
44.3k
  return static_cast<uint64_t>(p >> 64);
1445
#elif defined(_MSC_VER) && defined(_M_X64)
1446
  return __umulh(x, y);
1447
#else
1448
  return umul128(x, y).high();
1449
#endif
1450
44.3k
}
1451
1452
// Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a
1453
// 128-bit unsigned integer.
1454
inline auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept
1455
18.5k
    -> uint128_fallback {
1456
18.5k
  uint128_fallback r = umul128(x, y.high());
1457
18.5k
  r += umul128_upper64(x, y.low());
1458
18.5k
  return r;
1459
18.5k
}
1460
1461
FMT_API auto get_cached_power(int k) noexcept -> uint128_fallback;
1462
1463
// Type-specific information that Dragonbox uses.
1464
template <typename T, typename Enable = void> struct float_info;
1465
1466
template <> struct float_info<float> {
1467
  using carrier_uint = uint32_t;
1468
  static const int exponent_bits = 8;
1469
  static const int kappa = 1;
1470
  static const int big_divisor = 100;
1471
  static const int small_divisor = 10;
1472
  static const int min_k = -31;
1473
  static const int max_k = 46;
1474
  static const int shorter_interval_tie_lower_threshold = -35;
1475
  static const int shorter_interval_tie_upper_threshold = -35;
1476
};
1477
1478
template <> struct float_info<double> {
1479
  using carrier_uint = uint64_t;
1480
  static const int exponent_bits = 11;
1481
  static const int kappa = 2;
1482
  static const int big_divisor = 1000;
1483
  static const int small_divisor = 100;
1484
  static const int min_k = -292;
1485
  static const int max_k = 341;
1486
  static const int shorter_interval_tie_lower_threshold = -77;
1487
  static const int shorter_interval_tie_upper_threshold = -77;
1488
};
1489
1490
// An 80- or 128-bit floating point number.
1491
template <typename T>
1492
struct float_info<T, enable_if_t<std::numeric_limits<T>::digits == 64 ||
1493
                                 std::numeric_limits<T>::digits == 113 ||
1494
                                 is_float128<T>::value>> {
1495
  using carrier_uint = detail::uint128_t;
1496
  static const int exponent_bits = 15;
1497
};
1498
1499
// A double-double floating point number.
1500
template <typename T>
1501
struct float_info<T, enable_if_t<is_double_double<T>::value>> {
1502
  using carrier_uint = detail::uint128_t;
1503
};
1504
1505
template <typename T> struct decimal_fp {
1506
  using significand_type = typename float_info<T>::carrier_uint;
1507
  significand_type significand;
1508
  int exponent;
1509
};
1510
1511
template <typename T> FMT_API auto to_decimal(T x) noexcept -> decimal_fp<T>;
1512
}  // namespace dragonbox
1513
1514
// Returns true iff Float has the implicit bit which is not stored.
1515
0
template <typename Float> constexpr auto has_implicit_bit() -> bool {
1516
0
  // An 80-bit FP number has a 64-bit significand an no implicit bit.
1517
0
  return std::numeric_limits<Float>::digits != 64;
1518
0
}
Unexecuted instantiation: bool fmt::v12::detail::has_implicit_bit<double>()
Unexecuted instantiation: bool fmt::v12::detail::has_implicit_bit<float>()
Unexecuted instantiation: bool fmt::v12::detail::has_implicit_bit<long double>()
1519
1520
// Returns the number of significand bits stored in Float. The implicit bit is
1521
// not counted since it is not stored.
1522
189k
template <typename Float> constexpr auto num_significand_bits() -> int {
1523
  // std::numeric_limits may not support __float128.
1524
189k
  return is_float128<Float>() ? 112
1525
189k
                              : (std::numeric_limits<Float>::digits -
1526
189k
                                 (has_implicit_bit<Float>() ? 1 : 0));
1527
189k
}
int fmt::v12::detail::num_significand_bits<double>()
Line
Count
Source
1522
103k
template <typename Float> constexpr auto num_significand_bits() -> int {
1523
  // std::numeric_limits may not support __float128.
1524
103k
  return is_float128<Float>() ? 112
1525
103k
                              : (std::numeric_limits<Float>::digits -
1526
103k
                                 (has_implicit_bit<Float>() ? 1 : 0));
1527
103k
}
int fmt::v12::detail::num_significand_bits<float>()
Line
Count
Source
1522
61.0k
template <typename Float> constexpr auto num_significand_bits() -> int {
1523
  // std::numeric_limits may not support __float128.
1524
61.0k
  return is_float128<Float>() ? 112
1525
61.0k
                              : (std::numeric_limits<Float>::digits -
1526
61.0k
                                 (has_implicit_bit<Float>() ? 1 : 0));
1527
61.0k
}
int fmt::v12::detail::num_significand_bits<long double>()
Line
Count
Source
1522
24.6k
template <typename Float> constexpr auto num_significand_bits() -> int {
1523
  // std::numeric_limits may not support __float128.
1524
24.6k
  return is_float128<Float>() ? 112
1525
24.6k
                              : (std::numeric_limits<Float>::digits -
1526
24.6k
                                 (has_implicit_bit<Float>() ? 1 : 0));
1527
24.6k
}
1528
1529
template <typename Float>
1530
constexpr auto exponent_mask() ->
1531
77.6k
    typename dragonbox::float_info<Float>::carrier_uint {
1532
77.6k
  using float_uint = typename dragonbox::float_info<Float>::carrier_uint;
1533
77.6k
  return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1534
77.6k
         << num_significand_bits<Float>();
1535
77.6k
}
fmt::v12::detail::dragonbox::float_info<double, void>::carrier_uint fmt::v12::detail::exponent_mask<double>()
Line
Count
Source
1531
32.6k
    typename dragonbox::float_info<Float>::carrier_uint {
1532
32.6k
  using float_uint = typename dragonbox::float_info<Float>::carrier_uint;
1533
32.6k
  return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1534
32.6k
         << num_significand_bits<Float>();
1535
32.6k
}
fmt::v12::detail::dragonbox::float_info<float, void>::carrier_uint fmt::v12::detail::exponent_mask<float>()
Line
Count
Source
1531
20.4k
    typename dragonbox::float_info<Float>::carrier_uint {
1532
20.4k
  using float_uint = typename dragonbox::float_info<Float>::carrier_uint;
1533
20.4k
  return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1534
20.4k
         << num_significand_bits<Float>();
1535
20.4k
}
fmt::v12::detail::dragonbox::float_info<long double, void>::carrier_uint fmt::v12::detail::exponent_mask<long double>()
Line
Count
Source
1531
24.6k
    typename dragonbox::float_info<Float>::carrier_uint {
1532
24.6k
  using float_uint = typename dragonbox::float_info<Float>::carrier_uint;
1533
24.6k
  return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)
1534
24.6k
         << num_significand_bits<Float>();
1535
24.6k
}
1536
58.2k
template <typename Float> constexpr auto exponent_bias() -> int {
1537
  // std::numeric_limits may not support __float128.
1538
58.2k
  return is_float128<Float>() ? 16383
1539
58.2k
                              : std::numeric_limits<Float>::max_exponent - 1;
1540
58.2k
}
int fmt::v12::detail::exponent_bias<double>()
Line
Count
Source
1536
22.1k
template <typename Float> constexpr auto exponent_bias() -> int {
1537
  // std::numeric_limits may not support __float128.
1538
22.1k
  return is_float128<Float>() ? 16383
1539
22.1k
                              : std::numeric_limits<Float>::max_exponent - 1;
1540
22.1k
}
int fmt::v12::detail::exponent_bias<float>()
Line
Count
Source
1536
11.3k
template <typename Float> constexpr auto exponent_bias() -> int {
1537
  // std::numeric_limits may not support __float128.
1538
11.3k
  return is_float128<Float>() ? 16383
1539
11.3k
                              : std::numeric_limits<Float>::max_exponent - 1;
1540
11.3k
}
int fmt::v12::detail::exponent_bias<long double>()
Line
Count
Source
1536
24.6k
template <typename Float> constexpr auto exponent_bias() -> int {
1537
  // std::numeric_limits may not support __float128.
1538
24.6k
  return is_float128<Float>() ? 16383
1539
24.6k
                              : std::numeric_limits<Float>::max_exponent - 1;
1540
24.6k
}
1541
1542
15.8k
FMT_CONSTEXPR inline auto compute_exp_size(int exp) -> int {
1543
15.8k
  auto prefix_size = 2;  // sign + 'e'
1544
15.8k
  auto abs_exp = exp >= 0 ? exp : -exp;
1545
15.8k
  if (abs_exp < 100) return prefix_size + 2;
1546
8.82k
  return prefix_size + (abs_exp >= 1000 ? 4 : 3);
1547
15.8k
}
1548
1549
// Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1550
template <typename Char, typename OutputIt>
1551
15.5k
FMT_CONSTEXPR auto write_exponent(int exp, OutputIt out) -> OutputIt {
1552
15.5k
  FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1553
15.5k
  if (exp < 0) {
1554
9.82k
    *out++ = static_cast<Char>('-');
1555
9.82k
    exp = -exp;
1556
9.82k
  } else {
1557
5.71k
    *out++ = static_cast<Char>('+');
1558
5.71k
  }
1559
15.5k
  auto uexp = static_cast<uint32_t>(exp);
1560
15.5k
  if (is_constant_evaluated()) {
1561
0
    if (uexp < 10) *out++ = '0';
1562
0
    return format_decimal<Char>(out, uexp, count_digits(uexp));
1563
0
  }
1564
15.5k
  if (uexp >= 100u) {
1565
8.66k
    const char* top = digits2(uexp / 100);
1566
8.66k
    if (uexp >= 1000u) *out++ = static_cast<Char>(top[0]);
1567
8.66k
    *out++ = static_cast<Char>(top[1]);
1568
8.66k
    uexp %= 100;
1569
8.66k
  }
1570
15.5k
  const char* d = digits2(uexp);
1571
15.5k
  *out++ = static_cast<Char>(d[0]);
1572
15.5k
  *out++ = static_cast<Char>(d[1]);
1573
15.5k
  return out;
1574
15.5k
}
1575
1576
// A floating-point number f * pow(2, e) where F is an unsigned type.
1577
template <typename F> struct basic_fp {
1578
  F f;
1579
  int e;
1580
1581
  static constexpr int num_significand_bits =
1582
      static_cast<int>(sizeof(F) * num_bits<unsigned char>());
1583
1584
14.4k
  constexpr basic_fp() : f(0), e(0) {}
1585
  constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
1586
1587
  // Constructs fp from an IEEE754 floating-point number.
1588
15.4k
  template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
fmt::v12::detail::basic_fp<unsigned __int128>::basic_fp<long double>(long double)
Line
Count
Source
1588
13.1k
  template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
fmt::v12::detail::basic_fp<unsigned long>::basic_fp<double>(double)
Line
Count
Source
1588
2.30k
  template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }
1589
1590
  // Assigns n to this and return true iff predecessor is closer than successor.
1591
  template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
1592
29.9k
  FMT_CONSTEXPR auto assign(Float n) -> bool {
1593
29.9k
    static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1594
    // Assume Float is in the format [sign][exponent][significand].
1595
29.9k
    using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1596
29.9k
    const auto num_float_significand_bits =
1597
29.9k
        detail::num_significand_bits<Float>();
1598
29.9k
    const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1599
29.9k
    const auto significand_mask = implicit_bit - 1;
1600
29.9k
    auto u = bit_cast<carrier_uint>(n);
1601
29.9k
    f = static_cast<F>(u & significand_mask);
1602
29.9k
    auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1603
29.9k
                                     num_float_significand_bits);
1604
    // The predecessor is closer if n is a normalized power of 2 (f == 0)
1605
    // other than the smallest normalized number (biased_e > 1).
1606
29.9k
    auto is_predecessor_closer = f == 0 && biased_e > 1;
1607
29.9k
    if (biased_e == 0)
1608
5.60k
      biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
1609
24.3k
    else if (has_implicit_bit<Float>())
1610
4.52k
      f += static_cast<F>(implicit_bit);
1611
29.9k
    e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1612
29.9k
    if (!has_implicit_bit<Float>()) ++e;
1613
29.9k
    return is_predecessor_closer;
1614
29.9k
  }
_ZN3fmt3v126detail8basic_fpIoE6assignIfTnNSt3__19enable_ifIXntsr16is_double_doubleIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
1592
1.56k
  FMT_CONSTEXPR auto assign(Float n) -> bool {
1593
1.56k
    static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1594
    // Assume Float is in the format [sign][exponent][significand].
1595
1.56k
    using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1596
1.56k
    const auto num_float_significand_bits =
1597
1.56k
        detail::num_significand_bits<Float>();
1598
1.56k
    const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1599
1.56k
    const auto significand_mask = implicit_bit - 1;
1600
1.56k
    auto u = bit_cast<carrier_uint>(n);
1601
1.56k
    f = static_cast<F>(u & significand_mask);
1602
1.56k
    auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1603
1.56k
                                     num_float_significand_bits);
1604
    // The predecessor is closer if n is a normalized power of 2 (f == 0)
1605
    // other than the smallest normalized number (biased_e > 1).
1606
1.56k
    auto is_predecessor_closer = f == 0 && biased_e > 1;
1607
1.56k
    if (biased_e == 0)
1608
216
      biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
1609
1.35k
    else if (has_implicit_bit<Float>())
1610
1.35k
      f += static_cast<F>(implicit_bit);
1611
1.56k
    e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1612
1.56k
    if (!has_implicit_bit<Float>()) ++e;
1613
1.56k
    return is_predecessor_closer;
1614
1.56k
  }
_ZN3fmt3v126detail8basic_fpIoE6assignIeTnNSt3__19enable_ifIXntsr16is_double_doubleIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
1592
24.6k
  FMT_CONSTEXPR auto assign(Float n) -> bool {
1593
24.6k
    static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1594
    // Assume Float is in the format [sign][exponent][significand].
1595
24.6k
    using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1596
24.6k
    const auto num_float_significand_bits =
1597
24.6k
        detail::num_significand_bits<Float>();
1598
24.6k
    const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1599
24.6k
    const auto significand_mask = implicit_bit - 1;
1600
24.6k
    auto u = bit_cast<carrier_uint>(n);
1601
24.6k
    f = static_cast<F>(u & significand_mask);
1602
24.6k
    auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1603
24.6k
                                     num_float_significand_bits);
1604
    // The predecessor is closer if n is a normalized power of 2 (f == 0)
1605
    // other than the smallest normalized number (biased_e > 1).
1606
24.6k
    auto is_predecessor_closer = f == 0 && biased_e > 1;
1607
24.6k
    if (biased_e == 0)
1608
4.79k
      biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
1609
19.8k
    else if (has_implicit_bit<Float>())
1610
0
      f += static_cast<F>(implicit_bit);
1611
24.6k
    e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1612
24.6k
    if (!has_implicit_bit<Float>()) ++e;
1613
24.6k
    return is_predecessor_closer;
1614
24.6k
  }
_ZN3fmt3v126detail8basic_fpImE6assignIdTnNSt3__19enable_ifIXntsr16is_double_doubleIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
1592
2.30k
  FMT_CONSTEXPR auto assign(Float n) -> bool {
1593
2.30k
    static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1594
    // Assume Float is in the format [sign][exponent][significand].
1595
2.30k
    using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1596
2.30k
    const auto num_float_significand_bits =
1597
2.30k
        detail::num_significand_bits<Float>();
1598
2.30k
    const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1599
2.30k
    const auto significand_mask = implicit_bit - 1;
1600
2.30k
    auto u = bit_cast<carrier_uint>(n);
1601
2.30k
    f = static_cast<F>(u & significand_mask);
1602
2.30k
    auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1603
2.30k
                                     num_float_significand_bits);
1604
    // The predecessor is closer if n is a normalized power of 2 (f == 0)
1605
    // other than the smallest normalized number (biased_e > 1).
1606
2.30k
    auto is_predecessor_closer = f == 0 && biased_e > 1;
1607
2.30k
    if (biased_e == 0)
1608
361
      biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
1609
1.94k
    else if (has_implicit_bit<Float>())
1610
1.94k
      f += static_cast<F>(implicit_bit);
1611
2.30k
    e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1612
2.30k
    if (!has_implicit_bit<Float>()) ++e;
1613
2.30k
    return is_predecessor_closer;
1614
2.30k
  }
_ZN3fmt3v126detail8basic_fpIoE6assignIdTnNSt3__19enable_ifIXntsr16is_double_doubleIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
1592
1.46k
  FMT_CONSTEXPR auto assign(Float n) -> bool {
1593
1.46k
    static_assert(std::numeric_limits<Float>::digits <= 113, "unsupported FP");
1594
    // Assume Float is in the format [sign][exponent][significand].
1595
1.46k
    using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
1596
1.46k
    const auto num_float_significand_bits =
1597
1.46k
        detail::num_significand_bits<Float>();
1598
1.46k
    const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1599
1.46k
    const auto significand_mask = implicit_bit - 1;
1600
1.46k
    auto u = bit_cast<carrier_uint>(n);
1601
1.46k
    f = static_cast<F>(u & significand_mask);
1602
1.46k
    auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>
1603
1.46k
                                     num_float_significand_bits);
1604
    // The predecessor is closer if n is a normalized power of 2 (f == 0)
1605
    // other than the smallest normalized number (biased_e > 1).
1606
1.46k
    auto is_predecessor_closer = f == 0 && biased_e > 1;
1607
1.46k
    if (biased_e == 0)
1608
233
      biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).
1609
1.22k
    else if (has_implicit_bit<Float>())
1610
1.22k
      f += static_cast<F>(implicit_bit);
1611
1.46k
    e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1612
1.46k
    if (!has_implicit_bit<Float>()) ++e;
1613
1.46k
    return is_predecessor_closer;
1614
1.46k
  }
1615
1616
  template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
1617
  FMT_CONSTEXPR auto assign(Float n) -> bool {
1618
    static_assert(std::numeric_limits<double>::is_iec559, "unsupported FP");
1619
    return assign(static_cast<double>(n));
1620
  }
1621
};
1622
1623
using fp = basic_fp<unsigned long long>;
1624
1625
// Normalizes the value converted from double and multiplied by (1 << SHIFT).
1626
template <int SHIFT = 0, typename F>
1627
FMT_CONSTEXPR auto normalize(basic_fp<F> value) -> basic_fp<F> {
1628
  // Handle subnormals.
1629
  const auto implicit_bit = F(1) << num_significand_bits<double>();
1630
  const auto shifted_implicit_bit = implicit_bit << SHIFT;
1631
  while ((value.f & shifted_implicit_bit) == 0) {
1632
    value.f <<= 1;
1633
    --value.e;
1634
  }
1635
  // Subtract 1 to account for hidden bit.
1636
  const auto offset = basic_fp<F>::num_significand_bits -
1637
                      num_significand_bits<double>() - SHIFT - 1;
1638
  value.f <<= offset;
1639
  value.e -= offset;
1640
  return value;
1641
}
1642
1643
// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
1644
0
FMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t {
1645
0
#if FMT_USE_INT128
1646
0
  auto product = static_cast<__uint128_t>(lhs) * rhs;
1647
0
  auto f = static_cast<uint64_t>(product >> 64);
1648
0
  return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
1649
0
#else
1650
0
  // Multiply 32-bit parts of significands.
1651
0
  uint64_t mask = (1ULL << 32) - 1;
1652
0
  uint64_t a = lhs >> 32, b = lhs & mask;
1653
0
  uint64_t c = rhs >> 32, d = rhs & mask;
1654
0
  uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
1655
0
  // Compute mid 64-bit of result and round.
1656
0
  uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
1657
0
  return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1658
0
#endif
1659
0
}
1660
1661
0
FMT_CONSTEXPR inline auto operator*(fp x, fp y) -> fp {
1662
0
  return {multiply(x.f, y.f), x.e + y.e + 64};
1663
0
}
1664
1665
template <typename T, bool doublish = num_bits<T>() == num_bits<double>()>
1666
using convert_float_result =
1667
    conditional_t<std::is_same<T, float>::value || doublish, double, T>;
1668
1669
template <typename T>
1670
49.2k
constexpr auto convert_float(T value) -> convert_float_result<T> {
1671
49.2k
  return static_cast<convert_float_result<T>>(value);
1672
49.2k
}
_ZN3fmt3v126detail13convert_floatIeEENSt3__111conditionalIXoosr3std7is_sameIT_fEE5valueeqcl8num_bitsIS5_EEclL_ZNS1_8num_bitsIdEEivEEEdS5_E4typeES5_
Line
Count
Source
1670
27.4k
constexpr auto convert_float(T value) -> convert_float_result<T> {
1671
27.4k
  return static_cast<convert_float_result<T>>(value);
1672
27.4k
}
_ZN3fmt3v126detail13convert_floatIfEENSt3__111conditionalIXoosr3std7is_sameIT_fEE5valueeqcl8num_bitsIS5_EEclL_ZNS1_8num_bitsIdEEivEEEdS5_E4typeES5_
Line
Count
Source
1670
5.38k
constexpr auto convert_float(T value) -> convert_float_result<T> {
1671
5.38k
  return static_cast<convert_float_result<T>>(value);
1672
5.38k
}
_ZN3fmt3v126detail13convert_floatIdEENSt3__111conditionalIXoosr3std7is_sameIT_fEE5valueeqcl8num_bitsIS5_EEclL_ZNS1_8num_bitsIdEEivEEEdS5_E4typeES5_
Line
Count
Source
1670
16.3k
constexpr auto convert_float(T value) -> convert_float_result<T> {
1671
16.3k
  return static_cast<convert_float_result<T>>(value);
1672
16.3k
}
1673
1674
template <bool C, typename T, typename F, FMT_ENABLE_IF(C)>
1675
auto select(T true_value, F) -> T {
1676
  return true_value;
1677
}
1678
template <bool C, typename T, typename F, FMT_ENABLE_IF(!C)>
1679
5.91k
auto select(T, F false_value) -> F {
1680
5.91k
  return false_value;
1681
5.91k
}
1682
1683
template <typename Char, typename OutputIt>
1684
FMT_CONSTEXPR FMT_NOINLINE auto fill(OutputIt it, size_t n,
1685
16.1k
                                     const basic_specs& specs) -> OutputIt {
1686
16.1k
  auto fill_size = specs.fill_size();
1687
16.1k
  if (fill_size == 1) return detail::fill_n(it, n, specs.fill_unit<Char>());
1688
1.20k
  if (const Char* data = specs.fill<Char>()) {
1689
26.6k
    for (size_t i = 0; i < n; ++i) it = copy<Char>(data, data + fill_size, it);
1690
1.20k
  }
1691
1.20k
  return it;
1692
16.1k
}
1693
1694
// Writes the output of f, padded according to format specifications in specs.
1695
// size: output size in code units.
1696
// width: output display width in (terminal) column positions.
1697
template <typename Char, align default_align = align::left, typename OutputIt,
1698
          typename F>
1699
FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs& specs,
1700
58.2k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
58.2k
  static_assert(default_align == align::left || default_align == align::right,
1702
58.2k
                "");
1703
58.2k
  unsigned spec_width = to_unsigned(specs.width);
1704
58.2k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
58.2k
  auto* shifts =
1708
58.2k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
58.2k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
58.2k
  size_t right_padding = padding - left_padding;
1711
58.2k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
58.2k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
58.2k
  it = f(it);
1714
58.2k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
58.2k
  return base_iterator(out, it);
1716
58.2k
}
_ZN3fmt3v126detail12write_paddedIcLNS0_5alignE1ENS0_14basic_appenderIcEEZNS1_5writeIcS5_TnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SC_NS0_17basic_string_viewIS9_EERKNS0_12format_specsEEUlS5_E_EET1_SJ_SH_mmOT2_
Line
Count
Source
1700
1.92k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.92k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.92k
                "");
1703
1.92k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.92k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.92k
  auto* shifts =
1708
1.92k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.92k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.92k
  size_t right_padding = padding - left_padding;
1711
1.92k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.92k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.92k
  it = f(it);
1714
1.92k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.92k
  return base_iterator(out, it);
1716
1.92k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)1, fmt::v12::basic_appender<char>, fmt::v12::detail::write_char<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::detail::write_char<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_char<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
4.90k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
4.90k
  static_assert(default_align == align::left || default_align == align::right,
1702
4.90k
                "");
1703
4.90k
  unsigned spec_width = to_unsigned(specs.width);
1704
4.90k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
4.90k
  auto* shifts =
1708
4.90k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
4.90k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
4.90k
  size_t right_padding = padding - left_padding;
1711
4.90k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
4.90k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
4.90k
  it = f(it);
1714
4.90k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
4.90k
  return base_iterator(out, it);
1716
4.90k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned int>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned int>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.75k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.75k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.75k
                "");
1703
1.75k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.75k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.75k
  auto* shifts =
1708
1.75k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.75k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.75k
  size_t right_padding = padding - left_padding;
1711
1.75k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.75k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.75k
  it = f(it);
1714
1.75k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.75k
  return base_iterator(out, it);
1716
1.75k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)1, fmt::v12::basic_appender<char>, fmt::v12::detail::write_bytes<char, (fmt::v12::align)1, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_bytes<char, (fmt::v12::align)1, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.77k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.77k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.77k
                "");
1703
1.77k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.77k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.77k
  auto* shifts =
1708
1.77k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.77k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.77k
  size_t right_padding = padding - left_padding;
1711
1.77k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.77k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.77k
  it = f(it);
1714
1.77k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.77k
  return base_iterator(out, it);
1716
1.77k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)1, fmt::v12::basic_appender<char>, fmt::v12::detail::write_nonfinite<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, bool, fmt::v12::format_specs, fmt::v12::sign)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::detail::write_nonfinite<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, bool, fmt::v12::format_specs, fmt::v12::sign)::{lambda(fmt::v12::basic_appender<char>)#1}&, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_nonfinite<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, bool, fmt::v12::format_specs, fmt::v12::sign)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
6.00k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
6.00k
  static_assert(default_align == align::left || default_align == align::right,
1702
6.00k
                "");
1703
6.00k
  unsigned spec_width = to_unsigned(specs.width);
1704
6.00k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
6.00k
  auto* shifts =
1708
6.00k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
6.00k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
6.00k
  size_t right_padding = padding - left_padding;
1711
6.00k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
6.00k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
6.00k
  it = f(it);
1714
6.00k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
6.00k
  return base_iterator(out, it);
1716
6.00k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.02k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.02k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.02k
                "");
1703
1.02k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.02k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.02k
  auto* shifts =
1708
1.02k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.02k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.02k
  size_t right_padding = padding - left_padding;
1711
1.02k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.02k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.02k
  it = f(it);
1714
1.02k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.02k
  return base_iterator(out, it);
1716
1.02k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&)
Line
Count
Source
1700
754
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
754
  static_assert(default_align == align::left || default_align == align::right,
1702
754
                "");
1703
754
  unsigned spec_width = to_unsigned(specs.width);
1704
754
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
754
  auto* shifts =
1708
754
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
754
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
754
  size_t right_padding = padding - left_padding;
1711
754
  auto it = reserve(out, size + padding * specs.fill_size());
1712
754
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
754
  it = f(it);
1714
754
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
754
  return base_iterator(out, it);
1716
754
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&)
Line
Count
Source
1700
950
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
950
  static_assert(default_align == align::left || default_align == align::right,
1702
950
                "");
1703
950
  unsigned spec_width = to_unsigned(specs.width);
1704
950
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
950
  auto* shifts =
1708
950
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
950
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
950
  size_t right_padding = padding - left_padding;
1711
950
  auto it = reserve(out, size + padding * specs.fill_size());
1712
950
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
950
  it = f(it);
1714
950
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
950
  return base_iterator(out, it);
1716
950
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.06k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.06k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.06k
                "");
1703
1.06k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.06k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.06k
  auto* shifts =
1708
1.06k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.06k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.06k
  size_t right_padding = padding - left_padding;
1711
1.06k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.06k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.06k
  it = f(it);
1714
1.06k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.06k
  return base_iterator(out, it);
1716
1.06k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&)
Line
Count
Source
1700
1.03k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.03k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.03k
                "");
1703
1.03k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.03k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.03k
  auto* shifts =
1708
1.03k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.03k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.03k
  size_t right_padding = padding - left_padding;
1711
1.03k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.03k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.03k
  it = f(it);
1714
1.03k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.03k
  return base_iterator(out, it);
1716
1.03k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&)
Line
Count
Source
1700
1.22k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.22k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.22k
                "");
1703
1.22k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.22k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.22k
  auto* shifts =
1708
1.22k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.22k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.22k
  size_t right_padding = padding - left_padding;
1711
1.22k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.22k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.22k
  it = f(it);
1714
1.22k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.22k
  return base_iterator(out, it);
1716
1.22k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_bytes<char, (fmt::v12::align)2, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_bytes<char, (fmt::v12::align)2, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
3.94k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
3.94k
  static_assert(default_align == align::left || default_align == align::right,
1702
3.94k
                "");
1703
3.94k
  unsigned spec_width = to_unsigned(specs.width);
1704
3.94k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
3.94k
  auto* shifts =
1708
3.94k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
3.94k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
3.94k
  size_t right_padding = padding - left_padding;
1711
3.94k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
3.94k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
3.94k
  it = f(it);
1714
3.94k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
3.94k
  return base_iterator(out, it);
1716
3.94k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
3.02k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
3.02k
  static_assert(default_align == align::left || default_align == align::right,
1702
3.02k
                "");
1703
3.02k
  unsigned spec_width = to_unsigned(specs.width);
1704
3.02k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
3.02k
  auto* shifts =
1708
3.02k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
3.02k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
3.02k
  size_t right_padding = padding - left_padding;
1711
3.02k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
3.02k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
3.02k
  it = f(it);
1714
3.02k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
3.02k
  return base_iterator(out, it);
1716
3.02k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&)
Line
Count
Source
1700
5.80k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
5.80k
  static_assert(default_align == align::left || default_align == align::right,
1702
5.80k
                "");
1703
5.80k
  unsigned spec_width = to_unsigned(specs.width);
1704
5.80k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
5.80k
  auto* shifts =
1708
5.80k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
5.80k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
5.80k
  size_t right_padding = padding - left_padding;
1711
5.80k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
5.80k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
5.80k
  it = f(it);
1714
5.80k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
5.80k
  return base_iterator(out, it);
1716
5.80k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&)
Line
Count
Source
1700
3.93k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
3.93k
  static_assert(default_align == align::left || default_align == align::right,
1702
3.93k
                "");
1703
3.93k
  unsigned spec_width = to_unsigned(specs.width);
1704
3.93k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
3.93k
  auto* shifts =
1708
3.93k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
3.93k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
3.93k
  size_t right_padding = padding - left_padding;
1711
3.93k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
3.93k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
3.93k
  it = f(it);
1714
3.93k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
3.93k
  return base_iterator(out, it);
1716
3.93k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.32k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.32k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.32k
                "");
1703
1.32k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.32k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.32k
  auto* shifts =
1708
1.32k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.32k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.32k
  size_t right_padding = padding - left_padding;
1711
1.32k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.32k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.32k
  it = f(it);
1714
1.32k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.32k
  return base_iterator(out, it);
1716
1.32k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_ptr<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, unsigned long, fmt::v12::format_specs const*)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_ptr<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, unsigned long, fmt::v12::format_specs const*)::{lambda(fmt::v12::basic_appender<char>)#1}&)
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned long>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned long>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
2.45k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
2.45k
  static_assert(default_align == align::left || default_align == align::right,
1702
2.45k
                "");
1703
2.45k
  unsigned spec_width = to_unsigned(specs.width);
1704
2.45k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
2.45k
  auto* shifts =
1708
2.45k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
2.45k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
2.45k
  size_t right_padding = padding - left_padding;
1711
2.45k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
2.45k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
2.45k
  it = f(it);
1714
2.45k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
2.45k
  return base_iterator(out, it);
1716
2.45k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned __int128>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned __int128>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned __int128>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned __int128>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&)
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.47k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.47k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.47k
                "");
1703
1.47k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.47k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.47k
  auto* shifts =
1708
1.47k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.47k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.47k
  size_t right_padding = padding - left_padding;
1711
1.47k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.47k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.47k
  it = f(it);
1714
1.47k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.47k
  return base_iterator(out, it);
1716
1.47k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&)
Line
Count
Source
1700
1.39k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.39k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.39k
                "");
1703
1.39k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.39k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.39k
  auto* shifts =
1708
1.39k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.39k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.39k
  size_t right_padding = padding - left_padding;
1711
1.39k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.39k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.39k
  it = f(it);
1714
1.39k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.39k
  return base_iterator(out, it);
1716
1.39k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&)
Line
Count
Source
1700
1.19k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.19k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.19k
                "");
1703
1.19k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.19k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.19k
  auto* shifts =
1708
1.19k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.19k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.19k
  size_t right_padding = padding - left_padding;
1711
1.19k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.19k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.19k
  it = f(it);
1714
1.19k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.19k
  return base_iterator(out, it);
1716
1.19k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.48k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.48k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.48k
                "");
1703
1.48k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.48k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.48k
  auto* shifts =
1708
1.48k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.48k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.48k
  size_t right_padding = padding - left_padding;
1711
1.48k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.48k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.48k
  it = f(it);
1714
1.48k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.48k
  return base_iterator(out, it);
1716
1.48k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.41k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.41k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.41k
                "");
1703
1.41k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.41k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.41k
  auto* shifts =
1708
1.41k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.41k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.41k
  size_t right_padding = padding - left_padding;
1711
1.41k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.41k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.41k
  it = f(it);
1714
1.41k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.41k
  return base_iterator(out, it);
1716
1.41k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&)
Line
Count
Source
1700
1.37k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.37k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.37k
                "");
1703
1.37k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.37k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.37k
  auto* shifts =
1708
1.37k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.37k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.37k
  size_t right_padding = padding - left_padding;
1711
1.37k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.37k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.37k
  it = f(it);
1714
1.37k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.37k
  return base_iterator(out, it);
1716
1.37k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&)
Line
Count
Source
1700
1.18k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.18k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.18k
                "");
1703
1.18k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.18k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.18k
  auto* shifts =
1708
1.18k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.18k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.18k
  size_t right_padding = padding - left_padding;
1711
1.18k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.18k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.18k
  it = f(it);
1714
1.18k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.18k
  return base_iterator(out, it);
1716
1.18k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1700
1.19k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
1.19k
  static_assert(default_align == align::left || default_align == align::right,
1702
1.19k
                "");
1703
1.19k
  unsigned spec_width = to_unsigned(specs.width);
1704
1.19k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
1.19k
  auto* shifts =
1708
1.19k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
1.19k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
1.19k
  size_t right_padding = padding - left_padding;
1711
1.19k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
1.19k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
1.19k
  it = f(it);
1714
1.19k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
1.19k
  return base_iterator(out, it);
1716
1.19k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned long, char>(fmt::v12::basic_appender<char>, unsigned long, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned long, char>(fmt::v12::basic_appender<char>, unsigned long, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1700
4.68k
                                size_t size, size_t width, F&& f) -> OutputIt {
1701
4.68k
  static_assert(default_align == align::left || default_align == align::right,
1702
4.68k
                "");
1703
4.68k
  unsigned spec_width = to_unsigned(specs.width);
1704
4.68k
  size_t padding = spec_width > width ? spec_width - width : 0;
1705
  // Shifts are encoded as string literals because static constexpr is not
1706
  // supported in constexpr functions.
1707
4.68k
  auto* shifts =
1708
4.68k
      default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
1709
4.68k
  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];
1710
4.68k
  size_t right_padding = padding - left_padding;
1711
4.68k
  auto it = reserve(out, size + padding * specs.fill_size());
1712
4.68k
  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);
1713
4.68k
  it = f(it);
1714
4.68k
  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);
1715
4.68k
  return base_iterator(out, it);
1716
4.68k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned __int128, char>(fmt::v12::basic_appender<char>, unsigned __int128, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned __int128, char>(fmt::v12::basic_appender<char>, unsigned __int128, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
1717
1718
template <typename Char, align default_align = align::left, typename OutputIt,
1719
          typename F>
1720
constexpr auto write_padded(OutputIt out, const format_specs& specs,
1721
51.6k
                            size_t size, F&& f) -> OutputIt {
1722
51.6k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
51.6k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)1, fmt::v12::basic_appender<char>, fmt::v12::detail::write_char<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::detail::write_char<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_char<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
4.90k
                            size_t size, F&& f) -> OutputIt {
1722
4.90k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
4.90k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned int>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned int>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
1.75k
                            size_t size, F&& f) -> OutputIt {
1722
1.75k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.75k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)1, fmt::v12::basic_appender<char>, fmt::v12::detail::write_bytes<char, (fmt::v12::align)1, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_bytes<char, (fmt::v12::align)1, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
1.77k
                            size_t size, F&& f) -> OutputIt {
1722
1.77k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.77k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)1, fmt::v12::basic_appender<char>, fmt::v12::detail::write_nonfinite<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, bool, fmt::v12::format_specs, fmt::v12::sign)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::detail::write_nonfinite<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, bool, fmt::v12::format_specs, fmt::v12::sign)::{lambda(fmt::v12::basic_appender<char>)#1}, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_nonfinite<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, bool, fmt::v12::format_specs, fmt::v12::sign)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
6.00k
                            size_t size, F&& f) -> OutputIt {
1722
6.00k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
6.00k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
1.02k
                            size_t size, F&& f) -> OutputIt {
1722
1.02k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.02k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&&)
Line
Count
Source
1721
754
                            size_t size, F&& f) -> OutputIt {
1722
754
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
754
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&&)
Line
Count
Source
1721
950
                            size_t size, F&& f) -> OutputIt {
1722
950
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
950
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
1.06k
                            size_t size, F&& f) -> OutputIt {
1722
1.06k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.06k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&&)
Line
Count
Source
1721
1.03k
                            size_t size, F&& f) -> OutputIt {
1722
1.03k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.03k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&&)
Line
Count
Source
1721
1.22k
                            size_t size, F&& f) -> OutputIt {
1722
1.22k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.22k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_bytes<char, (fmt::v12::align)2, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_bytes<char, (fmt::v12::align)2, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
3.94k
                            size_t size, F&& f) -> OutputIt {
1722
3.94k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
3.94k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
3.02k
                            size_t size, F&& f) -> OutputIt {
1722
3.02k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
3.02k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&&)
Line
Count
Source
1721
5.80k
                            size_t size, F&& f) -> OutputIt {
1722
5.80k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
5.80k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&&)
Line
Count
Source
1721
3.93k
                            size_t size, F&& f) -> OutputIt {
1722
3.93k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
3.93k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1721
1.32k
                            size_t size, F&& f) -> OutputIt {
1722
1.32k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.32k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_ptr<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, unsigned long, fmt::v12::format_specs const*)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_ptr<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, unsigned long, fmt::v12::format_specs const*)::{lambda(fmt::v12::basic_appender<char>)#1}&)
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned long>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned long>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
2.45k
                            size_t size, F&& f) -> OutputIt {
1722
2.45k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
2.45k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned __int128>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned __int128>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned __int128>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned __int128>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
1.47k
                            size_t size, F&& f) -> OutputIt {
1722
1.47k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.47k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&&)
Line
Count
Source
1721
1.39k
                            size_t size, F&& f) -> OutputIt {
1722
1.39k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.39k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&&)
Line
Count
Source
1721
1.19k
                            size_t size, F&& f) -> OutputIt {
1722
1.19k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.19k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1721
1.48k
                            size_t size, F&& f) -> OutputIt {
1722
1.48k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.48k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Line
Count
Source
1721
1.41k
                            size_t size, F&& f) -> OutputIt {
1722
1.41k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.41k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&&)
Line
Count
Source
1721
1.37k
                            size_t size, F&& f) -> OutputIt {
1722
1.37k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.37k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&&)
Line
Count
Source
1721
1.18k
                            size_t size, F&& f) -> OutputIt {
1722
1.18k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.18k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Line
Count
Source
1721
1.19k
                            size_t size, F&& f) -> OutputIt {
1722
1.19k
  return write_padded<Char, default_align>(out, specs, size, size, f);
1723
1.19k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}&&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}&&)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_padded<char, (fmt::v12::align)2, fmt::v12::basic_appender<char>, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&>(fmt::v12::basic_appender<char>, fmt::v12::format_specs const&, unsigned long, fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}&)
1724
1725
template <typename Char, align default_align = align::left, typename OutputIt>
1726
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,
1727
5.72k
                               const format_specs& specs = {}) -> OutputIt {
1728
5.72k
  return write_padded<Char, default_align>(
1729
5.72k
      out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1730
5.61k
        const char* data = bytes.data();
1731
5.61k
        return copy<Char>(data, data + bytes.size(), it);
1732
5.61k
      });
fmt::v12::detail::write_bytes<char, (fmt::v12::align)1, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
1729
1.73k
      out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1730
1.73k
        const char* data = bytes.data();
1731
1.73k
        return copy<Char>(data, data + bytes.size(), it);
1732
1.73k
      });
fmt::v12::detail::write_bytes<char, (fmt::v12::align)2, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
1729
3.87k
      out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1730
3.87k
        const char* data = bytes.data();
1731
3.87k
        return copy<Char>(data, data + bytes.size(), it);
1732
3.87k
      });
1733
5.72k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_bytes<char, (fmt::v12::align)1, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)
Line
Count
Source
1727
1.77k
                               const format_specs& specs = {}) -> OutputIt {
1728
1.77k
  return write_padded<Char, default_align>(
1729
1.77k
      out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1730
1.77k
        const char* data = bytes.data();
1731
1.77k
        return copy<Char>(data, data + bytes.size(), it);
1732
1.77k
      });
1733
1.77k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_bytes<char, (fmt::v12::align)2, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>, fmt::v12::format_specs const&)
Line
Count
Source
1727
3.94k
                               const format_specs& specs = {}) -> OutputIt {
1728
3.94k
  return write_padded<Char, default_align>(
1729
3.94k
      out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1730
3.94k
        const char* data = bytes.data();
1731
3.94k
        return copy<Char>(data, data + bytes.size(), it);
1732
3.94k
      });
1733
3.94k
}
1734
1735
template <typename Char, typename OutputIt, typename UIntPtr>
1736
auto write_ptr(OutputIt out, UIntPtr value, const format_specs* specs)
1737
0
    -> OutputIt {
1738
0
  int num_digits = count_digits<4>(value);
1739
0
  auto size = to_unsigned(num_digits) + size_t(2);
1740
0
  auto write = [=](reserve_iterator<OutputIt> it) {
1741
0
    *it++ = static_cast<Char>('0');
1742
0
    *it++ = static_cast<Char>('x');
1743
0
    return format_base2e<Char>(4, it, value, num_digits);
1744
0
  };
1745
0
  return specs ? write_padded<Char, align::right>(out, *specs, size, write)
1746
0
               : base_iterator(out, write(reserve(out, size)));
1747
0
}
1748
1749
// Returns true iff the code point cp is printable.
1750
FMT_API auto is_printable(uint32_t cp) -> bool;
1751
1752
2.82k
inline auto needs_escape(uint32_t cp) -> bool {
1753
2.82k
  if (cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\') return true;
1754
1.28k
  if (const_check(FMT_OPTIMIZE_SIZE > 1)) return false;
1755
1.28k
  return !is_printable(cp);
1756
1.28k
}
1757
1758
template <typename Char> struct find_escape_result {
1759
  const Char* begin;
1760
  const Char* end;
1761
  uint32_t cp;
1762
};
1763
1764
template <typename Char>
1765
auto find_escape(const Char* begin, const Char* end)
1766
0
    -> find_escape_result<Char> {
1767
0
  for (; begin != end; ++begin) {
1768
0
    uint32_t cp = static_cast<unsigned_char<Char>>(*begin);
1769
0
    if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue;
1770
0
    if (needs_escape(cp)) return {begin, begin + 1, cp};
1771
0
  }
1772
0
  return {begin, nullptr, 0};
1773
0
}
1774
1775
inline auto find_escape(const char* begin, const char* end)
1776
0
    -> find_escape_result<char> {
1777
0
  if (const_check(!use_utf8)) return find_escape<char>(begin, end);
1778
0
  auto result = find_escape_result<char>{end, nullptr, 0};
1779
0
  for_each_codepoint(string_view(begin, to_unsigned(end - begin)),
1780
0
                     [&](uint32_t cp, string_view sv) {
1781
0
                       if (needs_escape(cp)) {
1782
0
                         result = {sv.begin(), sv.end(), cp};
1783
0
                         return false;
1784
0
                       }
1785
0
                       return true;
1786
0
                     });
1787
0
  return result;
1788
0
}
1789
1790
template <size_t width, typename Char, typename OutputIt>
1791
718
auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {
1792
718
  *out++ = static_cast<Char>('\\');
1793
718
  *out++ = static_cast<Char>(prefix);
1794
718
  Char buf[width];
1795
718
  fill_n(buf, width, static_cast<Char>('0'));
1796
718
  format_base2e(4, buf, cp, width);
1797
718
  return copy<Char>(buf, buf + width, out);
1798
718
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_codepoint<2ul, char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, unsigned int)
Line
Count
Source
1791
718
auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {
1792
718
  *out++ = static_cast<Char>('\\');
1793
718
  *out++ = static_cast<Char>(prefix);
1794
718
  Char buf[width];
1795
718
  fill_n(buf, width, static_cast<Char>('0'));
1796
718
  format_base2e(4, buf, cp, width);
1797
718
  return copy<Char>(buf, buf + width, out);
1798
718
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_codepoint<4ul, char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, unsigned int)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_codepoint<8ul, char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, char, unsigned int)
Unexecuted instantiation: _ZN3fmt3v126detail15write_codepointILm2EcZNS1_5writeIcNS0_14basic_appenderIcEETnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SB_NS0_17basic_string_viewIS8_EERKNS0_12format_specsEE23bounded_output_iteratorEET1_SI_cj
Unexecuted instantiation: _ZN3fmt3v126detail15write_codepointILm4EcZNS1_5writeIcNS0_14basic_appenderIcEETnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SB_NS0_17basic_string_viewIS8_EERKNS0_12format_specsEE23bounded_output_iteratorEET1_SI_cj
Unexecuted instantiation: _ZN3fmt3v126detail15write_codepointILm8EcZNS1_5writeIcNS0_14basic_appenderIcEETnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SB_NS0_17basic_string_viewIS8_EERKNS0_12format_specsEE23bounded_output_iteratorEET1_SI_cj
1799
1800
template <typename OutputIt, typename Char>
1801
auto write_escaped_cp(OutputIt out, const find_escape_result<Char>& escape)
1802
2.10k
    -> OutputIt {
1803
2.10k
  auto c = static_cast<Char>(escape.cp);
1804
2.10k
  switch (escape.cp) {
1805
258
  case '\n':
1806
258
    *out++ = static_cast<Char>('\\');
1807
258
    c = static_cast<Char>('n');
1808
258
    break;
1809
238
  case '\r':
1810
238
    *out++ = static_cast<Char>('\\');
1811
238
    c = static_cast<Char>('r');
1812
238
    break;
1813
234
  case '\t':
1814
234
    *out++ = static_cast<Char>('\\');
1815
234
    c = static_cast<Char>('t');
1816
234
    break;
1817
0
  case '"':  FMT_FALLTHROUGH;
1818
402
  case '\'': FMT_FALLTHROUGH;
1819
660
  case '\\': *out++ = static_cast<Char>('\\'); break;
1820
718
  default:
1821
718
    if (escape.cp < 0x100) return write_codepoint<2, Char>(out, 'x', escape.cp);
1822
358
    if (escape.cp < 0x10000)
1823
0
      return write_codepoint<4, Char>(out, 'u', escape.cp);
1824
358
    if (escape.cp < 0x110000)
1825
0
      return write_codepoint<8, Char>(out, 'U', escape.cp);
1826
358
    for (Char escape_char : basic_string_view<Char>(
1827
358
             escape.begin, to_unsigned(escape.end - escape.begin))) {
1828
358
      out = write_codepoint<2, Char>(out, 'x',
1829
358
                                     static_cast<uint32_t>(escape_char) & 0xFF);
1830
358
    }
1831
358
    return out;
1832
2.10k
  }
1833
1.39k
  *out++ = c;
1834
1.39k
  return out;
1835
2.10k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_escaped_cp<fmt::v12::basic_appender<char>, char>(fmt::v12::basic_appender<char>, fmt::v12::detail::find_escape_result<char> const&)
Line
Count
Source
1802
2.10k
    -> OutputIt {
1803
2.10k
  auto c = static_cast<Char>(escape.cp);
1804
2.10k
  switch (escape.cp) {
1805
258
  case '\n':
1806
258
    *out++ = static_cast<Char>('\\');
1807
258
    c = static_cast<Char>('n');
1808
258
    break;
1809
238
  case '\r':
1810
238
    *out++ = static_cast<Char>('\\');
1811
238
    c = static_cast<Char>('r');
1812
238
    break;
1813
234
  case '\t':
1814
234
    *out++ = static_cast<Char>('\\');
1815
234
    c = static_cast<Char>('t');
1816
234
    break;
1817
0
  case '"':  FMT_FALLTHROUGH;
1818
402
  case '\'': FMT_FALLTHROUGH;
1819
660
  case '\\': *out++ = static_cast<Char>('\\'); break;
1820
718
  default:
1821
718
    if (escape.cp < 0x100) return write_codepoint<2, Char>(out, 'x', escape.cp);
1822
358
    if (escape.cp < 0x10000)
1823
0
      return write_codepoint<4, Char>(out, 'u', escape.cp);
1824
358
    if (escape.cp < 0x110000)
1825
0
      return write_codepoint<8, Char>(out, 'U', escape.cp);
1826
358
    for (Char escape_char : basic_string_view<Char>(
1827
358
             escape.begin, to_unsigned(escape.end - escape.begin))) {
1828
358
      out = write_codepoint<2, Char>(out, 'x',
1829
358
                                     static_cast<uint32_t>(escape_char) & 0xFF);
1830
358
    }
1831
358
    return out;
1832
2.10k
  }
1833
1.39k
  *out++ = c;
1834
1.39k
  return out;
1835
2.10k
}
Unexecuted instantiation: _ZN3fmt3v126detail16write_escaped_cpIZNS1_5writeIcNS0_14basic_appenderIcEETnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SB_NS0_17basic_string_viewIS8_EERKNS0_12format_specsEE23bounded_output_iteratorcEES8_S8_RKNS1_18find_escape_resultISB_EE
1836
1837
template <typename Char, typename OutputIt>
1838
auto write_escaped_string(OutputIt out, basic_string_view<Char> str)
1839
0
    -> OutputIt {
1840
0
  *out++ = static_cast<Char>('"');
1841
0
  auto begin = str.begin(), end = str.end();
1842
0
  do {
1843
0
    auto escape = find_escape(begin, end);
1844
0
    out = copy<Char>(begin, escape.begin, out);
1845
0
    begin = escape.end;
1846
0
    if (!begin) break;
1847
0
    out = write_escaped_cp<OutputIt, Char>(out, escape);
1848
0
  } while (begin != end);
1849
0
  *out++ = static_cast<Char>('"');
1850
0
  return out;
1851
0
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_escaped_string<char, fmt::v12::basic_appender<char> >(fmt::v12::basic_appender<char>, fmt::v12::basic_string_view<char>)
Unexecuted instantiation: _ZN3fmt3v126detail20write_escaped_stringIcZNS1_5writeIcNS0_14basic_appenderIcEETnNSt3__19enable_ifIXsr3std7is_sameIT_cEE5valueEiE4typeELi0EEET0_SB_NS0_17basic_string_viewIS8_EERKNS0_12format_specsEE23bounded_output_iteratorEESB_SB_SD_
1852
1853
template <typename Char, typename OutputIt>
1854
2.82k
auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
1855
2.82k
  Char v_array[1] = {v};
1856
2.82k
  *out++ = static_cast<Char>('\'');
1857
2.82k
  if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('"')) ||
1858
2.10k
      v == static_cast<Char>('\'')) {
1859
2.10k
    out = write_escaped_cp(out,
1860
2.10k
                           find_escape_result<Char>{v_array, v_array + 1,
1861
2.10k
                                                    static_cast<uint32_t>(v)});
1862
2.10k
  } else {
1863
716
    *out++ = v;
1864
716
  }
1865
2.82k
  *out++ = static_cast<Char>('\'');
1866
2.82k
  return out;
1867
2.82k
}
1868
1869
template <typename Char, typename OutputIt>
1870
FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1871
4.90k
                              const format_specs& specs) -> OutputIt {
1872
4.90k
  bool is_debug = specs.type() == presentation_type::debug;
1873
4.90k
  return write_padded<Char>(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1874
4.85k
    if (is_debug) return write_escaped_char(it, value);
1875
2.03k
    *it++ = value;
1876
2.03k
    return it;
1877
4.85k
  });
1878
4.90k
}
1879
1880
template <typename Char> class digit_grouping {
1881
 private:
1882
  std::string grouping_;
1883
  std::basic_string<Char> thousands_sep_;
1884
1885
  struct next_state {
1886
    std::string::const_iterator group;
1887
    int pos;
1888
  };
1889
23.8k
  auto initial_state() const -> next_state { return {grouping_.begin(), 0}; }
1890
1891
  // Returns the next digit group separator position.
1892
23.8k
  auto next(next_state& state) const -> int {
1893
23.8k
    if (thousands_sep_.empty()) return max_value<int>();
1894
0
    if (state.group == grouping_.end()) return state.pos += grouping_.back();
1895
0
    if (*state.group <= 0 || *state.group == max_value<char>())
1896
0
      return max_value<int>();
1897
0
    state.pos += *state.group++;
1898
0
    return state.pos;
1899
0
  }
1900
1901
 public:
1902
14.4k
  explicit digit_grouping(locale_ref loc, bool localized = true) {
1903
14.4k
    if (!localized) return;
1904
730
    auto sep = thousands_sep<Char>(loc);
1905
730
    grouping_ = sep.grouping;
1906
730
    if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep);
1907
730
  }
1908
  digit_grouping(std::string grouping, std::basic_string<Char> sep)
1909
4.88k
      : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {}
1910
1911
14.1k
  auto has_separator() const -> bool { return !thousands_sep_.empty(); }
1912
1913
19.1k
  auto count_separators(int num_digits) const -> int {
1914
19.1k
    int count = 0;
1915
19.1k
    auto state = initial_state();
1916
19.1k
    while (num_digits > next(state)) ++count;
1917
19.1k
    return count;
1918
19.1k
  }
1919
1920
  // Applies grouping to digits and writes the output to out.
1921
  template <typename Out, typename C>
1922
4.65k
  auto apply(Out out, basic_string_view<C> digits) const -> Out {
1923
4.65k
    auto num_digits = static_cast<int>(digits.size());
1924
4.65k
    auto separators = basic_memory_buffer<int>();
1925
4.65k
    separators.push_back(0);
1926
4.65k
    auto state = initial_state();
1927
4.65k
    while (int i = next(state)) {
1928
4.65k
      if (i >= num_digits) break;
1929
0
      separators.push_back(i);
1930
0
    }
1931
4.65k
    for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);
1932
32.9k
         i < num_digits; ++i) {
1933
28.2k
      if (num_digits - i == separators[sep_index]) {
1934
0
        out = copy<Char>(thousands_sep_.data(),
1935
0
                         thousands_sep_.data() + thousands_sep_.size(), out);
1936
0
        --sep_index;
1937
0
      }
1938
28.2k
      *out++ = static_cast<Char>(digits[to_unsigned(i)]);
1939
28.2k
    }
1940
4.65k
    return out;
1941
4.65k
  }
1942
};
1943
1944
4.99k
FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
1945
4.99k
  prefix |= prefix != 0 ? value << 8 : value;
1946
4.99k
  prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
1947
4.99k
}
1948
1949
// Writes a decimal integer with digit grouping.
1950
template <typename OutputIt, typename UInt, typename Char>
1951
auto write_int(OutputIt out, UInt value, unsigned prefix,
1952
               const format_specs& specs, const digit_grouping<Char>& grouping)
1953
4.88k
    -> OutputIt {
1954
4.88k
  static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
1955
4.88k
  int num_digits = 0;
1956
4.88k
  auto buffer = memory_buffer();
1957
4.88k
  switch (specs.type()) {
1958
0
  default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH;
1959
1.84k
  case presentation_type::none:
1960
2.05k
  case presentation_type::dec:
1961
2.05k
    num_digits = count_digits(value);
1962
2.05k
    format_decimal<char>(appender(buffer), value, num_digits);
1963
2.05k
    break;
1964
903
  case presentation_type::hex:
1965
903
    if (specs.alt())
1966
456
      prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');
1967
903
    num_digits = count_digits<4>(value);
1968
903
    format_base2e<char>(4, appender(buffer), value, num_digits, specs.upper());
1969
903
    break;
1970
914
  case presentation_type::oct:
1971
914
    num_digits = count_digits<3>(value);
1972
    // Octal prefix '0' is counted as a digit, so only add it if precision
1973
    // is not greater than the number of digits.
1974
914
    if (specs.alt() && specs.precision <= num_digits && value != 0)
1975
482
      prefix_append(prefix, '0');
1976
914
    format_base2e<char>(3, appender(buffer), value, num_digits);
1977
914
    break;
1978
812
  case presentation_type::bin:
1979
812
    if (specs.alt())
1980
714
      prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');
1981
812
    num_digits = count_digits<1>(value);
1982
812
    format_base2e<char>(1, appender(buffer), value, num_digits);
1983
812
    break;
1984
198
  case presentation_type::chr:
1985
198
    return write_char<Char>(out, static_cast<Char>(value), specs);
1986
4.88k
  }
1987
1988
4.68k
  unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) +
1989
4.68k
                  to_unsigned(grouping.count_separators(num_digits));
1990
4.68k
  return write_padded<Char, align::right>(
1991
4.68k
      out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
1992
8.76k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1993
4.11k
          *it++ = static_cast<Char>(p & 0xff);
1994
4.65k
        return grouping.apply(it, string_view(buffer.data(), buffer.size()));
1995
4.65k
      });
fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned long, char>(fmt::v12::basic_appender<char>, unsigned long, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
1991
4.65k
      out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
1992
8.76k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1993
4.11k
          *it++ = static_cast<Char>(p & 0xff);
1994
4.65k
        return grouping.apply(it, string_view(buffer.data(), buffer.size()));
1995
4.65k
      });
Unexecuted instantiation: fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned __int128, char>(fmt::v12::basic_appender<char>, unsigned __int128, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
1996
4.88k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned long, char>(fmt::v12::basic_appender<char>, unsigned long, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)
Line
Count
Source
1953
4.88k
    -> OutputIt {
1954
4.88k
  static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
1955
4.88k
  int num_digits = 0;
1956
4.88k
  auto buffer = memory_buffer();
1957
4.88k
  switch (specs.type()) {
1958
0
  default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH;
1959
1.84k
  case presentation_type::none:
1960
2.05k
  case presentation_type::dec:
1961
2.05k
    num_digits = count_digits(value);
1962
2.05k
    format_decimal<char>(appender(buffer), value, num_digits);
1963
2.05k
    break;
1964
903
  case presentation_type::hex:
1965
903
    if (specs.alt())
1966
456
      prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');
1967
903
    num_digits = count_digits<4>(value);
1968
903
    format_base2e<char>(4, appender(buffer), value, num_digits, specs.upper());
1969
903
    break;
1970
914
  case presentation_type::oct:
1971
914
    num_digits = count_digits<3>(value);
1972
    // Octal prefix '0' is counted as a digit, so only add it if precision
1973
    // is not greater than the number of digits.
1974
914
    if (specs.alt() && specs.precision <= num_digits && value != 0)
1975
482
      prefix_append(prefix, '0');
1976
914
    format_base2e<char>(3, appender(buffer), value, num_digits);
1977
914
    break;
1978
812
  case presentation_type::bin:
1979
812
    if (specs.alt())
1980
714
      prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');
1981
812
    num_digits = count_digits<1>(value);
1982
812
    format_base2e<char>(1, appender(buffer), value, num_digits);
1983
812
    break;
1984
198
  case presentation_type::chr:
1985
198
    return write_char<Char>(out, static_cast<Char>(value), specs);
1986
4.88k
  }
1987
1988
4.68k
  unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) +
1989
4.68k
                  to_unsigned(grouping.count_separators(num_digits));
1990
4.68k
  return write_padded<Char, align::right>(
1991
4.68k
      out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
1992
4.68k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1993
4.68k
          *it++ = static_cast<Char>(p & 0xff);
1994
4.68k
        return grouping.apply(it, string_view(buffer.data(), buffer.size()));
1995
4.68k
      });
1996
4.88k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_int<fmt::v12::basic_appender<char>, unsigned __int128, char>(fmt::v12::basic_appender<char>, unsigned __int128, unsigned int, fmt::v12::format_specs const&, fmt::v12::detail::digit_grouping<char> const&)
1997
1998
#if FMT_USE_LOCALE
1999
// Writes a localized value.
2000
FMT_API auto write_loc(appender out, loc_value value, const format_specs& specs,
2001
                       locale_ref loc) -> bool;
2002
auto write_loc(basic_appender<wchar_t> out, loc_value value,
2003
               const format_specs& specs, locale_ref loc) -> bool;
2004
#endif
2005
template <typename OutputIt>
2006
inline auto write_loc(OutputIt, const loc_value&, const format_specs&,
2007
                      locale_ref) -> bool {
2008
  return false;
2009
}
2010
2011
template <typename UInt> struct write_int_arg {
2012
  UInt abs_value;
2013
  unsigned prefix;
2014
};
2015
2016
template <typename T>
2017
FMT_CONSTEXPR auto make_write_int_arg(T value, sign s)
2018
17.3k
    -> write_int_arg<uint32_or_64_or_128_t<T>> {
2019
17.3k
  auto prefix = 0u;
2020
17.3k
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2021
17.3k
  if (is_negative(value)) {
2022
4.85k
    prefix = 0x01000000 | '-';
2023
4.85k
    abs_value = 0 - abs_value;
2024
12.5k
  } else {
2025
12.5k
    constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '};
2026
12.5k
    prefix = prefixes[static_cast<int>(s)];
2027
12.5k
  }
2028
17.3k
  return {abs_value, prefix};
2029
17.3k
}
fmt::v12::detail::write_int_arg<std::__1::conditional<(((num_bits<int>)())<=(32))&&(!(0)), unsigned int, std::__1::conditional<((num_bits<int>)())<=(64), unsigned long, unsigned __int128>::type>::type> fmt::v12::detail::make_write_int_arg<int>(int, fmt::v12::sign)
Line
Count
Source
2018
5.92k
    -> write_int_arg<uint32_or_64_or_128_t<T>> {
2019
5.92k
  auto prefix = 0u;
2020
5.92k
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2021
5.92k
  if (is_negative(value)) {
2022
2.65k
    prefix = 0x01000000 | '-';
2023
2.65k
    abs_value = 0 - abs_value;
2024
3.27k
  } else {
2025
3.27k
    constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '};
2026
3.27k
    prefix = prefixes[static_cast<int>(s)];
2027
3.27k
  }
2028
5.92k
  return {abs_value, prefix};
2029
5.92k
}
fmt::v12::detail::write_int_arg<std::__1::conditional<(((num_bits<unsigned int>)())<=(32))&&(!(0)), unsigned int, std::__1::conditional<((num_bits<unsigned int>)())<=(64), unsigned long, unsigned __int128>::type>::type> fmt::v12::detail::make_write_int_arg<unsigned int>(unsigned int, fmt::v12::sign)
Line
Count
Source
2018
2.96k
    -> write_int_arg<uint32_or_64_or_128_t<T>> {
2019
2.96k
  auto prefix = 0u;
2020
2.96k
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2021
2.96k
  if (is_negative(value)) {
2022
0
    prefix = 0x01000000 | '-';
2023
0
    abs_value = 0 - abs_value;
2024
2.96k
  } else {
2025
2.96k
    constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '};
2026
2.96k
    prefix = prefixes[static_cast<int>(s)];
2027
2.96k
  }
2028
2.96k
  return {abs_value, prefix};
2029
2.96k
}
fmt::v12::detail::write_int_arg<std::__1::conditional<(((num_bits<long long>)())<=(32))&&(!(0)), unsigned int, std::__1::conditional<((num_bits<long long>)())<=(64), unsigned long, unsigned __int128>::type>::type> fmt::v12::detail::make_write_int_arg<long long>(long long, fmt::v12::sign)
Line
Count
Source
2018
5.43k
    -> write_int_arg<uint32_or_64_or_128_t<T>> {
2019
5.43k
  auto prefix = 0u;
2020
5.43k
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2021
5.43k
  if (is_negative(value)) {
2022
2.20k
    prefix = 0x01000000 | '-';
2023
2.20k
    abs_value = 0 - abs_value;
2024
3.23k
  } else {
2025
3.23k
    constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '};
2026
3.23k
    prefix = prefixes[static_cast<int>(s)];
2027
3.23k
  }
2028
5.43k
  return {abs_value, prefix};
2029
5.43k
}
fmt::v12::detail::write_int_arg<std::__1::conditional<(((num_bits<unsigned long long>)())<=(32))&&(!(0)), unsigned int, std::__1::conditional<((num_bits<unsigned long long>)())<=(64), unsigned long, unsigned __int128>::type>::type> fmt::v12::detail::make_write_int_arg<unsigned long long>(unsigned long long, fmt::v12::sign)
Line
Count
Source
2018
2.66k
    -> write_int_arg<uint32_or_64_or_128_t<T>> {
2019
2.66k
  auto prefix = 0u;
2020
2.66k
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2021
2.66k
  if (is_negative(value)) {
2022
0
    prefix = 0x01000000 | '-';
2023
0
    abs_value = 0 - abs_value;
2024
2.66k
  } else {
2025
2.66k
    constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '};
2026
2.66k
    prefix = prefixes[static_cast<int>(s)];
2027
2.66k
  }
2028
2.66k
  return {abs_value, prefix};
2029
2.66k
}
Unexecuted instantiation: fmt::v12::detail::write_int_arg<std::__1::conditional<(((num_bits<__int128>)())<=(32))&&(!(0)), unsigned int, std::__1::conditional<((num_bits<__int128>)())<=(64), unsigned long, unsigned __int128>::type>::type> fmt::v12::detail::make_write_int_arg<__int128>(__int128, fmt::v12::sign)
Unexecuted instantiation: fmt::v12::detail::write_int_arg<std::__1::conditional<(((num_bits<unsigned __int128>)())<=(32))&&(!(0)), unsigned int, std::__1::conditional<((num_bits<unsigned __int128>)())<=(64), unsigned long, unsigned __int128>::type>::type> fmt::v12::detail::make_write_int_arg<unsigned __int128>(unsigned __int128, fmt::v12::sign)
fmt::v12::detail::write_int_arg<std::__1::conditional<(((num_bits<unsigned char>)())<=(32))&&(!(0)), unsigned int, std::__1::conditional<((num_bits<unsigned char>)())<=(64), unsigned long, unsigned __int128>::type>::type> fmt::v12::detail::make_write_int_arg<unsigned char>(unsigned char, fmt::v12::sign)
Line
Count
Source
2018
398
    -> write_int_arg<uint32_or_64_or_128_t<T>> {
2019
398
  auto prefix = 0u;
2020
398
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2021
398
  if (is_negative(value)) {
2022
0
    prefix = 0x01000000 | '-';
2023
0
    abs_value = 0 - abs_value;
2024
398
  } else {
2025
398
    constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '};
2026
398
    prefix = prefixes[static_cast<int>(s)];
2027
398
  }
2028
398
  return {abs_value, prefix};
2029
398
}
2030
2031
template <typename Char = char> struct loc_writer {
2032
  basic_appender<Char> out;
2033
  const format_specs& specs;
2034
  std::basic_string<Char> sep;
2035
  std::string grouping;
2036
  std::basic_string<Char> decimal_point;
2037
2038
  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2039
4.88k
  auto operator()(T value) -> bool {
2040
4.88k
    auto arg = make_write_int_arg(value, specs.sign());
2041
4.88k
    write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2042
4.88k
              specs, digit_grouping<Char>(grouping, sep));
2043
4.88k
    return true;
2044
4.88k
  }
_ZN3fmt3v126detail10loc_writerIcEclIiTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
2039
2.05k
  auto operator()(T value) -> bool {
2040
2.05k
    auto arg = make_write_int_arg(value, specs.sign());
2041
2.05k
    write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2042
2.05k
              specs, digit_grouping<Char>(grouping, sep));
2043
2.05k
    return true;
2044
2.05k
  }
_ZN3fmt3v126detail10loc_writerIcEclIjTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
2039
1.05k
  auto operator()(T value) -> bool {
2040
1.05k
    auto arg = make_write_int_arg(value, specs.sign());
2041
1.05k
    write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2042
1.05k
              specs, digit_grouping<Char>(grouping, sep));
2043
1.05k
    return true;
2044
1.05k
  }
_ZN3fmt3v126detail10loc_writerIcEclIxTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
2039
845
  auto operator()(T value) -> bool {
2040
845
    auto arg = make_write_int_arg(value, specs.sign());
2041
845
    write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2042
845
              specs, digit_grouping<Char>(grouping, sep));
2043
845
    return true;
2044
845
  }
_ZN3fmt3v126detail10loc_writerIcEclIyTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
2039
933
  auto operator()(T value) -> bool {
2040
933
    auto arg = make_write_int_arg(value, specs.sign());
2041
933
    write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
2042
933
              specs, digit_grouping<Char>(grouping, sep));
2043
933
    return true;
2044
933
  }
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclInTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclIoTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
2045
2046
  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2047
786
  auto operator()(T) -> bool {
2048
786
    return false;
2049
786
  }
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclIbTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclIcTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
_ZN3fmt3v126detail10loc_writerIcEclIfTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
2047
222
  auto operator()(T) -> bool {
2048
222
    return false;
2049
222
  }
_ZN3fmt3v126detail10loc_writerIcEclIdTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
2047
198
  auto operator()(T) -> bool {
2048
198
    return false;
2049
198
  }
_ZN3fmt3v126detail10loc_writerIcEclIeTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS7_
Line
Count
Source
2047
366
  auto operator()(T) -> bool {
2048
366
    return false;
2049
366
  }
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclIPKcTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS9_
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclINS0_17basic_string_viewIcEETnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS9_
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclIPKvTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS9_
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclINS0_16basic_format_argINS0_7contextEE6handleETnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbSB_
Unexecuted instantiation: _ZN3fmt3v126detail10loc_writerIcEclINS0_9monostateETnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEbS8_
2050
};
2051
2052
// Size and padding computation separate from write_int to avoid template bloat.
2053
struct size_padding {
2054
  unsigned size;
2055
  unsigned padding;
2056
2057
  FMT_CONSTEXPR size_padding(int num_digits, unsigned prefix,
2058
                             const format_specs& specs)
2059
4.20k
      : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
2060
4.20k
    if (specs.align() == align::numeric) {
2061
670
      auto width = to_unsigned(specs.width);
2062
670
      if (width > size) {
2063
476
        padding = width - size;
2064
476
        size = width;
2065
476
      }
2066
3.53k
    } else if (specs.precision > num_digits) {
2067
0
      size = (prefix >> 24) + to_unsigned(specs.precision);
2068
0
      padding = to_unsigned(specs.precision - num_digits);
2069
0
    }
2070
4.20k
  }
2071
};
2072
2073
template <typename Char, typename OutputIt, typename T>
2074
FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
2075
12.5k
                                        const format_specs& specs) -> OutputIt {
2076
12.5k
  static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2077
2078
12.5k
  constexpr size_t buffer_size = num_bits<T>();
2079
12.5k
  char buffer[buffer_size];
2080
12.5k
  if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\0');
2081
12.5k
  const char* begin = nullptr;
2082
12.5k
  const char* end = buffer + buffer_size;
2083
2084
12.5k
  auto abs_value = arg.abs_value;
2085
12.5k
  auto prefix = arg.prefix;
2086
12.5k
  switch (specs.type()) {
2087
0
  default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH;
2088
6.32k
  case presentation_type::none:
2089
6.72k
  case presentation_type::dec:
2090
6.72k
    begin = do_format_decimal(buffer, abs_value, buffer_size);
2091
6.72k
    break;
2092
1.44k
  case presentation_type::hex:
2093
1.44k
    begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper());
2094
1.44k
    if (specs.alt())
2095
923
      prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');
2096
1.44k
    break;
2097
1.74k
  case presentation_type::oct: {
2098
1.74k
    begin = do_format_base2e(3, buffer, abs_value, buffer_size);
2099
    // Octal prefix '0' is counted as a digit, so only add it if precision
2100
    // is not greater than the number of digits.
2101
1.74k
    auto num_digits = end - begin;
2102
1.74k
    if (specs.alt() && specs.precision <= num_digits && abs_value != 0)
2103
906
      prefix_append(prefix, '0');
2104
1.74k
    break;
2105
6.32k
  }
2106
2.13k
  case presentation_type::bin:
2107
2.13k
    begin = do_format_base2e(1, buffer, abs_value, buffer_size);
2108
2.13k
    if (specs.alt())
2109
1.51k
      prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');
2110
2.13k
    break;
2111
451
  case presentation_type::chr:
2112
451
    return write_char<Char>(out, static_cast<Char>(abs_value), specs);
2113
12.5k
  }
2114
2115
  // Write an integer in the format
2116
  //   <left-padding><prefix><numeric-padding><digits><right-padding>
2117
  // prefix contains chars in three lower bytes and the size in the fourth byte.
2118
12.0k
  int num_digits = static_cast<int>(end - begin);
2119
  // Slightly faster check for specs.width == 0 && specs.precision == -1.
2120
12.0k
  if ((specs.width | (specs.precision + 1)) == 0) {
2121
7.84k
    auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
2122
15.3k
    for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2123
7.49k
      *it++ = static_cast<Char>(p & 0xff);
2124
7.84k
    return base_iterator(out, copy<Char>(begin, end, it));
2125
7.84k
  }
2126
4.20k
  auto sp = size_padding(num_digits, prefix, specs);
2127
4.20k
  unsigned padding = sp.padding;
2128
4.20k
  return write_padded<Char, align::right>(
2129
4.20k
      out, specs, sp.size, [=](reserve_iterator<OutputIt> it) {
2130
6.08k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2131
1.99k
          *it++ = static_cast<Char>(p & 0xff);
2132
4.09k
        it = detail::fill_n(it, padding, static_cast<Char>('0'));
2133
4.09k
        return copy<Char>(begin, end, it);
2134
4.09k
      });
fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned int>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2129
1.67k
      out, specs, sp.size, [=](reserve_iterator<OutputIt> it) {
2130
2.42k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2131
756
          *it++ = static_cast<Char>(p & 0xff);
2132
1.67k
        it = detail::fill_n(it, padding, static_cast<Char>('0'));
2133
1.67k
        return copy<Char>(begin, end, it);
2134
1.67k
      });
fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned long>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2129
2.42k
      out, specs, sp.size, [=](reserve_iterator<OutputIt> it) {
2130
3.65k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2131
1.23k
          *it++ = static_cast<Char>(p & 0xff);
2132
2.42k
        it = detail::fill_n(it, padding, static_cast<Char>('0'));
2133
2.42k
        return copy<Char>(begin, end, it);
2134
2.42k
      });
Unexecuted instantiation: fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned __int128>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned __int128>, fmt::v12::format_specs const&)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
2135
12.0k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned int>, fmt::v12::format_specs const&)
Line
Count
Source
2075
6.17k
                                        const format_specs& specs) -> OutputIt {
2076
6.17k
  static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2077
2078
6.17k
  constexpr size_t buffer_size = num_bits<T>();
2079
6.17k
  char buffer[buffer_size];
2080
6.17k
  if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\0');
2081
6.17k
  const char* begin = nullptr;
2082
6.17k
  const char* end = buffer + buffer_size;
2083
2084
6.17k
  auto abs_value = arg.abs_value;
2085
6.17k
  auto prefix = arg.prefix;
2086
6.17k
  switch (specs.type()) {
2087
0
  default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH;
2088
3.06k
  case presentation_type::none:
2089
3.27k
  case presentation_type::dec:
2090
3.27k
    begin = do_format_decimal(buffer, abs_value, buffer_size);
2091
3.27k
    break;
2092
797
  case presentation_type::hex:
2093
797
    begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper());
2094
797
    if (specs.alt())
2095
509
      prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');
2096
797
    break;
2097
881
  case presentation_type::oct: {
2098
881
    begin = do_format_base2e(3, buffer, abs_value, buffer_size);
2099
    // Octal prefix '0' is counted as a digit, so only add it if precision
2100
    // is not greater than the number of digits.
2101
881
    auto num_digits = end - begin;
2102
881
    if (specs.alt() && specs.precision <= num_digits && abs_value != 0)
2103
439
      prefix_append(prefix, '0');
2104
881
    break;
2105
3.06k
  }
2106
1.02k
  case presentation_type::bin:
2107
1.02k
    begin = do_format_base2e(1, buffer, abs_value, buffer_size);
2108
1.02k
    if (specs.alt())
2109
695
      prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');
2110
1.02k
    break;
2111
209
  case presentation_type::chr:
2112
209
    return write_char<Char>(out, static_cast<Char>(abs_value), specs);
2113
6.17k
  }
2114
2115
  // Write an integer in the format
2116
  //   <left-padding><prefix><numeric-padding><digits><right-padding>
2117
  // prefix contains chars in three lower bytes and the size in the fourth byte.
2118
5.97k
  int num_digits = static_cast<int>(end - begin);
2119
  // Slightly faster check for specs.width == 0 && specs.precision == -1.
2120
5.97k
  if ((specs.width | (specs.precision + 1)) == 0) {
2121
4.22k
    auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
2122
8.00k
    for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2123
3.78k
      *it++ = static_cast<Char>(p & 0xff);
2124
4.22k
    return base_iterator(out, copy<Char>(begin, end, it));
2125
4.22k
  }
2126
1.75k
  auto sp = size_padding(num_digits, prefix, specs);
2127
1.75k
  unsigned padding = sp.padding;
2128
1.75k
  return write_padded<Char, align::right>(
2129
1.75k
      out, specs, sp.size, [=](reserve_iterator<OutputIt> it) {
2130
1.75k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2131
1.75k
          *it++ = static_cast<Char>(p & 0xff);
2132
1.75k
        it = detail::fill_n(it, padding, static_cast<Char>('0'));
2133
1.75k
        return copy<Char>(begin, end, it);
2134
1.75k
      });
2135
5.97k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned long>, fmt::v12::format_specs const&)
Line
Count
Source
2075
6.32k
                                        const format_specs& specs) -> OutputIt {
2076
6.32k
  static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
2077
2078
6.32k
  constexpr size_t buffer_size = num_bits<T>();
2079
6.32k
  char buffer[buffer_size];
2080
6.32k
  if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\0');
2081
6.32k
  const char* begin = nullptr;
2082
6.32k
  const char* end = buffer + buffer_size;
2083
2084
6.32k
  auto abs_value = arg.abs_value;
2085
6.32k
  auto prefix = arg.prefix;
2086
6.32k
  switch (specs.type()) {
2087
0
  default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH;
2088
3.25k
  case presentation_type::none:
2089
3.44k
  case presentation_type::dec:
2090
3.44k
    begin = do_format_decimal(buffer, abs_value, buffer_size);
2091
3.44k
    break;
2092
648
  case presentation_type::hex:
2093
648
    begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper());
2094
648
    if (specs.alt())
2095
414
      prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');
2096
648
    break;
2097
867
  case presentation_type::oct: {
2098
867
    begin = do_format_base2e(3, buffer, abs_value, buffer_size);
2099
    // Octal prefix '0' is counted as a digit, so only add it if precision
2100
    // is not greater than the number of digits.
2101
867
    auto num_digits = end - begin;
2102
867
    if (specs.alt() && specs.precision <= num_digits && abs_value != 0)
2103
467
      prefix_append(prefix, '0');
2104
867
    break;
2105
3.25k
  }
2106
1.11k
  case presentation_type::bin:
2107
1.11k
    begin = do_format_base2e(1, buffer, abs_value, buffer_size);
2108
1.11k
    if (specs.alt())
2109
816
      prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');
2110
1.11k
    break;
2111
242
  case presentation_type::chr:
2112
242
    return write_char<Char>(out, static_cast<Char>(abs_value), specs);
2113
6.32k
  }
2114
2115
  // Write an integer in the format
2116
  //   <left-padding><prefix><numeric-padding><digits><right-padding>
2117
  // prefix contains chars in three lower bytes and the size in the fourth byte.
2118
6.07k
  int num_digits = static_cast<int>(end - begin);
2119
  // Slightly faster check for specs.width == 0 && specs.precision == -1.
2120
6.07k
  if ((specs.width | (specs.precision + 1)) == 0) {
2121
3.62k
    auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
2122
7.33k
    for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2123
3.70k
      *it++ = static_cast<Char>(p & 0xff);
2124
3.62k
    return base_iterator(out, copy<Char>(begin, end, it));
2125
3.62k
  }
2126
2.45k
  auto sp = size_padding(num_digits, prefix, specs);
2127
2.45k
  unsigned padding = sp.padding;
2128
2.45k
  return write_padded<Char, align::right>(
2129
2.45k
      out, specs, sp.size, [=](reserve_iterator<OutputIt> it) {
2130
2.45k
        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2131
2.45k
          *it++ = static_cast<Char>(p & 0xff);
2132
2.45k
        it = detail::fill_n(it, padding, static_cast<Char>('0'));
2133
2.45k
        return copy<Char>(begin, end, it);
2134
2.45k
      });
2135
6.07k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_int<char, fmt::v12::basic_appender<char>, unsigned __int128>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned __int128>, fmt::v12::format_specs const&)
2136
2137
template <typename Char, typename OutputIt, typename T>
2138
FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(OutputIt out,
2139
                                                   write_int_arg<T> arg,
2140
                                                   const format_specs& specs)
2141
12.5k
    -> OutputIt {
2142
12.5k
  return write_int<Char>(out, arg, specs);
2143
12.5k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_int_noinline<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned int>, fmt::v12::format_specs const&)
Line
Count
Source
2141
6.17k
    -> OutputIt {
2142
6.17k
  return write_int<Char>(out, arg, specs);
2143
6.17k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_int_noinline<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned long>, fmt::v12::format_specs const&)
Line
Count
Source
2141
6.32k
    -> OutputIt {
2142
6.32k
  return write_int<Char>(out, arg, specs);
2143
6.32k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_int_noinline<char, fmt::v12::basic_appender<char>, unsigned __int128>(fmt::v12::basic_appender<char>, fmt::v12::detail::write_int_arg<unsigned __int128>, fmt::v12::format_specs const&)
2144
2145
template <typename Char, typename T,
2146
          FMT_ENABLE_IF(is_integral<T>::value &&
2147
                        !std::is_same<T, bool>::value &&
2148
                        !std::is_same<T, Char>::value)>
2149
FMT_CONSTEXPR FMT_INLINE auto write(basic_appender<Char> out, T value,
2150
                                    const format_specs& specs, locale_ref loc)
2151
17.3k
    -> basic_appender<Char> {
2152
17.3k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2153
12.5k
  return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),
2154
12.5k
                                  specs);
2155
17.3k
}
_ZN3fmt3v126detail5writeIciTnNSt3__19enable_ifIXaaaasr11is_integralIT0_EE5valuentsr3std7is_sameIS5_bEE5valuentsr3std7is_sameIS5_T_EE5valueEiE4typeELi0EEENS0_14basic_appenderIS6_EESA_S5_RKNS0_12format_specsENS0_10locale_refE
Line
Count
Source
2151
5.92k
    -> basic_appender<Char> {
2152
5.92k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2153
3.89k
  return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),
2154
3.89k
                                  specs);
2155
5.92k
}
_ZN3fmt3v126detail5writeIcjTnNSt3__19enable_ifIXaaaasr11is_integralIT0_EE5valuentsr3std7is_sameIS5_bEE5valuentsr3std7is_sameIS5_T_EE5valueEiE4typeELi0EEENS0_14basic_appenderIS6_EESA_S5_RKNS0_12format_specsENS0_10locale_refE
Line
Count
Source
2151
2.60k
    -> basic_appender<Char> {
2152
2.60k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2153
1.90k
  return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),
2154
1.90k
                                  specs);
2155
2.60k
}
_ZN3fmt3v126detail5writeIcxTnNSt3__19enable_ifIXaaaasr11is_integralIT0_EE5valuentsr3std7is_sameIS5_bEE5valuentsr3std7is_sameIS5_T_EE5valueEiE4typeELi0EEENS0_14basic_appenderIS6_EESA_S5_RKNS0_12format_specsENS0_10locale_refE
Line
Count
Source
2151
5.43k
    -> basic_appender<Char> {
2152
5.43k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2153
4.59k
  return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),
2154
4.59k
                                  specs);
2155
5.43k
}
_ZN3fmt3v126detail5writeIcyTnNSt3__19enable_ifIXaaaasr11is_integralIT0_EE5valuentsr3std7is_sameIS5_bEE5valuentsr3std7is_sameIS5_T_EE5valueEiE4typeELi0EEENS0_14basic_appenderIS6_EESA_S5_RKNS0_12format_specsENS0_10locale_refE
Line
Count
Source
2151
2.66k
    -> basic_appender<Char> {
2152
2.66k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2153
1.73k
  return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),
2154
1.73k
                                  specs);
2155
2.66k
}
Unexecuted instantiation: _ZN3fmt3v126detail5writeIcnTnNSt3__19enable_ifIXaaaasr11is_integralIT0_EE5valuentsr3std7is_sameIS5_bEE5valuentsr3std7is_sameIS5_T_EE5valueEiE4typeELi0EEENS0_14basic_appenderIS6_EESA_S5_RKNS0_12format_specsENS0_10locale_refE
Unexecuted instantiation: _ZN3fmt3v126detail5writeIcoTnNSt3__19enable_ifIXaaaasr11is_integralIT0_EE5valuentsr3std7is_sameIS5_bEE5valuentsr3std7is_sameIS5_T_EE5valueEiE4typeELi0EEENS0_14basic_appenderIS6_EESA_S5_RKNS0_12format_specsENS0_10locale_refE
_ZN3fmt3v126detail5writeIchTnNSt3__19enable_ifIXaaaasr11is_integralIT0_EE5valuentsr3std7is_sameIS5_bEE5valuentsr3std7is_sameIS5_T_EE5valueEiE4typeELi0EEENS0_14basic_appenderIS6_EESA_S5_RKNS0_12format_specsENS0_10locale_refE
Line
Count
Source
2151
753
    -> basic_appender<Char> {
2152
753
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2153
398
  return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),
2154
398
                                  specs);
2155
753
}
2156
2157
// An inlined version of write used in format string compilation.
2158
template <typename Char, typename OutputIt, typename T,
2159
          FMT_ENABLE_IF(is_integral<T>::value &&
2160
                        !std::is_same<T, bool>::value &&
2161
                        !std::is_same<T, Char>::value &&
2162
                        !std::is_same<OutputIt, basic_appender<Char>>::value)>
2163
FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
2164
                                    const format_specs& specs, locale_ref loc)
2165
    -> OutputIt {
2166
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
2167
  return write_int<Char>(out, make_write_int_arg(value, specs.sign()), specs);
2168
}
2169
2170
template <typename Char, typename OutputIt>
2171
FMT_CONSTEXPR auto write(OutputIt out, Char value, const format_specs& specs,
2172
5.01k
                         locale_ref loc = {}) -> OutputIt {
2173
  // char is formatted as unsigned char for consistency across platforms.
2174
5.01k
  using unsigned_type =
2175
5.01k
      conditional_t<std::is_same<Char, char>::value, unsigned char, unsigned>;
2176
5.01k
  return check_char_specs(specs)
2177
5.01k
             ? write_char<Char>(out, value, specs)
2178
5.01k
             : write<Char>(out, static_cast<unsigned_type>(value), specs, loc);
2179
5.01k
}
2180
2181
template <typename Char, typename OutputIt,
2182
          FMT_ENABLE_IF(std::is_same<Char, char>::value)>
2183
FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
2184
6.11k
                         const format_specs& specs) -> OutputIt {
2185
6.11k
  bool is_debug = specs.type() == presentation_type::debug;
2186
6.11k
  if (specs.precision < 0 && specs.width == 0) {
2187
4.19k
    auto&& it = reserve(out, s.size());
2188
4.19k
    return is_debug ? write_escaped_string(it, s) : copy<char>(s, it);
2189
4.19k
  }
2190
2191
1.92k
  size_t display_width_limit =
2192
1.92k
      specs.precision < 0 ? SIZE_MAX : to_unsigned(specs.precision);
2193
1.92k
  size_t display_width =
2194
1.92k
      !is_debug || specs.precision == 0 ? 0 : 1;  // Account for opening '"'.
2195
1.92k
  size_t size = !is_debug || specs.precision == 0 ? 0 : 1;
2196
88.4k
  for_each_codepoint(s, [&](uint32_t cp, string_view sv) {
2197
88.4k
    if (is_debug && needs_escape(cp)) {
2198
0
      counting_buffer<char> buf;
2199
0
      write_escaped_cp(basic_appender<char>(buf),
2200
0
                       find_escape_result<char>{sv.begin(), sv.end(), cp});
2201
      // We're reinterpreting bytes as display width. That's okay
2202
      // because write_escaped_cp() only writes ASCII characters.
2203
0
      size_t cp_width = buf.count();
2204
0
      if (display_width + cp_width <= display_width_limit) {
2205
0
        display_width += cp_width;
2206
0
        size += cp_width;
2207
        // If this is the end of the string, account for closing '"'.
2208
0
        if (display_width < display_width_limit && sv.end() == s.end()) {
2209
0
          ++display_width;
2210
0
          ++size;
2211
0
        }
2212
0
        return true;
2213
0
      }
2214
2215
0
      size += display_width_limit - display_width;
2216
0
      display_width = display_width_limit;
2217
0
      return false;
2218
0
    }
2219
2220
88.4k
    size_t cp_width = display_width_of(cp);
2221
88.4k
    if (cp_width + display_width <= display_width_limit) {
2222
88.4k
      display_width += cp_width;
2223
88.4k
      size += sv.size();
2224
      // If this is the end of the string, account for closing '"'.
2225
88.4k
      if (is_debug && display_width < display_width_limit &&
2226
0
          sv.end() == s.end()) {
2227
0
        ++display_width;
2228
0
        ++size;
2229
0
      }
2230
88.4k
      return true;
2231
88.4k
    }
2232
2233
0
    return false;
2234
88.4k
  });
2235
2236
1.92k
  struct bounded_output_iterator {
2237
1.92k
    reserve_iterator<OutputIt> underlying_iterator;
2238
1.92k
    size_t bound;
2239
2240
1.92k
    FMT_CONSTEXPR auto operator*() -> bounded_output_iterator& { return *this; }
2241
1.92k
    FMT_CONSTEXPR auto operator++() -> bounded_output_iterator& {
2242
0
      return *this;
2243
0
    }
2244
1.92k
    FMT_CONSTEXPR auto operator++(int) -> bounded_output_iterator& {
2245
0
      return *this;
2246
0
    }
2247
1.92k
    FMT_CONSTEXPR auto operator=(char c) -> bounded_output_iterator& {
2248
0
      if (bound > 0) {
2249
0
        *underlying_iterator++ = c;
2250
0
        --bound;
2251
0
      }
2252
0
      return *this;
2253
0
    }
2254
1.92k
  };
2255
2256
1.92k
  return write_padded<char>(
2257
1.92k
      out, specs, size, display_width, [=](reserve_iterator<OutputIt> it) {
2258
1.87k
        return is_debug
2259
1.87k
                   ? write_escaped_string(bounded_output_iterator{it, size}, s)
2260
0
                         .underlying_iterator
2261
1.87k
                   : copy<char>(s.data(), s.data() + size, it);
2262
1.87k
      });
2263
6.11k
}
2264
2265
template <typename Char, typename OutputIt,
2266
          FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
2267
FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
2268
                         const format_specs& specs) -> OutputIt {
2269
  auto data = s.data();
2270
  auto size = s.size();
2271
  if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
2272
    size = to_unsigned(specs.precision);
2273
2274
  bool is_debug = specs.type() == presentation_type::debug;
2275
  if (is_debug) {
2276
    auto buf = counting_buffer<Char>();
2277
    write_escaped_string(basic_appender<Char>(buf), s);
2278
    size = buf.count();
2279
  }
2280
2281
  return write_padded<Char>(
2282
      out, specs, size, [=](reserve_iterator<OutputIt> it) {
2283
        return is_debug ? write_escaped_string(it, s)
2284
                        : copy<Char>(data, data + size, it);
2285
      });
2286
}
2287
2288
template <typename Char, typename OutputIt>
2289
FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
2290
0
                         const format_specs& specs, locale_ref) -> OutputIt {
2291
0
  return write<Char>(out, s, specs);
2292
0
}
2293
2294
template <typename Char, typename OutputIt>
2295
FMT_CONSTEXPR auto write(OutputIt out, const Char* s, const format_specs& specs,
2296
0
                         locale_ref) -> OutputIt {
2297
0
  if (specs.type() == presentation_type::pointer)
2298
0
    return write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
2299
0
  if (!s) report_error("string pointer is null");
2300
0
  return write<Char>(out, basic_string_view<Char>(s), specs, {});
2301
0
}
2302
2303
template <typename Char, typename OutputIt, typename T,
2304
          FMT_ENABLE_IF(is_integral<T>::value &&
2305
                        !std::is_same<T, bool>::value &&
2306
                        !std::is_same<T, Char>::value)>
2307
3.95k
FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2308
3.95k
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2309
3.95k
  bool negative = is_negative(value);
2310
  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2311
3.95k
  if (negative) abs_value = ~abs_value + 1;
2312
3.95k
  int num_digits = count_digits(abs_value);
2313
3.95k
  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2314
3.95k
  if (auto ptr = to_pointer<Char>(out, size)) {
2315
3.95k
    if (negative) *ptr++ = static_cast<Char>('-');
2316
3.95k
    format_decimal<Char>(ptr, abs_value, num_digits);
2317
3.95k
    return out;
2318
3.95k
  }
2319
3
  if (negative) *out++ = static_cast<Char>('-');
2320
3
  return format_decimal<Char>(out, abs_value, num_digits);
2321
3.95k
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEExTnNSt3__19enable_ifIXaaaasr11is_integralIT1_EE5valuentsr3std7is_sameIS7_bEE5valuentsr3std7is_sameIS7_T_EE5valueEiE4typeELi0EEET0_SB_S7_
Line
Count
Source
2307
1.14k
FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2308
1.14k
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2309
1.14k
  bool negative = is_negative(value);
2310
  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2311
1.14k
  if (negative) abs_value = ~abs_value + 1;
2312
1.14k
  int num_digits = count_digits(abs_value);
2313
1.14k
  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2314
1.14k
  if (auto ptr = to_pointer<Char>(out, size)) {
2315
1.14k
    if (negative) *ptr++ = static_cast<Char>('-');
2316
1.14k
    format_decimal<Char>(ptr, abs_value, num_digits);
2317
1.14k
    return out;
2318
1.14k
  }
2319
0
  if (negative) *out++ = static_cast<Char>('-');
2320
0
  return format_decimal<Char>(out, abs_value, num_digits);
2321
1.14k
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEiTnNSt3__19enable_ifIXaaaasr11is_integralIT1_EE5valuentsr3std7is_sameIS7_bEE5valuentsr3std7is_sameIS7_T_EE5valueEiE4typeELi0EEET0_SB_S7_
Line
Count
Source
2307
873
FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2308
873
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2309
873
  bool negative = is_negative(value);
2310
  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2311
873
  if (negative) abs_value = ~abs_value + 1;
2312
873
  int num_digits = count_digits(abs_value);
2313
873
  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2314
873
  if (auto ptr = to_pointer<Char>(out, size)) {
2315
872
    if (negative) *ptr++ = static_cast<Char>('-');
2316
872
    format_decimal<Char>(ptr, abs_value, num_digits);
2317
872
    return out;
2318
872
  }
2319
1
  if (negative) *out++ = static_cast<Char>('-');
2320
1
  return format_decimal<Char>(out, abs_value, num_digits);
2321
873
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEjTnNSt3__19enable_ifIXaaaasr11is_integralIT1_EE5valuentsr3std7is_sameIS7_bEE5valuentsr3std7is_sameIS7_T_EE5valueEiE4typeELi0EEET0_SB_S7_
Line
Count
Source
2307
967
FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2308
967
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2309
967
  bool negative = is_negative(value);
2310
  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2311
967
  if (negative) abs_value = ~abs_value + 1;
2312
967
  int num_digits = count_digits(abs_value);
2313
967
  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2314
967
  if (auto ptr = to_pointer<Char>(out, size)) {
2315
966
    if (negative) *ptr++ = static_cast<Char>('-');
2316
966
    format_decimal<Char>(ptr, abs_value, num_digits);
2317
966
    return out;
2318
966
  }
2319
1
  if (negative) *out++ = static_cast<Char>('-');
2320
1
  return format_decimal<Char>(out, abs_value, num_digits);
2321
967
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEyTnNSt3__19enable_ifIXaaaasr11is_integralIT1_EE5valuentsr3std7is_sameIS7_bEE5valuentsr3std7is_sameIS7_T_EE5valueEiE4typeELi0EEET0_SB_S7_
Line
Count
Source
2307
972
FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
2308
972
  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
2309
972
  bool negative = is_negative(value);
2310
  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
2311
972
  if (negative) abs_value = ~abs_value + 1;
2312
972
  int num_digits = count_digits(abs_value);
2313
972
  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2314
972
  if (auto ptr = to_pointer<Char>(out, size)) {
2315
971
    if (negative) *ptr++ = static_cast<Char>('-');
2316
971
    format_decimal<Char>(ptr, abs_value, num_digits);
2317
971
    return out;
2318
971
  }
2319
1
  if (negative) *out++ = static_cast<Char>('-');
2320
1
  return format_decimal<Char>(out, abs_value, num_digits);
2321
972
}
Unexecuted instantiation: _ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEnTnNSt3__19enable_ifIXaaaasr11is_integralIT1_EE5valuentsr3std7is_sameIS7_bEE5valuentsr3std7is_sameIS7_T_EE5valueEiE4typeELi0EEET0_SB_S7_
Unexecuted instantiation: _ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEoTnNSt3__19enable_ifIXaaaasr11is_integralIT1_EE5valuentsr3std7is_sameIS7_bEE5valuentsr3std7is_sameIS7_T_EE5valueEiE4typeELi0EEET0_SB_S7_
2322
2323
template <typename Char>
2324
FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
2325
5.64k
                               format_specs& specs) -> const Char* {
2326
5.64k
  FMT_ASSERT(begin != end, "");
2327
5.64k
  auto alignment = align::none;
2328
5.64k
  auto p = begin + code_point_length(begin);
2329
5.64k
  if (end - p <= 0) p = begin;
2330
10.7k
  for (;;) {
2331
10.7k
    switch (to_ascii(*p)) {
2332
384
    case '<': alignment = align::left; break;
2333
542
    case '>': alignment = align::right; break;
2334
616
    case '^': alignment = align::center; break;
2335
10.7k
    }
2336
10.7k
    if (alignment != align::none) {
2337
1.54k
      if (p != begin) {
2338
467
        auto c = *begin;
2339
467
        if (c == '}') return begin;
2340
467
        if (c == '{') {
2341
1
          report_error("invalid fill character '{'");
2342
1
          return begin;
2343
1
        }
2344
466
        specs.set_fill(basic_string_view<Char>(begin, to_unsigned(p - begin)));
2345
466
        begin = p + 1;
2346
1.07k
      } else {
2347
1.07k
        ++begin;
2348
1.07k
      }
2349
1.54k
      break;
2350
9.20k
    } else if (p == begin) {
2351
4.10k
      break;
2352
4.10k
    }
2353
5.10k
    p = begin;
2354
5.10k
  }
2355
5.64k
  specs.set_align(alignment);
2356
5.64k
  return begin;
2357
5.64k
}
2358
2359
template <typename Char, typename OutputIt>
2360
FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
2361
6.00k
                                     format_specs specs, sign s) -> OutputIt {
2362
6.00k
  auto str =
2363
6.00k
      isnan ? (specs.upper() ? "NAN" : "nan") : (specs.upper() ? "INF" : "inf");
2364
6.00k
  constexpr size_t str_size = 3;
2365
6.00k
  auto size = str_size + (s != sign::none ? 1 : 0);
2366
  // Replace '0'-padding with space for non-finite values.
2367
6.00k
  const bool is_zero_fill =
2368
6.00k
      specs.fill_size() == 1 && specs.fill_unit<Char>() == '0';
2369
6.00k
  if (is_zero_fill) specs.set_fill(' ');
2370
6.00k
  return write_padded<Char>(out, specs, size,
2371
6.00k
                            [=](reserve_iterator<OutputIt> it) {
2372
5.97k
                              if (s != sign::none)
2373
4.12k
                                *it++ = detail::getsign<Char>(s);
2374
5.97k
                              return copy<Char>(str, str + str_size, it);
2375
5.97k
                            });
2376
6.00k
}
2377
2378
// A decimal floating-point number significand * pow(10, exp).
2379
struct big_decimal_fp {
2380
  const char* significand;
2381
  int significand_size;
2382
  int exponent;
2383
};
2384
2385
22.5k
constexpr auto get_significand_size(const big_decimal_fp& f) -> int {
2386
22.5k
  return f.significand_size;
2387
22.5k
}
2388
template <typename T>
2389
14.1k
inline auto get_significand_size(const dragonbox::decimal_fp<T>& f) -> int {
2390
14.1k
  return count_digits(f.significand);
2391
14.1k
}
int fmt::v12::detail::get_significand_size<float>(fmt::v12::detail::dragonbox::decimal_fp<float> const&)
Line
Count
Source
2389
7.18k
inline auto get_significand_size(const dragonbox::decimal_fp<T>& f) -> int {
2390
7.18k
  return count_digits(f.significand);
2391
7.18k
}
int fmt::v12::detail::get_significand_size<double>(fmt::v12::detail::dragonbox::decimal_fp<double> const&)
Line
Count
Source
2389
6.92k
inline auto get_significand_size(const dragonbox::decimal_fp<T>& f) -> int {
2390
6.92k
  return count_digits(f.significand);
2391
6.92k
}
2392
2393
template <typename Char, typename OutputIt>
2394
constexpr auto write_significand(OutputIt out, const char* significand,
2395
6.67k
                                 int significand_size) -> OutputIt {
2396
6.67k
  return copy<Char>(significand, significand + significand_size, out);
2397
6.67k
}
2398
template <typename Char, typename OutputIt, typename UInt>
2399
inline auto write_significand(OutputIt out, UInt significand,
2400
9.34k
                              int significand_size) -> OutputIt {
2401
9.34k
  return format_decimal<Char>(out, significand, significand_size);
2402
9.34k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, unsigned int>(fmt::v12::basic_appender<char>, unsigned int, int)
Line
Count
Source
2400
4.53k
                              int significand_size) -> OutputIt {
2401
4.53k
  return format_decimal<Char>(out, significand, significand_size);
2402
4.53k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, unsigned long>(fmt::v12::basic_appender<char>, unsigned long, int)
Line
Count
Source
2400
4.80k
                              int significand_size) -> OutputIt {
2401
4.80k
  return format_decimal<Char>(out, significand, significand_size);
2402
4.80k
}
2403
template <typename Char, typename OutputIt, typename T, typename Grouping>
2404
FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2405
                                       int significand_size, int exponent,
2406
7.86k
                                       const Grouping& grouping) -> OutputIt {
2407
7.86k
  if (!grouping.has_separator()) {
2408
7.86k
    out = write_significand<Char>(out, significand, significand_size);
2409
7.86k
    return detail::fill_n(out, exponent, static_cast<Char>('0'));
2410
7.86k
  }
2411
0
  auto buffer = memory_buffer();
2412
0
  write_significand<char>(appender(buffer), significand, significand_size);
2413
0
  detail::fill_n(appender(buffer), exponent, '0');
2414
0
  return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2415
7.86k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, unsigned int, fmt::v12::detail::fallback_digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned int, int, int, fmt::v12::detail::fallback_digit_grouping<char> const&)
Line
Count
Source
2406
1.02k
                                       const Grouping& grouping) -> OutputIt {
2407
1.02k
  if (!grouping.has_separator()) {
2408
1.02k
    out = write_significand<Char>(out, significand, significand_size);
2409
1.02k
    return detail::fill_n(out, exponent, static_cast<Char>('0'));
2410
1.02k
  }
2411
0
  auto buffer = memory_buffer();
2412
0
  write_significand<char>(appender(buffer), significand, significand_size);
2413
0
  detail::fill_n(appender(buffer), exponent, '0');
2414
0
  return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2415
1.02k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, unsigned long, fmt::v12::detail::fallback_digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned long, int, int, fmt::v12::detail::fallback_digit_grouping<char> const&)
Line
Count
Source
2406
1.06k
                                       const Grouping& grouping) -> OutputIt {
2407
1.06k
  if (!grouping.has_separator()) {
2408
1.06k
    out = write_significand<Char>(out, significand, significand_size);
2409
1.06k
    return detail::fill_n(out, exponent, static_cast<Char>('0'));
2410
1.06k
  }
2411
0
  auto buffer = memory_buffer();
2412
0
  write_significand<char>(appender(buffer), significand, significand_size);
2413
0
  detail::fill_n(appender(buffer), exponent, '0');
2414
0
  return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2415
1.06k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, char const*, fmt::v12::detail::digit_grouping<char> >(fmt::v12::basic_appender<char>, char const*, int, int, fmt::v12::detail::digit_grouping<char> const&)
Line
Count
Source
2406
2.98k
                                       const Grouping& grouping) -> OutputIt {
2407
2.98k
  if (!grouping.has_separator()) {
2408
2.98k
    out = write_significand<Char>(out, significand, significand_size);
2409
2.98k
    return detail::fill_n(out, exponent, static_cast<Char>('0'));
2410
2.98k
  }
2411
0
  auto buffer = memory_buffer();
2412
0
  write_significand<char>(appender(buffer), significand, significand_size);
2413
0
  detail::fill_n(appender(buffer), exponent, '0');
2414
0
  return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2415
2.98k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, unsigned int, fmt::v12::detail::digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned int, int, int, fmt::v12::detail::digit_grouping<char> const&)
Line
Count
Source
2406
1.41k
                                       const Grouping& grouping) -> OutputIt {
2407
1.41k
  if (!grouping.has_separator()) {
2408
1.41k
    out = write_significand<Char>(out, significand, significand_size);
2409
1.41k
    return detail::fill_n(out, exponent, static_cast<Char>('0'));
2410
1.41k
  }
2411
0
  auto buffer = memory_buffer();
2412
0
  write_significand<char>(appender(buffer), significand, significand_size);
2413
0
  detail::fill_n(appender(buffer), exponent, '0');
2414
0
  return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2415
1.41k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, unsigned long, fmt::v12::detail::digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned long, int, int, fmt::v12::detail::digit_grouping<char> const&)
Line
Count
Source
2406
1.37k
                                       const Grouping& grouping) -> OutputIt {
2407
1.37k
  if (!grouping.has_separator()) {
2408
1.37k
    out = write_significand<Char>(out, significand, significand_size);
2409
1.37k
    return detail::fill_n(out, exponent, static_cast<Char>('0'));
2410
1.37k
  }
2411
0
  auto buffer = memory_buffer();
2412
0
  write_significand<char>(appender(buffer), significand, significand_size);
2413
0
  detail::fill_n(appender(buffer), exponent, '0');
2414
0
  return grouping.apply(out, string_view(buffer.data(), buffer.size()));
2415
1.37k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<char, fmt::v12::basic_appender<char>, char const*, fmt::v12::detail::fallback_digit_grouping<char> >(fmt::v12::basic_appender<char>, char const*, int, int, fmt::v12::detail::fallback_digit_grouping<char> const&)
2416
2417
template <typename Char, typename UInt,
2418
          FMT_ENABLE_IF(std::is_integral<UInt>::value)>
2419
inline auto write_significand(Char* out, UInt significand, int significand_size,
2420
10.4k
                              int integral_size, Char decimal_point) -> Char* {
2421
10.4k
  if (!decimal_point) return format_decimal(out, significand, significand_size);
2422
9.12k
  out += significand_size + 1;
2423
9.12k
  Char* end = out;
2424
9.12k
  int floating_size = significand_size - integral_size;
2425
37.9k
  for (int i = floating_size / 2; i > 0; --i) {
2426
28.8k
    out -= 2;
2427
28.8k
    write2digits(out, static_cast<size_t>(significand % 100));
2428
28.8k
    significand /= 100;
2429
28.8k
  }
2430
9.12k
  if (floating_size % 2 != 0) {
2431
5.14k
    *--out = static_cast<Char>('0' + significand % 10);
2432
5.14k
    significand /= 10;
2433
5.14k
  }
2434
9.12k
  *--out = decimal_point;
2435
9.12k
  format_decimal(out - integral_size, significand, integral_size);
2436
9.12k
  return end;
2437
10.4k
}
_ZN3fmt3v126detail17write_significandIcjTnNSt3__19enable_ifIXsr3std11is_integralIT0_EE5valueEiE4typeELi0EEEPT_S9_S5_iiS8_
Line
Count
Source
2420
5.21k
                              int integral_size, Char decimal_point) -> Char* {
2421
5.21k
  if (!decimal_point) return format_decimal(out, significand, significand_size);
2422
4.64k
  out += significand_size + 1;
2423
4.64k
  Char* end = out;
2424
4.64k
  int floating_size = significand_size - integral_size;
2425
13.7k
  for (int i = floating_size / 2; i > 0; --i) {
2426
9.09k
    out -= 2;
2427
9.09k
    write2digits(out, static_cast<size_t>(significand % 100));
2428
9.09k
    significand /= 100;
2429
9.09k
  }
2430
4.64k
  if (floating_size % 2 != 0) {
2431
3.10k
    *--out = static_cast<Char>('0' + significand % 10);
2432
3.10k
    significand /= 10;
2433
3.10k
  }
2434
4.64k
  *--out = decimal_point;
2435
4.64k
  format_decimal(out - integral_size, significand, integral_size);
2436
4.64k
  return end;
2437
5.21k
}
_ZN3fmt3v126detail17write_significandIcmTnNSt3__19enable_ifIXsr3std11is_integralIT0_EE5valueEiE4typeELi0EEEPT_S9_S5_iiS8_
Line
Count
Source
2420
5.23k
                              int integral_size, Char decimal_point) -> Char* {
2421
5.23k
  if (!decimal_point) return format_decimal(out, significand, significand_size);
2422
4.48k
  out += significand_size + 1;
2423
4.48k
  Char* end = out;
2424
4.48k
  int floating_size = significand_size - integral_size;
2425
24.2k
  for (int i = floating_size / 2; i > 0; --i) {
2426
19.7k
    out -= 2;
2427
19.7k
    write2digits(out, static_cast<size_t>(significand % 100));
2428
19.7k
    significand /= 100;
2429
19.7k
  }
2430
4.48k
  if (floating_size % 2 != 0) {
2431
2.04k
    *--out = static_cast<Char>('0' + significand % 10);
2432
2.04k
    significand /= 10;
2433
2.04k
  }
2434
4.48k
  *--out = decimal_point;
2435
4.48k
  format_decimal(out - integral_size, significand, integral_size);
2436
4.48k
  return end;
2437
5.23k
}
2438
2439
template <typename OutputIt, typename UInt, typename Char,
2440
          FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
2441
inline auto write_significand(OutputIt out, UInt significand,
2442
                              int significand_size, int integral_size,
2443
10.4k
                              Char decimal_point) -> OutputIt {
2444
  // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2445
10.4k
  Char buffer[digits10<UInt>() + 2];
2446
10.4k
  auto end = write_significand(buffer, significand, significand_size,
2447
10.4k
                               integral_size, decimal_point);
2448
10.4k
  return detail::copy_noinline<Char>(buffer, end, out);
2449
10.4k
}
_ZN3fmt3v126detail17write_significandINS0_14basic_appenderIcEEjcTnNSt3__19enable_ifIXntsr3std10is_pointerINS5_9remove_cvINS5_16remove_referenceIT_E4typeEE4typeEEE5valueEiE4typeELi0EEES9_S9_T0_iiT1_
Line
Count
Source
2443
5.21k
                              Char decimal_point) -> OutputIt {
2444
  // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2445
5.21k
  Char buffer[digits10<UInt>() + 2];
2446
5.21k
  auto end = write_significand(buffer, significand, significand_size,
2447
5.21k
                               integral_size, decimal_point);
2448
5.21k
  return detail::copy_noinline<Char>(buffer, end, out);
2449
5.21k
}
_ZN3fmt3v126detail17write_significandINS0_14basic_appenderIcEEmcTnNSt3__19enable_ifIXntsr3std10is_pointerINS5_9remove_cvINS5_16remove_referenceIT_E4typeEE4typeEEE5valueEiE4typeELi0EEES9_S9_T0_iiT1_
Line
Count
Source
2443
5.23k
                              Char decimal_point) -> OutputIt {
2444
  // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
2445
5.23k
  Char buffer[digits10<UInt>() + 2];
2446
5.23k
  auto end = write_significand(buffer, significand, significand_size,
2447
5.23k
                               integral_size, decimal_point);
2448
5.23k
  return detail::copy_noinline<Char>(buffer, end, out);
2449
5.23k
}
2450
2451
template <typename OutputIt, typename Char>
2452
FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,
2453
                                     int significand_size, int integral_size,
2454
15.2k
                                     Char decimal_point) -> OutputIt {
2455
15.2k
  out = detail::copy_noinline<Char>(significand, significand + integral_size,
2456
15.2k
                                    out);
2457
15.2k
  if (!decimal_point) return out;
2458
13.5k
  *out++ = decimal_point;
2459
13.5k
  return detail::copy_noinline<Char>(significand + integral_size,
2460
13.5k
                                     significand + significand_size, out);
2461
15.2k
}
2462
2463
template <typename OutputIt, typename Char, typename T, typename Grouping>
2464
FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
2465
                                       int significand_size, int integral_size,
2466
                                       Char decimal_point,
2467
10.2k
                                       const Grouping& grouping) -> OutputIt {
2468
10.2k
  if (!grouping.has_separator()) {
2469
10.2k
    return write_significand(out, significand, significand_size, integral_size,
2470
10.2k
                             decimal_point);
2471
10.2k
  }
2472
0
  auto buffer = basic_memory_buffer<Char>();
2473
0
  write_significand(basic_appender<Char>(buffer), significand, significand_size,
2474
0
                    integral_size, decimal_point);
2475
0
  grouping.apply(
2476
0
      out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2477
0
  return detail::copy_noinline<Char>(buffer.data() + integral_size,
2478
0
                                     buffer.end(), out);
2479
10.2k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<fmt::v12::basic_appender<char>, char, unsigned int, fmt::v12::detail::fallback_digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned int, int, int, char, fmt::v12::detail::fallback_digit_grouping<char> const&)
Line
Count
Source
2467
753
                                       const Grouping& grouping) -> OutputIt {
2468
753
  if (!grouping.has_separator()) {
2469
753
    return write_significand(out, significand, significand_size, integral_size,
2470
753
                             decimal_point);
2471
753
  }
2472
0
  auto buffer = basic_memory_buffer<Char>();
2473
0
  write_significand(basic_appender<Char>(buffer), significand, significand_size,
2474
0
                    integral_size, decimal_point);
2475
0
  grouping.apply(
2476
0
      out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2477
0
  return detail::copy_noinline<Char>(buffer.data() + integral_size,
2478
0
                                     buffer.end(), out);
2479
753
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<fmt::v12::basic_appender<char>, char, unsigned long, fmt::v12::detail::fallback_digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned long, int, int, char, fmt::v12::detail::fallback_digit_grouping<char> const&)
Line
Count
Source
2467
1.03k
                                       const Grouping& grouping) -> OutputIt {
2468
1.03k
  if (!grouping.has_separator()) {
2469
1.03k
    return write_significand(out, significand, significand_size, integral_size,
2470
1.03k
                             decimal_point);
2471
1.03k
  }
2472
0
  auto buffer = basic_memory_buffer<Char>();
2473
0
  write_significand(basic_appender<Char>(buffer), significand, significand_size,
2474
0
                    integral_size, decimal_point);
2475
0
  grouping.apply(
2476
0
      out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2477
0
  return detail::copy_noinline<Char>(buffer.data() + integral_size,
2478
0
                                     buffer.end(), out);
2479
1.03k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<fmt::v12::basic_appender<char>, char, char const*, fmt::v12::detail::digit_grouping<char> >(fmt::v12::basic_appender<char>, char const*, int, int, char, fmt::v12::detail::digit_grouping<char> const&)
Line
Count
Source
2467
5.72k
                                       const Grouping& grouping) -> OutputIt {
2468
5.72k
  if (!grouping.has_separator()) {
2469
5.72k
    return write_significand(out, significand, significand_size, integral_size,
2470
5.72k
                             decimal_point);
2471
5.72k
  }
2472
0
  auto buffer = basic_memory_buffer<Char>();
2473
0
  write_significand(basic_appender<Char>(buffer), significand, significand_size,
2474
0
                    integral_size, decimal_point);
2475
0
  grouping.apply(
2476
0
      out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2477
0
  return detail::copy_noinline<Char>(buffer.data() + integral_size,
2478
0
                                     buffer.end(), out);
2479
5.72k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<fmt::v12::basic_appender<char>, char, unsigned int, fmt::v12::detail::digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned int, int, int, char, fmt::v12::detail::digit_grouping<char> const&)
Line
Count
Source
2467
1.37k
                                       const Grouping& grouping) -> OutputIt {
2468
1.37k
  if (!grouping.has_separator()) {
2469
1.37k
    return write_significand(out, significand, significand_size, integral_size,
2470
1.37k
                             decimal_point);
2471
1.37k
  }
2472
0
  auto buffer = basic_memory_buffer<Char>();
2473
0
  write_significand(basic_appender<Char>(buffer), significand, significand_size,
2474
0
                    integral_size, decimal_point);
2475
0
  grouping.apply(
2476
0
      out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2477
0
  return detail::copy_noinline<Char>(buffer.data() + integral_size,
2478
0
                                     buffer.end(), out);
2479
1.37k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<fmt::v12::basic_appender<char>, char, unsigned long, fmt::v12::detail::digit_grouping<char> >(fmt::v12::basic_appender<char>, unsigned long, int, int, char, fmt::v12::detail::digit_grouping<char> const&)
Line
Count
Source
2467
1.31k
                                       const Grouping& grouping) -> OutputIt {
2468
1.31k
  if (!grouping.has_separator()) {
2469
1.31k
    return write_significand(out, significand, significand_size, integral_size,
2470
1.31k
                             decimal_point);
2471
1.31k
  }
2472
0
  auto buffer = basic_memory_buffer<Char>();
2473
0
  write_significand(basic_appender<Char>(buffer), significand, significand_size,
2474
0
                    integral_size, decimal_point);
2475
0
  grouping.apply(
2476
0
      out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
2477
0
  return detail::copy_noinline<Char>(buffer.data() + integral_size,
2478
0
                                     buffer.end(), out);
2479
1.31k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_significand<fmt::v12::basic_appender<char>, char, char const*, fmt::v12::detail::fallback_digit_grouping<char> >(fmt::v12::basic_appender<char>, char const*, int, int, char, fmt::v12::detail::fallback_digit_grouping<char> const&)
2480
2481
// Numbers with exponents greater or equal to the returned value will use
2482
// the exponential notation.
2483
52.7k
template <typename T> FMT_CONSTEVAL auto exp_upper() -> int {
2484
52.7k
  return std::numeric_limits<T>::digits10 != 0
2485
52.7k
             ? min_of(16, std::numeric_limits<T>::digits10 + 1)
2486
52.7k
             : 16;
2487
52.7k
}
int fmt::v12::detail::exp_upper<float>()
Line
Count
Source
2483
18.2k
template <typename T> FMT_CONSTEVAL auto exp_upper() -> int {
2484
18.2k
  return std::numeric_limits<T>::digits10 != 0
2485
18.2k
             ? min_of(16, std::numeric_limits<T>::digits10 + 1)
2486
18.2k
             : 16;
2487
18.2k
}
int fmt::v12::detail::exp_upper<double>()
Line
Count
Source
2483
19.9k
template <typename T> FMT_CONSTEVAL auto exp_upper() -> int {
2484
19.9k
  return std::numeric_limits<T>::digits10 != 0
2485
19.9k
             ? min_of(16, std::numeric_limits<T>::digits10 + 1)
2486
19.9k
             : 16;
2487
19.9k
}
int fmt::v12::detail::exp_upper<long double>()
Line
Count
Source
2483
14.5k
template <typename T> FMT_CONSTEVAL auto exp_upper() -> int {
2484
14.5k
  return std::numeric_limits<T>::digits10 != 0
2485
14.5k
             ? min_of(16, std::numeric_limits<T>::digits10 + 1)
2486
14.5k
             : 16;
2487
14.5k
}
2488
2489
// Use the fixed notation if the exponent is in [-4, exp_upper),
2490
// e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
2491
38.7k
constexpr auto use_fixed(int exp, int exp_upper) -> bool {
2492
38.7k
  return exp >= -4 && exp < exp_upper;
2493
38.7k
}
2494
2495
template <typename Char> class fallback_digit_grouping {
2496
 public:
2497
3.88k
  constexpr fallback_digit_grouping(locale_ref, bool) {}
2498
2499
3.88k
  constexpr auto has_separator() const -> bool { return false; }
2500
2501
3.88k
  constexpr auto count_separators(int) const -> int { return 0; }
2502
2503
  template <typename Out, typename C>
2504
0
  constexpr auto apply(Out out, basic_string_view<C>) const -> Out {
2505
0
    return out;
2506
0
  }
2507
};
2508
2509
template <typename Char, typename Grouping, typename OutputIt,
2510
          typename DecimalFP>
2511
FMT_CONSTEXPR20 auto write_fixed(OutputIt out, const DecimalFP& f,
2512
                                 int significand_size, Char decimal_point,
2513
                                 const format_specs& specs, sign s,
2514
26.8k
                                 locale_ref loc = {}) -> OutputIt {
2515
26.8k
  using iterator = reserve_iterator<OutputIt>;
2516
2517
26.8k
  int exp = f.exponent + significand_size;
2518
26.8k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2519
26.8k
  if (f.exponent >= 0) {
2520
    // 1234e5 -> 123400000[.0+]
2521
8.03k
    size += f.exponent;
2522
8.03k
    int num_zeros = specs.precision - exp;
2523
8.03k
    abort_fuzzing_if(num_zeros > 5000);
2524
8.03k
    if (specs.alt()) {
2525
1.01k
      ++size;
2526
1.01k
      if (num_zeros <= 0 && specs.type() != presentation_type::fixed)
2527
591
        num_zeros = 0;
2528
1.01k
      if (num_zeros > 0) size += num_zeros;
2529
1.01k
    }
2530
8.03k
    auto grouping = Grouping(loc, specs.localized());
2531
8.03k
    size += grouping.count_separators(exp);
2532
8.03k
    return write_padded<Char, align::right>(
2533
8.03k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
7.86k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
7.86k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
7.86k
                                       f.exponent, grouping);
2537
7.86k
          if (!specs.alt()) return it;
2538
1.01k
          *it++ = decimal_point;
2539
1.01k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
7.86k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2533
1.02k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.02k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.02k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.02k
                                       f.exponent, grouping);
2537
1.02k
          if (!specs.alt()) return it;
2538
0
          *it++ = decimal_point;
2539
0
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.02k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2533
1.06k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.06k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.06k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.06k
                                       f.exponent, grouping);
2537
1.06k
          if (!specs.alt()) return it;
2538
0
          *it++ = decimal_point;
2539
0
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.06k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2533
2.98k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
2.98k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
2.98k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
2.98k
                                       f.exponent, grouping);
2537
2.98k
          if (!specs.alt()) return it;
2538
619
          *it++ = decimal_point;
2539
619
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
2.98k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2533
1.41k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.41k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.41k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.41k
                                       f.exponent, grouping);
2537
1.41k
          if (!specs.alt()) return it;
2538
196
          *it++ = decimal_point;
2539
196
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.41k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2533
1.37k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.37k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.37k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.37k
                                       f.exponent, grouping);
2537
1.37k
          if (!specs.alt()) return it;
2538
201
          *it++ = decimal_point;
2539
201
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.37k
        });
2541
8.03k
  }
2542
18.8k
  if (exp > 0) {
2543
    // 1234e-2 -> 12.34[0+]
2544
10.3k
    int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
2545
10.3k
    size += 1 + max_of(num_zeros, 0);
2546
10.3k
    auto grouping = Grouping(loc, specs.localized());
2547
10.3k
    size += grouping.count_separators(exp);
2548
10.3k
    return write_padded<Char, align::right>(
2549
10.3k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
10.2k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
10.2k
          it = write_significand(it, f.significand, significand_size, exp,
2552
10.2k
                                 decimal_point, grouping);
2553
10.2k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
10.2k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2549
753
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
753
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
753
          it = write_significand(it, f.significand, significand_size, exp,
2552
753
                                 decimal_point, grouping);
2553
753
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
753
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2549
1.03k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
1.03k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
1.03k
          it = write_significand(it, f.significand, significand_size, exp,
2552
1.03k
                                 decimal_point, grouping);
2553
1.03k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
1.03k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2549
5.72k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
5.72k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
5.72k
          it = write_significand(it, f.significand, significand_size, exp,
2552
5.72k
                                 decimal_point, grouping);
2553
5.72k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
5.72k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2549
1.37k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
1.37k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
1.37k
          it = write_significand(it, f.significand, significand_size, exp,
2552
1.37k
                                 decimal_point, grouping);
2553
1.37k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
1.37k
        });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#2}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2549
1.31k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
1.31k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
1.31k
          it = write_significand(it, f.significand, significand_size, exp,
2552
1.31k
                                 decimal_point, grouping);
2553
1.31k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
1.31k
        });
2555
10.3k
  }
2556
  // 1234e-6 -> 0.001234
2557
8.49k
  int num_zeros = -exp;
2558
8.49k
  if (significand_size == 0 && specs.precision >= 0 &&
2559
512
      specs.precision < num_zeros) {
2560
512
    num_zeros = specs.precision;
2561
512
  }
2562
8.49k
  bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
2563
8.49k
  size += 1 + (pointy ? 1 : 0) + num_zeros;
2564
8.49k
  return write_padded<Char, align::right>(
2565
8.49k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
8.37k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
8.37k
        *it++ = Char('0');
2568
8.37k
        if (!pointy) return it;
2569
8.15k
        *it++ = decimal_point;
2570
8.15k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
8.15k
        return write_significand<Char>(it, f.significand, significand_size);
2572
8.37k
      });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2565
949
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
949
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
949
        *it++ = Char('0');
2568
949
        if (!pointy) return it;
2569
949
        *it++ = decimal_point;
2570
949
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
949
        return write_significand<Char>(it, f.significand, significand_size);
2572
949
      });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2565
1.22k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
1.22k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
1.22k
        *it++ = Char('0');
2568
1.22k
        if (!pointy) return it;
2569
1.22k
        *it++ = decimal_point;
2570
1.22k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
1.22k
        return write_significand<Char>(it, f.significand, significand_size);
2572
1.22k
      });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2565
3.90k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
3.90k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
3.90k
        *it++ = Char('0');
2568
3.90k
        if (!pointy) return it;
2569
3.69k
        *it++ = decimal_point;
2570
3.69k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
3.69k
        return write_significand<Char>(it, f.significand, significand_size);
2572
3.90k
      });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2565
1.14k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
1.14k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
1.14k
        *it++ = Char('0');
2568
1.14k
        if (!pointy) return it;
2569
1.14k
        *it++ = decimal_point;
2570
1.14k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
1.14k
        return write_significand<Char>(it, f.significand, significand_size);
2572
1.14k
      });
fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#3}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2565
1.14k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
1.14k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
1.14k
        *it++ = Char('0');
2568
1.14k
        if (!pointy) return it;
2569
1.14k
        *it++ = decimal_point;
2570
1.14k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
1.14k
        return write_significand<Char>(it, f.significand, significand_size);
2572
1.14k
      });
2573
18.8k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)
Line
Count
Source
2514
2.73k
                                 locale_ref loc = {}) -> OutputIt {
2515
2.73k
  using iterator = reserve_iterator<OutputIt>;
2516
2517
2.73k
  int exp = f.exponent + significand_size;
2518
2.73k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2519
2.73k
  if (f.exponent >= 0) {
2520
    // 1234e5 -> 123400000[.0+]
2521
1.02k
    size += f.exponent;
2522
1.02k
    int num_zeros = specs.precision - exp;
2523
1.02k
    abort_fuzzing_if(num_zeros > 5000);
2524
1.02k
    if (specs.alt()) {
2525
0
      ++size;
2526
0
      if (num_zeros <= 0 && specs.type() != presentation_type::fixed)
2527
0
        num_zeros = 0;
2528
0
      if (num_zeros > 0) size += num_zeros;
2529
0
    }
2530
1.02k
    auto grouping = Grouping(loc, specs.localized());
2531
1.02k
    size += grouping.count_separators(exp);
2532
1.02k
    return write_padded<Char, align::right>(
2533
1.02k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.02k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.02k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.02k
                                       f.exponent, grouping);
2537
1.02k
          if (!specs.alt()) return it;
2538
1.02k
          *it++ = decimal_point;
2539
1.02k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.02k
        });
2541
1.02k
  }
2542
1.70k
  if (exp > 0) {
2543
    // 1234e-2 -> 12.34[0+]
2544
754
    int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
2545
754
    size += 1 + max_of(num_zeros, 0);
2546
754
    auto grouping = Grouping(loc, specs.localized());
2547
754
    size += grouping.count_separators(exp);
2548
754
    return write_padded<Char, align::right>(
2549
754
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
754
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
754
          it = write_significand(it, f.significand, significand_size, exp,
2552
754
                                 decimal_point, grouping);
2553
754
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
754
        });
2555
754
  }
2556
  // 1234e-6 -> 0.001234
2557
950
  int num_zeros = -exp;
2558
950
  if (significand_size == 0 && specs.precision >= 0 &&
2559
0
      specs.precision < num_zeros) {
2560
0
    num_zeros = specs.precision;
2561
0
  }
2562
950
  bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
2563
950
  size += 1 + (pointy ? 1 : 0) + num_zeros;
2564
950
  return write_padded<Char, align::right>(
2565
950
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
950
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
950
        *it++ = Char('0');
2568
950
        if (!pointy) return it;
2569
950
        *it++ = decimal_point;
2570
950
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
950
        return write_significand<Char>(it, f.significand, significand_size);
2572
950
      });
2573
1.70k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)
Line
Count
Source
2514
3.32k
                                 locale_ref loc = {}) -> OutputIt {
2515
3.32k
  using iterator = reserve_iterator<OutputIt>;
2516
2517
3.32k
  int exp = f.exponent + significand_size;
2518
3.32k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2519
3.32k
  if (f.exponent >= 0) {
2520
    // 1234e5 -> 123400000[.0+]
2521
1.06k
    size += f.exponent;
2522
1.06k
    int num_zeros = specs.precision - exp;
2523
1.06k
    abort_fuzzing_if(num_zeros > 5000);
2524
1.06k
    if (specs.alt()) {
2525
0
      ++size;
2526
0
      if (num_zeros <= 0 && specs.type() != presentation_type::fixed)
2527
0
        num_zeros = 0;
2528
0
      if (num_zeros > 0) size += num_zeros;
2529
0
    }
2530
1.06k
    auto grouping = Grouping(loc, specs.localized());
2531
1.06k
    size += grouping.count_separators(exp);
2532
1.06k
    return write_padded<Char, align::right>(
2533
1.06k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.06k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.06k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.06k
                                       f.exponent, grouping);
2537
1.06k
          if (!specs.alt()) return it;
2538
1.06k
          *it++ = decimal_point;
2539
1.06k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.06k
        });
2541
1.06k
  }
2542
2.26k
  if (exp > 0) {
2543
    // 1234e-2 -> 12.34[0+]
2544
1.03k
    int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
2545
1.03k
    size += 1 + max_of(num_zeros, 0);
2546
1.03k
    auto grouping = Grouping(loc, specs.localized());
2547
1.03k
    size += grouping.count_separators(exp);
2548
1.03k
    return write_padded<Char, align::right>(
2549
1.03k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
1.03k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
1.03k
          it = write_significand(it, f.significand, significand_size, exp,
2552
1.03k
                                 decimal_point, grouping);
2553
1.03k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
1.03k
        });
2555
1.03k
  }
2556
  // 1234e-6 -> 0.001234
2557
1.22k
  int num_zeros = -exp;
2558
1.22k
  if (significand_size == 0 && specs.precision >= 0 &&
2559
0
      specs.precision < num_zeros) {
2560
0
    num_zeros = specs.precision;
2561
0
  }
2562
1.22k
  bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
2563
1.22k
  size += 1 + (pointy ? 1 : 0) + num_zeros;
2564
1.22k
  return write_padded<Char, align::right>(
2565
1.22k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
1.22k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
1.22k
        *it++ = Char('0');
2568
1.22k
        if (!pointy) return it;
2569
1.22k
        *it++ = decimal_point;
2570
1.22k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
1.22k
        return write_significand<Char>(it, f.significand, significand_size);
2572
1.22k
      });
2573
2.26k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)
Line
Count
Source
2514
12.8k
                                 locale_ref loc = {}) -> OutputIt {
2515
12.8k
  using iterator = reserve_iterator<OutputIt>;
2516
2517
12.8k
  int exp = f.exponent + significand_size;
2518
12.8k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2519
12.8k
  if (f.exponent >= 0) {
2520
    // 1234e5 -> 123400000[.0+]
2521
3.06k
    size += f.exponent;
2522
3.06k
    int num_zeros = specs.precision - exp;
2523
3.06k
    abort_fuzzing_if(num_zeros > 5000);
2524
3.06k
    if (specs.alt()) {
2525
620
      ++size;
2526
620
      if (num_zeros <= 0 && specs.type() != presentation_type::fixed)
2527
194
        num_zeros = 0;
2528
620
      if (num_zeros > 0) size += num_zeros;
2529
620
    }
2530
3.06k
    auto grouping = Grouping(loc, specs.localized());
2531
3.06k
    size += grouping.count_separators(exp);
2532
3.06k
    return write_padded<Char, align::right>(
2533
3.06k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
3.06k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
3.06k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
3.06k
                                       f.exponent, grouping);
2537
3.06k
          if (!specs.alt()) return it;
2538
3.06k
          *it++ = decimal_point;
2539
3.06k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
3.06k
        });
2541
3.06k
  }
2542
9.74k
  if (exp > 0) {
2543
    // 1234e-2 -> 12.34[0+]
2544
5.80k
    int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
2545
5.80k
    size += 1 + max_of(num_zeros, 0);
2546
5.80k
    auto grouping = Grouping(loc, specs.localized());
2547
5.80k
    size += grouping.count_separators(exp);
2548
5.80k
    return write_padded<Char, align::right>(
2549
5.80k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
5.80k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
5.80k
          it = write_significand(it, f.significand, significand_size, exp,
2552
5.80k
                                 decimal_point, grouping);
2553
5.80k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
5.80k
        });
2555
5.80k
  }
2556
  // 1234e-6 -> 0.001234
2557
3.93k
  int num_zeros = -exp;
2558
3.93k
  if (significand_size == 0 && specs.precision >= 0 &&
2559
512
      specs.precision < num_zeros) {
2560
512
    num_zeros = specs.precision;
2561
512
  }
2562
3.93k
  bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
2563
3.93k
  size += 1 + (pointy ? 1 : 0) + num_zeros;
2564
3.93k
  return write_padded<Char, align::right>(
2565
3.93k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
3.93k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
3.93k
        *it++ = Char('0');
2568
3.93k
        if (!pointy) return it;
2569
3.93k
        *it++ = decimal_point;
2570
3.93k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
3.93k
        return write_significand<Char>(it, f.significand, significand_size);
2572
3.93k
      });
2573
9.74k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)
Line
Count
Source
2514
4.05k
                                 locale_ref loc = {}) -> OutputIt {
2515
4.05k
  using iterator = reserve_iterator<OutputIt>;
2516
2517
4.05k
  int exp = f.exponent + significand_size;
2518
4.05k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2519
4.05k
  if (f.exponent >= 0) {
2520
    // 1234e5 -> 123400000[.0+]
2521
1.47k
    size += f.exponent;
2522
1.47k
    int num_zeros = specs.precision - exp;
2523
1.47k
    abort_fuzzing_if(num_zeros > 5000);
2524
1.47k
    if (specs.alt()) {
2525
196
      ++size;
2526
196
      if (num_zeros <= 0 && specs.type() != presentation_type::fixed)
2527
196
        num_zeros = 0;
2528
196
      if (num_zeros > 0) size += num_zeros;
2529
196
    }
2530
1.47k
    auto grouping = Grouping(loc, specs.localized());
2531
1.47k
    size += grouping.count_separators(exp);
2532
1.47k
    return write_padded<Char, align::right>(
2533
1.47k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.47k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.47k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.47k
                                       f.exponent, grouping);
2537
1.47k
          if (!specs.alt()) return it;
2538
1.47k
          *it++ = decimal_point;
2539
1.47k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.47k
        });
2541
1.47k
  }
2542
2.58k
  if (exp > 0) {
2543
    // 1234e-2 -> 12.34[0+]
2544
1.39k
    int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
2545
1.39k
    size += 1 + max_of(num_zeros, 0);
2546
1.39k
    auto grouping = Grouping(loc, specs.localized());
2547
1.39k
    size += grouping.count_separators(exp);
2548
1.39k
    return write_padded<Char, align::right>(
2549
1.39k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
1.39k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
1.39k
          it = write_significand(it, f.significand, significand_size, exp,
2552
1.39k
                                 decimal_point, grouping);
2553
1.39k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
1.39k
        });
2555
1.39k
  }
2556
  // 1234e-6 -> 0.001234
2557
1.19k
  int num_zeros = -exp;
2558
1.19k
  if (significand_size == 0 && specs.precision >= 0 &&
2559
0
      specs.precision < num_zeros) {
2560
0
    num_zeros = specs.precision;
2561
0
  }
2562
1.19k
  bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
2563
1.19k
  size += 1 + (pointy ? 1 : 0) + num_zeros;
2564
1.19k
  return write_padded<Char, align::right>(
2565
1.19k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
1.19k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
1.19k
        *it++ = Char('0');
2568
1.19k
        if (!pointy) return it;
2569
1.19k
        *it++ = decimal_point;
2570
1.19k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
1.19k
        return write_significand<Char>(it, f.significand, significand_size);
2572
1.19k
      });
2573
2.58k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_fixed<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)
Line
Count
Source
2514
3.97k
                                 locale_ref loc = {}) -> OutputIt {
2515
3.97k
  using iterator = reserve_iterator<OutputIt>;
2516
2517
3.97k
  int exp = f.exponent + significand_size;
2518
3.97k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2519
3.97k
  if (f.exponent >= 0) {
2520
    // 1234e5 -> 123400000[.0+]
2521
1.41k
    size += f.exponent;
2522
1.41k
    int num_zeros = specs.precision - exp;
2523
1.41k
    abort_fuzzing_if(num_zeros > 5000);
2524
1.41k
    if (specs.alt()) {
2525
201
      ++size;
2526
201
      if (num_zeros <= 0 && specs.type() != presentation_type::fixed)
2527
201
        num_zeros = 0;
2528
201
      if (num_zeros > 0) size += num_zeros;
2529
201
    }
2530
1.41k
    auto grouping = Grouping(loc, specs.localized());
2531
1.41k
    size += grouping.count_separators(exp);
2532
1.41k
    return write_padded<Char, align::right>(
2533
1.41k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2534
1.41k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2535
1.41k
          it = write_significand<Char>(it, f.significand, significand_size,
2536
1.41k
                                       f.exponent, grouping);
2537
1.41k
          if (!specs.alt()) return it;
2538
1.41k
          *it++ = decimal_point;
2539
1.41k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2540
1.41k
        });
2541
1.41k
  }
2542
2.56k
  if (exp > 0) {
2543
    // 1234e-2 -> 12.34[0+]
2544
1.37k
    int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
2545
1.37k
    size += 1 + max_of(num_zeros, 0);
2546
1.37k
    auto grouping = Grouping(loc, specs.localized());
2547
1.37k
    size += grouping.count_separators(exp);
2548
1.37k
    return write_padded<Char, align::right>(
2549
1.37k
        out, specs, static_cast<size_t>(size), [&](iterator it) {
2550
1.37k
          if (s != sign::none) *it++ = detail::getsign<Char>(s);
2551
1.37k
          it = write_significand(it, f.significand, significand_size, exp,
2552
1.37k
                                 decimal_point, grouping);
2553
1.37k
          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;
2554
1.37k
        });
2555
1.37k
  }
2556
  // 1234e-6 -> 0.001234
2557
1.18k
  int num_zeros = -exp;
2558
1.18k
  if (significand_size == 0 && specs.precision >= 0 &&
2559
0
      specs.precision < num_zeros) {
2560
0
    num_zeros = specs.precision;
2561
0
  }
2562
1.18k
  bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();
2563
1.18k
  size += 1 + (pointy ? 1 : 0) + num_zeros;
2564
1.18k
  return write_padded<Char, align::right>(
2565
1.18k
      out, specs, static_cast<size_t>(size), [&](iterator it) {
2566
1.18k
        if (s != sign::none) *it++ = detail::getsign<Char>(s);
2567
1.18k
        *it++ = Char('0');
2568
1.18k
        if (!pointy) return it;
2569
1.18k
        *it++ = decimal_point;
2570
1.18k
        it = detail::fill_n(it, num_zeros, Char('0'));
2571
1.18k
        return write_significand<Char>(it, f.significand, significand_size);
2572
1.18k
      });
2573
2.56k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::write_fixed<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, int, char, fmt::v12::format_specs const&, fmt::v12::sign, fmt::v12::locale_ref)
2574
2575
template <typename Char, typename Grouping, typename OutputIt,
2576
          typename DecimalFP>
2577
FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
2578
                                    const format_specs& specs, sign s,
2579
36.6k
                                    int exp_upper, locale_ref loc) -> OutputIt {
2580
36.6k
  Char point = specs.localized() ? detail::decimal_point<Char>(loc) : Char('.');
2581
36.6k
  int significand_size = get_significand_size(f);
2582
36.6k
  int exp = f.exponent + significand_size - 1;
2583
36.6k
  if (specs.type() == presentation_type::fixed ||
2584
29.1k
      (specs.type() != presentation_type::exp &&
2585
26.8k
       use_fixed(exp, specs.precision > 0 ? specs.precision : exp_upper))) {
2586
20.8k
    return write_fixed<Char, Grouping>(out, f, significand_size, point, specs,
2587
20.8k
                                       s, loc);
2588
20.8k
  }
2589
2590
  // Write value in the exponential format.
2591
15.8k
  int num_zeros = 0;
2592
15.8k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2593
15.8k
  if (specs.alt()) {
2594
2.38k
    num_zeros = max_of(specs.precision - significand_size, 0);
2595
2.38k
    size += num_zeros;
2596
13.4k
  } else if (significand_size == 1) {
2597
3.02k
    point = Char();
2598
3.02k
  }
2599
15.8k
  size += (point ? 1 : 0) + compute_exp_size(exp);
2600
15.8k
  char exp_char = specs.upper() ? 'E' : 'e';
2601
15.8k
  auto write = [=](reserve_iterator<OutputIt> it) {
2602
15.5k
    if (s != sign::none) *it++ = detail::getsign<Char>(s);
2603
    // Insert a decimal point after the first digit and add an exponent.
2604
15.5k
    it = write_significand(it, f.significand, significand_size, 1, point);
2605
15.5k
    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));
2606
15.5k
    *it++ = Char(exp_char);
2607
15.5k
    return write_exponent<Char>(exp, it);
2608
15.5k
  };
fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2601
9.56k
  auto write = [=](reserve_iterator<OutputIt> it) {
2602
9.56k
    if (s != sign::none) *it++ = detail::getsign<Char>(s);
2603
    // Insert a decimal point after the first digit and add an exponent.
2604
9.56k
    it = write_significand(it, f.significand, significand_size, 1, point);
2605
9.56k
    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));
2606
9.56k
    *it++ = Char(exp_char);
2607
9.56k
    return write_exponent<Char>(exp, it);
2608
9.56k
  };
fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2601
3.08k
  auto write = [=](reserve_iterator<OutputIt> it) {
2602
3.08k
    if (s != sign::none) *it++ = detail::getsign<Char>(s);
2603
    // Insert a decimal point after the first digit and add an exponent.
2604
3.08k
    it = write_significand(it, f.significand, significand_size, 1, point);
2605
3.08k
    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));
2606
3.08k
    *it++ = Char(exp_char);
2607
3.08k
    return write_exponent<Char>(exp, it);
2608
3.08k
  };
fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)::{lambda(fmt::v12::basic_appender<char>)#1}::operator()(fmt::v12::basic_appender<char>) const
Line
Count
Source
2601
2.88k
  auto write = [=](reserve_iterator<OutputIt> it) {
2602
2.88k
    if (s != sign::none) *it++ = detail::getsign<Char>(s);
2603
    // Insert a decimal point after the first digit and add an exponent.
2604
2.88k
    it = write_significand(it, f.significand, significand_size, 1, point);
2605
2.88k
    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));
2606
2.88k
    *it++ = Char(exp_char);
2607
2.88k
    return write_exponent<Char>(exp, it);
2608
2.88k
  };
2609
15.8k
  size_t usize = static_cast<size_t>(size);
2610
15.8k
  return specs.width > 0
2611
15.8k
             ? write_padded<Char, align::right>(out, specs, usize, write)
2612
15.8k
             : base_iterator(out, write(reserve(out, usize)));
2613
36.6k
}
fmt::v12::basic_appender<char> fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Line
Count
Source
2579
22.5k
                                    int exp_upper, locale_ref loc) -> OutputIt {
2580
22.5k
  Char point = specs.localized() ? detail::decimal_point<Char>(loc) : Char('.');
2581
22.5k
  int significand_size = get_significand_size(f);
2582
22.5k
  int exp = f.exponent + significand_size - 1;
2583
22.5k
  if (specs.type() == presentation_type::fixed ||
2584
15.0k
      (specs.type() != presentation_type::exp &&
2585
12.8k
       use_fixed(exp, specs.precision > 0 ? specs.precision : exp_upper))) {
2586
12.8k
    return write_fixed<Char, Grouping>(out, f, significand_size, point, specs,
2587
12.8k
                                       s, loc);
2588
12.8k
  }
2589
2590
  // Write value in the exponential format.
2591
9.74k
  int num_zeros = 0;
2592
9.74k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2593
9.74k
  if (specs.alt()) {
2594
1.99k
    num_zeros = max_of(specs.precision - significand_size, 0);
2595
1.99k
    size += num_zeros;
2596
7.75k
  } else if (significand_size == 1) {
2597
1.70k
    point = Char();
2598
1.70k
  }
2599
9.74k
  size += (point ? 1 : 0) + compute_exp_size(exp);
2600
9.74k
  char exp_char = specs.upper() ? 'E' : 'e';
2601
9.74k
  auto write = [=](reserve_iterator<OutputIt> it) {
2602
9.74k
    if (s != sign::none) *it++ = detail::getsign<Char>(s);
2603
    // Insert a decimal point after the first digit and add an exponent.
2604
9.74k
    it = write_significand(it, f.significand, significand_size, 1, point);
2605
9.74k
    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));
2606
9.74k
    *it++ = Char(exp_char);
2607
9.74k
    return write_exponent<Char>(exp, it);
2608
9.74k
  };
2609
9.74k
  size_t usize = static_cast<size_t>(size);
2610
9.74k
  return specs.width > 0
2611
9.74k
             ? write_padded<Char, align::right>(out, specs, usize, write)
2612
9.74k
             : base_iterator(out, write(reserve(out, usize)));
2613
22.5k
}
fmt::v12::basic_appender<char> fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Line
Count
Source
2579
7.18k
                                    int exp_upper, locale_ref loc) -> OutputIt {
2580
7.18k
  Char point = specs.localized() ? detail::decimal_point<Char>(loc) : Char('.');
2581
7.18k
  int significand_size = get_significand_size(f);
2582
7.18k
  int exp = f.exponent + significand_size - 1;
2583
7.18k
  if (specs.type() == presentation_type::fixed ||
2584
7.18k
      (specs.type() != presentation_type::exp &&
2585
7.18k
       use_fixed(exp, specs.precision > 0 ? specs.precision : exp_upper))) {
2586
4.05k
    return write_fixed<Char, Grouping>(out, f, significand_size, point, specs,
2587
4.05k
                                       s, loc);
2588
4.05k
  }
2589
2590
  // Write value in the exponential format.
2591
3.12k
  int num_zeros = 0;
2592
3.12k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2593
3.12k
  if (specs.alt()) {
2594
197
    num_zeros = max_of(specs.precision - significand_size, 0);
2595
197
    size += num_zeros;
2596
2.93k
  } else if (significand_size == 1) {
2597
574
    point = Char();
2598
574
  }
2599
3.12k
  size += (point ? 1 : 0) + compute_exp_size(exp);
2600
3.12k
  char exp_char = specs.upper() ? 'E' : 'e';
2601
3.12k
  auto write = [=](reserve_iterator<OutputIt> it) {
2602
3.12k
    if (s != sign::none) *it++ = detail::getsign<Char>(s);
2603
    // Insert a decimal point after the first digit and add an exponent.
2604
3.12k
    it = write_significand(it, f.significand, significand_size, 1, point);
2605
3.12k
    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));
2606
3.12k
    *it++ = Char(exp_char);
2607
3.12k
    return write_exponent<Char>(exp, it);
2608
3.12k
  };
2609
3.12k
  size_t usize = static_cast<size_t>(size);
2610
3.12k
  return specs.width > 0
2611
3.12k
             ? write_padded<Char, align::right>(out, specs, usize, write)
2612
3.12k
             : base_iterator(out, write(reserve(out, usize)));
2613
7.18k
}
fmt::v12::basic_appender<char> fmt::v12::detail::do_write_float<char, fmt::v12::detail::digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Line
Count
Source
2579
6.92k
                                    int exp_upper, locale_ref loc) -> OutputIt {
2580
6.92k
  Char point = specs.localized() ? detail::decimal_point<Char>(loc) : Char('.');
2581
6.92k
  int significand_size = get_significand_size(f);
2582
6.92k
  int exp = f.exponent + significand_size - 1;
2583
6.92k
  if (specs.type() == presentation_type::fixed ||
2584
6.92k
      (specs.type() != presentation_type::exp &&
2585
6.92k
       use_fixed(exp, specs.precision > 0 ? specs.precision : exp_upper))) {
2586
3.97k
    return write_fixed<Char, Grouping>(out, f, significand_size, point, specs,
2587
3.97k
                                       s, loc);
2588
3.97k
  }
2589
2590
  // Write value in the exponential format.
2591
2.95k
  int num_zeros = 0;
2592
2.95k
  long long size = significand_size + (s != sign::none ? 1 : 0);
2593
2.95k
  if (specs.alt()) {
2594
198
    num_zeros = max_of(specs.precision - significand_size, 0);
2595
198
    size += num_zeros;
2596
2.75k
  } else if (significand_size == 1) {
2597
751
    point = Char();
2598
751
  }
2599
2.95k
  size += (point ? 1 : 0) + compute_exp_size(exp);
2600
2.95k
  char exp_char = specs.upper() ? 'E' : 'e';
2601
2.95k
  auto write = [=](reserve_iterator<OutputIt> it) {
2602
2.95k
    if (s != sign::none) *it++ = detail::getsign<Char>(s);
2603
    // Insert a decimal point after the first digit and add an exponent.
2604
2.95k
    it = write_significand(it, f.significand, significand_size, 1, point);
2605
2.95k
    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));
2606
2.95k
    *it++ = Char(exp_char);
2607
2.95k
    return write_exponent<Char>(exp, it);
2608
2.95k
  };
2609
2.95k
  size_t usize = static_cast<size_t>(size);
2610
2.95k
  return specs.width > 0
2611
2.95k
             ? write_padded<Char, align::right>(out, specs, usize, write)
2612
2.95k
             : base_iterator(out, write(reserve(out, usize)));
2613
6.92k
}
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Unexecuted instantiation: fmt::v12::basic_appender<char> fmt::v12::detail::do_write_float<char, fmt::v12::detail::fallback_digit_grouping<char>, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
2614
2615
template <typename Char, typename OutputIt, typename DecimalFP>
2616
FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,
2617
                                 const format_specs& specs, sign s,
2618
36.6k
                                 int exp_upper, locale_ref loc) -> OutputIt {
2619
36.6k
  if (is_constant_evaluated()) {
2620
0
    return do_write_float<Char, fallback_digit_grouping<Char>>(out, f, specs, s,
2621
0
                                                               exp_upper, loc);
2622
36.6k
  } else {
2623
36.6k
    return do_write_float<Char, digit_grouping<Char>>(out, f, specs, s,
2624
36.6k
                                                      exp_upper, loc);
2625
36.6k
  }
2626
36.6k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_float<char, fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp>(fmt::v12::basic_appender<char>, fmt::v12::detail::big_decimal_fp const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Line
Count
Source
2618
22.5k
                                 int exp_upper, locale_ref loc) -> OutputIt {
2619
22.5k
  if (is_constant_evaluated()) {
2620
0
    return do_write_float<Char, fallback_digit_grouping<Char>>(out, f, specs, s,
2621
0
                                                               exp_upper, loc);
2622
22.5k
  } else {
2623
22.5k
    return do_write_float<Char, digit_grouping<Char>>(out, f, specs, s,
2624
22.5k
                                                      exp_upper, loc);
2625
22.5k
  }
2626
22.5k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_float<char, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<float> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Line
Count
Source
2618
7.18k
                                 int exp_upper, locale_ref loc) -> OutputIt {
2619
7.18k
  if (is_constant_evaluated()) {
2620
0
    return do_write_float<Char, fallback_digit_grouping<Char>>(out, f, specs, s,
2621
0
                                                               exp_upper, loc);
2622
7.18k
  } else {
2623
7.18k
    return do_write_float<Char, digit_grouping<Char>>(out, f, specs, s,
2624
7.18k
                                                      exp_upper, loc);
2625
7.18k
  }
2626
7.18k
}
fmt::v12::basic_appender<char> fmt::v12::detail::write_float<char, fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> >(fmt::v12::basic_appender<char>, fmt::v12::detail::dragonbox::decimal_fp<double> const&, fmt::v12::format_specs const&, fmt::v12::sign, int, fmt::v12::locale_ref)
Line
Count
Source
2618
6.92k
                                 int exp_upper, locale_ref loc) -> OutputIt {
2619
6.92k
  if (is_constant_evaluated()) {
2620
0
    return do_write_float<Char, fallback_digit_grouping<Char>>(out, f, specs, s,
2621
0
                                                               exp_upper, loc);
2622
6.92k
  } else {
2623
6.92k
    return do_write_float<Char, digit_grouping<Char>>(out, f, specs, s,
2624
6.92k
                                                      exp_upper, loc);
2625
6.92k
  }
2626
6.92k
}
2627
2628
5.10k
template <typename T> constexpr auto isnan(T value) -> bool {
2629
5.10k
  return value != value;  // std::isnan doesn't support __float128.
2630
5.10k
}
bool fmt::v12::detail::isnan<long double>(long double)
Line
Count
Source
2628
1.71k
template <typename T> constexpr auto isnan(T value) -> bool {
2629
1.71k
  return value != value;  // std::isnan doesn't support __float128.
2630
1.71k
}
bool fmt::v12::detail::isnan<float>(float)
Line
Count
Source
2628
1.80k
template <typename T> constexpr auto isnan(T value) -> bool {
2629
1.80k
  return value != value;  // std::isnan doesn't support __float128.
2630
1.80k
}
bool fmt::v12::detail::isnan<double>(double)
Line
Count
Source
2628
1.58k
template <typename T> constexpr auto isnan(T value) -> bool {
2629
1.58k
  return value != value;  // std::isnan doesn't support __float128.
2630
1.58k
}
2631
2632
template <typename T, typename Enable = void>
2633
struct has_isfinite : std::false_type {};
2634
2635
template <typename T>
2636
struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
2637
    : std::true_type {};
2638
2639
template <typename T,
2640
          FMT_ENABLE_IF(is_floating_point<T>::value&& has_isfinite<T>::value)>
2641
45.8k
FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
2642
45.8k
  constexpr T inf = T(std::numeric_limits<double>::infinity());
2643
45.8k
  if (is_constant_evaluated())
2644
0
    return !detail::isnan(value) && value < inf && value > -inf;
2645
45.8k
  return std::isfinite(value);
2646
45.8k
}
_ZN3fmt3v126detail8isfiniteIeTnNSt3__19enable_ifIXaasr17is_floating_pointIT_EE5valuesr12has_isfiniteIS5_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
2641
16.3k
FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
2642
16.3k
  constexpr T inf = T(std::numeric_limits<double>::infinity());
2643
16.3k
  if (is_constant_evaluated())
2644
0
    return !detail::isnan(value) && value < inf && value > -inf;
2645
16.3k
  return std::isfinite(value);
2646
16.3k
}
_ZN3fmt3v126detail8isfiniteIfTnNSt3__19enable_ifIXaasr17is_floating_pointIT_EE5valuesr12has_isfiniteIS5_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
2641
14.3k
FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
2642
14.3k
  constexpr T inf = T(std::numeric_limits<double>::infinity());
2643
14.3k
  if (is_constant_evaluated())
2644
0
    return !detail::isnan(value) && value < inf && value > -inf;
2645
14.3k
  return std::isfinite(value);
2646
14.3k
}
_ZN3fmt3v126detail8isfiniteIdTnNSt3__19enable_ifIXaasr17is_floating_pointIT_EE5valuesr12has_isfiniteIS5_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
2641
15.1k
FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
2642
15.1k
  constexpr T inf = T(std::numeric_limits<double>::infinity());
2643
15.1k
  if (is_constant_evaluated())
2644
0
    return !detail::isnan(value) && value < inf && value > -inf;
2645
15.1k
  return std::isfinite(value);
2646
15.1k
}
2647
template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
2648
FMT_CONSTEXPR auto isfinite(T value) -> bool {
2649
  T inf = T(std::numeric_limits<double>::infinity());
2650
  // std::isfinite doesn't support __float128.
2651
  return !detail::isnan(value) && value < inf && value > -inf;
2652
}
2653
2654
template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
2655
58.7k
FMT_INLINE FMT_CONSTEXPR auto signbit(T value) -> bool {
2656
58.7k
  if (is_constant_evaluated()) {
2657
#ifdef __cpp_if_constexpr
2658
    if constexpr (std::numeric_limits<double>::is_iec559) {
2659
      auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2660
      return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2661
    }
2662
#endif
2663
0
  }
2664
58.7k
  return std::signbit(static_cast<double>(value));
2665
58.7k
}
_ZN3fmt3v126detail7signbitIfTnNSt3__19enable_ifIXsr17is_floating_pointIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
2655
20.4k
FMT_INLINE FMT_CONSTEXPR auto signbit(T value) -> bool {
2656
20.4k
  if (is_constant_evaluated()) {
2657
#ifdef __cpp_if_constexpr
2658
    if constexpr (std::numeric_limits<double>::is_iec559) {
2659
      auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2660
      return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2661
    }
2662
#endif
2663
0
  }
2664
20.4k
  return std::signbit(static_cast<double>(value));
2665
20.4k
}
_ZN3fmt3v126detail7signbitIdTnNSt3__19enable_ifIXsr17is_floating_pointIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
2655
21.9k
FMT_INLINE FMT_CONSTEXPR auto signbit(T value) -> bool {
2656
21.9k
  if (is_constant_evaluated()) {
2657
#ifdef __cpp_if_constexpr
2658
    if constexpr (std::numeric_limits<double>::is_iec559) {
2659
      auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2660
      return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2661
    }
2662
#endif
2663
0
  }
2664
21.9k
  return std::signbit(static_cast<double>(value));
2665
21.9k
}
_ZN3fmt3v126detail7signbitIeTnNSt3__19enable_ifIXsr17is_floating_pointIT_EE5valueEiE4typeELi0EEEbS5_
Line
Count
Source
2655
16.3k
FMT_INLINE FMT_CONSTEXPR auto signbit(T value) -> bool {
2656
16.3k
  if (is_constant_evaluated()) {
2657
#ifdef __cpp_if_constexpr
2658
    if constexpr (std::numeric_limits<double>::is_iec559) {
2659
      auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
2660
      return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2661
    }
2662
#endif
2663
0
  }
2664
16.3k
  return std::signbit(static_cast<double>(value));
2665
16.3k
}
2666
2667
6.88k
inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {
2668
  // Adjust fixed precision by exponent because it is relative to decimal
2669
  // point.
2670
6.88k
  if (exp10 > 0 && precision > max_value<int>() - exp10)
2671
8
    FMT_THROW(format_error("number is too big"));
2672
6.87k
  precision += exp10;
2673
6.87k
}
2674
2675
class bigint {
2676
 private:
2677
  // A bigint is a number in the form bigit_[N - 1] ... bigit_[0] * 32^exp_.
2678
  using bigit = uint32_t;  // A big digit.
2679
  using double_bigit = uint64_t;
2680
  enum { bigit_bits = num_bits<bigit>() };
2681
  enum { bigits_capacity = 32 };
2682
  basic_memory_buffer<bigit, bigits_capacity> bigits_;
2683
  int exp_;
2684
2685
  friend struct formatter<bigint>;
2686
2687
579k
  FMT_CONSTEXPR auto get_bigit(int i) const -> bigit {
2688
579k
    return i >= exp_ && i < num_bigits() ? bigits_[i - exp_] : 0;
2689
579k
  }
2690
2691
431M
  FMT_CONSTEXPR void subtract_bigits(int index, bigit other, bigit& borrow) {
2692
431M
    auto result = double_bigit(bigits_[index]) - other - borrow;
2693
431M
    bigits_[index] = static_cast<bigit>(result);
2694
431M
    borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
2695
431M
  }
2696
2697
3.09M
  FMT_CONSTEXPR void remove_leading_zeros() {
2698
3.09M
    int num_bigits = static_cast<int>(bigits_.size()) - 1;
2699
3.33M
    while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits;
2700
3.09M
    bigits_.resize(to_unsigned(num_bigits + 1));
2701
3.09M
  }
2702
2703
  // Computes *this -= other assuming aligned bigints and *this >= other.
2704
3.00M
  FMT_CONSTEXPR void subtract_aligned(const bigint& other) {
2705
3.00M
    FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
2706
3.00M
    FMT_ASSERT(compare(*this, other) >= 0, "");
2707
3.00M
    bigit borrow = 0;
2708
3.00M
    int i = other.exp_ - exp_;
2709
434M
    for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
2710
431M
      subtract_bigits(i, other.bigits_[j], borrow);
2711
3.00M
    if (borrow != 0) subtract_bigits(i, 0, borrow);
2712
3.00M
    FMT_ASSERT(borrow == 0, "");
2713
3.00M
    remove_leading_zeros();
2714
3.00M
  }
2715
2716
1.61M
  FMT_CONSTEXPR void multiply(uint32_t value) {
2717
1.61M
    bigit carry = 0;
2718
1.61M
    const double_bigit wide_value = value;
2719
142M
    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2720
140M
      double_bigit result = bigits_[i] * wide_value + carry;
2721
140M
      bigits_[i] = static_cast<bigit>(result);
2722
140M
      carry = static_cast<bigit>(result >> bigit_bits);
2723
140M
    }
2724
1.61M
    if (carry != 0) bigits_.push_back(carry);
2725
1.61M
  }
2726
2727
  template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2728
                                         std::is_same<UInt, uint128_t>::value)>
2729
6.29k
  FMT_CONSTEXPR void multiply(UInt value) {
2730
6.29k
    using half_uint =
2731
6.29k
        conditional_t<std::is_same<UInt, uint128_t>::value, uint64_t, uint32_t>;
2732
6.29k
    const int shift = num_bits<half_uint>() - bigit_bits;
2733
6.29k
    const UInt lower = static_cast<half_uint>(value);
2734
6.29k
    const UInt upper = value >> num_bits<half_uint>();
2735
6.29k
    UInt carry = 0;
2736
1.17M
    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2737
1.16M
      UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
2738
1.16M
      carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
2739
1.16M
              (carry >> bigit_bits);
2740
1.16M
      bigits_[i] = static_cast<bigit>(result);
2741
1.16M
    }
2742
14.5k
    while (carry != 0) {
2743
8.29k
      bigits_.push_back(static_cast<bigit>(carry));
2744
8.29k
      carry >>= bigit_bits;
2745
8.29k
    }
2746
6.29k
  }
2747
2748
  template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
2749
                                         std::is_same<UInt, uint128_t>::value)>
2750
37.9k
  FMT_CONSTEXPR void assign(UInt n) {
2751
37.9k
    size_t num_bigits = 0;
2752
45.1k
    do {
2753
45.1k
      bigits_[num_bigits++] = static_cast<bigit>(n);
2754
45.1k
      n >>= bigit_bits;
2755
45.1k
    } while (n != 0);
2756
37.9k
    bigits_.resize(num_bigits);
2757
37.9k
    exp_ = 0;
2758
37.9k
  }
_ZN3fmt3v126detail6bigint6assignImTnNSt3__19enable_ifIXoosr3std7is_sameIT_mEE5valuesr3std7is_sameIS6_oEE5valueEiE4typeELi0EEEvS6_
Line
Count
Source
2750
29.7k
  FMT_CONSTEXPR void assign(UInt n) {
2751
29.7k
    size_t num_bigits = 0;
2752
29.7k
    do {
2753
29.7k
      bigits_[num_bigits++] = static_cast<bigit>(n);
2754
29.7k
      n >>= bigit_bits;
2755
29.7k
    } while (n != 0);
2756
29.7k
    bigits_.resize(num_bigits);
2757
29.7k
    exp_ = 0;
2758
29.7k
  }
_ZN3fmt3v126detail6bigint6assignIoTnNSt3__19enable_ifIXoosr3std7is_sameIT_mEE5valuesr3std7is_sameIS6_oEE5valueEiE4typeELi0EEEvS6_
Line
Count
Source
2750
8.18k
  FMT_CONSTEXPR void assign(UInt n) {
2751
8.18k
    size_t num_bigits = 0;
2752
15.4k
    do {
2753
15.4k
      bigits_[num_bigits++] = static_cast<bigit>(n);
2754
15.4k
      n >>= bigit_bits;
2755
15.4k
    } while (n != 0);
2756
8.18k
    bigits_.resize(num_bigits);
2757
8.18k
    exp_ = 0;
2758
8.18k
  }
2759
2760
 public:
2761
57.9k
  FMT_CONSTEXPR bigint() : exp_(0) {}
2762
0
  explicit bigint(uint64_t n) { assign(n); }
2763
2764
  bigint(const bigint&) = delete;
2765
  void operator=(const bigint&) = delete;
2766
2767
6.83k
  FMT_CONSTEXPR void assign(const bigint& other) {
2768
6.83k
    auto size = other.bigits_.size();
2769
6.83k
    bigits_.resize(size);
2770
6.83k
    auto data = other.bigits_.data();
2771
6.83k
    copy<bigit>(data, data + size, bigits_.data());
2772
6.83k
    exp_ = other.exp_;
2773
6.83k
  }
2774
2775
37.9k
  template <typename Int> FMT_CONSTEXPR void operator=(Int n) {
2776
37.9k
    FMT_ASSERT(n > 0, "");
2777
37.9k
    assign(uint64_or_128_t<Int>(n));
2778
37.9k
  }
void fmt::v12::detail::bigint::operator=<int>(int)
Line
Count
Source
2775
29.5k
  template <typename Int> FMT_CONSTEXPR void operator=(Int n) {
2776
29.5k
    FMT_ASSERT(n > 0, "");
2777
29.5k
    assign(uint64_or_128_t<Int>(n));
2778
29.5k
  }
void fmt::v12::detail::bigint::operator=<unsigned __int128>(unsigned __int128)
Line
Count
Source
2775
8.18k
  template <typename Int> FMT_CONSTEXPR void operator=(Int n) {
2776
8.18k
    FMT_ASSERT(n > 0, "");
2777
8.18k
    assign(uint64_or_128_t<Int>(n));
2778
8.18k
  }
void fmt::v12::detail::bigint::operator=<unsigned long long>(unsigned long long)
Line
Count
Source
2775
199
  template <typename Int> FMT_CONSTEXPR void operator=(Int n) {
2776
199
    FMT_ASSERT(n > 0, "");
2777
199
    assign(uint64_or_128_t<Int>(n));
2778
199
  }
2779
2780
16.1M
  FMT_CONSTEXPR auto num_bigits() const -> int {
2781
16.1M
    return static_cast<int>(bigits_.size()) + exp_;
2782
16.1M
  }
2783
2784
45.8k
  FMT_CONSTEXPR auto operator<<=(int shift) -> bigint& {
2785
45.8k
    FMT_ASSERT(shift >= 0, "");
2786
45.8k
    exp_ += shift / bigit_bits;
2787
45.8k
    shift %= bigit_bits;
2788
45.8k
    if (shift == 0) return *this;
2789
42.1k
    bigit carry = 0;
2790
3.49M
    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
2791
3.44M
      bigit c = bigits_[i] >> (bigit_bits - shift);
2792
3.44M
      bigits_[i] = (bigits_[i] << shift) + carry;
2793
3.44M
      carry = c;
2794
3.44M
    }
2795
42.1k
    if (carry != 0) bigits_.push_back(carry);
2796
42.1k
    return *this;
2797
45.8k
  }
2798
2799
1.61M
  template <typename Int> FMT_CONSTEXPR auto operator*=(Int value) -> bigint& {
2800
1.61M
    FMT_ASSERT(value > 0, "");
2801
1.61M
    multiply(uint32_or_64_or_128_t<Int>(value));
2802
1.61M
    return *this;
2803
1.61M
  }
fmt::v12::detail::bigint& fmt::v12::detail::bigint::operator*=<int>(int)
Line
Count
Source
2799
1.61M
  template <typename Int> FMT_CONSTEXPR auto operator*=(Int value) -> bigint& {
2800
1.61M
    FMT_ASSERT(value > 0, "");
2801
1.61M
    multiply(uint32_or_64_or_128_t<Int>(value));
2802
1.61M
    return *this;
2803
1.61M
  }
fmt::v12::detail::bigint& fmt::v12::detail::bigint::operator*=<unsigned __int128>(unsigned __int128)
Line
Count
Source
2799
6.29k
  template <typename Int> FMT_CONSTEXPR auto operator*=(Int value) -> bigint& {
2800
6.29k
    FMT_ASSERT(value > 0, "");
2801
6.29k
    multiply(uint32_or_64_or_128_t<Int>(value));
2802
6.29k
    return *this;
2803
6.29k
  }
2804
2805
7.58M
  friend FMT_CONSTEXPR auto compare(const bigint& b1, const bigint& b2) -> int {
2806
7.58M
    int num_bigits1 = b1.num_bigits(), num_bigits2 = b2.num_bigits();
2807
7.58M
    if (num_bigits1 != num_bigits2) return num_bigits1 > num_bigits2 ? 1 : -1;
2808
6.20M
    int i = static_cast<int>(b1.bigits_.size()) - 1;
2809
6.20M
    int j = static_cast<int>(b2.bigits_.size()) - 1;
2810
6.20M
    int end = i - j;
2811
6.20M
    if (end < 0) end = 0;
2812
6.39M
    for (; i >= end; --i, --j) {
2813
6.32M
      bigit b1_bigit = b1.bigits_[i], b2_bigit = b2.bigits_[j];
2814
6.32M
      if (b1_bigit != b2_bigit) return b1_bigit > b2_bigit ? 1 : -1;
2815
6.32M
    }
2816
71.6k
    if (i != j) return i > j ? 1 : -1;
2817
5.20k
    return 0;
2818
71.6k
  }
2819
2820
  // Returns compare(lhs1 + lhs2, rhs).
2821
  friend FMT_CONSTEXPR auto add_compare(const bigint& lhs1, const bigint& lhs2,
2822
146k
                                        const bigint& rhs) -> int {
2823
146k
    int max_lhs_bigits = max_of(lhs1.num_bigits(), lhs2.num_bigits());
2824
146k
    int num_rhs_bigits = rhs.num_bigits();
2825
146k
    if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
2826
142k
    if (max_lhs_bigits > num_rhs_bigits) return 1;
2827
141k
    double_bigit borrow = 0;
2828
141k
    int min_exp = min_of(min_of(lhs1.exp_, lhs2.exp_), rhs.exp_);
2829
194k
    for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
2830
193k
      double_bigit sum = double_bigit(lhs1.get_bigit(i)) + lhs2.get_bigit(i);
2831
193k
      bigit rhs_bigit = rhs.get_bigit(i);
2832
193k
      if (sum > rhs_bigit + borrow) return 1;
2833
181k
      borrow = rhs_bigit + borrow - sum;
2834
181k
      if (borrow > 1) return -1;
2835
52.6k
      borrow <<= bigit_bits;
2836
52.6k
    }
2837
1.18k
    return borrow != 0 ? -1 : 0;
2838
141k
  }
2839
2840
  // Assigns pow(10, exp) to this bigint.
2841
14.4k
  FMT_CONSTEXPR20 void assign_pow10(int exp) {
2842
14.4k
    FMT_ASSERT(exp >= 0, "");
2843
14.4k
    if (exp == 0) return *this = 1;
2844
12.1k
    int bitmask = 1 << (num_bits<unsigned>() -
2845
12.1k
                        countl_zero(static_cast<uint32_t>(exp)) - 1);
2846
    // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
2847
    // repeated squaring and multiplication.
2848
12.1k
    *this = 5;
2849
12.1k
    bitmask >>= 1;
2850
103k
    while (bitmask != 0) {
2851
91.5k
      square();
2852
91.5k
      if ((exp & bitmask) != 0) *this *= 5;
2853
91.5k
      bitmask >>= 1;
2854
91.5k
    }
2855
12.1k
    *this <<= exp;  // Multiply by pow(2, exp) by shifting.
2856
12.1k
  }
2857
2858
91.5k
  FMT_CONSTEXPR20 void square() {
2859
91.5k
    int num_bigits = static_cast<int>(bigits_.size());
2860
91.5k
    int num_result_bigits = 2 * num_bigits;
2861
91.5k
    basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
2862
91.5k
    bigits_.resize(to_unsigned(num_result_bigits));
2863
91.5k
    auto sum = uint128_t();
2864
1.90M
    for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
2865
      // Compute bigit at position bigit_index of the result by adding
2866
      // cross-product terms n[i] * n[j] such that i + j == bigit_index.
2867
100M
      for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
2868
        // Most terms are multiplied twice which can be optimized in the future.
2869
98.4M
        sum += double_bigit(n[i]) * n[j];
2870
98.4M
      }
2871
1.81M
      bigits_[bigit_index] = static_cast<bigit>(sum);
2872
1.81M
      sum >>= num_bits<bigit>();  // Compute the carry.
2873
1.81M
    }
2874
    // Do the same for the top half.
2875
1.90M
    for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
2876
1.81M
         ++bigit_index) {
2877
98.4M
      for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
2878
96.6M
        sum += double_bigit(n[i++]) * n[j--];
2879
1.81M
      bigits_[bigit_index] = static_cast<bigit>(sum);
2880
1.81M
      sum >>= num_bits<bigit>();
2881
1.81M
    }
2882
91.5k
    remove_leading_zeros();
2883
91.5k
    exp_ *= 2;
2884
91.5k
  }
2885
2886
  // If this bigint has a bigger exponent than other, adds trailing zero to make
2887
  // exponents equal. This simplifies some operations such as subtraction.
2888
605k
  FMT_CONSTEXPR void align(const bigint& other) {
2889
605k
    int exp_difference = exp_ - other.exp_;
2890
605k
    if (exp_difference <= 0) return;
2891
3.07k
    int num_bigits = static_cast<int>(bigits_.size());
2892
3.07k
    bigits_.resize(to_unsigned(num_bigits + exp_difference));
2893
11.4k
    for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
2894
8.35k
      bigits_[j] = bigits_[i];
2895
3.07k
    fill_n(bigits_.data(), to_unsigned(exp_difference), 0U);
2896
3.07k
    exp_ -= exp_difference;
2897
3.07k
  }
2898
2899
  // Divides this bignum by divisor, assigning the remainder to this and
2900
  // returning the quotient.
2901
1.45M
  FMT_CONSTEXPR auto divmod_assign(const bigint& divisor) -> int {
2902
1.45M
    FMT_ASSERT(this != &divisor, "");
2903
1.45M
    if (compare(*this, divisor) < 0) return 0;
2904
605k
    FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
2905
605k
    align(divisor);
2906
605k
    int quotient = 0;
2907
3.00M
    do {
2908
3.00M
      subtract_aligned(divisor);
2909
3.00M
      ++quotient;
2910
3.00M
    } while (compare(*this, divisor) >= 0);
2911
605k
    return quotient;
2912
1.45M
  }
2913
};
2914
2915
// format_dragon flags.
2916
enum dragon {
2917
  predecessor_closer = 1,
2918
  fixup = 2,  // Run fixup to correct exp10 which can be off by one.
2919
  fixed = 4,
2920
};
2921
2922
// Formats a floating-point number using a variation of the Fixed-Precision
2923
// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
2924
// https://fmt.dev/papers/p372-steele.pdf.
2925
FMT_CONSTEXPR20 inline void format_dragon(basic_fp<uint128_t> value,
2926
                                          unsigned flags, int num_digits,
2927
14.4k
                                          buffer<char>& buf, int& exp10) {
2928
14.4k
  bigint numerator;    // 2 * R in (FPP)^2.
2929
14.4k
  bigint denominator;  // 2 * S in (FPP)^2.
2930
  // lower and upper are differences between value and corresponding boundaries.
2931
14.4k
  bigint lower;             // (M^- in (FPP)^2).
2932
14.4k
  bigint upper_store;       // upper's value if different from lower.
2933
14.4k
  bigint* upper = nullptr;  // (M^+ in (FPP)^2).
2934
  // Shift numerator and denominator by an extra bit or two (if lower boundary
2935
  // is closer) to make lower and upper integers. This eliminates multiplication
2936
  // by 2 during later computations.
2937
14.4k
  bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0;
2938
14.4k
  int shift = is_predecessor_closer ? 2 : 1;
2939
14.4k
  if (value.e >= 0) {
2940
3.64k
    numerator = value.f;
2941
3.64k
    numerator <<= value.e + shift;
2942
3.64k
    lower = 1;
2943
3.64k
    lower <<= value.e;
2944
3.64k
    if (is_predecessor_closer) {
2945
546
      upper_store = 1;
2946
546
      upper_store <<= value.e + 1;
2947
546
      upper = &upper_store;
2948
546
    }
2949
3.64k
    denominator.assign_pow10(exp10);
2950
3.64k
    denominator <<= shift;
2951
10.8k
  } else if (exp10 < 0) {
2952
6.29k
    numerator.assign_pow10(-exp10);
2953
6.29k
    lower.assign(numerator);
2954
6.29k
    if (is_predecessor_closer) {
2955
537
      upper_store.assign(numerator);
2956
537
      upper_store <<= 1;
2957
537
      upper = &upper_store;
2958
537
    }
2959
6.29k
    numerator *= value.f;
2960
6.29k
    numerator <<= shift;
2961
6.29k
    denominator = 1;
2962
6.29k
    denominator <<= shift - value.e;
2963
6.29k
  } else {
2964
4.54k
    numerator = value.f;
2965
4.54k
    numerator <<= shift;
2966
4.54k
    denominator.assign_pow10(exp10);
2967
4.54k
    denominator <<= shift - value.e;
2968
4.54k
    lower = 1;
2969
4.54k
    if (is_predecessor_closer) {
2970
199
      upper_store = 1ULL << 1;
2971
199
      upper = &upper_store;
2972
199
    }
2973
4.54k
  }
2974
14.4k
  int even = static_cast<int>((value.f & 1) == 0);
2975
14.4k
  if (!upper) upper = &lower;
2976
14.4k
  bool shortest = num_digits < 0;
2977
14.4k
  if ((flags & dragon::fixup) != 0) {
2978
11.4k
    if (add_compare(numerator, *upper, denominator) + even <= 0) {
2979
8.29k
      --exp10;
2980
8.29k
      numerator *= 10;
2981
8.29k
      if (num_digits < 0) {
2982
6.28k
        lower *= 10;
2983
6.28k
        if (upper != &lower) *upper *= 10;
2984
6.28k
      }
2985
8.29k
    }
2986
11.4k
    if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1);
2987
11.4k
  }
2988
  // Invariant: value == (numerator / denominator) * pow(10, exp10).
2989
14.4k
  if (shortest) {
2990
    // Generate the shortest representation.
2991
8.65k
    num_digits = 0;
2992
8.65k
    char* data = buf.data();
2993
125k
    for (;;) {
2994
125k
      int digit = numerator.divmod_assign(denominator);
2995
125k
      bool low = compare(numerator, lower) - even < 0;  // numerator <[=] lower.
2996
      // numerator + upper >[=] pow10:
2997
125k
      bool high = add_compare(numerator, *upper, denominator) + even > 0;
2998
125k
      data[num_digits++] = static_cast<char>('0' + digit);
2999
125k
      if (low || high) {
3000
8.65k
        if (!low) {
3001
1.71k
          ++data[num_digits - 1];
3002
6.93k
        } else if (high) {
3003
3.63k
          int result = add_compare(numerator, numerator, denominator);
3004
          // Round half to even.
3005
3.63k
          if (result > 0 || (result == 0 && (digit % 2) != 0))
3006
1.72k
            ++data[num_digits - 1];
3007
3.63k
        }
3008
8.65k
        buf.try_resize(to_unsigned(num_digits));
3009
8.65k
        exp10 -= num_digits - 1;
3010
8.65k
        return;
3011
8.65k
      }
3012
117k
      numerator *= 10;
3013
117k
      lower *= 10;
3014
117k
      if (upper != &lower) *upper *= 10;
3015
117k
    }
3016
8.65k
  }
3017
  // Generate the given number of digits.
3018
5.83k
  exp10 -= num_digits - 1;
3019
5.83k
  if (num_digits <= 0) {
3020
834
    auto digit = '0';
3021
834
    if (num_digits == 0) {
3022
575
      denominator *= 10;
3023
575
      digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
3024
575
    }
3025
834
    buf.push_back(digit);
3026
834
    return;
3027
834
  }
3028
4.99k
  buf.try_resize(to_unsigned(num_digits));
3029
1.32M
  for (int i = 0; i < num_digits - 1; ++i) {
3030
1.32M
    int digit = numerator.divmod_assign(denominator);
3031
1.32M
    buf[i] = static_cast<char>('0' + digit);
3032
1.32M
    numerator *= 10;
3033
1.32M
  }
3034
4.99k
  int digit = numerator.divmod_assign(denominator);
3035
4.99k
  auto result = add_compare(numerator, numerator, denominator);
3036
4.99k
  if (result > 0 || (result == 0 && (digit % 2) != 0)) {
3037
1.69k
    if (digit == 9) {
3038
643
      const auto overflow = '0' + 10;
3039
643
      buf[num_digits - 1] = overflow;
3040
      // Propagate the carry.
3041
2.27k
      for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
3042
1.63k
        buf[i] = '0';
3043
1.63k
        ++buf[i - 1];
3044
1.63k
      }
3045
643
      if (buf[0] == overflow) {
3046
393
        buf[0] = '1';
3047
393
        if ((flags & dragon::fixed) != 0)
3048
198
          buf.push_back('0');
3049
195
        else
3050
195
          ++exp10;
3051
393
      }
3052
643
      return;
3053
643
    }
3054
1.05k
    ++digit;
3055
1.05k
  }
3056
4.35k
  buf[num_digits - 1] = static_cast<char>('0' + digit);
3057
4.35k
}
3058
3059
// Formats a floating-point number using the hexfloat format.
3060
template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
3061
FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs,
3062
4.01k
                                     buffer<char>& buf) {
3063
  // float is passed as double to reduce the number of instantiations and to
3064
  // simplify implementation.
3065
4.01k
  static_assert(!std::is_same<Float, float>::value, "");
3066
3067
4.01k
  using info = dragonbox::float_info<Float>;
3068
3069
  // Assume Float is in the format [sign][exponent][significand].
3070
4.01k
  using carrier_uint = typename info::carrier_uint;
3071
3072
4.01k
  const auto num_float_significand_bits = detail::num_significand_bits<Float>();
3073
3074
4.01k
  basic_fp<carrier_uint> f(value);
3075
4.01k
  f.e += num_float_significand_bits;
3076
4.01k
  if (!has_implicit_bit<Float>()) --f.e;
3077
3078
4.01k
  const auto num_fraction_bits =
3079
4.01k
      num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3080
4.01k
  const auto num_xdigits = (num_fraction_bits + 3) / 4;
3081
3082
4.01k
  const auto leading_shift = ((num_xdigits - 1) * 4);
3083
4.01k
  const auto leading_mask = carrier_uint(0xF) << leading_shift;
3084
4.01k
  const auto leading_xdigit =
3085
4.01k
      static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
3086
4.01k
  if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
3087
3088
4.01k
  int print_xdigits = num_xdigits - 1;
3089
4.01k
  if (specs.precision >= 0 && print_xdigits > specs.precision) {
3090
940
    const int shift = ((print_xdigits - specs.precision - 1) * 4);
3091
940
    const auto mask = carrier_uint(0xF) << shift;
3092
940
    const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
3093
3094
940
    if (v >= 8) {
3095
525
      const auto inc = carrier_uint(1) << (shift + 4);
3096
525
      f.f += inc;
3097
525
      f.f &= ~(inc - 1);
3098
525
    }
3099
3100
    // Check long double overflow
3101
940
    if (!has_implicit_bit<Float>()) {
3102
533
      const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3103
533
      if ((f.f & implicit_bit) == implicit_bit) {
3104
196
        f.f >>= 4;
3105
196
        f.e += 4;
3106
196
      }
3107
533
    }
3108
3109
940
    print_xdigits = specs.precision;
3110
940
  }
3111
3112
4.01k
  char xdigits[num_bits<carrier_uint>() / 4];
3113
4.01k
  detail::fill_n(xdigits, sizeof(xdigits), '0');
3114
4.01k
  format_base2e(4, xdigits, f.f, num_xdigits, specs.upper());
3115
3116
  // Remove zero tail
3117
25.0k
  while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
3118
3119
4.01k
  buf.push_back('0');
3120
4.01k
  buf.push_back(specs.upper() ? 'X' : 'x');
3121
4.01k
  buf.push_back(xdigits[0]);
3122
4.01k
  if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision)
3123
3.18k
    buf.push_back('.');
3124
4.01k
  buf.append(xdigits + 1, xdigits + 1 + print_xdigits);
3125
556k
  for (; print_xdigits < specs.precision; ++print_xdigits) buf.push_back('0');
3126
3127
4.01k
  buf.push_back(specs.upper() ? 'P' : 'p');
3128
3129
4.01k
  uint32_t abs_e;
3130
4.01k
  if (f.e < 0) {
3131
2.73k
    buf.push_back('-');
3132
2.73k
    abs_e = static_cast<uint32_t>(-f.e);
3133
2.73k
  } else {
3134
1.28k
    buf.push_back('+');
3135
1.28k
    abs_e = static_cast<uint32_t>(f.e);
3136
1.28k
  }
3137
4.01k
  format_decimal<char>(appender(buf), abs_e, detail::count_digits(abs_e));
3138
4.01k
}
_ZN3fmt3v126detail15format_hexfloatIeTnNSt3__19enable_ifIXntsr16is_double_doubleIT_EE5valueEiE4typeELi0EEEvS5_NS0_12format_specsERNS1_6bufferIcEE
Line
Count
Source
3062
1.71k
                                     buffer<char>& buf) {
3063
  // float is passed as double to reduce the number of instantiations and to
3064
  // simplify implementation.
3065
1.71k
  static_assert(!std::is_same<Float, float>::value, "");
3066
3067
1.71k
  using info = dragonbox::float_info<Float>;
3068
3069
  // Assume Float is in the format [sign][exponent][significand].
3070
1.71k
  using carrier_uint = typename info::carrier_uint;
3071
3072
1.71k
  const auto num_float_significand_bits = detail::num_significand_bits<Float>();
3073
3074
1.71k
  basic_fp<carrier_uint> f(value);
3075
1.71k
  f.e += num_float_significand_bits;
3076
1.71k
  if (!has_implicit_bit<Float>()) --f.e;
3077
3078
1.71k
  const auto num_fraction_bits =
3079
1.71k
      num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3080
1.71k
  const auto num_xdigits = (num_fraction_bits + 3) / 4;
3081
3082
1.71k
  const auto leading_shift = ((num_xdigits - 1) * 4);
3083
1.71k
  const auto leading_mask = carrier_uint(0xF) << leading_shift;
3084
1.71k
  const auto leading_xdigit =
3085
1.71k
      static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
3086
1.71k
  if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
3087
3088
1.71k
  int print_xdigits = num_xdigits - 1;
3089
1.71k
  if (specs.precision >= 0 && print_xdigits > specs.precision) {
3090
533
    const int shift = ((print_xdigits - specs.precision - 1) * 4);
3091
533
    const auto mask = carrier_uint(0xF) << shift;
3092
533
    const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
3093
3094
533
    if (v >= 8) {
3095
327
      const auto inc = carrier_uint(1) << (shift + 4);
3096
327
      f.f += inc;
3097
327
      f.f &= ~(inc - 1);
3098
327
    }
3099
3100
    // Check long double overflow
3101
533
    if (!has_implicit_bit<Float>()) {
3102
533
      const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3103
533
      if ((f.f & implicit_bit) == implicit_bit) {
3104
196
        f.f >>= 4;
3105
196
        f.e += 4;
3106
196
      }
3107
533
    }
3108
3109
533
    print_xdigits = specs.precision;
3110
533
  }
3111
3112
1.71k
  char xdigits[num_bits<carrier_uint>() / 4];
3113
1.71k
  detail::fill_n(xdigits, sizeof(xdigits), '0');
3114
1.71k
  format_base2e(4, xdigits, f.f, num_xdigits, specs.upper());
3115
3116
  // Remove zero tail
3117
9.45k
  while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
3118
3119
1.71k
  buf.push_back('0');
3120
1.71k
  buf.push_back(specs.upper() ? 'X' : 'x');
3121
1.71k
  buf.push_back(xdigits[0]);
3122
1.71k
  if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision)
3123
1.41k
    buf.push_back('.');
3124
1.71k
  buf.append(xdigits + 1, xdigits + 1 + print_xdigits);
3125
254k
  for (; print_xdigits < specs.precision; ++print_xdigits) buf.push_back('0');
3126
3127
1.71k
  buf.push_back(specs.upper() ? 'P' : 'p');
3128
3129
1.71k
  uint32_t abs_e;
3130
1.71k
  if (f.e < 0) {
3131
1.25k
    buf.push_back('-');
3132
1.25k
    abs_e = static_cast<uint32_t>(-f.e);
3133
1.25k
  } else {
3134
454
    buf.push_back('+');
3135
454
    abs_e = static_cast<uint32_t>(f.e);
3136
454
  }
3137
1.71k
  format_decimal<char>(appender(buf), abs_e, detail::count_digits(abs_e));
3138
1.71k
}
_ZN3fmt3v126detail15format_hexfloatIdTnNSt3__19enable_ifIXntsr16is_double_doubleIT_EE5valueEiE4typeELi0EEEvS5_NS0_12format_specsERNS1_6bufferIcEE
Line
Count
Source
3062
2.30k
                                     buffer<char>& buf) {
3063
  // float is passed as double to reduce the number of instantiations and to
3064
  // simplify implementation.
3065
2.30k
  static_assert(!std::is_same<Float, float>::value, "");
3066
3067
2.30k
  using info = dragonbox::float_info<Float>;
3068
3069
  // Assume Float is in the format [sign][exponent][significand].
3070
2.30k
  using carrier_uint = typename info::carrier_uint;
3071
3072
2.30k
  const auto num_float_significand_bits = detail::num_significand_bits<Float>();
3073
3074
2.30k
  basic_fp<carrier_uint> f(value);
3075
2.30k
  f.e += num_float_significand_bits;
3076
2.30k
  if (!has_implicit_bit<Float>()) --f.e;
3077
3078
2.30k
  const auto num_fraction_bits =
3079
2.30k
      num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3080
2.30k
  const auto num_xdigits = (num_fraction_bits + 3) / 4;
3081
3082
2.30k
  const auto leading_shift = ((num_xdigits - 1) * 4);
3083
2.30k
  const auto leading_mask = carrier_uint(0xF) << leading_shift;
3084
2.30k
  const auto leading_xdigit =
3085
2.30k
      static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
3086
2.30k
  if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
3087
3088
2.30k
  int print_xdigits = num_xdigits - 1;
3089
2.30k
  if (specs.precision >= 0 && print_xdigits > specs.precision) {
3090
407
    const int shift = ((print_xdigits - specs.precision - 1) * 4);
3091
407
    const auto mask = carrier_uint(0xF) << shift;
3092
407
    const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
3093
3094
407
    if (v >= 8) {
3095
198
      const auto inc = carrier_uint(1) << (shift + 4);
3096
198
      f.f += inc;
3097
198
      f.f &= ~(inc - 1);
3098
198
    }
3099
3100
    // Check long double overflow
3101
407
    if (!has_implicit_bit<Float>()) {
3102
0
      const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3103
0
      if ((f.f & implicit_bit) == implicit_bit) {
3104
0
        f.f >>= 4;
3105
0
        f.e += 4;
3106
0
      }
3107
0
    }
3108
3109
407
    print_xdigits = specs.precision;
3110
407
  }
3111
3112
2.30k
  char xdigits[num_bits<carrier_uint>() / 4];
3113
2.30k
  detail::fill_n(xdigits, sizeof(xdigits), '0');
3114
2.30k
  format_base2e(4, xdigits, f.f, num_xdigits, specs.upper());
3115
3116
  // Remove zero tail
3117
15.5k
  while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
3118
3119
2.30k
  buf.push_back('0');
3120
2.30k
  buf.push_back(specs.upper() ? 'X' : 'x');
3121
2.30k
  buf.push_back(xdigits[0]);
3122
2.30k
  if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision)
3123
1.76k
    buf.push_back('.');
3124
2.30k
  buf.append(xdigits + 1, xdigits + 1 + print_xdigits);
3125
301k
  for (; print_xdigits < specs.precision; ++print_xdigits) buf.push_back('0');
3126
3127
2.30k
  buf.push_back(specs.upper() ? 'P' : 'p');
3128
3129
2.30k
  uint32_t abs_e;
3130
2.30k
  if (f.e < 0) {
3131
1.47k
    buf.push_back('-');
3132
1.47k
    abs_e = static_cast<uint32_t>(-f.e);
3133
1.47k
  } else {
3134
828
    buf.push_back('+');
3135
828
    abs_e = static_cast<uint32_t>(f.e);
3136
828
  }
3137
2.30k
  format_decimal<char>(appender(buf), abs_e, detail::count_digits(abs_e));
3138
2.30k
}
3139
3140
template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>
3141
FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs,
3142
                                     buffer<char>& buf) {
3143
  format_hexfloat(static_cast<double>(value), specs, buf);
3144
}
3145
3146
2.92k
constexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t {
3147
  // For checking rounding thresholds.
3148
  // The kth entry is chosen to be the smallest integer such that the
3149
  // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k.
3150
  // It is equal to ceil(2^31 + 2^32/10^(k + 1)).
3151
  // These are stored in a string literal because we cannot have static arrays
3152
  // in constexpr functions and non-static ones are poorly optimized.
3153
2.92k
  return U"\x9999999a\x828f5c29\x80418938\x80068db9\x8000a7c6\x800010c7"
3154
2.92k
         U"\x800001ae\x8000002b"[index];
3155
2.92k
}
3156
3157
template <typename Float>
3158
FMT_CONSTEXPR20 auto format_float(Float value, int precision,
3159
                                  const format_specs& specs, bool binary32,
3160
22.6k
                                  buffer<char>& buf) -> int {
3161
  // float is passed as double to reduce the number of instantiations.
3162
22.6k
  static_assert(!std::is_same<Float, float>::value, "");
3163
22.6k
  auto converted_value = convert_float(value);
3164
3165
22.6k
  const bool fixed = specs.type() == presentation_type::fixed;
3166
22.6k
  if (value == 0) {
3167
2.37k
    if (precision <= 0 || !fixed) {
3168
1.86k
      buf.push_back('0');
3169
1.86k
      return 0;
3170
1.86k
    }
3171
512
    buf.try_resize(to_unsigned(precision));
3172
512
    fill_n(buf.data(), precision, '0');
3173
512
    return -precision;
3174
2.37k
  }
3175
3176
20.2k
  int exp = 0;
3177
20.2k
  bool use_dragon = true;
3178
20.2k
  unsigned dragon_flags = 0;
3179
20.2k
  if (!is_fast_float<Float>() || is_constant_evaluated()) {
3180
11.4k
    const auto inv_log2_10 = 0.3010299956639812;  // 1 / log2(10)
3181
11.4k
    using info = dragonbox::float_info<decltype(converted_value)>;
3182
11.4k
    const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3183
    // Compute exp, an approximate power of 10, such that
3184
    //   10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3185
    // This is based on log10(value) == log2(value) / log2(10) and approximation
3186
    // of log2(value) by e + num_fraction_bits idea from double-conversion.
3187
11.4k
    auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3188
11.4k
    exp = static_cast<int>(e);
3189
11.4k
    if (e > exp) ++exp;  // Compute ceil.
3190
11.4k
    dragon_flags = dragon::fixup;
3191
11.4k
  } else {
3192
    // Extract significand bits and exponent bits.
3193
8.77k
    using info = dragonbox::float_info<double>;
3194
8.77k
    auto br = bit_cast<uint64_t>(static_cast<double>(value));
3195
3196
8.77k
    const uint64_t significand_mask =
3197
8.77k
        (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3198
8.77k
    uint64_t significand = (br & significand_mask);
3199
8.77k
    int exponent = static_cast<int>((br & exponent_mask<double>()) >>
3200
8.77k
                                    num_significand_bits<double>());
3201
3202
8.77k
    if (exponent != 0) {  // Check if normal.
3203
8.10k
      exponent -= exponent_bias<double>() + num_significand_bits<double>();
3204
8.10k
      significand |=
3205
8.10k
          (static_cast<uint64_t>(1) << num_significand_bits<double>());
3206
8.10k
      significand <<= 1;
3207
8.10k
    } else {
3208
      // Normalize subnormal inputs.
3209
671
      FMT_ASSERT(significand != 0, "zeros should not appear here");
3210
671
      int shift = countl_zero(significand);
3211
671
      FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3212
671
                 "");
3213
671
      shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3214
671
      exponent = (std::numeric_limits<double>::min_exponent -
3215
671
                  num_significand_bits<double>()) -
3216
671
                 shift;
3217
671
      significand <<= shift;
3218
671
    }
3219
3220
    // Compute the first several nonzero decimal significand digits.
3221
    // We call the number we get the first segment.
3222
8.77k
    const int k = info::kappa - dragonbox::floor_log10_pow2(exponent);
3223
8.77k
    exp = -k;
3224
8.77k
    const int beta = exponent + dragonbox::floor_log2_pow10(k);
3225
8.77k
    uint64_t first_segment;
3226
8.77k
    bool has_more_segments;
3227
8.77k
    int digits_in_the_first_segment;
3228
8.77k
    {
3229
8.77k
      const auto r = dragonbox::umul192_upper128(
3230
8.77k
          significand << beta, dragonbox::get_cached_power(k));
3231
8.77k
      first_segment = r.high();
3232
8.77k
      has_more_segments = r.low() != 0;
3233
3234
      // The first segment can have 18 ~ 19 digits.
3235
8.77k
      if (first_segment >= 1000000000000000000ULL) {
3236
5.79k
        digits_in_the_first_segment = 19;
3237
5.79k
      } else {
3238
        // When it is of 18-digits, we align it to 19-digits by adding a bogus
3239
        // zero at the end.
3240
2.97k
        digits_in_the_first_segment = 18;
3241
2.97k
        first_segment *= 10;
3242
2.97k
      }
3243
8.77k
    }
3244
3245
    // Compute the actual number of decimal digits to print.
3246
8.77k
    if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment);
3247
3248
    // Use Dragon4 only when there might be not enough digits in the first
3249
    // segment.
3250
8.77k
    if (digits_in_the_first_segment > precision) {
3251
5.73k
      use_dragon = false;
3252
3253
5.73k
      if (precision <= 0) {
3254
1.11k
        exp += digits_in_the_first_segment;
3255
3256
1.11k
        if (precision < 0) {
3257
          // Nothing to do, since all we have are just leading zeros.
3258
512
          buf.try_resize(0);
3259
600
        } else {
3260
          // We may need to round-up.
3261
600
          buf.try_resize(1);
3262
600
          if ((first_segment | static_cast<uint64_t>(has_more_segments)) >
3263
600
              5000000000000000000ULL) {
3264
334
            buf[0] = '1';
3265
334
          } else {
3266
266
            buf[0] = '0';
3267
266
          }
3268
600
        }
3269
1.11k
      }  // precision <= 0
3270
4.62k
      else {
3271
4.62k
        exp += digits_in_the_first_segment - precision;
3272
3273
        // When precision > 0, we divide the first segment into three
3274
        // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits
3275
        // in 32-bits which usually allows faster calculation than in
3276
        // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize
3277
        // division-by-constant for large 64-bit divisors, we do it here
3278
        // manually. The magic number 7922816251426433760 below is equal to
3279
        // ceil(2^(64+32) / 10^10).
3280
4.62k
        const uint32_t first_subsegment = static_cast<uint32_t>(
3281
4.62k
            dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >>
3282
4.62k
            32);
3283
4.62k
        const uint64_t second_third_subsegments =
3284
4.62k
            first_segment - first_subsegment * 10000000000ULL;
3285
3286
4.62k
        uint64_t prod;
3287
4.62k
        uint32_t digits;
3288
4.62k
        bool should_round_up;
3289
4.62k
        int number_of_digits_to_print = min_of(precision, 9);
3290
3291
        // Print a 9-digits subsegment, either the first or the second.
3292
6.18k
        auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
3293
6.18k
          int number_of_digits_printed = 0;
3294
3295
          // If we want to print an odd number of digits from the subsegment,
3296
6.18k
          if ((number_of_digits_to_print & 1) != 0) {
3297
            // Convert to 64-bit fixed-point fractional form with 1-digit
3298
            // integer part. The magic number 720575941 is a good enough
3299
            // approximation of 2^(32 + 24) / 10^8; see
3300
            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3301
            // for details.
3302
5.21k
            prod = ((subsegment * static_cast<uint64_t>(720575941)) >> 24) + 1;
3303
5.21k
            digits = static_cast<uint32_t>(prod >> 32);
3304
5.21k
            *buffer = static_cast<char>('0' + digits);
3305
5.21k
            number_of_digits_printed++;
3306
5.21k
          }
3307
          // If we want to print an even number of digits from the
3308
          // first_subsegment,
3309
970
          else {
3310
            // Convert to 64-bit fixed-point fractional form with 2-digits
3311
            // integer part. The magic number 450359963 is a good enough
3312
            // approximation of 2^(32 + 20) / 10^7; see
3313
            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3314
            // for details.
3315
970
            prod = ((subsegment * static_cast<uint64_t>(450359963)) >> 20) + 1;
3316
970
            digits = static_cast<uint32_t>(prod >> 32);
3317
970
            write2digits(buffer, digits);
3318
970
            number_of_digits_printed += 2;
3319
970
          }
3320
3321
          // Print all digit pairs.
3322
22.9k
          while (number_of_digits_printed < number_of_digits_to_print) {
3323
16.7k
            prod = static_cast<uint32_t>(prod) * static_cast<uint64_t>(100);
3324
16.7k
            digits = static_cast<uint32_t>(prod >> 32);
3325
16.7k
            write2digits(buffer + number_of_digits_printed, digits);
3326
16.7k
            number_of_digits_printed += 2;
3327
16.7k
          }
3328
6.18k
        };
3329
3330
        // Print first subsegment.
3331
4.62k
        print_subsegment(first_subsegment, buf.data());
3332
3333
        // Perform rounding if the first subsegment is the last subsegment to
3334
        // print.
3335
4.62k
        if (precision <= 9) {
3336
          // Rounding inside the subsegment.
3337
          // We round-up if:
3338
          //  - either the fractional part is strictly larger than 1/2, or
3339
          //  - the fractional part is exactly 1/2 and the last digit is odd.
3340
          // We rely on the following observations:
3341
          //  - If fractional_part >= threshold, then the fractional part is
3342
          //    strictly larger than 1/2.
3343
          //  - If the MSB of fractional_part is set, then the fractional part
3344
          //    must be at least 1/2.
3345
          //  - When the MSB of fractional_part is set, either
3346
          //    second_third_subsegments being nonzero or has_more_segments
3347
          //    being true means there are further digits not printed, so the
3348
          //    fractional part is strictly larger than 1/2.
3349
3.06k
          if (precision < 9) {
3350
2.20k
            uint32_t fractional_part = static_cast<uint32_t>(prod);
3351
2.20k
            should_round_up =
3352
2.20k
                fractional_part >= fractional_part_rounding_thresholds(
3353
2.20k
                                       8 - number_of_digits_to_print) ||
3354
989
                ((fractional_part >> 31) &
3355
989
                 ((digits & 1) | (second_third_subsegments != 0) |
3356
989
                  has_more_segments)) != 0;
3357
2.20k
          }
3358
          // Rounding at the subsegment boundary.
3359
          // In this case, the fractional part is at least 1/2 if and only if
3360
          // second_third_subsegments >= 5000000000ULL, and is strictly larger
3361
          // than 1/2 if we further have either second_third_subsegments >
3362
          // 5000000000ULL or has_more_segments == true.
3363
862
          else {
3364
862
            should_round_up = second_third_subsegments > 5000000000ULL ||
3365
658
                              (second_third_subsegments == 5000000000ULL &&
3366
388
                               ((digits & 1) != 0 || has_more_segments));
3367
862
          }
3368
3.06k
        }
3369
        // Otherwise, print the second subsegment.
3370
1.56k
        else {
3371
          // Compilers are not aware of how to leverage the maximum value of
3372
          // second_third_subsegments to find out a better magic number which
3373
          // allows us to eliminate an additional shift. 1844674407370955162 =
3374
          // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))).
3375
1.56k
          const uint32_t second_subsegment =
3376
1.56k
              static_cast<uint32_t>(dragonbox::umul128_upper64(
3377
1.56k
                  second_third_subsegments, 1844674407370955162ULL));
3378
1.56k
          const uint32_t third_subsegment =
3379
1.56k
              static_cast<uint32_t>(second_third_subsegments) -
3380
1.56k
              second_subsegment * 10;
3381
3382
1.56k
          number_of_digits_to_print = precision - 9;
3383
1.56k
          print_subsegment(second_subsegment, buf.data() + 9);
3384
3385
          // Rounding inside the subsegment.
3386
1.56k
          if (precision < 18) {
3387
            // The condition third_subsegment != 0 implies that the segment was
3388
            // of 19 digits, so in this case the third segment should be
3389
            // consisting of a genuine digit from the input.
3390
724
            uint32_t fractional_part = static_cast<uint32_t>(prod);
3391
724
            should_round_up =
3392
724
                fractional_part >= fractional_part_rounding_thresholds(
3393
724
                                       8 - number_of_digits_to_print) ||
3394
503
                ((fractional_part >> 31) &
3395
503
                 ((digits & 1) | (third_subsegment != 0) |
3396
503
                  has_more_segments)) != 0;
3397
724
          }
3398
          // Rounding at the subsegment boundary.
3399
838
          else {
3400
            // In this case, the segment must be of 19 digits, thus
3401
            // the third subsegment should be consisting of a genuine digit from
3402
            // the input.
3403
838
            should_round_up = third_subsegment > 5 ||
3404
601
                              (third_subsegment == 5 &&
3405
388
                               ((digits & 1) != 0 || has_more_segments));
3406
838
          }
3407
1.56k
        }
3408
3409
        // Round-up if necessary.
3410
4.62k
        if (should_round_up) {
3411
2.47k
          ++buf[precision - 1];
3412
5.53k
          for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) {
3413
3.06k
            buf[i] = '0';
3414
3.06k
            ++buf[i - 1];
3415
3.06k
          }
3416
2.47k
          if (buf[0] > '9') {
3417
691
            buf[0] = '1';
3418
691
            if (fixed)
3419
350
              buf[precision++] = '0';
3420
341
            else
3421
341
              ++exp;
3422
691
          }
3423
2.47k
        }
3424
4.62k
        buf.try_resize(to_unsigned(precision));
3425
4.62k
      }
3426
5.73k
    }  // if (digits_in_the_first_segment > precision)
3427
3.03k
    else {
3428
      // Adjust the exponent for its use in Dragon4.
3429
3.03k
      exp += digits_in_the_first_segment - 1;
3430
3.03k
    }
3431
8.77k
  }
3432
20.2k
  if (use_dragon) {
3433
14.4k
    auto f = basic_fp<uint128_t>();
3434
14.4k
    bool is_predecessor_closer = binary32 ? f.assign(static_cast<float>(value))
3435
14.4k
                                          : f.assign(converted_value);
3436
14.4k
    if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3437
14.4k
    if (fixed) dragon_flags |= dragon::fixed;
3438
    // Limit precision to the maximum possible number of significant digits in
3439
    // an IEEE754 double because we don't need to generate zeros.
3440
14.4k
    const int max_double_digits = 767;
3441
14.4k
    if (precision > max_double_digits) precision = max_double_digits;
3442
14.4k
    format_dragon(f, dragon_flags, precision, buf, exp);
3443
14.4k
  }
3444
20.2k
  if (!fixed && !specs.alt()) {
3445
    // Remove trailing zeros.
3446
11.7k
    auto num_digits = buf.size();
3447
684k
    while (num_digits > 0 && buf[num_digits - 1] == '0') {
3448
672k
      --num_digits;
3449
672k
      ++exp;
3450
672k
    }
3451
11.7k
    buf.try_resize(num_digits);
3452
11.7k
  }
3453
20.2k
  return exp;
3454
22.6k
}
int fmt::v12::detail::format_float<long double>(long double, int, fmt::v12::format_specs const&, bool, fmt::v12::detail::buffer<char>&)
Line
Count
Source
3160
12.8k
                                  buffer<char>& buf) -> int {
3161
  // float is passed as double to reduce the number of instantiations.
3162
12.8k
  static_assert(!std::is_same<Float, float>::value, "");
3163
12.8k
  auto converted_value = convert_float(value);
3164
3165
12.8k
  const bool fixed = specs.type() == presentation_type::fixed;
3166
12.8k
  if (value == 0) {
3167
1.41k
    if (precision <= 0 || !fixed) {
3168
1.16k
      buf.push_back('0');
3169
1.16k
      return 0;
3170
1.16k
    }
3171
255
    buf.try_resize(to_unsigned(precision));
3172
255
    fill_n(buf.data(), precision, '0');
3173
255
    return -precision;
3174
1.41k
  }
3175
3176
11.4k
  int exp = 0;
3177
11.4k
  bool use_dragon = true;
3178
11.4k
  unsigned dragon_flags = 0;
3179
11.4k
  if (!is_fast_float<Float>() || is_constant_evaluated()) {
3180
11.4k
    const auto inv_log2_10 = 0.3010299956639812;  // 1 / log2(10)
3181
11.4k
    using info = dragonbox::float_info<decltype(converted_value)>;
3182
11.4k
    const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3183
    // Compute exp, an approximate power of 10, such that
3184
    //   10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3185
    // This is based on log10(value) == log2(value) / log2(10) and approximation
3186
    // of log2(value) by e + num_fraction_bits idea from double-conversion.
3187
11.4k
    auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3188
11.4k
    exp = static_cast<int>(e);
3189
11.4k
    if (e > exp) ++exp;  // Compute ceil.
3190
11.4k
    dragon_flags = dragon::fixup;
3191
11.4k
  } else {
3192
    // Extract significand bits and exponent bits.
3193
0
    using info = dragonbox::float_info<double>;
3194
0
    auto br = bit_cast<uint64_t>(static_cast<double>(value));
3195
3196
0
    const uint64_t significand_mask =
3197
0
        (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3198
0
    uint64_t significand = (br & significand_mask);
3199
0
    int exponent = static_cast<int>((br & exponent_mask<double>()) >>
3200
0
                                    num_significand_bits<double>());
3201
3202
0
    if (exponent != 0) {  // Check if normal.
3203
0
      exponent -= exponent_bias<double>() + num_significand_bits<double>();
3204
0
      significand |=
3205
0
          (static_cast<uint64_t>(1) << num_significand_bits<double>());
3206
0
      significand <<= 1;
3207
0
    } else {
3208
      // Normalize subnormal inputs.
3209
0
      FMT_ASSERT(significand != 0, "zeros should not appear here");
3210
0
      int shift = countl_zero(significand);
3211
0
      FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3212
0
                 "");
3213
0
      shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3214
0
      exponent = (std::numeric_limits<double>::min_exponent -
3215
0
                  num_significand_bits<double>()) -
3216
0
                 shift;
3217
0
      significand <<= shift;
3218
0
    }
3219
3220
    // Compute the first several nonzero decimal significand digits.
3221
    // We call the number we get the first segment.
3222
0
    const int k = info::kappa - dragonbox::floor_log10_pow2(exponent);
3223
0
    exp = -k;
3224
0
    const int beta = exponent + dragonbox::floor_log2_pow10(k);
3225
0
    uint64_t first_segment;
3226
0
    bool has_more_segments;
3227
0
    int digits_in_the_first_segment;
3228
0
    {
3229
0
      const auto r = dragonbox::umul192_upper128(
3230
0
          significand << beta, dragonbox::get_cached_power(k));
3231
0
      first_segment = r.high();
3232
0
      has_more_segments = r.low() != 0;
3233
3234
      // The first segment can have 18 ~ 19 digits.
3235
0
      if (first_segment >= 1000000000000000000ULL) {
3236
0
        digits_in_the_first_segment = 19;
3237
0
      } else {
3238
        // When it is of 18-digits, we align it to 19-digits by adding a bogus
3239
        // zero at the end.
3240
0
        digits_in_the_first_segment = 18;
3241
0
        first_segment *= 10;
3242
0
      }
3243
0
    }
3244
3245
    // Compute the actual number of decimal digits to print.
3246
0
    if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment);
3247
3248
    // Use Dragon4 only when there might be not enough digits in the first
3249
    // segment.
3250
0
    if (digits_in_the_first_segment > precision) {
3251
0
      use_dragon = false;
3252
3253
0
      if (precision <= 0) {
3254
0
        exp += digits_in_the_first_segment;
3255
3256
0
        if (precision < 0) {
3257
          // Nothing to do, since all we have are just leading zeros.
3258
0
          buf.try_resize(0);
3259
0
        } else {
3260
          // We may need to round-up.
3261
0
          buf.try_resize(1);
3262
0
          if ((first_segment | static_cast<uint64_t>(has_more_segments)) >
3263
0
              5000000000000000000ULL) {
3264
0
            buf[0] = '1';
3265
0
          } else {
3266
0
            buf[0] = '0';
3267
0
          }
3268
0
        }
3269
0
      }  // precision <= 0
3270
0
      else {
3271
0
        exp += digits_in_the_first_segment - precision;
3272
3273
        // When precision > 0, we divide the first segment into three
3274
        // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits
3275
        // in 32-bits which usually allows faster calculation than in
3276
        // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize
3277
        // division-by-constant for large 64-bit divisors, we do it here
3278
        // manually. The magic number 7922816251426433760 below is equal to
3279
        // ceil(2^(64+32) / 10^10).
3280
0
        const uint32_t first_subsegment = static_cast<uint32_t>(
3281
0
            dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >>
3282
0
            32);
3283
0
        const uint64_t second_third_subsegments =
3284
0
            first_segment - first_subsegment * 10000000000ULL;
3285
3286
0
        uint64_t prod;
3287
0
        uint32_t digits;
3288
0
        bool should_round_up;
3289
0
        int number_of_digits_to_print = min_of(precision, 9);
3290
3291
        // Print a 9-digits subsegment, either the first or the second.
3292
0
        auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
3293
0
          int number_of_digits_printed = 0;
3294
3295
          // If we want to print an odd number of digits from the subsegment,
3296
0
          if ((number_of_digits_to_print & 1) != 0) {
3297
            // Convert to 64-bit fixed-point fractional form with 1-digit
3298
            // integer part. The magic number 720575941 is a good enough
3299
            // approximation of 2^(32 + 24) / 10^8; see
3300
            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3301
            // for details.
3302
0
            prod = ((subsegment * static_cast<uint64_t>(720575941)) >> 24) + 1;
3303
0
            digits = static_cast<uint32_t>(prod >> 32);
3304
0
            *buffer = static_cast<char>('0' + digits);
3305
0
            number_of_digits_printed++;
3306
0
          }
3307
          // If we want to print an even number of digits from the
3308
          // first_subsegment,
3309
0
          else {
3310
            // Convert to 64-bit fixed-point fractional form with 2-digits
3311
            // integer part. The magic number 450359963 is a good enough
3312
            // approximation of 2^(32 + 20) / 10^7; see
3313
            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3314
            // for details.
3315
0
            prod = ((subsegment * static_cast<uint64_t>(450359963)) >> 20) + 1;
3316
0
            digits = static_cast<uint32_t>(prod >> 32);
3317
0
            write2digits(buffer, digits);
3318
0
            number_of_digits_printed += 2;
3319
0
          }
3320
3321
          // Print all digit pairs.
3322
0
          while (number_of_digits_printed < number_of_digits_to_print) {
3323
0
            prod = static_cast<uint32_t>(prod) * static_cast<uint64_t>(100);
3324
0
            digits = static_cast<uint32_t>(prod >> 32);
3325
0
            write2digits(buffer + number_of_digits_printed, digits);
3326
0
            number_of_digits_printed += 2;
3327
0
          }
3328
0
        };
3329
3330
        // Print first subsegment.
3331
0
        print_subsegment(first_subsegment, buf.data());
3332
3333
        // Perform rounding if the first subsegment is the last subsegment to
3334
        // print.
3335
0
        if (precision <= 9) {
3336
          // Rounding inside the subsegment.
3337
          // We round-up if:
3338
          //  - either the fractional part is strictly larger than 1/2, or
3339
          //  - the fractional part is exactly 1/2 and the last digit is odd.
3340
          // We rely on the following observations:
3341
          //  - If fractional_part >= threshold, then the fractional part is
3342
          //    strictly larger than 1/2.
3343
          //  - If the MSB of fractional_part is set, then the fractional part
3344
          //    must be at least 1/2.
3345
          //  - When the MSB of fractional_part is set, either
3346
          //    second_third_subsegments being nonzero or has_more_segments
3347
          //    being true means there are further digits not printed, so the
3348
          //    fractional part is strictly larger than 1/2.
3349
0
          if (precision < 9) {
3350
0
            uint32_t fractional_part = static_cast<uint32_t>(prod);
3351
0
            should_round_up =
3352
0
                fractional_part >= fractional_part_rounding_thresholds(
3353
0
                                       8 - number_of_digits_to_print) ||
3354
0
                ((fractional_part >> 31) &
3355
0
                 ((digits & 1) | (second_third_subsegments != 0) |
3356
0
                  has_more_segments)) != 0;
3357
0
          }
3358
          // Rounding at the subsegment boundary.
3359
          // In this case, the fractional part is at least 1/2 if and only if
3360
          // second_third_subsegments >= 5000000000ULL, and is strictly larger
3361
          // than 1/2 if we further have either second_third_subsegments >
3362
          // 5000000000ULL or has_more_segments == true.
3363
0
          else {
3364
0
            should_round_up = second_third_subsegments > 5000000000ULL ||
3365
0
                              (second_third_subsegments == 5000000000ULL &&
3366
0
                               ((digits & 1) != 0 || has_more_segments));
3367
0
          }
3368
0
        }
3369
        // Otherwise, print the second subsegment.
3370
0
        else {
3371
          // Compilers are not aware of how to leverage the maximum value of
3372
          // second_third_subsegments to find out a better magic number which
3373
          // allows us to eliminate an additional shift. 1844674407370955162 =
3374
          // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))).
3375
0
          const uint32_t second_subsegment =
3376
0
              static_cast<uint32_t>(dragonbox::umul128_upper64(
3377
0
                  second_third_subsegments, 1844674407370955162ULL));
3378
0
          const uint32_t third_subsegment =
3379
0
              static_cast<uint32_t>(second_third_subsegments) -
3380
0
              second_subsegment * 10;
3381
3382
0
          number_of_digits_to_print = precision - 9;
3383
0
          print_subsegment(second_subsegment, buf.data() + 9);
3384
3385
          // Rounding inside the subsegment.
3386
0
          if (precision < 18) {
3387
            // The condition third_subsegment != 0 implies that the segment was
3388
            // of 19 digits, so in this case the third segment should be
3389
            // consisting of a genuine digit from the input.
3390
0
            uint32_t fractional_part = static_cast<uint32_t>(prod);
3391
0
            should_round_up =
3392
0
                fractional_part >= fractional_part_rounding_thresholds(
3393
0
                                       8 - number_of_digits_to_print) ||
3394
0
                ((fractional_part >> 31) &
3395
0
                 ((digits & 1) | (third_subsegment != 0) |
3396
0
                  has_more_segments)) != 0;
3397
0
          }
3398
          // Rounding at the subsegment boundary.
3399
0
          else {
3400
            // In this case, the segment must be of 19 digits, thus
3401
            // the third subsegment should be consisting of a genuine digit from
3402
            // the input.
3403
0
            should_round_up = third_subsegment > 5 ||
3404
0
                              (third_subsegment == 5 &&
3405
0
                               ((digits & 1) != 0 || has_more_segments));
3406
0
          }
3407
0
        }
3408
3409
        // Round-up if necessary.
3410
0
        if (should_round_up) {
3411
0
          ++buf[precision - 1];
3412
0
          for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) {
3413
0
            buf[i] = '0';
3414
0
            ++buf[i - 1];
3415
0
          }
3416
0
          if (buf[0] > '9') {
3417
0
            buf[0] = '1';
3418
0
            if (fixed)
3419
0
              buf[precision++] = '0';
3420
0
            else
3421
0
              ++exp;
3422
0
          }
3423
0
        }
3424
0
        buf.try_resize(to_unsigned(precision));
3425
0
      }
3426
0
    }  // if (digits_in_the_first_segment > precision)
3427
0
    else {
3428
      // Adjust the exponent for its use in Dragon4.
3429
0
      exp += digits_in_the_first_segment - 1;
3430
0
    }
3431
0
  }
3432
11.4k
  if (use_dragon) {
3433
11.4k
    auto f = basic_fp<uint128_t>();
3434
11.4k
    bool is_predecessor_closer = binary32 ? f.assign(static_cast<float>(value))
3435
11.4k
                                          : f.assign(converted_value);
3436
11.4k
    if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3437
11.4k
    if (fixed) dragon_flags |= dragon::fixed;
3438
    // Limit precision to the maximum possible number of significant digits in
3439
    // an IEEE754 double because we don't need to generate zeros.
3440
11.4k
    const int max_double_digits = 767;
3441
11.4k
    if (precision > max_double_digits) precision = max_double_digits;
3442
11.4k
    format_dragon(f, dragon_flags, precision, buf, exp);
3443
11.4k
  }
3444
11.4k
  if (!fixed && !specs.alt()) {
3445
    // Remove trailing zeros.
3446
9.45k
    auto num_digits = buf.size();
3447
251k
    while (num_digits > 0 && buf[num_digits - 1] == '0') {
3448
242k
      --num_digits;
3449
242k
      ++exp;
3450
242k
    }
3451
9.45k
    buf.try_resize(num_digits);
3452
9.45k
  }
3453
11.4k
  return exp;
3454
12.8k
}
int fmt::v12::detail::format_float<double>(double, int, fmt::v12::format_specs const&, bool, fmt::v12::detail::buffer<char>&)
Line
Count
Source
3160
9.73k
                                  buffer<char>& buf) -> int {
3161
  // float is passed as double to reduce the number of instantiations.
3162
9.73k
  static_assert(!std::is_same<Float, float>::value, "");
3163
9.73k
  auto converted_value = convert_float(value);
3164
3165
9.73k
  const bool fixed = specs.type() == presentation_type::fixed;
3166
9.73k
  if (value == 0) {
3167
959
    if (precision <= 0 || !fixed) {
3168
702
      buf.push_back('0');
3169
702
      return 0;
3170
702
    }
3171
257
    buf.try_resize(to_unsigned(precision));
3172
257
    fill_n(buf.data(), precision, '0');
3173
257
    return -precision;
3174
959
  }
3175
3176
8.77k
  int exp = 0;
3177
8.77k
  bool use_dragon = true;
3178
8.77k
  unsigned dragon_flags = 0;
3179
8.77k
  if (!is_fast_float<Float>() || is_constant_evaluated()) {
3180
0
    const auto inv_log2_10 = 0.3010299956639812;  // 1 / log2(10)
3181
0
    using info = dragonbox::float_info<decltype(converted_value)>;
3182
0
    const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3183
    // Compute exp, an approximate power of 10, such that
3184
    //   10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3185
    // This is based on log10(value) == log2(value) / log2(10) and approximation
3186
    // of log2(value) by e + num_fraction_bits idea from double-conversion.
3187
0
    auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3188
0
    exp = static_cast<int>(e);
3189
0
    if (e > exp) ++exp;  // Compute ceil.
3190
0
    dragon_flags = dragon::fixup;
3191
8.77k
  } else {
3192
    // Extract significand bits and exponent bits.
3193
8.77k
    using info = dragonbox::float_info<double>;
3194
8.77k
    auto br = bit_cast<uint64_t>(static_cast<double>(value));
3195
3196
8.77k
    const uint64_t significand_mask =
3197
8.77k
        (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3198
8.77k
    uint64_t significand = (br & significand_mask);
3199
8.77k
    int exponent = static_cast<int>((br & exponent_mask<double>()) >>
3200
8.77k
                                    num_significand_bits<double>());
3201
3202
8.77k
    if (exponent != 0) {  // Check if normal.
3203
8.10k
      exponent -= exponent_bias<double>() + num_significand_bits<double>();
3204
8.10k
      significand |=
3205
8.10k
          (static_cast<uint64_t>(1) << num_significand_bits<double>());
3206
8.10k
      significand <<= 1;
3207
8.10k
    } else {
3208
      // Normalize subnormal inputs.
3209
671
      FMT_ASSERT(significand != 0, "zeros should not appear here");
3210
671
      int shift = countl_zero(significand);
3211
671
      FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3212
671
                 "");
3213
671
      shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3214
671
      exponent = (std::numeric_limits<double>::min_exponent -
3215
671
                  num_significand_bits<double>()) -
3216
671
                 shift;
3217
671
      significand <<= shift;
3218
671
    }
3219
3220
    // Compute the first several nonzero decimal significand digits.
3221
    // We call the number we get the first segment.
3222
8.77k
    const int k = info::kappa - dragonbox::floor_log10_pow2(exponent);
3223
8.77k
    exp = -k;
3224
8.77k
    const int beta = exponent + dragonbox::floor_log2_pow10(k);
3225
8.77k
    uint64_t first_segment;
3226
8.77k
    bool has_more_segments;
3227
8.77k
    int digits_in_the_first_segment;
3228
8.77k
    {
3229
8.77k
      const auto r = dragonbox::umul192_upper128(
3230
8.77k
          significand << beta, dragonbox::get_cached_power(k));
3231
8.77k
      first_segment = r.high();
3232
8.77k
      has_more_segments = r.low() != 0;
3233
3234
      // The first segment can have 18 ~ 19 digits.
3235
8.77k
      if (first_segment >= 1000000000000000000ULL) {
3236
5.79k
        digits_in_the_first_segment = 19;
3237
5.79k
      } else {
3238
        // When it is of 18-digits, we align it to 19-digits by adding a bogus
3239
        // zero at the end.
3240
2.97k
        digits_in_the_first_segment = 18;
3241
2.97k
        first_segment *= 10;
3242
2.97k
      }
3243
8.77k
    }
3244
3245
    // Compute the actual number of decimal digits to print.
3246
8.77k
    if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment);
3247
3248
    // Use Dragon4 only when there might be not enough digits in the first
3249
    // segment.
3250
8.77k
    if (digits_in_the_first_segment > precision) {
3251
5.73k
      use_dragon = false;
3252
3253
5.73k
      if (precision <= 0) {
3254
1.11k
        exp += digits_in_the_first_segment;
3255
3256
1.11k
        if (precision < 0) {
3257
          // Nothing to do, since all we have are just leading zeros.
3258
512
          buf.try_resize(0);
3259
600
        } else {
3260
          // We may need to round-up.
3261
600
          buf.try_resize(1);
3262
600
          if ((first_segment | static_cast<uint64_t>(has_more_segments)) >
3263
600
              5000000000000000000ULL) {
3264
334
            buf[0] = '1';
3265
334
          } else {
3266
266
            buf[0] = '0';
3267
266
          }
3268
600
        }
3269
1.11k
      }  // precision <= 0
3270
4.62k
      else {
3271
4.62k
        exp += digits_in_the_first_segment - precision;
3272
3273
        // When precision > 0, we divide the first segment into three
3274
        // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits
3275
        // in 32-bits which usually allows faster calculation than in
3276
        // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize
3277
        // division-by-constant for large 64-bit divisors, we do it here
3278
        // manually. The magic number 7922816251426433760 below is equal to
3279
        // ceil(2^(64+32) / 10^10).
3280
4.62k
        const uint32_t first_subsegment = static_cast<uint32_t>(
3281
4.62k
            dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >>
3282
4.62k
            32);
3283
4.62k
        const uint64_t second_third_subsegments =
3284
4.62k
            first_segment - first_subsegment * 10000000000ULL;
3285
3286
4.62k
        uint64_t prod;
3287
4.62k
        uint32_t digits;
3288
4.62k
        bool should_round_up;
3289
4.62k
        int number_of_digits_to_print = min_of(precision, 9);
3290
3291
        // Print a 9-digits subsegment, either the first or the second.
3292
4.62k
        auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
3293
4.62k
          int number_of_digits_printed = 0;
3294
3295
          // If we want to print an odd number of digits from the subsegment,
3296
4.62k
          if ((number_of_digits_to_print & 1) != 0) {
3297
            // Convert to 64-bit fixed-point fractional form with 1-digit
3298
            // integer part. The magic number 720575941 is a good enough
3299
            // approximation of 2^(32 + 24) / 10^8; see
3300
            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3301
            // for details.
3302
4.62k
            prod = ((subsegment * static_cast<uint64_t>(720575941)) >> 24) + 1;
3303
4.62k
            digits = static_cast<uint32_t>(prod >> 32);
3304
4.62k
            *buffer = static_cast<char>('0' + digits);
3305
4.62k
            number_of_digits_printed++;
3306
4.62k
          }
3307
          // If we want to print an even number of digits from the
3308
          // first_subsegment,
3309
4.62k
          else {
3310
            // Convert to 64-bit fixed-point fractional form with 2-digits
3311
            // integer part. The magic number 450359963 is a good enough
3312
            // approximation of 2^(32 + 20) / 10^7; see
3313
            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case
3314
            // for details.
3315
4.62k
            prod = ((subsegment * static_cast<uint64_t>(450359963)) >> 20) + 1;
3316
4.62k
            digits = static_cast<uint32_t>(prod >> 32);
3317
4.62k
            write2digits(buffer, digits);
3318
4.62k
            number_of_digits_printed += 2;
3319
4.62k
          }
3320
3321
          // Print all digit pairs.
3322
4.62k
          while (number_of_digits_printed < number_of_digits_to_print) {
3323
4.62k
            prod = static_cast<uint32_t>(prod) * static_cast<uint64_t>(100);
3324
4.62k
            digits = static_cast<uint32_t>(prod >> 32);
3325
4.62k
            write2digits(buffer + number_of_digits_printed, digits);
3326
4.62k
            number_of_digits_printed += 2;
3327
4.62k
          }
3328
4.62k
        };
3329
3330
        // Print first subsegment.
3331
4.62k
        print_subsegment(first_subsegment, buf.data());
3332
3333
        // Perform rounding if the first subsegment is the last subsegment to
3334
        // print.
3335
4.62k
        if (precision <= 9) {
3336
          // Rounding inside the subsegment.
3337
          // We round-up if:
3338
          //  - either the fractional part is strictly larger than 1/2, or
3339
          //  - the fractional part is exactly 1/2 and the last digit is odd.
3340
          // We rely on the following observations:
3341
          //  - If fractional_part >= threshold, then the fractional part is
3342
          //    strictly larger than 1/2.
3343
          //  - If the MSB of fractional_part is set, then the fractional part
3344
          //    must be at least 1/2.
3345
          //  - When the MSB of fractional_part is set, either
3346
          //    second_third_subsegments being nonzero or has_more_segments
3347
          //    being true means there are further digits not printed, so the
3348
          //    fractional part is strictly larger than 1/2.
3349
3.06k
          if (precision < 9) {
3350
2.20k
            uint32_t fractional_part = static_cast<uint32_t>(prod);
3351
2.20k
            should_round_up =
3352
2.20k
                fractional_part >= fractional_part_rounding_thresholds(
3353
2.20k
                                       8 - number_of_digits_to_print) ||
3354
989
                ((fractional_part >> 31) &
3355
989
                 ((digits & 1) | (second_third_subsegments != 0) |
3356
989
                  has_more_segments)) != 0;
3357
2.20k
          }
3358
          // Rounding at the subsegment boundary.
3359
          // In this case, the fractional part is at least 1/2 if and only if
3360
          // second_third_subsegments >= 5000000000ULL, and is strictly larger
3361
          // than 1/2 if we further have either second_third_subsegments >
3362
          // 5000000000ULL or has_more_segments == true.
3363
862
          else {
3364
862
            should_round_up = second_third_subsegments > 5000000000ULL ||
3365
658
                              (second_third_subsegments == 5000000000ULL &&
3366
388
                               ((digits & 1) != 0 || has_more_segments));
3367
862
          }
3368
3.06k
        }
3369
        // Otherwise, print the second subsegment.
3370
1.56k
        else {
3371
          // Compilers are not aware of how to leverage the maximum value of
3372
          // second_third_subsegments to find out a better magic number which
3373
          // allows us to eliminate an additional shift. 1844674407370955162 =
3374
          // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))).
3375
1.56k
          const uint32_t second_subsegment =
3376
1.56k
              static_cast<uint32_t>(dragonbox::umul128_upper64(
3377
1.56k
                  second_third_subsegments, 1844674407370955162ULL));
3378
1.56k
          const uint32_t third_subsegment =
3379
1.56k
              static_cast<uint32_t>(second_third_subsegments) -
3380
1.56k
              second_subsegment * 10;
3381
3382
1.56k
          number_of_digits_to_print = precision - 9;
3383
1.56k
          print_subsegment(second_subsegment, buf.data() + 9);
3384
3385
          // Rounding inside the subsegment.
3386
1.56k
          if (precision < 18) {
3387
            // The condition third_subsegment != 0 implies that the segment was
3388
            // of 19 digits, so in this case the third segment should be
3389
            // consisting of a genuine digit from the input.
3390
724
            uint32_t fractional_part = static_cast<uint32_t>(prod);
3391
724
            should_round_up =
3392
724
                fractional_part >= fractional_part_rounding_thresholds(
3393
724
                                       8 - number_of_digits_to_print) ||
3394
503
                ((fractional_part >> 31) &
3395
503
                 ((digits & 1) | (third_subsegment != 0) |
3396
503
                  has_more_segments)) != 0;
3397
724
          }
3398
          // Rounding at the subsegment boundary.
3399
838
          else {
3400
            // In this case, the segment must be of 19 digits, thus
3401
            // the third subsegment should be consisting of a genuine digit from
3402
            // the input.
3403
838
            should_round_up = third_subsegment > 5 ||
3404
601
                              (third_subsegment == 5 &&
3405
388
                               ((digits & 1) != 0 || has_more_segments));
3406
838
          }
3407
1.56k
        }
3408
3409
        // Round-up if necessary.
3410
4.62k
        if (should_round_up) {
3411
2.47k
          ++buf[precision - 1];
3412
5.53k
          for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) {
3413
3.06k
            buf[i] = '0';
3414
3.06k
            ++buf[i - 1];
3415
3.06k
          }
3416
2.47k
          if (buf[0] > '9') {
3417
691
            buf[0] = '1';
3418
691
            if (fixed)
3419
350
              buf[precision++] = '0';
3420
341
            else
3421
341
              ++exp;
3422
691
          }
3423
2.47k
        }
3424
4.62k
        buf.try_resize(to_unsigned(precision));
3425
4.62k
      }
3426
5.73k
    }  // if (digits_in_the_first_segment > precision)
3427
3.03k
    else {
3428
      // Adjust the exponent for its use in Dragon4.
3429
3.03k
      exp += digits_in_the_first_segment - 1;
3430
3.03k
    }
3431
8.77k
  }
3432
8.77k
  if (use_dragon) {
3433
3.02k
    auto f = basic_fp<uint128_t>();
3434
3.02k
    bool is_predecessor_closer = binary32 ? f.assign(static_cast<float>(value))
3435
3.02k
                                          : f.assign(converted_value);
3436
3.02k
    if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;
3437
3.02k
    if (fixed) dragon_flags |= dragon::fixed;
3438
    // Limit precision to the maximum possible number of significant digits in
3439
    // an IEEE754 double because we don't need to generate zeros.
3440
3.02k
    const int max_double_digits = 767;
3441
3.02k
    if (precision > max_double_digits) precision = max_double_digits;
3442
3.02k
    format_dragon(f, dragon_flags, precision, buf, exp);
3443
3.02k
  }
3444
8.77k
  if (!fixed && !specs.alt()) {
3445
    // Remove trailing zeros.
3446
2.31k
    auto num_digits = buf.size();
3447
432k
    while (num_digits > 0 && buf[num_digits - 1] == '0') {
3448
430k
      --num_digits;
3449
430k
      ++exp;
3450
430k
    }
3451
2.31k
    buf.try_resize(num_digits);
3452
2.31k
  }
3453
8.77k
  return exp;
3454
9.73k
}
3455
3456
template <typename Char, typename OutputIt, typename T,
3457
          FMT_ENABLE_IF(is_floating_point<T>::value)>
3458
FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs specs,
3459
45.8k
                           locale_ref loc = {}) -> OutputIt {
3460
45.8k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
3461
3462
  // Use signbit because value < 0 is false for NaN.
3463
45.8k
  sign s = detail::signbit(value) ? sign::minus : specs.sign();
3464
3465
45.8k
  if (!detail::isfinite(value))
3466
5.10k
    return write_nonfinite<Char>(out, detail::isnan(value), specs, s);
3467
3468
40.7k
  if (specs.align() == align::numeric && s != sign::none) {
3469
1.43k
    *out++ = detail::getsign<Char>(s);
3470
1.43k
    s = sign::none;
3471
1.43k
    if (specs.width != 0) --specs.width;
3472
1.43k
  }
3473
3474
40.7k
  const int exp_upper = detail::exp_upper<T>();
3475
40.7k
  int precision = specs.precision;
3476
40.7k
  if (precision < 0) {
3477
34.5k
    if (specs.type() != presentation_type::none) {
3478
10.9k
      precision = 6;
3479
23.6k
    } else if (is_fast_float<T>::value && !is_constant_evaluated()) {
3480
      // Use Dragonbox for the shortest format.
3481
14.1k
      auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));
3482
14.1k
      return write_float<Char>(out, dec, specs, s, exp_upper, loc);
3483
14.1k
    }
3484
34.5k
  }
3485
3486
26.6k
  memory_buffer buffer;
3487
26.6k
  if (specs.type() == presentation_type::hexfloat) {
3488
4.01k
    if (s != sign::none) buffer.push_back(detail::getsign<char>(s));
3489
4.01k
    format_hexfloat(convert_float(value), specs, buffer);
3490
4.01k
    return write_bytes<Char, align::right>(out, {buffer.data(), buffer.size()},
3491
4.01k
                                           specs);
3492
4.01k
  }
3493
3494
22.6k
  if (specs.type() == presentation_type::exp) {
3495
2.31k
    if (precision == max_value<int>())
3496
3
      report_error("number is too big");
3497
2.31k
    else
3498
2.31k
      ++precision;
3499
2.31k
    if (specs.precision != 0) specs.set_alt();
3500
20.3k
  } else if (specs.type() == presentation_type::fixed) {
3501
7.59k
    if (specs.precision != 0) specs.set_alt();
3502
12.7k
  } else if (precision == 0) {
3503
632
    precision = 1;
3504
632
  }
3505
22.6k
  int exp = format_float(convert_float(value), precision, specs,
3506
22.6k
                         std::is_same<T, float>(), buffer);
3507
3508
22.6k
  specs.precision = precision;
3509
22.6k
  auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3510
22.6k
  return write_float<Char>(out, f, specs, s, exp_upper, loc);
3511
26.6k
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEeTnNSt3__19enable_ifIXsr17is_floating_pointIT1_EE5valueEiE4typeELi0EEET0_SA_S7_NS0_12format_specsENS0_10locale_refE
Line
Count
Source
3459
16.3k
                           locale_ref loc = {}) -> OutputIt {
3460
16.3k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
3461
3462
  // Use signbit because value < 0 is false for NaN.
3463
16.3k
  sign s = detail::signbit(value) ? sign::minus : specs.sign();
3464
3465
16.3k
  if (!detail::isfinite(value))
3466
1.71k
    return write_nonfinite<Char>(out, detail::isnan(value), specs, s);
3467
3468
14.5k
  if (specs.align() == align::numeric && s != sign::none) {
3469
485
    *out++ = detail::getsign<Char>(s);
3470
485
    s = sign::none;
3471
485
    if (specs.width != 0) --specs.width;
3472
485
  }
3473
3474
14.5k
  const int exp_upper = detail::exp_upper<T>();
3475
14.5k
  int precision = specs.precision;
3476
14.5k
  if (precision < 0) {
3477
12.4k
    if (specs.type() != presentation_type::none) {
3478
2.95k
      precision = 6;
3479
9.53k
    } else if (is_fast_float<T>::value && !is_constant_evaluated()) {
3480
      // Use Dragonbox for the shortest format.
3481
0
      auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));
3482
0
      return write_float<Char>(out, dec, specs, s, exp_upper, loc);
3483
0
    }
3484
12.4k
  }
3485
3486
14.5k
  memory_buffer buffer;
3487
14.5k
  if (specs.type() == presentation_type::hexfloat) {
3488
1.71k
    if (s != sign::none) buffer.push_back(detail::getsign<char>(s));
3489
1.71k
    format_hexfloat(convert_float(value), specs, buffer);
3490
1.71k
    return write_bytes<Char, align::right>(out, {buffer.data(), buffer.size()},
3491
1.71k
                                           specs);
3492
1.71k
  }
3493
3494
12.8k
  if (specs.type() == presentation_type::exp) {
3495
1.04k
    if (precision == max_value<int>())
3496
1
      report_error("number is too big");
3497
1.04k
    else
3498
1.04k
      ++precision;
3499
1.04k
    if (specs.precision != 0) specs.set_alt();
3500
11.8k
  } else if (specs.type() == presentation_type::fixed) {
3501
1.60k
    if (specs.precision != 0) specs.set_alt();
3502
10.2k
  } else if (precision == 0) {
3503
200
    precision = 1;
3504
200
  }
3505
12.8k
  int exp = format_float(convert_float(value), precision, specs,
3506
12.8k
                         std::is_same<T, float>(), buffer);
3507
3508
12.8k
  specs.precision = precision;
3509
12.8k
  auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3510
12.8k
  return write_float<Char>(out, f, specs, s, exp_upper, loc);
3511
14.5k
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEfTnNSt3__19enable_ifIXsr17is_floating_pointIT1_EE5valueEiE4typeELi0EEET0_SA_S7_NS0_12format_specsENS0_10locale_refE
Line
Count
Source
3459
14.3k
                           locale_ref loc = {}) -> OutputIt {
3460
14.3k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
3461
3462
  // Use signbit because value < 0 is false for NaN.
3463
14.3k
  sign s = detail::signbit(value) ? sign::minus : specs.sign();
3464
3465
14.3k
  if (!detail::isfinite(value))
3466
1.80k
    return write_nonfinite<Char>(out, detail::isnan(value), specs, s);
3467
3468
12.5k
  if (specs.align() == align::numeric && s != sign::none) {
3469
520
    *out++ = detail::getsign<Char>(s);
3470
520
    s = sign::none;
3471
520
    if (specs.width != 0) --specs.width;
3472
520
  }
3473
3474
12.5k
  const int exp_upper = detail::exp_upper<T>();
3475
12.5k
  int precision = specs.precision;
3476
12.5k
  if (precision < 0) {
3477
10.7k
    if (specs.type() != presentation_type::none) {
3478
3.56k
      precision = 6;
3479
7.18k
    } else if (is_fast_float<T>::value && !is_constant_evaluated()) {
3480
      // Use Dragonbox for the shortest format.
3481
7.18k
      auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));
3482
7.18k
      return write_float<Char>(out, dec, specs, s, exp_upper, loc);
3483
7.18k
    }
3484
10.7k
  }
3485
3486
5.38k
  memory_buffer buffer;
3487
5.38k
  if (specs.type() == presentation_type::hexfloat) {
3488
974
    if (s != sign::none) buffer.push_back(detail::getsign<char>(s));
3489
974
    format_hexfloat(convert_float(value), specs, buffer);
3490
974
    return write_bytes<Char, align::right>(out, {buffer.data(), buffer.size()},
3491
974
                                           specs);
3492
974
  }
3493
3494
4.41k
  if (specs.type() == presentation_type::exp) {
3495
467
    if (precision == max_value<int>())
3496
1
      report_error("number is too big");
3497
466
    else
3498
466
      ++precision;
3499
467
    if (specs.precision != 0) specs.set_alt();
3500
3.94k
  } else if (specs.type() == presentation_type::fixed) {
3501
2.35k
    if (specs.precision != 0) specs.set_alt();
3502
2.35k
  } else if (precision == 0) {
3503
202
    precision = 1;
3504
202
  }
3505
4.41k
  int exp = format_float(convert_float(value), precision, specs,
3506
4.41k
                         std::is_same<T, float>(), buffer);
3507
3508
4.41k
  specs.precision = precision;
3509
4.41k
  auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3510
4.41k
  return write_float<Char>(out, f, specs, s, exp_upper, loc);
3511
5.38k
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEdTnNSt3__19enable_ifIXsr17is_floating_pointIT1_EE5valueEiE4typeELi0EEET0_SA_S7_NS0_12format_specsENS0_10locale_refE
Line
Count
Source
3459
15.1k
                           locale_ref loc = {}) -> OutputIt {
3460
15.1k
  if (specs.localized() && write_loc(out, value, specs, loc)) return out;
3461
3462
  // Use signbit because value < 0 is false for NaN.
3463
15.1k
  sign s = detail::signbit(value) ? sign::minus : specs.sign();
3464
3465
15.1k
  if (!detail::isfinite(value))
3466
1.58k
    return write_nonfinite<Char>(out, detail::isnan(value), specs, s);
3467
3468
13.5k
  if (specs.align() == align::numeric && s != sign::none) {
3469
425
    *out++ = detail::getsign<Char>(s);
3470
425
    s = sign::none;
3471
425
    if (specs.width != 0) --specs.width;
3472
425
  }
3473
3474
13.5k
  const int exp_upper = detail::exp_upper<T>();
3475
13.5k
  int precision = specs.precision;
3476
13.5k
  if (precision < 0) {
3477
11.3k
    if (specs.type() != presentation_type::none) {
3478
4.39k
      precision = 6;
3479
6.92k
    } else if (is_fast_float<T>::value && !is_constant_evaluated()) {
3480
      // Use Dragonbox for the shortest format.
3481
6.92k
      auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));
3482
6.92k
      return write_float<Char>(out, dec, specs, s, exp_upper, loc);
3483
6.92k
    }
3484
11.3k
  }
3485
3486
6.65k
  memory_buffer buffer;
3487
6.65k
  if (specs.type() == presentation_type::hexfloat) {
3488
1.33k
    if (s != sign::none) buffer.push_back(detail::getsign<char>(s));
3489
1.33k
    format_hexfloat(convert_float(value), specs, buffer);
3490
1.33k
    return write_bytes<Char, align::right>(out, {buffer.data(), buffer.size()},
3491
1.33k
                                           specs);
3492
1.33k
  }
3493
3494
5.32k
  if (specs.type() == presentation_type::exp) {
3495
800
    if (precision == max_value<int>())
3496
1
      report_error("number is too big");
3497
799
    else
3498
799
      ++precision;
3499
800
    if (specs.precision != 0) specs.set_alt();
3500
4.52k
  } else if (specs.type() == presentation_type::fixed) {
3501
3.63k
    if (specs.precision != 0) specs.set_alt();
3502
3.63k
  } else if (precision == 0) {
3503
230
    precision = 1;
3504
230
  }
3505
5.32k
  int exp = format_float(convert_float(value), precision, specs,
3506
5.32k
                         std::is_same<T, float>(), buffer);
3507
3508
5.32k
  specs.precision = precision;
3509
5.32k
  auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
3510
5.32k
  return write_float<Char>(out, f, specs, s, exp_upper, loc);
3511
6.65k
}
3512
3513
template <typename Char, typename OutputIt, typename T,
3514
          FMT_ENABLE_IF(is_fast_float<T>::value)>
3515
12.8k
FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3516
12.8k
  if (is_constant_evaluated()) return write<Char>(out, value, format_specs());
3517
3518
12.8k
  auto s = detail::signbit(value) ? sign::minus : sign::none;
3519
12.8k
  auto mask = exponent_mask<fast_float_t<T>>();
3520
12.8k
  if ((bit_cast<decltype(mask)>(value) & mask) == mask)
3521
903
    return write_nonfinite<Char>(out, std::isnan(value), {}, s);
3522
3523
11.9k
  auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));
3524
11.9k
  auto significand = dec.significand;
3525
11.9k
  int significand_size = count_digits(significand);
3526
11.9k
  int exponent = dec.exponent + significand_size - 1;
3527
11.9k
  if (use_fixed(exponent, detail::exp_upper<T>())) {
3528
6.05k
    return write_fixed<Char, fallback_digit_grouping<Char>>(
3529
6.05k
        out, dec, significand_size, Char('.'), {}, s);
3530
6.05k
  }
3531
3532
  // Write value in the exponential format.
3533
5.91k
  const char* prefix = "e+";
3534
5.91k
  int abs_exponent = exponent;
3535
5.91k
  if (exponent < 0) {
3536
3.18k
    abs_exponent = -exponent;
3537
3.18k
    prefix = "e-";
3538
3.18k
  }
3539
5.91k
  auto has_decimal_point = significand_size != 1;
3540
5.91k
  size_t size = std::is_pointer<OutputIt>::value
3541
5.91k
                    ? 0u
3542
5.91k
                    : to_unsigned((s != sign::none ? 1 : 0) + significand_size +
3543
5.91k
                                  (has_decimal_point ? 1 : 0) +
3544
5.91k
                                  (abs_exponent >= 100 ? 5 : 4));
3545
5.91k
  if (auto ptr = to_pointer<Char>(out, size)) {
3546
5.91k
    if (s != sign::none) *ptr++ = Char('-');
3547
5.91k
    if (has_decimal_point) {
3548
5.38k
      auto begin = ptr;
3549
5.38k
      ptr = format_decimal<Char>(ptr, significand, significand_size + 1);
3550
5.38k
      *begin = begin[1];
3551
5.38k
      begin[1] = '.';
3552
5.38k
    } else {
3553
527
      *ptr++ = static_cast<Char>('0' + significand);
3554
527
    }
3555
5.91k
    if (std::is_same<Char, char>::value) {
3556
5.91k
      memcpy(ptr, prefix, 2);
3557
5.91k
      ptr += 2;
3558
5.91k
    } else {
3559
0
      *ptr++ = prefix[0];
3560
0
      *ptr++ = prefix[1];
3561
0
    }
3562
5.91k
    if (abs_exponent >= 100) {
3563
1.52k
      *ptr++ = static_cast<Char>('0' + abs_exponent / 100);
3564
1.52k
      abs_exponent %= 100;
3565
1.52k
    }
3566
5.91k
    write2digits(ptr, static_cast<unsigned>(abs_exponent));
3567
5.91k
    return select<std::is_pointer<OutputIt>::value>(ptr + 2, out);
3568
5.91k
  }
3569
0
  auto it = reserve(out, size);
3570
0
  if (s != sign::none) *it++ = Char('-');
3571
  // Insert a decimal point after the first digit and add an exponent.
3572
0
  it = write_significand(it, significand, significand_size, 1,
3573
0
                         has_decimal_point ? Char('.') : Char());
3574
0
  *it++ = Char('e');
3575
0
  it = write_exponent<Char>(exponent, it);
3576
0
  return base_iterator(out, it);
3577
5.91k
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEfTnNSt3__19enable_ifIXsr13is_fast_floatIT1_EE5valueEiE4typeELi0EEET0_SA_S7_
Line
Count
Source
3515
6.07k
FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3516
6.07k
  if (is_constant_evaluated()) return write<Char>(out, value, format_specs());
3517
3518
6.07k
  auto s = detail::signbit(value) ? sign::minus : sign::none;
3519
6.07k
  auto mask = exponent_mask<fast_float_t<T>>();
3520
6.07k
  if ((bit_cast<decltype(mask)>(value) & mask) == mask)
3521
433
    return write_nonfinite<Char>(out, std::isnan(value), {}, s);
3522
3523
5.64k
  auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));
3524
5.64k
  auto significand = dec.significand;
3525
5.64k
  int significand_size = count_digits(significand);
3526
5.64k
  int exponent = dec.exponent + significand_size - 1;
3527
5.64k
  if (use_fixed(exponent, detail::exp_upper<T>())) {
3528
2.73k
    return write_fixed<Char, fallback_digit_grouping<Char>>(
3529
2.73k
        out, dec, significand_size, Char('.'), {}, s);
3530
2.73k
  }
3531
3532
  // Write value in the exponential format.
3533
2.90k
  const char* prefix = "e+";
3534
2.90k
  int abs_exponent = exponent;
3535
2.90k
  if (exponent < 0) {
3536
1.83k
    abs_exponent = -exponent;
3537
1.83k
    prefix = "e-";
3538
1.83k
  }
3539
2.90k
  auto has_decimal_point = significand_size != 1;
3540
2.90k
  size_t size = std::is_pointer<OutputIt>::value
3541
2.90k
                    ? 0u
3542
2.90k
                    : to_unsigned((s != sign::none ? 1 : 0) + significand_size +
3543
2.90k
                                  (has_decimal_point ? 1 : 0) +
3544
2.90k
                                  (abs_exponent >= 100 ? 5 : 4));
3545
2.90k
  if (auto ptr = to_pointer<Char>(out, size)) {
3546
2.90k
    if (s != sign::none) *ptr++ = Char('-');
3547
2.90k
    if (has_decimal_point) {
3548
2.57k
      auto begin = ptr;
3549
2.57k
      ptr = format_decimal<Char>(ptr, significand, significand_size + 1);
3550
2.57k
      *begin = begin[1];
3551
2.57k
      begin[1] = '.';
3552
2.57k
    } else {
3553
330
      *ptr++ = static_cast<Char>('0' + significand);
3554
330
    }
3555
2.90k
    if (std::is_same<Char, char>::value) {
3556
2.90k
      memcpy(ptr, prefix, 2);
3557
2.90k
      ptr += 2;
3558
2.90k
    } else {
3559
0
      *ptr++ = prefix[0];
3560
0
      *ptr++ = prefix[1];
3561
0
    }
3562
2.90k
    if (abs_exponent >= 100) {
3563
0
      *ptr++ = static_cast<Char>('0' + abs_exponent / 100);
3564
0
      abs_exponent %= 100;
3565
0
    }
3566
2.90k
    write2digits(ptr, static_cast<unsigned>(abs_exponent));
3567
2.90k
    return select<std::is_pointer<OutputIt>::value>(ptr + 2, out);
3568
2.90k
  }
3569
0
  auto it = reserve(out, size);
3570
0
  if (s != sign::none) *it++ = Char('-');
3571
  // Insert a decimal point after the first digit and add an exponent.
3572
0
  it = write_significand(it, significand, significand_size, 1,
3573
0
                         has_decimal_point ? Char('.') : Char());
3574
0
  *it++ = Char('e');
3575
0
  it = write_exponent<Char>(exponent, it);
3576
0
  return base_iterator(out, it);
3577
2.90k
}
_ZN3fmt3v126detail5writeIcNS0_14basic_appenderIcEEdTnNSt3__19enable_ifIXsr13is_fast_floatIT1_EE5valueEiE4typeELi0EEET0_SA_S7_
Line
Count
Source
3515
6.80k
FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
3516
6.80k
  if (is_constant_evaluated()) return write<Char>(out, value, format_specs());
3517
3518
6.80k
  auto s = detail::signbit(value) ? sign::minus : sign::none;
3519
6.80k
  auto mask = exponent_mask<fast_float_t<T>>();
3520
6.80k
  if ((bit_cast<decltype(mask)>(value) & mask) == mask)
3521
470
    return write_nonfinite<Char>(out, std::isnan(value), {}, s);
3522
3523
6.33k
  auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));
3524
6.33k
  auto significand = dec.significand;
3525
6.33k
  int significand_size = count_digits(significand);
3526
6.33k
  int exponent = dec.exponent + significand_size - 1;
3527
6.33k
  if (use_fixed(exponent, detail::exp_upper<T>())) {
3528
3.32k
    return write_fixed<Char, fallback_digit_grouping<Char>>(
3529
3.32k
        out, dec, significand_size, Char('.'), {}, s);
3530
3.32k
  }
3531
3532
  // Write value in the exponential format.
3533
3.00k
  const char* prefix = "e+";
3534
3.00k
  int abs_exponent = exponent;
3535
3.00k
  if (exponent < 0) {
3536
1.35k
    abs_exponent = -exponent;
3537
1.35k
    prefix = "e-";
3538
1.35k
  }
3539
3.00k
  auto has_decimal_point = significand_size != 1;
3540
3.00k
  size_t size = std::is_pointer<OutputIt>::value
3541
3.00k
                    ? 0u
3542
3.00k
                    : to_unsigned((s != sign::none ? 1 : 0) + significand_size +
3543
3.00k
                                  (has_decimal_point ? 1 : 0) +
3544
3.00k
                                  (abs_exponent >= 100 ? 5 : 4));
3545
3.00k
  if (auto ptr = to_pointer<Char>(out, size)) {
3546
3.00k
    if (s != sign::none) *ptr++ = Char('-');
3547
3.00k
    if (has_decimal_point) {
3548
2.81k
      auto begin = ptr;
3549
2.81k
      ptr = format_decimal<Char>(ptr, significand, significand_size + 1);
3550
2.81k
      *begin = begin[1];
3551
2.81k
      begin[1] = '.';
3552
2.81k
    } else {
3553
197
      *ptr++ = static_cast<Char>('0' + significand);
3554
197
    }
3555
3.00k
    if (std::is_same<Char, char>::value) {
3556
3.00k
      memcpy(ptr, prefix, 2);
3557
3.00k
      ptr += 2;
3558
3.00k
    } else {
3559
0
      *ptr++ = prefix[0];
3560
0
      *ptr++ = prefix[1];
3561
0
    }
3562
3.00k
    if (abs_exponent >= 100) {
3563
1.52k
      *ptr++ = static_cast<Char>('0' + abs_exponent / 100);
3564
1.52k
      abs_exponent %= 100;
3565
1.52k
    }
3566
3.00k
    write2digits(ptr, static_cast<unsigned>(abs_exponent));
3567
3.00k
    return select<std::is_pointer<OutputIt>::value>(ptr + 2, out);
3568
3.00k
  }
3569
0
  auto it = reserve(out, size);
3570
0
  if (s != sign::none) *it++ = Char('-');
3571
  // Insert a decimal point after the first digit and add an exponent.
3572
0
  it = write_significand(it, significand, significand_size, 1,
3573
0
                         has_decimal_point ? Char('.') : Char());
3574
0
  *it++ = Char('e');
3575
0
  it = write_exponent<Char>(exponent, it);
3576
0
  return base_iterator(out, it);
3577
3.00k
}
3578
3579
template <typename Char, typename OutputIt, typename T,
3580
          FMT_ENABLE_IF(is_floating_point<T>::value &&
3581
                        !is_fast_float<T>::value)>
3582
5.94k
inline auto write(OutputIt out, T value) -> OutputIt {
3583
5.94k
  return write<Char>(out, value, {});
3584
5.94k
}
3585
3586
template <typename Char, typename OutputIt>
3587
auto write(OutputIt out, monostate, format_specs = {}, locale_ref = {})
3588
0
    -> OutputIt {
3589
0
  FMT_ASSERT(false, "");
3590
0
  return out;
3591
0
}
3592
3593
template <typename Char, typename OutputIt>
3594
FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value)
3595
66.4k
    -> OutputIt {
3596
66.4k
  return copy_noinline<Char>(value.begin(), value.end(), out);
3597
66.4k
}
3598
3599
template <typename Char, typename OutputIt, typename T,
3600
          FMT_ENABLE_IF(has_to_string_view<T>::value)>
3601
constexpr auto write(OutputIt out, const T& value) -> OutputIt {
3602
  return write<Char>(out, to_string_view(value));
3603
}
3604
3605
// FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
3606
template <
3607
    typename Char, typename OutputIt, typename T,
3608
    bool check = std::is_enum<T>::value && !std::is_same<T, Char>::value &&
3609
                 mapped_type_constant<T, Char>::value != type::custom_type,
3610
    FMT_ENABLE_IF(check)>
3611
FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
3612
  return write<Char>(out, static_cast<underlying_t<T>>(value));
3613
}
3614
3615
template <typename Char, typename OutputIt, typename T,
3616
          FMT_ENABLE_IF(std::is_same<T, bool>::value)>
3617
FMT_CONSTEXPR auto write(OutputIt out, T value, const format_specs& specs = {},
3618
2.70k
                         locale_ref = {}) -> OutputIt {
3619
2.70k
  return specs.type() != presentation_type::none &&
3620
1.12k
                 specs.type() != presentation_type::string
3621
2.70k
             ? write<Char>(out, value ? 1 : 0, specs, {})
3622
2.70k
             : write_bytes<Char>(out, value ? "true" : "false", specs);
3623
2.70k
}
3624
3625
template <typename Char, typename OutputIt>
3626
505
FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
3627
505
  auto it = reserve(out, 1);
3628
505
  *it++ = value;
3629
505
  return base_iterator(out, it);
3630
505
}
3631
3632
template <typename Char, typename OutputIt>
3633
66.4k
FMT_CONSTEXPR20 auto write(OutputIt out, const Char* value) -> OutputIt {
3634
66.4k
  if (value) return write(out, basic_string_view<Char>(value));
3635
0
  report_error("string pointer is null");
3636
0
  return out;
3637
66.4k
}
3638
3639
template <typename Char, typename OutputIt, typename T,
3640
          FMT_ENABLE_IF(std::is_same<T, void>::value)>
3641
auto write(OutputIt out, const T* value, const format_specs& specs = {},
3642
0
           locale_ref = {}) -> OutputIt {
3643
0
  return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
3644
0
}
3645
3646
template <typename Char, typename OutputIt, typename T,
3647
          FMT_ENABLE_IF(mapped_type_constant<T, Char>::value ==
3648
                            type::custom_type &&
3649
                        !std::is_fundamental<T>::value)>
3650
FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> OutputIt {
3651
  auto f = formatter<T, Char>();
3652
  auto parse_ctx = parse_context<Char>({});
3653
  f.parse(parse_ctx);
3654
  auto ctx = basic_format_context<OutputIt, Char>(out, {}, {});
3655
  return f.format(value, ctx);
3656
}
3657
3658
template <typename T>
3659
using is_builtin =
3660
    bool_constant<std::is_same<T, int>::value || FMT_BUILTIN_TYPES>;
3661
3662
// An argument visitor that formats the argument and writes it via the output
3663
// iterator. It's a class and not a generic lambda for compatibility with C++11.
3664
template <typename Char> struct default_arg_formatter {
3665
  using context = buffered_context<Char>;
3666
3667
  basic_appender<Char> out;
3668
3669
16
  void operator()(monostate) { report_error("argument not found"); }
3670
3671
  template <typename T, FMT_ENABLE_IF(is_builtin<T>::value)>
3672
23.2k
  void operator()(T value) {
3673
23.2k
    write<Char>(out, value);
3674
23.2k
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIiTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
873
  void operator()(T value) {
3673
873
    write<Char>(out, value);
3674
873
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIjTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
967
  void operator()(T value) {
3673
967
    write<Char>(out, value);
3674
967
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIxTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
383
  void operator()(T value) {
3673
383
    write<Char>(out, value);
3674
383
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIyTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
972
  void operator()(T value) {
3673
972
    write<Char>(out, value);
3674
972
  }
Unexecuted instantiation: _ZN3fmt3v126detail21default_arg_formatterIcEclInTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Unexecuted instantiation: _ZN3fmt3v126detail21default_arg_formatterIcEclIoTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
_ZN3fmt3v126detail21default_arg_formatterIcEclIbTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
721
  void operator()(T value) {
3673
721
    write<Char>(out, value);
3674
721
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIcTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
505
  void operator()(T value) {
3673
505
    write<Char>(out, value);
3674
505
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIfTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
6.07k
  void operator()(T value) {
3673
6.07k
    write<Char>(out, value);
3674
6.07k
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIdTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
6.80k
  void operator()(T value) {
3673
6.80k
    write<Char>(out, value);
3674
6.80k
  }
_ZN3fmt3v126detail21default_arg_formatterIcEclIeTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3672
5.94k
  void operator()(T value) {
3673
5.94k
    write<Char>(out, value);
3674
5.94k
  }
Unexecuted instantiation: _ZN3fmt3v126detail21default_arg_formatterIcEclIPKcTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS9_
Unexecuted instantiation: _ZN3fmt3v126detail21default_arg_formatterIcEclINS0_17basic_string_viewIcEETnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS9_
Unexecuted instantiation: _ZN3fmt3v126detail21default_arg_formatterIcEclIPKvTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS9_
3675
3676
  template <typename T, FMT_ENABLE_IF(!is_builtin<T>::value)>
3677
  void operator()(T) {
3678
    FMT_ASSERT(false, "");
3679
  }
3680
3681
309
  void operator()(typename basic_format_arg<context>::handle h) {
3682
    // Use a null locale since the default format must be unlocalized.
3683
309
    auto parse_ctx = parse_context<Char>({});
3684
309
    auto format_ctx = context(out, {}, {});
3685
309
    h.format(parse_ctx, format_ctx);
3686
309
  }
3687
};
3688
3689
template <typename Char> struct arg_formatter {
3690
  basic_appender<Char> out;
3691
  const format_specs& specs;
3692
  FMT_NO_UNIQUE_ADDRESS locale_ref locale;
3693
3694
  template <typename T, FMT_ENABLE_IF(is_builtin<T>::value)>
3695
62.5k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
62.5k
    detail::write<Char>(out, value, specs, locale);
3697
62.5k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIiTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
4.99k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
4.99k
    detail::write<Char>(out, value, specs, locale);
3697
4.99k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIjTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
2.60k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
2.60k
    detail::write<Char>(out, value, specs, locale);
3697
2.60k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIxTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
5.43k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
5.43k
    detail::write<Char>(out, value, specs, locale);
3697
5.43k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIyTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
2.66k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
2.66k
    detail::write<Char>(out, value, specs, locale);
3697
2.66k
  }
Unexecuted instantiation: _ZN3fmt3v126detail13arg_formatterIcEclInTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Unexecuted instantiation: _ZN3fmt3v126detail13arg_formatterIcEclIoTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
_ZN3fmt3v126detail13arg_formatterIcEclIbTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
1.98k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
1.98k
    detail::write<Char>(out, value, specs, locale);
3697
1.98k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIcTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
5.01k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
5.01k
    detail::write<Char>(out, value, specs, locale);
3697
5.01k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIfTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
14.3k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
14.3k
    detail::write<Char>(out, value, specs, locale);
3697
14.3k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIdTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
15.1k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
15.1k
    detail::write<Char>(out, value, specs, locale);
3697
15.1k
  }
_ZN3fmt3v126detail13arg_formatterIcEclIeTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS7_
Line
Count
Source
3695
10.3k
  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {
3696
10.3k
    detail::write<Char>(out, value, specs, locale);
3697
10.3k
  }
Unexecuted instantiation: _ZN3fmt3v126detail13arg_formatterIcEclIPKcTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS9_
Unexecuted instantiation: _ZN3fmt3v126detail13arg_formatterIcEclINS0_17basic_string_viewIcEETnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS9_
Unexecuted instantiation: _ZN3fmt3v126detail13arg_formatterIcEclIPKvTnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS9_
Unexecuted instantiation: _ZN3fmt3v126detail13arg_formatterIcEclINS0_9monostateETnNSt3__19enable_ifIXsr10is_builtinIT_EE5valueEiE4typeELi0EEEvS8_
3698
3699
  template <typename T, FMT_ENABLE_IF(!is_builtin<T>::value)>
3700
  void operator()(T) {
3701
    FMT_ASSERT(false, "");
3702
  }
3703
3704
0
  void operator()(typename basic_format_arg<buffered_context<Char>>::handle) {
3705
    // User-defined types are handled separately because they require access
3706
    // to the parse context.
3707
0
  }
3708
};
3709
3710
struct dynamic_spec_getter {
3711
  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
3712
1.09k
  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3713
1.09k
    return is_negative(value) ? ~0ull : static_cast<unsigned long long>(value);
3714
1.09k
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIiTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3712
324
  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3713
324
    return is_negative(value) ? ~0ull : static_cast<unsigned long long>(value);
3714
324
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIjTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3712
219
  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3713
219
    return is_negative(value) ? ~0ull : static_cast<unsigned long long>(value);
3714
219
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIxTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3712
304
  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3713
304
    return is_negative(value) ? ~0ull : static_cast<unsigned long long>(value);
3714
304
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIyTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3712
246
  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
3713
246
    return is_negative(value) ? ~0ull : static_cast<unsigned long long>(value);
3714
246
  }
Unexecuted instantiation: _ZN3fmt3v126detail19dynamic_spec_getterclInTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Unexecuted instantiation: _ZN3fmt3v126detail19dynamic_spec_getterclIoTnNSt3__19enable_ifIXsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
3715
3716
  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
3717
7
  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3718
7
    report_error("width/precision is not integer");
3719
7
    return 0;
3720
7
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIbTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3717
1
  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3718
1
    report_error("width/precision is not integer");
3719
1
    return 0;
3720
1
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIcTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3717
1
  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3718
1
    report_error("width/precision is not integer");
3719
1
    return 0;
3720
1
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIfTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3717
1
  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3718
1
    report_error("width/precision is not integer");
3719
1
    return 0;
3720
1
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIdTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3717
1
  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3718
1
    report_error("width/precision is not integer");
3719
1
    return 0;
3720
1
  }
_ZN3fmt3v126detail19dynamic_spec_getterclIeTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS6_
Line
Count
Source
3717
2
  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3718
2
    report_error("width/precision is not integer");
3719
2
    return 0;
3720
2
  }
Unexecuted instantiation: _ZN3fmt3v126detail19dynamic_spec_getterclIPKcTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS8_
Unexecuted instantiation: _ZN3fmt3v126detail19dynamic_spec_getterclINS0_17basic_string_viewIcEETnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS8_
Unexecuted instantiation: _ZN3fmt3v126detail19dynamic_spec_getterclIPKvTnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS8_
_ZN3fmt3v126detail19dynamic_spec_getterclINS0_16basic_format_argINS0_7contextEE6handleETnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEySA_
Line
Count
Source
3717
1
  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
3718
1
    report_error("width/precision is not integer");
3719
1
    return 0;
3720
1
  }
Unexecuted instantiation: _ZN3fmt3v126detail19dynamic_spec_getterclINS0_9monostateETnNSt3__19enable_ifIXntsr10is_integerIT_EE5valueEiE4typeELi0EEEyS7_
3721
};
3722
3723
template <typename Context>
3724
FMT_CONSTEXPR void handle_dynamic_spec(
3725
    arg_id_kind kind, int& value,
3726
8.23k
    const arg_ref<typename Context::char_type>& ref, Context& ctx) {
3727
8.23k
  if (kind == arg_id_kind::none) return;
3728
1.12k
  auto arg =
3729
1.12k
      kind == arg_id_kind::index ? ctx.arg(ref.index) : ctx.arg(ref.name);
3730
1.12k
  if (!arg) report_error("argument not found");
3731
1.12k
  unsigned long long result = arg.visit(dynamic_spec_getter());
3732
1.12k
  if (result > to_unsigned(max_value<int>()))
3733
136
    report_error("width/precision is out of range");
3734
1.12k
  value = static_cast<int>(result);
3735
1.12k
}
3736
3737
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
3738
template <typename T, typename Char, size_t N,
3739
          fmt::detail::fixed_string<Char, N> Str>
3740
struct static_named_arg : view {
3741
  static constexpr auto name = Str.data;
3742
3743
  const T& value;
3744
  static_named_arg(const T& v) : value(v) {}
3745
};
3746
3747
template <typename T, typename Char, size_t N,
3748
          fmt::detail::fixed_string<Char, N> Str>
3749
struct is_named_arg<static_named_arg<T, Char, N, Str>> : std::true_type {};
3750
3751
template <typename T, typename Char, size_t N,
3752
          fmt::detail::fixed_string<Char, N> Str>
3753
struct is_static_named_arg<static_named_arg<T, Char, N, Str>> : std::true_type {
3754
};
3755
3756
template <typename Char, size_t N, fmt::detail::fixed_string<Char, N> Str>
3757
struct udl_arg {
3758
  template <typename T> auto operator=(T&& value) const {
3759
    return static_named_arg<T, Char, N, Str>(std::forward<T>(value));
3760
  }
3761
};
3762
#else
3763
template <typename Char> struct udl_arg {
3764
  const Char* str;
3765
3766
  template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
3767
    return {str, std::forward<T>(value)};
3768
  }
3769
};
3770
#endif  // FMT_USE_NONTYPE_TEMPLATE_ARGS
3771
3772
template <typename Char = char> struct format_handler {
3773
  parse_context<Char> parse_ctx;
3774
  buffered_context<Char> ctx;
3775
3776
94.3k
  void on_text(const Char* begin, const Char* end) {
3777
94.3k
    copy_noinline<Char>(begin, end, ctx.out());
3778
94.3k
  }
3779
3780
6.38k
  FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); }
3781
85.0k
  FMT_CONSTEXPR auto on_arg_id(int id) -> int {
3782
85.0k
    parse_ctx.check_arg_id(id);
3783
85.0k
    return id;
3784
85.0k
  }
3785
76
  FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
3786
76
    parse_ctx.check_arg_id(id);
3787
76
    int arg_id = ctx.arg_id(id);
3788
76
    if (arg_id < 0) report_error("argument not found");
3789
76
    return arg_id;
3790
76
  }
3791
3792
22.3k
  FMT_INLINE void on_replacement_field(int id, const Char*) {
3793
22.3k
    ctx.arg(id).visit(default_arg_formatter<Char>{ctx.out()});
3794
22.3k
  }
3795
3796
  auto on_format_specs(int id, const Char* begin, const Char* end)
3797
68.9k
      -> const Char* {
3798
68.9k
    auto arg = ctx.arg(id);
3799
68.9k
    if (!arg) report_error("argument not found");
3800
    // Not using a visitor for custom types gives better codegen.
3801
68.9k
    if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin();
3802
3803
63.2k
    auto specs = dynamic_format_specs<Char>();
3804
63.2k
    begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type());
3805
63.2k
    if (specs.dynamic()) {
3806
1.12k
      handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref,
3807
1.12k
                          ctx);
3808
1.12k
      handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
3809
1.12k
                          specs.precision_ref, ctx);
3810
1.12k
    }
3811
3812
63.2k
    arg.visit(arg_formatter<Char>{ctx.out(), specs, ctx.locale()});
3813
63.2k
    return begin;
3814
68.9k
  }
3815
3816
7.16k
  FMT_NORETURN void on_error(const char* message) { report_error(message); }
3817
};
3818
3819
// It is used in format-inl.h and os.cc.
3820
using format_func = void (*)(detail::buffer<char>&, int, const char*);
3821
FMT_API void do_report_error(format_func func, int error_code,
3822
                             const char* message) noexcept;
3823
3824
FMT_API void format_error_code(buffer<char>& out, int error_code,
3825
                               string_view message) noexcept;
3826
3827
template <typename T, typename Char, type TYPE>
3828
template <typename FormatContext>
3829
FMT_CONSTEXPR auto native_formatter<T, Char, TYPE>::format(
3830
    const T& val, FormatContext& ctx) const -> decltype(ctx.out()) {
3831
  if (!specs_.dynamic())
3832
    return write<Char>(ctx.out(), val, specs_, ctx.locale());
3833
  auto specs = format_specs(specs_);
3834
  handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref,
3835
                      ctx);
3836
  handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
3837
                      specs_.precision_ref, ctx);
3838
  return write<Char>(ctx.out(), val, specs, ctx.locale());
3839
}
3840
}  // namespace detail
3841
3842
FMT_BEGIN_EXPORT
3843
3844
// A generic formatting context with custom output iterator and character
3845
// (code unit) support. Char is the format string code unit type which can be
3846
// different from OutputIt::value_type.
3847
template <typename OutputIt, typename Char> class generic_context {
3848
 private:
3849
  OutputIt out_;
3850
  basic_format_args<generic_context> args_;
3851
  locale_ref loc_;
3852
3853
 public:
3854
  using char_type = Char;
3855
  using iterator = OutputIt;
3856
  enum { builtin_types = FMT_BUILTIN_TYPES };
3857
3858
  constexpr generic_context(OutputIt out,
3859
                            basic_format_args<generic_context> args,
3860
                            locale_ref loc = {})
3861
      : out_(out), args_(args), loc_(loc) {}
3862
  generic_context(generic_context&&) = default;
3863
  generic_context(const generic_context&) = delete;
3864
  void operator=(const generic_context&) = delete;
3865
3866
  constexpr auto arg(int id) const -> basic_format_arg<generic_context> {
3867
    return args_.get(id);
3868
  }
3869
  auto arg(basic_string_view<Char> name) const
3870
      -> basic_format_arg<generic_context> {
3871
    return args_.get(name);
3872
  }
3873
  constexpr auto arg_id(basic_string_view<Char> name) const -> int {
3874
    return args_.get_id(name);
3875
  }
3876
3877
  constexpr auto out() const -> iterator { return out_; }
3878
3879
  void advance_to(iterator it) {
3880
    if (!detail::is_back_insert_iterator<iterator>()) out_ = it;
3881
  }
3882
3883
  constexpr auto locale() const -> locale_ref { return loc_; }
3884
};
3885
3886
class loc_value {
3887
 private:
3888
  basic_format_arg<context> value_;
3889
3890
 public:
3891
  template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>
3892
5.67k
  loc_value(T value) : value_(value) {}
_ZN3fmt3v129loc_valueC2IiTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
2.05k
  loc_value(T value) : value_(value) {}
_ZN3fmt3v129loc_valueC2IeTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
366
  loc_value(T value) : value_(value) {}
_ZN3fmt3v129loc_valueC2IjTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
701
  loc_value(T value) : value_(value) {}
_ZN3fmt3v129loc_valueC2IxTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
845
  loc_value(T value) : value_(value) {}
_ZN3fmt3v129loc_valueC2IyTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
933
  loc_value(T value) : value_(value) {}
Unexecuted instantiation: _ZN3fmt3v129loc_valueC2InTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Unexecuted instantiation: _ZN3fmt3v129loc_valueC2IoTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
_ZN3fmt3v129loc_valueC2IhTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
355
  loc_value(T value) : value_(value) {}
_ZN3fmt3v129loc_valueC2IfTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
222
  loc_value(T value) : value_(value) {}
_ZN3fmt3v129loc_valueC2IdTnNSt3__19enable_ifIXntsr6detail11is_float128IT_EE5valueEiE4typeELi0EEES5_
Line
Count
Source
3892
198
  loc_value(T value) : value_(value) {}
3893
3894
  template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>
3895
  loc_value(T) {}
3896
3897
5.67k
  template <typename Visitor> auto visit(Visitor&& vis) -> decltype(vis(0)) {
3898
5.67k
    return value_.visit(vis);
3899
5.67k
  }
3900
};
3901
3902
// A locale facet that formats values in UTF-8.
3903
// It is parameterized on the locale to avoid the heavy <locale> include.
3904
template <typename Locale> class format_facet : public Locale::facet {
3905
 private:
3906
  std::string separator_;
3907
  std::string grouping_;
3908
  std::string decimal_point_;
3909
3910
 protected:
3911
  virtual auto do_put(appender out, loc_value val,
3912
                      const format_specs& specs) const -> bool;
3913
3914
 public:
3915
  static FMT_API typename Locale::id id;
3916
3917
  explicit format_facet(Locale& loc);
3918
  explicit format_facet(string_view sep = "", std::string grouping = "\3",
3919
                        std::string decimal_point = ".")
3920
      : separator_(sep.data(), sep.size()),
3921
        grouping_(grouping),
3922
        decimal_point_(decimal_point) {}
3923
3924
  auto put(appender out, loc_value val, const format_specs& specs) const
3925
5.67k
      -> bool {
3926
5.67k
    return do_put(out, val, specs);
3927
5.67k
  }
3928
};
3929
3930
#define FMT_FORMAT_AS(Type, Base)                                   \
3931
  template <typename Char>                                          \
3932
  struct formatter<Type, Char> : formatter<Base, Char> {            \
3933
    template <typename FormatContext>                               \
3934
    FMT_CONSTEXPR auto format(Type value, FormatContext& ctx) const \
3935
        -> decltype(ctx.out()) {                                    \
3936
      return formatter<Base, Char>::format(value, ctx);             \
3937
    }                                                               \
3938
  }
3939
3940
FMT_FORMAT_AS(signed char, int);
3941
FMT_FORMAT_AS(unsigned char, unsigned);
3942
FMT_FORMAT_AS(short, int);
3943
FMT_FORMAT_AS(unsigned short, unsigned);
3944
FMT_FORMAT_AS(long, detail::long_type);
3945
FMT_FORMAT_AS(unsigned long, detail::ulong_type);
3946
FMT_FORMAT_AS(Char*, const Char*);
3947
FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
3948
FMT_FORMAT_AS(std::nullptr_t, const void*);
3949
FMT_FORMAT_AS(void*, const void*);
3950
3951
template <typename Char, size_t N>
3952
struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {};
3953
3954
template <typename Char, typename Traits, typename Allocator>
3955
class formatter<std::basic_string<Char, Traits, Allocator>, Char>
3956
    : public formatter<basic_string_view<Char>, Char> {};
3957
3958
template <int N, typename Char>
3959
struct formatter<detail::bitint<N>, Char> : formatter<long long, Char> {};
3960
template <int N, typename Char>
3961
struct formatter<detail::ubitint<N>, Char>
3962
    : formatter<unsigned long long, Char> {};
3963
3964
template <typename Char>
3965
struct formatter<detail::float128, Char>
3966
    : detail::native_formatter<detail::float128, Char,
3967
                               detail::type::float_type> {};
3968
3969
template <typename T, typename Char>
3970
struct formatter<T, Char, void_t<detail::format_as_result<T>>>
3971
    : formatter<detail::format_as_result<T>, Char> {
3972
  template <typename FormatContext>
3973
  FMT_CONSTEXPR auto format(const T& value, FormatContext& ctx) const
3974
      -> decltype(ctx.out()) {
3975
    auto&& val = format_as(value);  // Make an lvalue reference for format.
3976
    return formatter<detail::format_as_result<T>, Char>::format(val, ctx);
3977
  }
3978
};
3979
3980
/**
3981
 * Converts `p` to `const void*` for pointer formatting.
3982
 *
3983
 * **Example**:
3984
 *
3985
 *     auto s = fmt::format("{}", fmt::ptr(p));
3986
 */
3987
template <typename T> auto ptr(T p) -> const void* {
3988
  static_assert(std::is_pointer<T>::value, "fmt::ptr used with non-pointer");
3989
  return detail::bit_cast<const void*>(p);
3990
}
3991
3992
/**
3993
 * Converts `e` to the underlying type.
3994
 *
3995
 * **Example**:
3996
 *
3997
 *     enum class color { red, green, blue };
3998
 *     auto s = fmt::format("{}", fmt::underlying(color::red));  // s == "0"
3999
 */
4000
template <typename Enum>
4001
constexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {
4002
  return static_cast<underlying_t<Enum>>(e);
4003
}
4004
4005
namespace enums {
4006
template <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
4007
constexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {
4008
  return static_cast<underlying_t<Enum>>(e);
4009
}
4010
}  // namespace enums
4011
4012
#ifdef __cpp_lib_byte
4013
template <typename Char>
4014
struct formatter<std::byte, Char> : formatter<unsigned, Char> {
4015
  static auto format_as(std::byte b) -> unsigned char {
4016
    return static_cast<unsigned char>(b);
4017
  }
4018
  template <typename Context>
4019
  auto format(std::byte b, Context& ctx) const -> decltype(ctx.out()) {
4020
    return formatter<unsigned, Char>::format(format_as(b), ctx);
4021
  }
4022
};
4023
#endif
4024
4025
struct bytes {
4026
  string_view data;
4027
4028
0
  inline explicit bytes(string_view s) : data(s) {}
4029
};
4030
4031
template <> struct formatter<bytes> {
4032
 private:
4033
  detail::dynamic_format_specs<> specs_;
4034
4035
 public:
4036
0
  FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
4037
0
    return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
4038
0
                              detail::type::string_type);
4039
0
  }
4040
4041
  template <typename FormatContext>
4042
  auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) {
4043
    auto specs = specs_;
4044
    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
4045
                                specs.width_ref, ctx);
4046
    detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
4047
                                specs.precision_ref, ctx);
4048
    return detail::write_bytes<char>(ctx.out(), b.data, specs);
4049
  }
4050
};
4051
4052
// group_digits_view is not derived from view because it copies the argument.
4053
template <typename T> struct group_digits_view {
4054
  T value;
4055
};
4056
4057
/**
4058
 * Returns a view that formats an integer value using ',' as a
4059
 * locale-independent thousands separator.
4060
 *
4061
 * **Example**:
4062
 *
4063
 *     fmt::print("{}", fmt::group_digits(12345));
4064
 *     // Output: "12,345"
4065
 */
4066
template <typename T> auto group_digits(T value) -> group_digits_view<T> {
4067
  return {value};
4068
}
4069
4070
template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
4071
 private:
4072
  detail::dynamic_format_specs<> specs_;
4073
4074
 public:
4075
  FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
4076
    return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
4077
                              detail::type::int_type);
4078
  }
4079
4080
  template <typename FormatContext>
4081
  auto format(group_digits_view<T> view, FormatContext& ctx) const
4082
      -> decltype(ctx.out()) {
4083
    auto specs = specs_;
4084
    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
4085
                                specs.width_ref, ctx);
4086
    detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
4087
                                specs.precision_ref, ctx);
4088
    auto arg = detail::make_write_int_arg(view.value, specs.sign());
4089
    return detail::write_int(
4090
        ctx.out(), static_cast<detail::uint64_or_128_t<T>>(arg.abs_value),
4091
        arg.prefix, specs, detail::digit_grouping<char>("\3", ","));
4092
  }
4093
};
4094
4095
template <typename T, typename Char> struct nested_view {
4096
  const formatter<T, Char>* fmt;
4097
  const T* value;
4098
};
4099
4100
template <typename T, typename Char>
4101
struct formatter<nested_view<T, Char>, Char> {
4102
  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
4103
    return ctx.begin();
4104
  }
4105
  template <typename FormatContext>
4106
  auto format(nested_view<T, Char> view, FormatContext& ctx) const
4107
      -> decltype(ctx.out()) {
4108
    return view.fmt->format(*view.value, ctx);
4109
  }
4110
};
4111
4112
template <typename T, typename Char = char> struct nested_formatter {
4113
 private:
4114
  basic_specs specs_;
4115
  int width_;
4116
  formatter<T, Char> formatter_;
4117
4118
 public:
4119
  constexpr nested_formatter() : width_(0) {}
4120
4121
  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
4122
    auto it = ctx.begin(), end = ctx.end();
4123
    if (it == end) return it;
4124
    auto specs = format_specs();
4125
    it = detail::parse_align(it, end, specs);
4126
    specs_ = specs;
4127
    Char c = *it;
4128
    auto width_ref = detail::arg_ref<Char>();
4129
    if ((c >= '0' && c <= '9') || c == '{') {
4130
      it = detail::parse_width(it, end, specs, width_ref, ctx);
4131
      width_ = specs.width;
4132
    }
4133
    ctx.advance_to(it);
4134
    return formatter_.parse(ctx);
4135
  }
4136
4137
  template <typename FormatContext, typename F>
4138
  auto write_padded(FormatContext& ctx, F write) const -> decltype(ctx.out()) {
4139
    if (width_ == 0) return write(ctx.out());
4140
    auto buf = basic_memory_buffer<Char>();
4141
    write(basic_appender<Char>(buf));
4142
    auto specs = format_specs();
4143
    specs.width = width_;
4144
    specs.copy_fill_from(specs_);
4145
    specs.set_align(specs_.align());
4146
    return detail::write<Char>(
4147
        ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
4148
  }
4149
4150
  auto nested(const T& value) const -> nested_view<T, Char> {
4151
    return nested_view<T, Char>{&formatter_, &value};
4152
  }
4153
};
4154
4155
inline namespace literals {
4156
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
4157
template <detail::fixed_string S> constexpr auto operator""_a() {
4158
  using char_t = remove_cvref_t<decltype(*S.data)>;
4159
  return detail::udl_arg<char_t, sizeof(S.data) / sizeof(char_t), S>();
4160
}
4161
#else
4162
/**
4163
 * User-defined literal equivalent of `fmt::arg`.
4164
 *
4165
 * **Example**:
4166
 *
4167
 *     using namespace fmt::literals;
4168
 *     fmt::print("The answer is {answer}.", "answer"_a=42);
4169
 */
4170
0
constexpr auto operator""_a(const char* s, size_t) -> detail::udl_arg<char> {
4171
0
  return {s};
4172
0
}
4173
#endif  // FMT_USE_NONTYPE_TEMPLATE_ARGS
4174
}  // namespace literals
4175
4176
/// A fast integer formatter.
4177
class format_int {
4178
 private:
4179
  // Buffer should be large enough to hold all digits (digits10 + 1),
4180
  // a sign and a null character.
4181
  enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
4182
  mutable char buffer_[buffer_size];
4183
  char* str_;
4184
4185
  template <typename UInt>
4186
0
  FMT_CONSTEXPR20 auto format_unsigned(UInt value) -> char* {
4187
0
    auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
4188
0
    return detail::do_format_decimal(buffer_, n, buffer_size - 1);
4189
0
  }
Unexecuted instantiation: char* fmt::v12::format_int::format_unsigned<unsigned int>(unsigned int)
Unexecuted instantiation: char* fmt::v12::format_int::format_unsigned<unsigned long>(unsigned long)
Unexecuted instantiation: char* fmt::v12::format_int::format_unsigned<unsigned long long>(unsigned long long)
4190
4191
  template <typename Int>
4192
0
  FMT_CONSTEXPR20 auto format_signed(Int value) -> char* {
4193
0
    auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
4194
0
    bool negative = value < 0;
4195
0
    if (negative) abs_value = 0 - abs_value;
4196
0
    auto begin = format_unsigned(abs_value);
4197
0
    if (negative) *--begin = '-';
4198
0
    return begin;
4199
0
  }
Unexecuted instantiation: char* fmt::v12::format_int::format_signed<int>(int)
Unexecuted instantiation: char* fmt::v12::format_int::format_signed<long>(long)
Unexecuted instantiation: char* fmt::v12::format_int::format_signed<long long>(long long)
4200
4201
 public:
4202
0
  FMT_CONSTEXPR20 explicit format_int(int value) : str_(format_signed(value)) {}
4203
  FMT_CONSTEXPR20 explicit format_int(long value)
4204
0
      : str_(format_signed(value)) {}
4205
  FMT_CONSTEXPR20 explicit format_int(long long value)
4206
0
      : str_(format_signed(value)) {}
4207
  FMT_CONSTEXPR20 explicit format_int(unsigned value)
4208
0
      : str_(format_unsigned(value)) {}
4209
  FMT_CONSTEXPR20 explicit format_int(unsigned long value)
4210
0
      : str_(format_unsigned(value)) {}
4211
  FMT_CONSTEXPR20 explicit format_int(unsigned long long value)
4212
0
      : str_(format_unsigned(value)) {}
4213
4214
  /// Returns the number of characters written to the output buffer.
4215
0
  FMT_CONSTEXPR20 auto size() const -> size_t {
4216
0
    return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
4217
0
  }
4218
4219
  /// Returns a pointer to the output buffer content. No terminating null
4220
  /// character is appended.
4221
0
  FMT_CONSTEXPR20 auto data() const -> const char* { return str_; }
4222
4223
  /// Returns a pointer to the output buffer content with terminating null
4224
  /// character appended.
4225
0
  FMT_CONSTEXPR20 auto c_str() const -> const char* {
4226
0
    buffer_[buffer_size - 1] = '\0';
4227
0
    return str_;
4228
0
  }
4229
4230
  /// Returns the content of the output buffer as an `std::string`.
4231
0
  inline auto str() const -> std::string { return {str_, size()}; }
4232
};
4233
4234
#if FMT_CLANG_ANALYZER
4235
#  define FMT_STRING_IMPL(s, base) s
4236
#else
4237
#  define FMT_STRING_IMPL(s, base)                                           \
4238
0
    [] {                                                                     \
4239
0
      /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
4240
0
      /* Use a macro-like name to avoid shadowing warnings. */               \
4241
0
      struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base {            \
4242
0
        using char_type = fmt::remove_cvref_t<decltype(s[0])>;               \
4243
0
        constexpr explicit operator fmt::basic_string_view<char_type>()      \
4244
0
            const {                                                          \
4245
0
          return fmt::detail::compile_string_to_view<char_type>(s);          \
4246
0
        }                                                                    \
Unexecuted instantiation: fmt::v12::detail::write_floating_seconds<std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l> > >(fmt::v12::basic_memory_buffer<char, 500ul, fmt::v12::detail::allocator<char> >&, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l> >, int)::{lambda()#1}::operator()() const::FMT_COMPILE_STRING::operator fmt::v12::basic_string_view<char>() const
Unexecuted instantiation: format.cc:fmt::v12::detail::format_error_code(fmt::v12::detail::buffer<char>&, int, fmt::v12::basic_string_view<char>)::$_0::operator()() const::FMT_COMPILE_STRING::operator fmt::v12::basic_string_view<char>() const
Unexecuted instantiation: format.cc:fmt::v12::detail::format_error_code(fmt::v12::detail::buffer<char>&, int, fmt::v12::basic_string_view<char>)::$_1::operator()() const::FMT_COMPILE_STRING::operator fmt::v12::basic_string_view<char>() const
Unexecuted instantiation: fmt::v12::formatter<fmt::v12::detail::bigint, char, void>::format(fmt::v12::detail::bigint const&, fmt::v12::context&) const::{lambda()#1}::operator()() const::FMT_COMPILE_STRING::operator fmt::v12::basic_string_view<char>() const
Unexecuted instantiation: fmt::v12::formatter<fmt::v12::detail::bigint, char, void>::format(fmt::v12::detail::bigint const&, fmt::v12::context&) const::{lambda()#2}::operator()() const::FMT_COMPILE_STRING::operator fmt::v12::basic_string_view<char>() const
Unexecuted instantiation: fmt::v12::formatter<fmt::v12::detail::bigint, char, void>::format(fmt::v12::detail::bigint const&, fmt::v12::context&) const::{lambda()#3}::operator()() const::FMT_COMPILE_STRING::operator fmt::v12::basic_string_view<char>() const
4247
0
      };                                                                     \
4248
0
      using FMT_STRING_VIEW =                                                \
4249
0
          fmt::basic_string_view<typename FMT_COMPILE_STRING::char_type>;    \
4250
0
      fmt::detail::ignore_unused(FMT_STRING_VIEW(FMT_COMPILE_STRING()));     \
4251
0
      return FMT_COMPILE_STRING();                                           \
4252
0
    }()
Unexecuted instantiation: format.cc:fmt::v12::detail::format_error_code(fmt::v12::detail::buffer<char>&, int, fmt::v12::basic_string_view<char>)::$_0::operator()() const
Unexecuted instantiation: format.cc:fmt::v12::detail::format_error_code(fmt::v12::detail::buffer<char>&, int, fmt::v12::basic_string_view<char>)::$_1::operator()() const
4253
#endif  // FMT_CLANG_ANALYZER
4254
4255
/**
4256
 * Constructs a legacy compile-time format string from a string literal `s`.
4257
 *
4258
 * **Example**:
4259
 *
4260
 *     // A compile-time error because 'd' is an invalid specifier for strings.
4261
 *     std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
4262
 */
4263
0
#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string)
4264
4265
FMT_API auto vsystem_error(int error_code, string_view fmt, format_args args)
4266
    -> std::system_error;
4267
4268
/**
4269
 * Constructs `std::system_error` with a message formatted with
4270
 * `fmt::format(fmt, args...)`.
4271
 * `error_code` is a system error code as given by `errno`.
4272
 *
4273
 * **Example**:
4274
 *
4275
 *     // This throws std::system_error with the description
4276
 *     //   cannot open file 'madeup': No such file or directory
4277
 *     // or similar (system message may vary).
4278
 *     const char* filename = "madeup";
4279
 *     FILE* file = fopen(filename, "r");
4280
 *     if (!file)
4281
 *       throw fmt::system_error(errno, "cannot open file '{}'", filename);
4282
 */
4283
template <typename... T>
4284
auto system_error(int error_code, format_string<T...> fmt, T&&... args)
4285
0
    -> std::system_error {
4286
0
  return vsystem_error(error_code, fmt.str, vargs<T...>{{args...}});
4287
0
}
4288
4289
/**
4290
 * Formats an error message for an error returned by an operating system or a
4291
 * language runtime, for example a file opening error, and writes it to `out`.
4292
 * The format is the same as the one used by `std::system_error(ec, message)`
4293
 * where `ec` is `std::error_code(error_code, std::generic_category())`.
4294
 * It is implementation-defined but normally looks like:
4295
 *
4296
 *     <message>: <system-message>
4297
 *
4298
 * where `<message>` is the passed message and `<system-message>` is the system
4299
 * message corresponding to the error code.
4300
 * `error_code` is a system error code as given by `errno`.
4301
 */
4302
FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
4303
                                 const char* message) noexcept;
4304
4305
// Reports a system error without throwing an exception.
4306
// Can be used to report errors from destructors.
4307
FMT_API void report_system_error(int error_code, const char* message) noexcept;
4308
4309
inline auto vformat(locale_ref loc, string_view fmt, format_args args)
4310
0
    -> std::string {
4311
0
  auto buf = memory_buffer();
4312
0
  detail::vformat_to(buf, fmt, args, loc);
4313
0
  return {buf.data(), buf.size()};
4314
0
}
4315
4316
template <typename... T>
4317
FMT_INLINE auto format(locale_ref loc, format_string<T...> fmt, T&&... args)
4318
    -> std::string {
4319
  return vformat(loc, fmt.str, vargs<T...>{{args...}});
4320
}
4321
4322
template <typename OutputIt,
4323
          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
4324
auto vformat_to(OutputIt out, locale_ref loc, string_view fmt, format_args args)
4325
    -> OutputIt {
4326
  auto&& buf = detail::get_buffer<char>(out);
4327
  detail::vformat_to(buf, fmt, args, loc);
4328
  return detail::get_iterator(buf, out);
4329
}
4330
4331
template <typename OutputIt, typename... T,
4332
          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
4333
FMT_INLINE auto format_to(OutputIt out, locale_ref loc, format_string<T...> fmt,
4334
                          T&&... args) -> OutputIt {
4335
  return fmt::vformat_to(out, loc, fmt.str, vargs<T...>{{args...}});
4336
}
4337
4338
template <typename... T>
4339
FMT_NODISCARD FMT_INLINE auto formatted_size(locale_ref loc,
4340
                                             format_string<T...> fmt,
4341
                                             T&&... args) -> size_t {
4342
  auto buf = detail::counting_buffer<>();
4343
  detail::vformat_to(buf, fmt.str, vargs<T...>{{args...}}, loc);
4344
  return buf.count();
4345
}
4346
4347
FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
4348
4349
/**
4350
 * Formats `args` according to specifications in `fmt` and returns the result
4351
 * as a string.
4352
 *
4353
 * **Example**:
4354
 *
4355
 *     #include <fmt/format.h>
4356
 *     std::string message = fmt::format("The answer is {}.", 42);
4357
 */
4358
template <typename... T>
4359
FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
4360
    -> std::string {
4361
  return vformat(fmt.str, vargs<T...>{{args...}});
4362
}
4363
4364
/**
4365
 * Converts `value` to `std::string` using the default format for type `T`.
4366
 *
4367
 * **Example**:
4368
 *
4369
 *     std::string answer = fmt::to_string(42);
4370
 */
4371
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
4372
FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(T value) -> std::string {
4373
  // The buffer should be large enough to store the number including the sign
4374
  // or "false" for bool.
4375
  char buffer[max_of(detail::digits10<T>() + 2, 5)];
4376
  return {buffer, detail::write<char>(buffer, value)};
4377
}
4378
4379
template <typename T, FMT_ENABLE_IF(detail::use_format_as<T>::value)>
4380
FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value)
4381
    -> std::string {
4382
  return to_string(format_as(value));
4383
}
4384
4385
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
4386
                                    !detail::use_format_as<T>::value)>
4387
FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value)
4388
    -> std::string {
4389
  auto buffer = memory_buffer();
4390
  detail::write<char>(appender(buffer), value);
4391
  return {buffer.data(), buffer.size()};
4392
}
4393
4394
FMT_END_EXPORT
4395
FMT_END_NAMESPACE
4396
4397
#ifdef FMT_HEADER_ONLY
4398
#  define FMT_FUNC inline
4399
#  include "format-inl.h"
4400
#endif
4401
4402
// Restore _LIBCPP_REMOVE_TRANSITIVE_INCLUDES.
4403
#ifdef FMT_REMOVE_TRANSITIVE_INCLUDES
4404
#  undef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
4405
#endif
4406
4407
#endif  // FMT_FORMAT_H_