1 /*
2 Formatting library for C++
3
4 Copyright (c) 2012 - present, Victor Zverovich
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 --- Optional exception to the license ---
26
27 As an exception, if, as a result of your compiling your source code, portions
28 of this Software are embedded into a machine-executable object form of such
29 source code, you may redistribute such embedded portions in such object form
30 without including the above copyright and permission notices.
31 */
32
33 #ifndef FMT_FORMAT_H_
34 #define FMT_FORMAT_H_
35
36 #include <cmath> // std::signbit
37 #include <cstdint> // uint32_t
38 #include <limits> // std::numeric_limits
39 #include <memory> // std::uninitialized_copy
40 #include <stdexcept> // std::runtime_error
41 #include <system_error> // std::system_error
42 #include <utility> // std::swap
43
44 #include "core.h"
45
46 #ifdef __INTEL_COMPILER
47 # define FMT_ICC_VERSION __INTEL_COMPILER
48 #elif defined(__ICL)
49 # define FMT_ICC_VERSION __ICL
50 #else
51 # define FMT_ICC_VERSION 0
52 #endif
53
54 #ifdef __NVCC__
55 # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
56 #else
57 # define FMT_CUDA_VERSION 0
58 #endif
59
60 #ifdef __has_builtin
61 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
62 #else
63 # define FMT_HAS_BUILTIN(x) 0
64 #endif
65
66 #if FMT_GCC_VERSION || FMT_CLANG_VERSION
67 # define FMT_NOINLINE __attribute__((noinline))
68 #else
69 # define FMT_NOINLINE
70 #endif
71
72 #if FMT_MSC_VER
73 # define FMT_MSC_DEFAULT = default
74 #else
75 # define FMT_MSC_DEFAULT
76 #endif
77
78 #ifndef FMT_THROW
79 # if FMT_EXCEPTIONS
80 # if FMT_MSC_VER || FMT_NVCC
81 FMT_BEGIN_NAMESPACE
82 namespace detail {
do_throw(const Exception & x)83 template <typename Exception> inline void do_throw(const Exception& x) {
84 // Silence unreachable code warnings in MSVC and NVCC because these
85 // are nearly impossible to fix in a generic code.
86 volatile bool b = true;
87 if (b) throw x;
88 }
89 } // namespace detail
90 FMT_END_NAMESPACE
91 # define FMT_THROW(x) detail::do_throw(x)
92 # else
93 # define FMT_THROW(x) throw x
94 # endif
95 # else
96 # define FMT_THROW(x) \
97 do { \
98 FMT_ASSERT(false, (x).what()); \
99 } while (false)
100 # endif
101 #endif
102
103 #if FMT_EXCEPTIONS
104 # define FMT_TRY try
105 # define FMT_CATCH(x) catch (x)
106 #else
107 # define FMT_TRY if (true)
108 # define FMT_CATCH(x) if (false)
109 #endif
110
111 #ifndef FMT_DEPRECATED
112 # if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900
113 # define FMT_DEPRECATED [[deprecated]]
114 # else
115 # if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
116 # define FMT_DEPRECATED __attribute__((deprecated))
117 # elif FMT_MSC_VER
118 # define FMT_DEPRECATED __declspec(deprecated)
119 # else
120 # define FMT_DEPRECATED /* deprecated */
121 # endif
122 # endif
123 #endif
124
125 // Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers.
126 #if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC
127 # define FMT_DEPRECATED_ALIAS
128 #else
129 # define FMT_DEPRECATED_ALIAS FMT_DEPRECATED
130 #endif
131
132 #ifndef FMT_USE_USER_DEFINED_LITERALS
133 // EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
134 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
135 FMT_MSC_VER >= 1900) && \
136 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480)
137 # define FMT_USE_USER_DEFINED_LITERALS 1
138 # else
139 # define FMT_USE_USER_DEFINED_LITERALS 0
140 # endif
141 #endif
142
143 // Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
144 // integer formatter template instantiations to just one by only using the
145 // largest integer type. This results in a reduction in binary size but will
146 // cause a decrease in integer formatting performance.
147 #if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
148 # define FMT_REDUCE_INT_INSTANTIATIONS 0
149 #endif
150
151 // __builtin_clz is broken in clang with Microsoft CodeGen:
152 // https://github.com/fmtlib/fmt/issues/519
153 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER
154 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
155 #endif
156 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER
157 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
158 #endif
159 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctz))
160 # define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
161 #endif
162 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctzll))
163 # define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
164 #endif
165
166 #if FMT_MSC_VER
167 # include <intrin.h> // _BitScanReverse[64], _BitScanForward[64], _umul128
168 #endif
169
170 // Some compilers masquerade as both MSVC and GCC-likes or otherwise support
171 // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
172 // MSVC intrinsics if the clz and clzll builtins are not available.
173 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(FMT_BUILTIN_CTZLL)
174 FMT_BEGIN_NAMESPACE
175 namespace detail {
176 // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
177 # if !defined(__clang__)
178 # pragma managed(push, off)
179 # pragma intrinsic(_BitScanForward)
180 # pragma intrinsic(_BitScanReverse)
181 # if defined(_WIN64)
182 # pragma intrinsic(_BitScanForward64)
183 # pragma intrinsic(_BitScanReverse64)
184 # endif
185 # endif
186
187 inline auto clz(uint32_t x) -> int {
188 unsigned long r = 0;
189 _BitScanReverse(&r, x);
190 FMT_ASSERT(x != 0, "");
191 // Static analysis complains about using uninitialized data
192 // "r", but the only way that can happen is if "x" is 0,
193 // which the callers guarantee to not happen.
194 FMT_MSC_WARNING(suppress : 6102)
195 return 31 ^ static_cast<int>(r);
196 }
197 # define FMT_BUILTIN_CLZ(n) detail::clz(n)
198
199 inline auto clzll(uint64_t x) -> int {
200 unsigned long r = 0;
201 # ifdef _WIN64
202 _BitScanReverse64(&r, x);
203 # else
204 // Scan the high 32 bits.
205 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 ^ (r + 32);
206 // Scan the low 32 bits.
207 _BitScanReverse(&r, static_cast<uint32_t>(x));
208 # endif
209 FMT_ASSERT(x != 0, "");
210 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
211 return 63 ^ static_cast<int>(r);
212 }
213 # define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
214
215 inline auto ctz(uint32_t x) -> int {
216 unsigned long r = 0;
217 _BitScanForward(&r, x);
218 FMT_ASSERT(x != 0, "");
219 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
220 return static_cast<int>(r);
221 }
222 # define FMT_BUILTIN_CTZ(n) detail::ctz(n)
223
224 inline auto ctzll(uint64_t x) -> int {
225 unsigned long r = 0;
226 FMT_ASSERT(x != 0, "");
227 FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
228 # ifdef _WIN64
229 _BitScanForward64(&r, x);
230 # else
231 // Scan the low 32 bits.
232 if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r);
233 // Scan the high 32 bits.
234 _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
235 r += 32;
236 # endif
237 return static_cast<int>(r);
238 }
239 # define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
240 # if !defined(__clang__)
241 # pragma managed(pop)
242 # endif
243 } // namespace detail
244 FMT_END_NAMESPACE
245 #endif
246
247 FMT_BEGIN_NAMESPACE
248 namespace detail {
249
250 #if __cplusplus >= 202002L || \
251 (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002)
252 # define FMT_CONSTEXPR20 constexpr
253 #else
254 # define FMT_CONSTEXPR20
255 #endif
256
257 // An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't have
258 // undefined behavior (e.g. due to type aliasing).
259 // Example: uint64_t d = bit_cast<uint64_t>(2.718);
260 template <typename Dest, typename Source>
261 inline auto bit_cast(const Source& source) -> Dest {
262 static_assert(sizeof(Dest) == sizeof(Source), "size mismatch");
263 Dest dest;
264 std::memcpy(&dest, &source, sizeof(dest));
265 return dest;
266 }
267
268 inline auto is_big_endian() -> bool {
269 const auto u = 1u;
270 struct bytes {
271 char data[sizeof(u)];
272 };
273 return bit_cast<bytes>(u).data[0] == 0;
274 }
275
276 // A fallback implementation of uintptr_t for systems that lack it.
277 struct fallback_uintptr {
278 unsigned char value[sizeof(void*)];
279
280 fallback_uintptr() = default;
fallback_uintptrfallback_uintptr281 explicit fallback_uintptr(const void* p) {
282 *this = bit_cast<fallback_uintptr>(p);
283 if (is_big_endian()) {
284 for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j)
285 std::swap(value[i], value[j]);
286 }
287 }
288 };
289 #ifdef UINTPTR_MAX
290 using uintptr_t = ::uintptr_t;
291 inline auto to_uintptr(const void* p) -> uintptr_t {
292 return bit_cast<uintptr_t>(p);
293 }
294 #else
295 using uintptr_t = fallback_uintptr;
296 inline auto to_uintptr(const void* p) -> fallback_uintptr {
297 return fallback_uintptr(p);
298 }
299 #endif
300
301 // Returns the largest possible value for type T. Same as
302 // std::numeric_limits<T>::max() but shorter and not affected by the max macro.
303 template <typename T> constexpr auto max_value() -> T {
304 return (std::numeric_limits<T>::max)();
305 }
306 template <typename T> constexpr auto num_bits() -> int {
307 return std::numeric_limits<T>::digits;
308 }
309 // std::numeric_limits<T>::digits may return 0 for 128-bit ints.
310 template <> constexpr auto num_bits<int128_t>() -> int { return 128; }
311 template <> constexpr auto num_bits<uint128_t>() -> int { return 128; }
312 template <> constexpr auto num_bits<fallback_uintptr>() -> int {
313 return static_cast<int>(sizeof(void*) *
314 std::numeric_limits<unsigned char>::digits);
315 }
316
assume(bool condition)317 FMT_INLINE void assume(bool condition) {
318 (void)condition;
319 #if FMT_HAS_BUILTIN(__builtin_assume)
320 __builtin_assume(condition);
321 #endif
322 }
323
324 // An approximation of iterator_t for pre-C++20 systems.
325 template <typename T>
326 using iterator_t = decltype(std::begin(std::declval<T&>()));
327 template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>()));
328
329 // A workaround for std::string not having mutable data() until C++17.
330 template <typename Char>
331 inline auto get_data(std::basic_string<Char>& s) -> Char* {
332 return &s[0];
333 }
334 template <typename Container>
335 inline auto get_data(Container& c) -> typename Container::value_type* {
336 return c.data();
337 }
338
339 #if defined(_SECURE_SCL) && _SECURE_SCL
340 // Make a checked iterator to avoid MSVC warnings.
341 template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
342 template <typename T> auto make_checked(T* p, size_t size) -> checked_ptr<T> {
343 return {p, size};
344 }
345 #else
346 template <typename T> using checked_ptr = T*;
347 template <typename T> inline auto make_checked(T* p, size_t) -> T* { return p; }
348 #endif
349
350 // Attempts to reserve space for n extra characters in the output range.
351 // Returns a pointer to the reserved range or a reference to it.
352 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
353 #if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
354 __attribute__((no_sanitize("undefined")))
355 #endif
356 inline auto
357 reserve(std::back_insert_iterator<Container> it, size_t n)
358 -> checked_ptr<typename Container::value_type> {
359 Container& c = get_container(it);
360 size_t size = c.size();
361 c.resize(size + n);
362 return make_checked(get_data(c) + size, n);
363 }
364
365 template <typename T>
366 inline auto reserve(buffer_appender<T> it, size_t n) -> buffer_appender<T> {
367 buffer<T>& buf = get_container(it);
368 buf.try_reserve(buf.size() + n);
369 return it;
370 }
371
372 template <typename Iterator>
373 constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
374 return it;
375 }
376
377 template <typename OutputIt>
378 using reserve_iterator =
379 remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>;
380
381 template <typename T, typename OutputIt>
382 constexpr auto to_pointer(OutputIt, size_t) -> T* {
383 return nullptr;
384 }
385 template <typename T> auto to_pointer(buffer_appender<T> it, size_t n) -> T* {
386 buffer<T>& buf = get_container(it);
387 auto size = buf.size();
388 if (buf.capacity() < size + n) return nullptr;
389 buf.try_resize(size + n);
390 return buf.data() + size;
391 }
392
393 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
394 inline auto base_iterator(std::back_insert_iterator<Container>& it,
395 checked_ptr<typename Container::value_type>)
396 -> std::back_insert_iterator<Container> {
397 return it;
398 }
399
400 template <typename Iterator>
401 constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
402 return it;
403 }
404
405 // <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
406 // instead (#1998).
407 template <typename OutputIt, typename Size, typename T>
408 FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
409 -> OutputIt {
410 for (Size i = 0; i < count; ++i) *out++ = value;
411 return out;
412 }
413 template <typename T, typename Size>
414 FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
415 if (is_constant_evaluated()) {
416 return fill_n<T*, Size, T>(out, count, value);
417 }
418 std::memset(out, value, to_unsigned(count));
419 return out + count;
420 }
421
422 #ifdef __cpp_char8_t
423 using char8_type = char8_t;
424 #else
425 enum char8_type : unsigned char {};
426 #endif
427
428 template <typename OutChar, typename InputIt, typename OutputIt>
429 FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end,
430 OutputIt out) -> OutputIt {
431 return copy_str<OutChar>(begin, end, out);
432 }
433
434 // A public domain branchless UTF-8 decoder by Christopher Wellons:
435 // https://github.com/skeeto/branchless-utf8
436 /* Decode the next character, c, from s, reporting errors in e.
437 *
438 * Since this is a branchless decoder, four bytes will be read from the
439 * buffer regardless of the actual length of the next character. This
440 * means the buffer _must_ have at least three bytes of zero padding
441 * following the end of the data stream.
442 *
443 * Errors are reported in e, which will be non-zero if the parsed
444 * character was somehow invalid: invalid byte sequence, non-canonical
445 * encoding, or a surrogate half.
446 *
447 * The function returns a pointer to the next character. When an error
448 * occurs, this pointer will be a guess that depends on the particular
449 * error, but it will always advance at least one byte.
450 */
451 FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
452 -> const char* {
453 constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
454 constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
455 constexpr const int shiftc[] = {0, 18, 12, 6, 0};
456 constexpr const int shifte[] = {0, 6, 4, 2, 0};
457
458 int len = code_point_length(s);
459 const char* next = s + len;
460
461 // Assume a four-byte character and load four bytes. Unused bits are
462 // shifted out.
463 *c = uint32_t(s[0] & masks[len]) << 18;
464 *c |= uint32_t(s[1] & 0x3f) << 12;
465 *c |= uint32_t(s[2] & 0x3f) << 6;
466 *c |= uint32_t(s[3] & 0x3f) << 0;
467 *c >>= shiftc[len];
468
469 // Accumulate the various error conditions.
470 using uchar = unsigned char;
471 *e = (*c < mins[len]) << 6; // non-canonical encoding
472 *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half?
473 *e |= (*c > 0x10FFFF) << 8; // out of range?
474 *e |= (uchar(s[1]) & 0xc0) >> 2;
475 *e |= (uchar(s[2]) & 0xc0) >> 4;
476 *e |= uchar(s[3]) >> 6;
477 *e ^= 0x2a; // top two bits of each tail byte correct?
478 *e >>= shifte[len];
479
480 return next;
481 }
482
483 template <typename F>
for_each_codepoint(string_view s,F f)484 FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) {
485 auto decode = [f](const char* p) {
486 auto cp = uint32_t();
487 auto error = 0;
488 p = utf8_decode(p, &cp, &error);
489 f(cp, error);
490 return p;
491 };
492 auto p = s.data();
493 const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars.
494 if (s.size() >= block_size) {
495 for (auto end = p + s.size() - block_size + 1; p < end;) p = decode(p);
496 }
497 if (auto num_chars_left = s.data() + s.size() - p) {
498 char buf[2 * block_size - 1] = {};
499 copy_str<char>(p, p + num_chars_left, buf);
500 p = buf;
501 do {
502 p = decode(p);
503 } while (p - buf < num_chars_left);
504 }
505 }
506
507 template <typename Char>
508 inline auto compute_width(basic_string_view<Char> s) -> size_t {
509 return s.size();
510 }
511
512 // Computes approximate display width of a UTF-8 string.
compute_width(string_view s)513 FMT_CONSTEXPR inline size_t compute_width(string_view s) {
514 size_t num_code_points = 0;
515 // It is not a lambda for compatibility with C++14.
516 struct count_code_points {
517 size_t* count;
518 FMT_CONSTEXPR void operator()(uint32_t cp, int error) const {
519 *count += detail::to_unsigned(
520 1 +
521 (error == 0 && cp >= 0x1100 &&
522 (cp <= 0x115f || // Hangul Jamo init. consonants
523 cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET
524 cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET
525 // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:
526 (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
527 (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables
528 (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs
529 (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms
530 (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms
531 (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms
532 (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms
533 (cp >= 0x20000 && cp <= 0x2fffd) || // CJK
534 (cp >= 0x30000 && cp <= 0x3fffd) ||
535 // Miscellaneous Symbols and Pictographs + Emoticons:
536 (cp >= 0x1f300 && cp <= 0x1f64f) ||
537 // Supplemental Symbols and Pictographs:
538 (cp >= 0x1f900 && cp <= 0x1f9ff))));
539 }
540 };
541 for_each_codepoint(s, count_code_points{&num_code_points});
542 return num_code_points;
543 }
544
545 inline auto compute_width(basic_string_view<char8_type> s) -> size_t {
546 return compute_width(basic_string_view<char>(
547 reinterpret_cast<const char*>(s.data()), s.size()));
548 }
549
550 template <typename Char>
551 inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
552 size_t size = s.size();
553 return n < size ? n : size;
554 }
555
556 // Calculates the index of the nth code point in a UTF-8 string.
557 inline auto code_point_index(basic_string_view<char8_type> s, size_t n)
558 -> size_t {
559 const char8_type* data = s.data();
560 size_t num_code_points = 0;
561 for (size_t i = 0, size = s.size(); i != size; ++i) {
562 if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) return i;
563 }
564 return s.size();
565 }
566
567 template <typename T>
568 using is_fast_float = bool_constant<std::numeric_limits<T>::is_iec559 &&
569 sizeof(T) <= sizeof(double)>;
570
571 #ifndef FMT_USE_FULL_CACHE_DRAGONBOX
572 # define FMT_USE_FULL_CACHE_DRAGONBOX 0
573 #endif
574
575 template <typename T>
576 template <typename U>
append(const U * begin,const U * end)577 void buffer<T>::append(const U* begin, const U* end) {
578 while (begin != end) {
579 auto count = to_unsigned(end - begin);
580 try_reserve(size_ + count);
581 auto free_cap = capacity_ - size_;
582 if (free_cap < count) count = free_cap;
583 std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
584 size_ += count;
585 begin += count;
586 }
587 }
588
589 template <typename T, typename Enable = void>
590 struct is_locale : std::false_type {};
591 template <typename T>
592 struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {};
593 } // namespace detail
594
595 FMT_MODULE_EXPORT_BEGIN
596
597 // The number of characters to store in the basic_memory_buffer object itself
598 // to avoid dynamic memory allocation.
599 enum { inline_buffer_size = 500 };
600
601 /**
602 \rst
603 A dynamically growing memory buffer for trivially copyable/constructible types
604 with the first ``SIZE`` elements stored in the object itself.
605
606 You can use the ``memory_buffer`` type alias for ``char`` instead.
607
608 **Example**::
609
610 fmt::memory_buffer out;
611 format_to(out, "The answer is {}.", 42);
612
613 This will append the following output to the ``out`` object:
614
615 .. code-block:: none
616
617 The answer is 42.
618
619 The output can be converted to an ``std::string`` with ``to_string(out)``.
620 \endrst
621 */
622 template <typename T, size_t SIZE = inline_buffer_size,
623 typename Allocator = std::allocator<T>>
624 class basic_memory_buffer final : public detail::buffer<T> {
625 private:
626 T store_[SIZE];
627
628 // Don't inherit from Allocator avoid generating type_info for it.
629 Allocator alloc_;
630
631 // Deallocate memory allocated by the buffer.
632 void deallocate() {
633 T* data = this->data();
634 if (data != store_) alloc_.deallocate(data, this->capacity());
635 }
636
637 protected:
638 void grow(size_t size) final FMT_OVERRIDE;
639
640 public:
641 using value_type = T;
642 using const_reference = const T&;
643
644 explicit basic_memory_buffer(const Allocator& alloc = Allocator())
645 : alloc_(alloc) {
646 this->set(store_, SIZE);
647 }
648 ~basic_memory_buffer() { deallocate(); }
649
650 private:
651 // Move data from other to this buffer.
652 void move(basic_memory_buffer& other) {
653 alloc_ = std::move(other.alloc_);
654 T* data = other.data();
655 size_t size = other.size(), capacity = other.capacity();
656 if (data == other.store_) {
657 this->set(store_, capacity);
658 std::uninitialized_copy(other.store_, other.store_ + size,
659 detail::make_checked(store_, capacity));
660 } else {
661 this->set(data, capacity);
662 // Set pointer to the inline array so that delete is not called
663 // when deallocating.
664 other.set(other.store_, 0);
665 }
666 this->resize(size);
667 }
668
669 public:
670 /**
671 \rst
672 Constructs a :class:`fmt::basic_memory_buffer` object moving the content
673 of the other object to it.
674 \endrst
675 */
676 basic_memory_buffer(basic_memory_buffer&& other) FMT_NOEXCEPT { move(other); }
677
678 /**
679 \rst
680 Moves the content of the other ``basic_memory_buffer`` object to this one.
681 \endrst
682 */
683 auto operator=(basic_memory_buffer&& other) FMT_NOEXCEPT
684 -> basic_memory_buffer& {
685 FMT_ASSERT(this != &other, "");
686 deallocate();
687 move(other);
688 return *this;
689 }
690
691 // Returns a copy of the allocator associated with this buffer.
692 auto get_allocator() const -> Allocator { return alloc_; }
693
694 /**
695 Resizes the buffer to contain *count* elements. If T is a POD type new
696 elements may not be initialized.
697 */
698 void resize(size_t count) { this->try_resize(count); }
699
700 /** Increases the buffer capacity to *new_capacity*. */
701 void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
702
703 // Directly append data into the buffer
704 using detail::buffer<T>::append;
705 template <typename ContiguousRange>
706 void append(const ContiguousRange& range) {
707 append(range.data(), range.data() + range.size());
708 }
709 };
710
711 template <typename T, size_t SIZE, typename Allocator>
712 void basic_memory_buffer<T, SIZE, Allocator>::grow(size_t size) {
713 #ifdef FMT_FUZZ
714 if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much");
715 #endif
716 const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
717 size_t old_capacity = this->capacity();
718 size_t new_capacity = old_capacity + old_capacity / 2;
719 if (size > new_capacity)
720 new_capacity = size;
721 else if (new_capacity > max_size)
722 new_capacity = size > max_size ? size : max_size;
723 T* old_data = this->data();
724 T* new_data =
725 std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
726 // The following code doesn't throw, so the raw pointer above doesn't leak.
727 std::uninitialized_copy(old_data, old_data + this->size(),
728 detail::make_checked(new_data, new_capacity));
729 this->set(new_data, new_capacity);
730 // deallocate must not throw according to the standard, but even if it does,
731 // the buffer already uses the new storage and will deallocate it in
732 // destructor.
733 if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
734 }
735
736 using memory_buffer = basic_memory_buffer<char>;
737
738 template <typename T, size_t SIZE, typename Allocator>
739 struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
740 };
741
742 namespace detail {
743 FMT_API void print(std::FILE*, string_view);
744 }
745
746 /** A formatting error such as invalid format string. */
747 FMT_CLASS_API
748 class FMT_API format_error : public std::runtime_error {
749 public:
750 explicit format_error(const char* message) : std::runtime_error(message) {}
751 explicit format_error(const std::string& message)
752 : std::runtime_error(message) {}
753 format_error(const format_error&) = default;
754 format_error& operator=(const format_error&) = default;
755 format_error(format_error&&) = default;
756 format_error& operator=(format_error&&) = default;
757 ~format_error() FMT_NOEXCEPT FMT_OVERRIDE FMT_MSC_DEFAULT;
758 };
759
760 /**
761 \rst
762 Constructs a `~fmt::format_arg_store` object that contains references
763 to arguments and can be implicitly converted to `~fmt::format_args`.
764 If ``fmt`` is a compile-time string then `make_args_checked` checks
765 its validity at compile time.
766 \endrst
767 */
768 template <typename... Args, typename S, typename Char = char_t<S>>
769 FMT_INLINE auto make_args_checked(const S& fmt,
770 const remove_reference_t<Args>&... args)
771 -> format_arg_store<buffer_context<Char>, remove_reference_t<Args>...> {
772 static_assert(
773 detail::count<(
774 std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
775 std::is_reference<Args>::value)...>() == 0,
776 "passing views as lvalues is disallowed");
777 detail::check_format_string<Args...>(fmt);
778 return {args...};
779 }
780
781 // compile-time support
782 namespace detail_exported {
783 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
784 template <typename Char, size_t N> struct fixed_string {
785 constexpr fixed_string(const Char (&str)[N]) {
786 detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str),
787 str + N, data);
788 }
789 Char data[N]{};
790 };
791 #endif
792
793 // Converts a compile-time string to basic_string_view.
794 template <typename Char, size_t N>
795 constexpr auto compile_string_to_view(const Char (&s)[N])
796 -> basic_string_view<Char> {
797 // Remove trailing NUL character if needed. Won't be present if this is used
798 // with a raw character array (i.e. not defined as a string).
799 return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
800 }
801 template <typename Char>
802 constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
803 -> basic_string_view<Char> {
804 return {s.data(), s.size()};
805 }
806 } // namespace detail_exported
807
808 FMT_BEGIN_DETAIL_NAMESPACE
809
810 inline void throw_format_error(const char* message) {
811 FMT_THROW(format_error(message));
812 }
813
814 template <typename T> struct is_integral : std::is_integral<T> {};
815 template <> struct is_integral<int128_t> : std::true_type {};
816 template <> struct is_integral<uint128_t> : std::true_type {};
817
818 template <typename T>
819 using is_signed =
820 std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
821 std::is_same<T, int128_t>::value>;
822
823 // Returns true if value is negative, false otherwise.
824 // Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
825 template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
826 FMT_CONSTEXPR auto is_negative(T value) -> bool {
827 return value < 0;
828 }
829 template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
830 FMT_CONSTEXPR auto is_negative(T) -> bool {
831 return false;
832 }
833
834 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
835 FMT_CONSTEXPR auto is_supported_floating_point(T) -> uint16_t {
836 return (std::is_same<T, float>::value && FMT_USE_FLOAT) ||
837 (std::is_same<T, double>::value && FMT_USE_DOUBLE) ||
838 (std::is_same<T, long double>::value && FMT_USE_LONG_DOUBLE);
839 }
840
841 // Smallest of uint32_t, uint64_t, uint128_t that is large enough to
842 // represent all values of an integral type T.
843 template <typename T>
844 using uint32_or_64_or_128_t =
845 conditional_t<num_bits<T>() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS,
846 uint32_t,
847 conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
848 template <typename T>
849 using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;
850
851 #define FMT_POWERS_OF_10(factor) \
852 factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
853 (factor)*1000000, (factor)*10000000, (factor)*100000000, \
854 (factor)*1000000000
855
856 // Static data is placed in this class template for the header-only config.
857 template <typename T = void> struct basic_data {
858 // log10(2) = 0x0.4d104d427de7fbcc...
859 static const uint64_t log10_2_significand = 0x4d104d427de7fbcc;
860
861 // GCC generates slightly better code for pairs than chars.
862 FMT_API static constexpr const char digits[100][2] = {
863 {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
864 {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
865 {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
866 {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'},
867 {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'},
868 {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'},
869 {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'},
870 {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'},
871 {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'},
872 {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'},
873 {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'},
874 {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'},
875 {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'},
876 {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'},
877 {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'},
878 {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'},
879 {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}};
880
881 FMT_API static constexpr const char hex_digits[] = "0123456789abcdef";
882 FMT_API static constexpr const char signs[4] = {0, '-', '+', ' '};
883 FMT_API static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
884 0x1000000u | ' '};
885 FMT_API static constexpr const char left_padding_shifts[5] = {31, 31, 0, 1,
886 0};
887 FMT_API static constexpr const char right_padding_shifts[5] = {0, 31, 0, 1,
888 0};
889 };
890
891 #ifdef FMT_SHARED
892 // Required for -flto, -fivisibility=hidden and -shared to work
893 extern template struct basic_data<void>;
894 #endif
895
896 // This is a struct rather than an alias to avoid shadowing warnings in gcc.
897 struct data : basic_data<> {};
898
899 template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
900 int count = 1;
901 for (;;) {
902 // Integer division is slow so do it for a group of four digits instead
903 // of for every digit. The idea comes from the talk by Alexandrescu
904 // "Three Optimization Tips for C++". See speed-test for a comparison.
905 if (n < 10) return count;
906 if (n < 100) return count + 1;
907 if (n < 1000) return count + 2;
908 if (n < 10000) return count + 3;
909 n /= 10000u;
910 count += 4;
911 }
912 }
913 #if FMT_USE_INT128
914 FMT_CONSTEXPR inline auto count_digits(uint128_t n) -> int {
915 return count_digits_fallback(n);
916 }
917 #endif
918
919 // Returns the number of decimal digits in n. Leading zeros are not counted
920 // except for n == 0 in which case count_digits returns 1.
921 FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {
922 #ifdef FMT_BUILTIN_CLZLL
923 if (!is_constant_evaluated()) {
924 // https://github.com/fmtlib/format-benchmark/blob/master/digits10
925 // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
926 constexpr uint16_t bsr2log10[] = {
927 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
928 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
929 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
930 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
931 auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
932 constexpr const uint64_t zero_or_powers_of_10[] = {
933 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
934 10000000000000000000ULL};
935 return t - (n < zero_or_powers_of_10[t]);
936 }
937 #endif
938 return count_digits_fallback(n);
939 }
940
941 // Counts the number of digits in n. BITS = log2(radix).
942 template <int BITS, typename UInt>
943 FMT_CONSTEXPR auto count_digits(UInt n) -> int {
944 #ifdef FMT_BUILTIN_CLZ
945 if (num_bits<UInt>() == 32)
946 return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
947 #endif
948 int num_digits = 0;
949 do {
950 ++num_digits;
951 } while ((n >>= BITS) != 0);
952 return num_digits;
953 }
954
955 template <> auto count_digits<4>(detail::fallback_uintptr n) -> int;
956
957 // It is a separate function rather than a part of count_digits to workaround
958 // the lack of static constexpr in constexpr functions.
959 FMT_INLINE uint64_t count_digits_inc(int n) {
960 // An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
961 // This increments the upper 32 bits (log10(T) - 1) when >= T is added.
962 #define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)
963 static constexpr uint64_t table[] = {
964 FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8
965 FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64
966 FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512
967 FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096
968 FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k
969 FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k
970 FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k
971 FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M
972 FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M
973 FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M
974 FMT_INC(1000000000), FMT_INC(1000000000) // 4B
975 };
976 return table[n];
977 }
978
979 // Optional version of count_digits for better performance on 32-bit platforms.
980 FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {
981 #ifdef FMT_BUILTIN_CLZ
982 if (!is_constant_evaluated()) {
983 auto inc = count_digits_inc(FMT_BUILTIN_CLZ(n | 1) ^ 31);
984 return static_cast<int>((n + inc) >> 32);
985 }
986 #endif
987 return count_digits_fallback(n);
988 }
989
990 template <typename Int> constexpr auto digits10() FMT_NOEXCEPT -> int {
991 return std::numeric_limits<Int>::digits10;
992 }
993 template <> constexpr auto digits10<int128_t>() FMT_NOEXCEPT -> int {
994 return 38;
995 }
996 template <> constexpr auto digits10<uint128_t>() FMT_NOEXCEPT -> int {
997 return 38;
998 }
999
1000 template <typename Char> struct thousands_sep_result {
1001 std::string grouping;
1002 Char thousands_sep;
1003 };
1004
1005 template <typename Char>
1006 FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>;
1007 template <typename Char>
1008 inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> {
1009 auto result = thousands_sep_impl<char>(loc);
1010 return {result.grouping, Char(result.thousands_sep)};
1011 }
1012 template <>
1013 inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<wchar_t> {
1014 return thousands_sep_impl<wchar_t>(loc);
1015 }
1016
1017 template <typename Char>
1018 FMT_API auto decimal_point_impl(locale_ref loc) -> Char;
1019 template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
1020 return Char(decimal_point_impl<char>(loc));
1021 }
1022 template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
1023 return decimal_point_impl<wchar_t>(loc);
1024 }
1025
1026 // Compares two characters for equality.
1027 template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
1028 return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1029 }
1030 inline auto equal2(const char* lhs, const char* rhs) -> bool {
1031 return memcmp(lhs, rhs, 2) == 0;
1032 }
1033
1034 // Copies two characters from src to dst.
1035 template <typename Char> void copy2(Char* dst, const char* src) {
1036 *dst++ = static_cast<Char>(*src++);
1037 *dst = static_cast<Char>(*src);
1038 }
1039 FMT_INLINE void copy2(char* dst, const char* src) { memcpy(dst, src, 2); }
1040
1041 template <typename Iterator> struct format_decimal_result {
1042 Iterator begin;
1043 Iterator end;
1044 };
1045
1046 // Formats a decimal unsigned integer value writing into out pointing to a
1047 // buffer of specified size. The caller must ensure that the buffer is large
1048 // enough.
1049 template <typename Char, typename UInt>
1050 FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
1051 -> format_decimal_result<Char*> {
1052 FMT_ASSERT(size >= count_digits(value), "invalid digit count");
1053 out += size;
1054 Char* end = out;
1055 if (is_constant_evaluated()) {
1056 while (value >= 10) {
1057 *--out = static_cast<Char>('0' + value % 10);
1058 value /= 10;
1059 }
1060 *--out = static_cast<Char>('0' + value);
1061 return {out, end};
1062 }
1063 while (value >= 100) {
1064 // Integer division is slow so do it for a group of two digits instead
1065 // of for every digit. The idea comes from the talk by Alexandrescu
1066 // "Three Optimization Tips for C++". See speed-test for a comparison.
1067 out -= 2;
1068 copy2(out, data::digits[value % 100]);
1069 value /= 100;
1070 }
1071 if (value < 10) {
1072 *--out = static_cast<Char>('0' + value);
1073 return {out, end};
1074 }
1075 out -= 2;
1076 copy2(out, data::digits[value]);
1077 return {out, end};
1078 }
1079
1080 template <typename Char, typename UInt, typename Iterator,
1081 FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)>
1082 inline auto format_decimal(Iterator out, UInt value, int size)
1083 -> format_decimal_result<Iterator> {
1084 // Buffer is large enough to hold all digits (digits10 + 1).
1085 Char buffer[digits10<UInt>() + 1];
1086 auto end = format_decimal(buffer, value, size).end;
1087 return {out, detail::copy_str_noinline<Char>(buffer, end, out)};
1088 }
1089
1090 template <unsigned BASE_BITS, typename Char, typename UInt>
1091 FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits,
1092 bool upper = false) -> Char* {
1093 buffer += num_digits;
1094 Char* end = buffer;
1095 do {
1096 const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits;
1097 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1098 *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
1099 : digits[digit]);
1100 } while ((value >>= BASE_BITS) != 0);
1101 return end;
1102 }
1103
1104 template <unsigned BASE_BITS, typename Char>
1105 auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits,
1106 bool = false) -> Char* {
1107 auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
1108 int start = (num_digits + char_digits - 1) / char_digits - 1;
1109 if (int start_digits = num_digits % char_digits) {
1110 unsigned value = n.value[start--];
1111 buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
1112 }
1113 for (; start >= 0; --start) {
1114 unsigned value = n.value[start];
1115 buffer += char_digits;
1116 auto p = buffer;
1117 for (int i = 0; i < char_digits; ++i) {
1118 unsigned digit = (value & ((1 << BASE_BITS) - 1));
1119 *--p = static_cast<Char>(data::hex_digits[digit]);
1120 value >>= BASE_BITS;
1121 }
1122 }
1123 return buffer;
1124 }
1125
1126 template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1127 inline auto format_uint(It out, UInt value, int num_digits, bool upper = false)
1128 -> It {
1129 if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
1130 format_uint<BASE_BITS>(ptr, value, num_digits, upper);
1131 return out;
1132 }
1133 // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
1134 char buffer[num_bits<UInt>() / BASE_BITS + 1];
1135 format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1136 return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out);
1137 }
1138
1139 // A converter from UTF-8 to UTF-16.
1140 class utf8_to_utf16 {
1141 private:
1142 basic_memory_buffer<wchar_t> buffer_;
1143
1144 public:
1145 FMT_API explicit utf8_to_utf16(string_view s);
1146 operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; }
1147 auto size() const -> size_t { return buffer_.size() - 1; }
1148 auto c_str() const -> const wchar_t* { return &buffer_[0]; }
1149 auto str() const -> std::wstring { return {&buffer_[0], size()}; }
1150 };
1151
1152 namespace dragonbox {
1153
1154 // Type-specific information that Dragonbox uses.
1155 template <class T> struct float_info;
1156
1157 template <> struct float_info<float> {
1158 using carrier_uint = uint32_t;
1159 static const int significand_bits = 23;
1160 static const int exponent_bits = 8;
1161 static const int min_exponent = -126;
1162 static const int max_exponent = 127;
1163 static const int exponent_bias = -127;
1164 static const int decimal_digits = 9;
1165 static const int kappa = 1;
1166 static const int big_divisor = 100;
1167 static const int small_divisor = 10;
1168 static const int min_k = -31;
1169 static const int max_k = 46;
1170 static const int cache_bits = 64;
1171 static const int divisibility_check_by_5_threshold = 39;
1172 static const int case_fc_pm_half_lower_threshold = -1;
1173 static const int case_fc_pm_half_upper_threshold = 6;
1174 static const int case_fc_lower_threshold = -2;
1175 static const int case_fc_upper_threshold = 6;
1176 static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
1177 static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1178 static const int shorter_interval_tie_lower_threshold = -35;
1179 static const int shorter_interval_tie_upper_threshold = -35;
1180 static const int max_trailing_zeros = 7;
1181 };
1182
1183 template <> struct float_info<double> {
1184 using carrier_uint = uint64_t;
1185 static const int significand_bits = 52;
1186 static const int exponent_bits = 11;
1187 static const int min_exponent = -1022;
1188 static const int max_exponent = 1023;
1189 static const int exponent_bias = -1023;
1190 static const int decimal_digits = 17;
1191 static const int kappa = 2;
1192 static const int big_divisor = 1000;
1193 static const int small_divisor = 100;
1194 static const int min_k = -292;
1195 static const int max_k = 326;
1196 static const int cache_bits = 128;
1197 static const int divisibility_check_by_5_threshold = 86;
1198 static const int case_fc_pm_half_lower_threshold = -2;
1199 static const int case_fc_pm_half_upper_threshold = 9;
1200 static const int case_fc_lower_threshold = -4;
1201 static const int case_fc_upper_threshold = 9;
1202 static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
1203 static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1204 static const int shorter_interval_tie_lower_threshold = -77;
1205 static const int shorter_interval_tie_upper_threshold = -77;
1206 static const int max_trailing_zeros = 16;
1207 };
1208
1209 template <typename T> struct decimal_fp {
1210 using significand_type = typename float_info<T>::carrier_uint;
1211 significand_type significand;
1212 int exponent;
1213 };
1214
1215 template <typename T>
1216 FMT_API auto to_decimal(T x) FMT_NOEXCEPT -> decimal_fp<T>;
1217 } // namespace dragonbox
1218
1219 template <typename T>
1220 constexpr auto exponent_mask() ->
1221 typename dragonbox::float_info<T>::carrier_uint {
1222 using uint = typename dragonbox::float_info<T>::carrier_uint;
1223 return ((uint(1) << dragonbox::float_info<T>::exponent_bits) - 1)
1224 << dragonbox::float_info<T>::significand_bits;
1225 }
1226
1227 // Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
1228 template <typename Char, typename It>
1229 auto write_exponent(int exp, It it) -> It {
1230 FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
1231 if (exp < 0) {
1232 *it++ = static_cast<Char>('-');
1233 exp = -exp;
1234 } else {
1235 *it++ = static_cast<Char>('+');
1236 }
1237 if (exp >= 100) {
1238 const char* top = data::digits[exp / 100];
1239 if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
1240 *it++ = static_cast<Char>(top[1]);
1241 exp %= 100;
1242 }
1243 const char* d = data::digits[exp];
1244 *it++ = static_cast<Char>(d[0]);
1245 *it++ = static_cast<Char>(d[1]);
1246 return it;
1247 }
1248
1249 template <typename T>
1250 auto format_float(T value, int precision, float_specs specs, buffer<char>& buf)
1251 -> int;
1252
1253 // Formats a floating-point number with snprintf.
1254 template <typename T>
1255 auto snprintf_float(T value, int precision, float_specs specs,
1256 buffer<char>& buf) -> int;
1257
1258 template <typename T> auto promote_float(T value) -> T { return value; }
1259 inline auto promote_float(float value) -> double {
1260 return static_cast<double>(value);
1261 }
1262
1263 template <typename OutputIt, typename Char>
1264 FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
1265 const fill_t<Char>& fill) -> OutputIt {
1266 auto fill_size = fill.size();
1267 if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
1268 auto data = fill.data();
1269 for (size_t i = 0; i < n; ++i)
1270 it = copy_str<Char>(data, data + fill_size, it);
1271 return it;
1272 }
1273
1274 // Writes the output of f, padded according to format specifications in specs.
1275 // size: output size in code units.
1276 // width: output display width in (terminal) column positions.
1277 template <align::type align = align::left, typename OutputIt, typename Char,
1278 typename F>
1279 FMT_CONSTEXPR auto write_padded(OutputIt out,
1280 const basic_format_specs<Char>& specs,
1281 size_t size, size_t width, F&& f) -> OutputIt {
1282 static_assert(align == align::left || align == align::right, "");
1283 unsigned spec_width = to_unsigned(specs.width);
1284 size_t padding = spec_width > width ? spec_width - width : 0;
1285 auto* shifts = align == align::left ? data::left_padding_shifts
1286 : data::right_padding_shifts;
1287 size_t left_padding = padding >> shifts[specs.align];
1288 size_t right_padding = padding - left_padding;
1289 auto it = reserve(out, size + padding * specs.fill.size());
1290 if (left_padding != 0) it = fill(it, left_padding, specs.fill);
1291 it = f(it);
1292 if (right_padding != 0) it = fill(it, right_padding, specs.fill);
1293 return base_iterator(out, it);
1294 }
1295
1296 template <align::type align = align::left, typename OutputIt, typename Char,
1297 typename F>
1298 constexpr auto write_padded(OutputIt out, const basic_format_specs<Char>& specs,
1299 size_t size, F&& f) -> OutputIt {
1300 return write_padded<align>(out, specs, size, size, f);
1301 }
1302
1303 template <align::type align = align::left, typename Char, typename OutputIt>
1304 FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,
1305 const basic_format_specs<Char>& specs)
1306 -> OutputIt {
1307 return write_padded<align>(
1308 out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
1309 const char* data = bytes.data();
1310 return copy_str<Char>(data, data + bytes.size(), it);
1311 });
1312 }
1313
1314 template <typename Char, typename OutputIt, typename UIntPtr>
1315 auto write_ptr(OutputIt out, UIntPtr value,
1316 const basic_format_specs<Char>* specs) -> OutputIt {
1317 int num_digits = count_digits<4>(value);
1318 auto size = to_unsigned(num_digits) + size_t(2);
1319 auto write = [=](reserve_iterator<OutputIt> it) {
1320 *it++ = static_cast<Char>('0');
1321 *it++ = static_cast<Char>('x');
1322 return format_uint<4, Char>(it, value, num_digits);
1323 };
1324 return specs ? write_padded<align::right>(out, *specs, size, write)
1325 : base_iterator(out, write(reserve(out, size)));
1326 }
1327
1328 template <typename Char, typename OutputIt>
1329 FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
1330 const basic_format_specs<Char>& specs)
1331 -> OutputIt {
1332 return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
1333 *it++ = value;
1334 return it;
1335 });
1336 }
1337 template <typename Char, typename OutputIt>
1338 FMT_CONSTEXPR auto write(OutputIt out, Char value,
1339 const basic_format_specs<Char>& specs,
1340 locale_ref loc = {}) -> OutputIt {
1341 return check_char_specs(specs)
1342 ? write_char(out, value, specs)
1343 : write(out, static_cast<int>(value), specs, loc);
1344 }
1345
1346 // Data for write_int that doesn't depend on output iterator type. It is used to
1347 // avoid template code bloat.
1348 template <typename Char> struct write_int_data {
1349 size_t size;
1350 size_t padding;
1351
1352 FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
1353 const basic_format_specs<Char>& specs)
1354 : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
1355 if (specs.align == align::numeric) {
1356 auto width = to_unsigned(specs.width);
1357 if (width > size) {
1358 padding = width - size;
1359 size = width;
1360 }
1361 } else if (specs.precision > num_digits) {
1362 size = (prefix >> 24) + to_unsigned(specs.precision);
1363 padding = to_unsigned(specs.precision - num_digits);
1364 }
1365 }
1366 };
1367
1368 // Writes an integer in the format
1369 // <left-padding><prefix><numeric-padding><digits><right-padding>
1370 // where <digits> are written by write_digits(it).
1371 // prefix contains chars in three lower bytes and the size in the fourth byte.
1372 template <typename OutputIt, typename Char, typename W>
1373 FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
1374 unsigned prefix,
1375 const basic_format_specs<Char>& specs,
1376 W write_digits) -> OutputIt {
1377 // Slightly faster check for specs.width == 0 && specs.precision == -1.
1378 if ((specs.width | (specs.precision + 1)) == 0) {
1379 auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
1380 if (prefix != 0) {
1381 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1382 *it++ = static_cast<Char>(p & 0xff);
1383 }
1384 return base_iterator(out, write_digits(it));
1385 }
1386 auto data = write_int_data<Char>(num_digits, prefix, specs);
1387 return write_padded<align::right>(
1388 out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
1389 for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
1390 *it++ = static_cast<Char>(p & 0xff);
1391 it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
1392 return write_digits(it);
1393 });
1394 }
1395
1396 template <typename OutputIt, typename UInt, typename Char>
1397 auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
1398 const basic_format_specs<Char>& specs, locale_ref loc)
1399 -> bool {
1400 static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
1401 const auto sep_size = 1;
1402 auto ts = thousands_sep<Char>(loc);
1403 if (!ts.thousands_sep) return false;
1404 int num_digits = count_digits(value);
1405 int size = num_digits, n = num_digits;
1406 const std::string& groups = ts.grouping;
1407 std::string::const_iterator group = groups.cbegin();
1408 while (group != groups.cend() && n > *group && *group > 0 &&
1409 *group != max_value<char>()) {
1410 size += sep_size;
1411 n -= *group;
1412 ++group;
1413 }
1414 if (group == groups.cend()) size += sep_size * ((n - 1) / groups.back());
1415 char digits[40];
1416 format_decimal(digits, value, num_digits);
1417 basic_memory_buffer<Char> buffer;
1418 if (prefix != 0) ++size;
1419 const auto usize = to_unsigned(size);
1420 buffer.resize(usize);
1421 basic_string_view<Char> s(&ts.thousands_sep, sep_size);
1422 // Index of a decimal digit with the least significant digit having index 0.
1423 int digit_index = 0;
1424 group = groups.cbegin();
1425 auto p = buffer.data() + size - 1;
1426 for (int i = num_digits - 1; i > 0; --i) {
1427 *p-- = static_cast<Char>(digits[i]);
1428 if (*group <= 0 || ++digit_index % *group != 0 ||
1429 *group == max_value<char>())
1430 continue;
1431 if (group + 1 != groups.cend()) {
1432 digit_index = 0;
1433 ++group;
1434 }
1435 std::uninitialized_copy(s.data(), s.data() + s.size(),
1436 make_checked(p, s.size()));
1437 p -= s.size();
1438 }
1439 *p-- = static_cast<Char>(*digits);
1440 if (prefix != 0) *p = static_cast<Char>(prefix);
1441 auto data = buffer.data();
1442 out = write_padded<align::right>(
1443 out, specs, usize, usize, [=](reserve_iterator<OutputIt> it) {
1444 return copy_str<Char>(data, data + size, it);
1445 });
1446 return true;
1447 }
1448
1449 FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
1450 prefix |= prefix != 0 ? value << 8 : value;
1451 prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
1452 }
1453
1454 template <typename UInt> struct write_int_arg {
1455 UInt abs_value;
1456 unsigned prefix;
1457 };
1458
1459 template <typename T>
1460 FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign)
1461 -> write_int_arg<uint32_or_64_or_128_t<T>> {
1462 auto prefix = 0u;
1463 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
1464 if (is_negative(value)) {
1465 prefix = 0x01000000 | '-';
1466 abs_value = 0 - abs_value;
1467 } else {
1468 prefix = data::prefixes[sign];
1469 }
1470 return {abs_value, prefix};
1471 }
1472
1473 template <typename Char, typename OutputIt, typename T>
1474 FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
1475 const basic_format_specs<Char>& specs,
1476 locale_ref loc) -> OutputIt {
1477 static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
1478 auto abs_value = arg.abs_value;
1479 auto prefix = arg.prefix;
1480 auto utype = static_cast<unsigned>(specs.type);
1481 switch (specs.type) {
1482 case 0:
1483 case 'd': {
1484 if (specs.localized &&
1485 write_int_localized(out, static_cast<uint64_or_128_t<T>>(abs_value),
1486 prefix, specs, loc)) {
1487 return out;
1488 }
1489 auto num_digits = count_digits(abs_value);
1490 return write_int(
1491 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
1492 return format_decimal<Char>(it, abs_value, num_digits).end;
1493 });
1494 }
1495 case 'x':
1496 case 'X': {
1497 if (specs.alt) prefix_append(prefix, (utype << 8) | '0');
1498 bool upper = specs.type != 'x';
1499 int num_digits = count_digits<4>(abs_value);
1500 return write_int(
1501 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
1502 return format_uint<4, Char>(it, abs_value, num_digits, upper);
1503 });
1504 }
1505 case 'b':
1506 case 'B': {
1507 if (specs.alt) prefix_append(prefix, (utype << 8) | '0');
1508 int num_digits = count_digits<1>(abs_value);
1509 return write_int(out, num_digits, prefix, specs,
1510 [=](reserve_iterator<OutputIt> it) {
1511 return format_uint<1, Char>(it, abs_value, num_digits);
1512 });
1513 }
1514 case 'o': {
1515 int num_digits = count_digits<3>(abs_value);
1516 if (specs.alt && specs.precision <= num_digits && abs_value != 0) {
1517 // Octal prefix '0' is counted as a digit, so only add it if precision
1518 // is not greater than the number of digits.
1519 prefix_append(prefix, '0');
1520 }
1521 return write_int(out, num_digits, prefix, specs,
1522 [=](reserve_iterator<OutputIt> it) {
1523 return format_uint<3, Char>(it, abs_value, num_digits);
1524 });
1525 }
1526 case 'c':
1527 return write_char(out, static_cast<Char>(abs_value), specs);
1528 default:
1529 FMT_THROW(format_error("invalid type specifier"));
1530 }
1531 return out;
1532 }
1533 template <typename Char, typename OutputIt, typename T,
1534 FMT_ENABLE_IF(is_integral<T>::value &&
1535 !std::is_same<T, bool>::value &&
1536 std::is_same<OutputIt, buffer_appender<Char>>::value)>
1537 FMT_CONSTEXPR auto write(OutputIt out, T value,
1538 const basic_format_specs<Char>& specs, locale_ref loc)
1539 -> OutputIt {
1540 return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
1541 }
1542 // An inlined version of write used in format string compilation.
1543 template <typename Char, typename OutputIt, typename T,
1544 FMT_ENABLE_IF(is_integral<T>::value &&
1545 !std::is_same<T, bool>::value &&
1546 !std::is_same<OutputIt, buffer_appender<Char>>::value)>
1547 FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
1548 const basic_format_specs<Char>& specs,
1549 locale_ref loc) -> OutputIt {
1550 return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
1551 }
1552
1553 template <typename Char, typename OutputIt>
1554 FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
1555 const basic_format_specs<Char>& specs) -> OutputIt {
1556 auto data = s.data();
1557 auto size = s.size();
1558 if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
1559 size = code_point_index(s, to_unsigned(specs.precision));
1560 auto width =
1561 specs.width != 0 ? compute_width(basic_string_view<Char>(data, size)) : 0;
1562 return write_padded(out, specs, size, width,
1563 [=](reserve_iterator<OutputIt> it) {
1564 return copy_str<Char>(data, data + size, it);
1565 });
1566 }
1567 template <typename Char, typename OutputIt>
1568 FMT_CONSTEXPR auto write(OutputIt out,
1569 basic_string_view<type_identity_t<Char>> s,
1570 const basic_format_specs<Char>& specs, locale_ref)
1571 -> OutputIt {
1572 check_string_type_spec(specs.type);
1573 return write(out, s, specs);
1574 }
1575 template <typename Char, typename OutputIt>
1576 FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
1577 const basic_format_specs<Char>& specs, locale_ref)
1578 -> OutputIt {
1579 return check_cstring_type_spec(specs.type)
1580 ? write(out, basic_string_view<Char>(s), specs, {})
1581 : write_ptr<Char>(out, to_uintptr(s), &specs);
1582 }
1583
1584 template <typename Char, typename OutputIt>
1585 auto write_nonfinite(OutputIt out, bool isinf, basic_format_specs<Char> specs,
1586 const float_specs& fspecs) -> OutputIt {
1587 auto str =
1588 isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan");
1589 constexpr size_t str_size = 3;
1590 auto sign = fspecs.sign;
1591 auto size = str_size + (sign ? 1 : 0);
1592 // Replace '0'-padding with space for non-finite values.
1593 const bool is_zero_fill =
1594 specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
1595 if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
1596 return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
1597 if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1598 return copy_str<Char>(str, str + str_size, it);
1599 });
1600 }
1601
1602 // A decimal floating-point number significand * pow(10, exp).
1603 struct big_decimal_fp {
1604 const char* significand;
1605 int significand_size;
1606 int exponent;
1607 };
1608
1609 inline auto get_significand_size(const big_decimal_fp& fp) -> int {
1610 return fp.significand_size;
1611 }
1612 template <typename T>
1613 inline auto get_significand_size(const dragonbox::decimal_fp<T>& fp) -> int {
1614 return count_digits(fp.significand);
1615 }
1616
1617 template <typename Char, typename OutputIt>
1618 inline auto write_significand(OutputIt out, const char* significand,
1619 int& significand_size) -> OutputIt {
1620 return copy_str<Char>(significand, significand + significand_size, out);
1621 }
1622 template <typename Char, typename OutputIt, typename UInt>
1623 inline auto write_significand(OutputIt out, UInt significand,
1624 int significand_size) -> OutputIt {
1625 return format_decimal<Char>(out, significand, significand_size).end;
1626 }
1627
1628 template <typename Char, typename UInt,
1629 FMT_ENABLE_IF(std::is_integral<UInt>::value)>
1630 inline auto write_significand(Char* out, UInt significand, int significand_size,
1631 int integral_size, Char decimal_point) -> Char* {
1632 if (!decimal_point)
1633 return format_decimal(out, significand, significand_size).end;
1634 auto end = format_decimal(out + 1, significand, significand_size).end;
1635 if (integral_size == 1) {
1636 out[0] = out[1];
1637 } else {
1638 std::uninitialized_copy_n(out + 1, integral_size,
1639 make_checked(out, to_unsigned(integral_size)));
1640 }
1641 out[integral_size] = decimal_point;
1642 return end;
1643 }
1644
1645 template <typename OutputIt, typename UInt, typename Char,
1646 FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
1647 inline auto write_significand(OutputIt out, UInt significand,
1648 int significand_size, int integral_size,
1649 Char decimal_point) -> OutputIt {
1650 // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
1651 Char buffer[digits10<UInt>() + 2];
1652 auto end = write_significand(buffer, significand, significand_size,
1653 integral_size, decimal_point);
1654 return detail::copy_str_noinline<Char>(buffer, end, out);
1655 }
1656
1657 template <typename OutputIt, typename Char>
1658 inline auto write_significand(OutputIt out, const char* significand,
1659 int significand_size, int integral_size,
1660 Char decimal_point) -> OutputIt {
1661 out = detail::copy_str_noinline<Char>(significand,
1662 significand + integral_size, out);
1663 if (!decimal_point) return out;
1664 *out++ = decimal_point;
1665 return detail::copy_str_noinline<Char>(significand + integral_size,
1666 significand + significand_size, out);
1667 }
1668
1669 template <typename OutputIt, typename DecimalFP, typename Char>
1670 auto write_float(OutputIt out, const DecimalFP& fp,
1671 const basic_format_specs<Char>& specs, float_specs fspecs,
1672 Char decimal_point) -> OutputIt {
1673 auto significand = fp.significand;
1674 int significand_size = get_significand_size(fp);
1675 static const Char zero = static_cast<Char>('0');
1676 auto sign = fspecs.sign;
1677 size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
1678 using iterator = reserve_iterator<OutputIt>;
1679
1680 int output_exp = fp.exponent + significand_size - 1;
1681 auto use_exp_format = [=]() {
1682 if (fspecs.format == float_format::exp) return true;
1683 if (fspecs.format != float_format::general) return false;
1684 // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
1685 // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
1686 const int exp_lower = -4, exp_upper = 16;
1687 return output_exp < exp_lower ||
1688 output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
1689 };
1690 if (use_exp_format()) {
1691 int num_zeros = 0;
1692 if (fspecs.showpoint) {
1693 num_zeros = fspecs.precision - significand_size;
1694 if (num_zeros < 0) num_zeros = 0;
1695 size += to_unsigned(num_zeros);
1696 } else if (significand_size == 1) {
1697 decimal_point = Char();
1698 }
1699 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
1700 int exp_digits = 2;
1701 if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
1702
1703 size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
1704 char exp_char = fspecs.upper ? 'E' : 'e';
1705 auto write = [=](iterator it) {
1706 if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1707 // Insert a decimal point after the first digit and add an exponent.
1708 it = write_significand(it, significand, significand_size, 1,
1709 decimal_point);
1710 if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
1711 *it++ = static_cast<Char>(exp_char);
1712 return write_exponent<Char>(output_exp, it);
1713 };
1714 return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
1715 : base_iterator(out, write(reserve(out, size)));
1716 }
1717
1718 int exp = fp.exponent + significand_size;
1719 if (fp.exponent >= 0) {
1720 // 1234e5 -> 123400000[.0+]
1721 size += to_unsigned(fp.exponent);
1722 int num_zeros = fspecs.precision - exp;
1723 #ifdef FMT_FUZZ
1724 if (num_zeros > 5000)
1725 throw std::runtime_error("fuzz mode - avoiding excessive cpu use");
1726 #endif
1727 if (fspecs.showpoint) {
1728 if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1;
1729 if (num_zeros > 0) size += to_unsigned(num_zeros) + 1;
1730 }
1731 return write_padded<align::right>(out, specs, size, [&](iterator it) {
1732 if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1733 it = write_significand<Char>(it, significand, significand_size);
1734 it = detail::fill_n(it, fp.exponent, zero);
1735 if (!fspecs.showpoint) return it;
1736 *it++ = decimal_point;
1737 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
1738 });
1739 } else if (exp > 0) {
1740 // 1234e-2 -> 12.34[0+]
1741 int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
1742 size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
1743 return write_padded<align::right>(out, specs, size, [&](iterator it) {
1744 if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1745 it = write_significand(it, significand, significand_size, exp,
1746 decimal_point);
1747 return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
1748 });
1749 }
1750 // 1234e-6 -> 0.001234
1751 int num_zeros = -exp;
1752 if (significand_size == 0 && fspecs.precision >= 0 &&
1753 fspecs.precision < num_zeros) {
1754 num_zeros = fspecs.precision;
1755 }
1756 bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
1757 size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
1758 return write_padded<align::right>(out, specs, size, [&](iterator it) {
1759 if (sign) *it++ = static_cast<Char>(data::signs[sign]);
1760 *it++ = zero;
1761 if (!pointy) return it;
1762 *it++ = decimal_point;
1763 it = detail::fill_n(it, num_zeros, zero);
1764 return write_significand<Char>(it, significand, significand_size);
1765 });
1766 }
1767
1768 template <typename Char, typename OutputIt, typename T,
1769 FMT_ENABLE_IF(std::is_floating_point<T>::value)>
1770 auto write(OutputIt out, T value, basic_format_specs<Char> specs,
1771 locale_ref loc = {}) -> OutputIt {
1772 if (const_check(!is_supported_floating_point(value))) return out;
1773 float_specs fspecs = parse_float_type_spec(specs);
1774 fspecs.sign = specs.sign;
1775 if (std::signbit(value)) { // value < 0 is false for NaN so use signbit.
1776 fspecs.sign = sign::minus;
1777 value = -value;
1778 } else if (fspecs.sign == sign::minus) {
1779 fspecs.sign = sign::none;
1780 }
1781
1782 if (!std::isfinite(value))
1783 return write_nonfinite(out, std::isinf(value), specs, fspecs);
1784
1785 if (specs.align == align::numeric && fspecs.sign) {
1786 auto it = reserve(out, 1);
1787 *it++ = static_cast<Char>(data::signs[fspecs.sign]);
1788 out = base_iterator(out, it);
1789 fspecs.sign = sign::none;
1790 if (specs.width != 0) --specs.width;
1791 }
1792
1793 memory_buffer buffer;
1794 if (fspecs.format == float_format::hex) {
1795 if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]);
1796 snprintf_float(promote_float(value), specs.precision, fspecs, buffer);
1797 return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
1798 specs);
1799 }
1800 int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
1801 if (fspecs.format == float_format::exp) {
1802 if (precision == max_value<int>())
1803 FMT_THROW(format_error("number is too big"));
1804 else
1805 ++precision;
1806 }
1807 if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
1808 fspecs.use_grisu = is_fast_float<T>();
1809 int exp = format_float(promote_float(value), precision, fspecs, buffer);
1810 fspecs.precision = precision;
1811 Char point =
1812 fspecs.locale ? decimal_point<Char>(loc) : static_cast<Char>('.');
1813 auto fp = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
1814 return write_float(out, fp, specs, fspecs, point);
1815 }
1816
1817 template <typename Char, typename OutputIt, typename T,
1818 FMT_ENABLE_IF(is_fast_float<T>::value)>
1819 auto write(OutputIt out, T value) -> OutputIt {
1820 if (const_check(!is_supported_floating_point(value))) return out;
1821
1822 using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
1823 using uint = typename dragonbox::float_info<floaty>::carrier_uint;
1824 auto bits = bit_cast<uint>(value);
1825
1826 auto fspecs = float_specs();
1827 auto sign_bit = bits & (uint(1) << (num_bits<uint>() - 1));
1828 if (sign_bit != 0) {
1829 fspecs.sign = sign::minus;
1830 value = -value;
1831 }
1832
1833 static const auto specs = basic_format_specs<Char>();
1834 uint mask = exponent_mask<floaty>();
1835 if ((bits & mask) == mask)
1836 return write_nonfinite(out, std::isinf(value), specs, fspecs);
1837
1838 auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
1839 return write_float(out, dec, specs, fspecs, static_cast<Char>('.'));
1840 }
1841
1842 template <typename Char, typename OutputIt, typename T,
1843 FMT_ENABLE_IF(std::is_floating_point<T>::value &&
1844 !is_fast_float<T>::value)>
1845 inline auto write(OutputIt out, T value) -> OutputIt {
1846 return write(out, value, basic_format_specs<Char>());
1847 }
1848
1849 template <typename Char, typename OutputIt>
1850 auto write(OutputIt out, monostate, basic_format_specs<Char> = {},
1851 locale_ref = {}) -> OutputIt {
1852 FMT_ASSERT(false, "");
1853 return out;
1854 }
1855
1856 template <typename Char, typename OutputIt>
1857 FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value)
1858 -> OutputIt {
1859 auto it = reserve(out, value.size());
1860 it = copy_str_noinline<Char>(value.begin(), value.end(), it);
1861 return base_iterator(out, it);
1862 }
1863
1864 template <typename Char, typename OutputIt, typename T,
1865 FMT_ENABLE_IF(is_string<T>::value)>
1866 constexpr auto write(OutputIt out, const T& value) -> OutputIt {
1867 return write<Char>(out, to_string_view(value));
1868 }
1869
1870 template <typename Char, typename OutputIt, typename T,
1871 FMT_ENABLE_IF(is_integral<T>::value &&
1872 !std::is_same<T, bool>::value &&
1873 !std::is_same<T, Char>::value)>
1874 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
1875 auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
1876 bool negative = is_negative(value);
1877 // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
1878 if (negative) abs_value = ~abs_value + 1;
1879 int num_digits = count_digits(abs_value);
1880 auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
1881 auto it = reserve(out, size);
1882 if (auto ptr = to_pointer<Char>(it, size)) {
1883 if (negative) *ptr++ = static_cast<Char>('-');
1884 format_decimal<Char>(ptr, abs_value, num_digits);
1885 return out;
1886 }
1887 if (negative) *it++ = static_cast<Char>('-');
1888 it = format_decimal<Char>(it, abs_value, num_digits).end;
1889 return base_iterator(out, it);
1890 }
1891
1892 // FMT_ENABLE_IF() condition separated to workaround MSVC bug
1893 template <
1894 typename Char, typename OutputIt, typename T,
1895 bool check =
1896 std::is_enum<T>::value && !std::is_same<T, Char>::value &&
1897 mapped_type_constant<T, basic_format_context<OutputIt, Char>>::value !=
1898 type::custom_type,
1899 FMT_ENABLE_IF(check)>
1900 FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
1901 return write<Char>(
1902 out, static_cast<typename std::underlying_type<T>::type>(value));
1903 }
1904
1905 template <typename Char, typename OutputIt, typename T,
1906 FMT_ENABLE_IF(std::is_same<T, bool>::value)>
1907 FMT_CONSTEXPR auto write(OutputIt out, T value,
1908 const basic_format_specs<Char>& specs = {},
1909 locale_ref = {}) -> OutputIt {
1910 return specs.type && specs.type != 's'
1911 ? write(out, value ? 1 : 0, specs, {})
1912 : write_bytes(out, value ? "true" : "false", specs);
1913 }
1914
1915 template <typename Char, typename OutputIt>
1916 FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
1917 auto it = reserve(out, 1);
1918 *it++ = value;
1919 return base_iterator(out, it);
1920 }
1921
1922 template <typename Char, typename OutputIt>
1923 FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
1924 -> OutputIt {
1925 if (!value) {
1926 FMT_THROW(format_error("string pointer is null"));
1927 } else {
1928 auto length = std::char_traits<Char>::length(value);
1929 out = write(out, basic_string_view<Char>(value, length));
1930 }
1931 return out;
1932 }
1933
1934 template <typename Char, typename OutputIt, typename T,
1935 FMT_ENABLE_IF(std::is_same<T, void>::value)>
1936 auto write(OutputIt out, const T* value,
1937 const basic_format_specs<Char>& specs = {}, locale_ref = {})
1938 -> OutputIt {
1939 check_pointer_type_spec(specs.type, error_handler());
1940 return write_ptr<Char>(out, to_uintptr(value), &specs);
1941 }
1942
1943 template <typename Char, typename OutputIt, typename T>
1944 FMT_CONSTEXPR auto write(OutputIt out, const T& value) ->
1945 typename std::enable_if<
1946 mapped_type_constant<T, basic_format_context<OutputIt, Char>>::value ==
1947 type::custom_type,
1948 OutputIt>::type {
1949 using context_type = basic_format_context<OutputIt, Char>;
1950 using formatter_type =
1951 conditional_t<has_formatter<T, context_type>::value,
1952 typename context_type::template formatter_type<T>,
1953 fallback_formatter<T, Char>>;
1954 context_type ctx(out, {}, {});
1955 return formatter_type().format(value, ctx);
1956 }
1957
1958 // An argument visitor that formats the argument and writes it via the output
1959 // iterator. It's a class and not a generic lambda for compatibility with C++11.
1960 template <typename Char> struct default_arg_formatter {
1961 using iterator = buffer_appender<Char>;
1962 using context = buffer_context<Char>;
1963
1964 iterator out;
1965 basic_format_args<context> args;
1966 locale_ref loc;
1967
1968 template <typename T> auto operator()(T value) -> iterator {
1969 return write<Char>(out, value);
1970 }
1971 auto operator()(typename basic_format_arg<context>::handle h) -> iterator {
1972 basic_format_parse_context<Char> parse_ctx({});
1973 context format_ctx(out, args, loc);
1974 h.format(parse_ctx, format_ctx);
1975 return format_ctx.out();
1976 }
1977 };
1978
1979 template <typename Char> struct arg_formatter {
1980 using iterator = buffer_appender<Char>;
1981 using context = buffer_context<Char>;
1982
1983 iterator out;
1984 const basic_format_specs<Char>& specs;
1985 locale_ref locale;
1986
1987 template <typename T>
1988 FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator {
1989 return detail::write(out, value, specs, locale);
1990 }
1991 auto operator()(typename basic_format_arg<context>::handle) -> iterator {
1992 // User-defined types are handled separately because they require access
1993 // to the parse context.
1994 return out;
1995 }
1996 };
1997
1998 template <typename Char> struct custom_formatter {
1999 basic_format_parse_context<Char>& parse_ctx;
2000 buffer_context<Char>& ctx;
2001
2002 void operator()(
2003 typename basic_format_arg<buffer_context<Char>>::handle h) const {
2004 h.format(parse_ctx, ctx);
2005 }
2006 template <typename T> void operator()(T) const {}
2007 };
2008
2009 template <typename T>
2010 using is_integer =
2011 bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
2012 !std::is_same<T, char>::value &&
2013 !std::is_same<T, wchar_t>::value>;
2014
2015 template <typename ErrorHandler> class width_checker {
2016 public:
2017 explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}
2018
2019 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2020 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
2021 if (is_negative(value)) handler_.on_error("negative width");
2022 return static_cast<unsigned long long>(value);
2023 }
2024
2025 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2026 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
2027 handler_.on_error("width is not integer");
2028 return 0;
2029 }
2030
2031 private:
2032 ErrorHandler& handler_;
2033 };
2034
2035 template <typename ErrorHandler> class precision_checker {
2036 public:
2037 explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}
2038
2039 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
2040 FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
2041 if (is_negative(value)) handler_.on_error("negative precision");
2042 return static_cast<unsigned long long>(value);
2043 }
2044
2045 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
2046 FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
2047 handler_.on_error("precision is not integer");
2048 return 0;
2049 }
2050
2051 private:
2052 ErrorHandler& handler_;
2053 };
2054
2055 template <template <typename> class Handler, typename FormatArg,
2056 typename ErrorHandler>
2057 FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int {
2058 unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg);
2059 if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big");
2060 return static_cast<int>(value);
2061 }
2062
2063 template <typename Context, typename ID>
2064 FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) ->
2065 typename Context::format_arg {
2066 auto arg = ctx.arg(id);
2067 if (!arg) ctx.on_error("argument not found");
2068 return arg;
2069 }
2070
2071 // The standard format specifier handler with checking.
2072 template <typename Char> class specs_handler : public specs_setter<Char> {
2073 private:
2074 basic_format_parse_context<Char>& parse_context_;
2075 buffer_context<Char>& context_;
2076
2077 // This is only needed for compatibility with gcc 4.4.
2078 using format_arg = basic_format_arg<buffer_context<Char>>;
2079
2080 FMT_CONSTEXPR auto get_arg(auto_id) -> format_arg {
2081 return detail::get_arg(context_, parse_context_.next_arg_id());
2082 }
2083
2084 FMT_CONSTEXPR auto get_arg(int arg_id) -> format_arg {
2085 parse_context_.check_arg_id(arg_id);
2086 return detail::get_arg(context_, arg_id);
2087 }
2088
2089 FMT_CONSTEXPR auto get_arg(basic_string_view<Char> arg_id) -> format_arg {
2090 parse_context_.check_arg_id(arg_id);
2091 return detail::get_arg(context_, arg_id);
2092 }
2093
2094 public:
2095 FMT_CONSTEXPR specs_handler(basic_format_specs<Char>& specs,
2096 basic_format_parse_context<Char>& parse_ctx,
2097 buffer_context<Char>& ctx)
2098 : specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {}
2099
2100 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
2101 this->specs_.width = get_dynamic_spec<width_checker>(
2102 get_arg(arg_id), context_.error_handler());
2103 }
2104
2105 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
2106 this->specs_.precision = get_dynamic_spec<precision_checker>(
2107 get_arg(arg_id), context_.error_handler());
2108 }
2109
2110 void on_error(const char* message) { context_.on_error(message); }
2111 };
2112
2113 template <template <typename> class Handler, typename Context>
2114 FMT_CONSTEXPR void handle_dynamic_spec(int& value,
2115 arg_ref<typename Context::char_type> ref,
2116 Context& ctx) {
2117 switch (ref.kind) {
2118 case arg_id_kind::none:
2119 break;
2120 case arg_id_kind::index:
2121 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.index),
2122 ctx.error_handler());
2123 break;
2124 case arg_id_kind::name:
2125 value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
2126 ctx.error_handler());
2127 break;
2128 }
2129 }
2130
2131 #define FMT_STRING_IMPL(s, base, explicit) \
2132 [] { \
2133 /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
2134 /* Use a macro-like name to avoid shadowing warnings. */ \
2135 struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
2136 using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
2137 FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
2138 operator fmt::basic_string_view<char_type>() const { \
2139 return fmt::detail_exported::compile_string_to_view<char_type>(s); \
2140 } \
2141 }; \
2142 return FMT_COMPILE_STRING(); \
2143 }()
2144
2145 /**
2146 \rst
2147 Constructs a compile-time format string from a string literal *s*.
2148
2149 **Example**::
2150
2151 // A compile-time error because 'd' is an invalid specifier for strings.
2152 std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
2153 \endrst
2154 */
2155 #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, )
2156
2157 #if FMT_USE_USER_DEFINED_LITERALS
2158 template <typename Char> struct udl_formatter {
2159 basic_string_view<Char> str;
2160
2161 template <typename... T>
2162 auto operator()(T&&... args) const -> std::basic_string<Char> {
2163 return vformat(str, fmt::make_args_checked<T...>(str, args...));
2164 }
2165 };
2166
2167 # if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
2168 template <typename T, typename Char, size_t N,
2169 fmt::detail_exported::fixed_string<Char, N> Str>
2170 struct statically_named_arg : view {
2171 static constexpr auto name = Str.data;
2172
2173 const T& value;
2174 statically_named_arg(const T& v) : value(v) {}
2175 };
2176
2177 template <typename T, typename Char, size_t N,
2178 fmt::detail_exported::fixed_string<Char, N> Str>
2179 struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
2180
2181 template <typename T, typename Char, size_t N,
2182 fmt::detail_exported::fixed_string<Char, N> Str>
2183 struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
2184 : std::true_type {};
2185
2186 template <typename Char, size_t N,
2187 fmt::detail_exported::fixed_string<Char, N> Str>
2188 struct udl_arg {
2189 template <typename T> auto operator=(T&& value) const {
2190 return statically_named_arg<T, Char, N, Str>(std::forward<T>(value));
2191 }
2192 };
2193 # else
2194 template <typename Char> struct udl_arg {
2195 const Char* str;
2196
2197 template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
2198 return {str, std::forward<T>(value)};
2199 }
2200 };
2201 # endif
2202 #endif // FMT_USE_USER_DEFINED_LITERALS
2203
2204 template <typename Locale, typename Char>
2205 auto vformat(const Locale& loc, basic_string_view<Char> format_str,
2206 basic_format_args<buffer_context<type_identity_t<Char>>> args)
2207 -> std::basic_string<Char> {
2208 basic_memory_buffer<Char> buffer;
2209 detail::vformat_to(buffer, format_str, args, detail::locale_ref(loc));
2210 return {buffer.data(), buffer.size()};
2211 }
2212
2213 using format_func = void (*)(detail::buffer<char>&, int, const char*);
2214
2215 FMT_API void format_error_code(buffer<char>& out, int error_code,
2216 string_view message) FMT_NOEXCEPT;
2217
2218 FMT_API void report_error(format_func func, int error_code,
2219 const char* message) FMT_NOEXCEPT;
2220 FMT_END_DETAIL_NAMESPACE
2221
2222 FMT_API auto vsystem_error(int error_code, string_view format_str,
2223 format_args args) -> std::system_error;
2224
2225 /**
2226 \rst
2227 Constructs :class:`std::system_error` with a message formatted with
2228 ``fmt::format(fmt, args...)``.
2229 *error_code* is a system error code as given by ``errno``.
2230
2231 **Example**::
2232
2233 // This throws std::system_error with the description
2234 // cannot open file 'madeup': No such file or directory
2235 // or similar (system message may vary).
2236 const char* filename = "madeup";
2237 std::FILE* file = std::fopen(filename, "r");
2238 if (!file)
2239 throw fmt::system_error(errno, "cannot open file '{}'", filename);
2240 \endrst
2241 */
2242 template <typename... T>
2243 auto system_error(int error_code, format_string<T...> fmt, T&&... args)
2244 -> std::system_error {
2245 return vsystem_error(error_code, fmt, fmt::make_format_args(args...));
2246 }
2247
2248 /**
2249 \rst
2250 Formats an error message for an error returned by an operating system or a
2251 language runtime, for example a file opening error, and writes it to *out*.
2252 The format is the same as the one used by ``std::system_error(ec, message)``
2253 where ``ec`` is ``std::error_code(error_code, std::generic_category()})``.
2254 It is implementation-defined but normally looks like:
2255
2256 .. parsed-literal::
2257 *<message>*: *<system-message>*
2258
2259 where *<message>* is the passed message and *<system-message>* is the system
2260 message corresponding to the error code.
2261 *error_code* is a system error code as given by ``errno``.
2262 \endrst
2263 */
2264 FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
2265 const char* message) FMT_NOEXCEPT;
2266
2267 // Reports a system error without throwing an exception.
2268 // Can be used to report errors from destructors.
2269 FMT_API void report_system_error(int error_code,
2270 const char* message) FMT_NOEXCEPT;
2271
2272 /** Fast integer formatter. */
2273 class format_int {
2274 private:
2275 // Buffer should be large enough to hold all digits (digits10 + 1),
2276 // a sign and a null character.
2277 enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
2278 mutable char buffer_[buffer_size];
2279 char* str_;
2280
2281 template <typename UInt> auto format_unsigned(UInt value) -> char* {
2282 auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
2283 return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
2284 }
2285
2286 template <typename Int> auto format_signed(Int value) -> char* {
2287 auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
2288 bool negative = value < 0;
2289 if (negative) abs_value = 0 - abs_value;
2290 auto begin = format_unsigned(abs_value);
2291 if (negative) *--begin = '-';
2292 return begin;
2293 }
2294
2295 public:
2296 explicit format_int(int value) : str_(format_signed(value)) {}
2297 explicit format_int(long value) : str_(format_signed(value)) {}
2298 explicit format_int(long long value) : str_(format_signed(value)) {}
2299 explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
2300 explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
2301 explicit format_int(unsigned long long value)
2302 : str_(format_unsigned(value)) {}
2303
2304 /** Returns the number of characters written to the output buffer. */
2305 auto size() const -> size_t {
2306 return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
2307 }
2308
2309 /**
2310 Returns a pointer to the output buffer content. No terminating null
2311 character is appended.
2312 */
2313 auto data() const -> const char* { return str_; }
2314
2315 /**
2316 Returns a pointer to the output buffer content with terminating null
2317 character appended.
2318 */
2319 auto c_str() const -> const char* {
2320 buffer_[buffer_size - 1] = '\0';
2321 return str_;
2322 }
2323
2324 /**
2325 \rst
2326 Returns the content of the output buffer as an ``std::string``.
2327 \endrst
2328 */
2329 auto str() const -> std::string { return std::string(str_, size()); }
2330 };
2331
2332 template <typename T, typename Char>
2333 template <typename FormatContext>
2334 FMT_CONSTEXPR FMT_INLINE auto
2335 formatter<T, Char,
2336 enable_if_t<detail::type_constant<T, Char>::value !=
2337 detail::type::custom_type>>::format(const T& val,
2338 FormatContext& ctx)
2339 const -> decltype(ctx.out()) {
2340 if (specs_.width_ref.kind != detail::arg_id_kind::none ||
2341 specs_.precision_ref.kind != detail::arg_id_kind::none) {
2342 auto specs = specs_;
2343 detail::handle_dynamic_spec<detail::width_checker>(specs.width,
2344 specs.width_ref, ctx);
2345 detail::handle_dynamic_spec<detail::precision_checker>(
2346 specs.precision, specs.precision_ref, ctx);
2347 return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
2348 }
2349 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
2350 }
2351
2352 #define FMT_FORMAT_AS(Type, Base) \
2353 template <typename Char> \
2354 struct formatter<Type, Char> : formatter<Base, Char> { \
2355 template <typename FormatContext> \
2356 auto format(Type const& val, FormatContext& ctx) const \
2357 -> decltype(ctx.out()) { \
2358 return formatter<Base, Char>::format(static_cast<Base>(val), ctx); \
2359 } \
2360 }
2361
2362 FMT_FORMAT_AS(signed char, int);
2363 FMT_FORMAT_AS(unsigned char, unsigned);
2364 FMT_FORMAT_AS(short, int);
2365 FMT_FORMAT_AS(unsigned short, unsigned);
2366 FMT_FORMAT_AS(long, long long);
2367 FMT_FORMAT_AS(unsigned long, unsigned long long);
2368 FMT_FORMAT_AS(Char*, const Char*);
2369 FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
2370 FMT_FORMAT_AS(std::nullptr_t, const void*);
2371 FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
2372
2373 template <typename Char>
2374 struct formatter<void*, Char> : formatter<const void*, Char> {
2375 template <typename FormatContext>
2376 auto format(void* val, FormatContext& ctx) const -> decltype(ctx.out()) {
2377 return formatter<const void*, Char>::format(val, ctx);
2378 }
2379 };
2380
2381 template <typename Char, size_t N>
2382 struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
2383 template <typename FormatContext>
2384 FMT_CONSTEXPR auto format(const Char* val, FormatContext& ctx) const
2385 -> decltype(ctx.out()) {
2386 return formatter<basic_string_view<Char>, Char>::format(val, ctx);
2387 }
2388 };
2389
2390 // A formatter for types known only at run time such as variant alternatives.
2391 //
2392 // Usage:
2393 // using variant = std::variant<int, std::string>;
2394 // template <>
2395 // struct formatter<variant>: dynamic_formatter<> {
2396 // auto format(const variant& v, format_context& ctx) {
2397 // return visit([&](const auto& val) {
2398 // return dynamic_formatter<>::format(val, ctx);
2399 // }, v);
2400 // }
2401 // };
2402 template <typename Char = char> class dynamic_formatter {
2403 private:
2404 detail::dynamic_format_specs<Char> specs_;
2405 const Char* format_str_;
2406
2407 struct null_handler : detail::error_handler {
2408 void on_align(align_t) {}
2409 void on_sign(sign_t) {}
2410 void on_hash() {}
2411 };
2412
2413 template <typename Context> void handle_specs(Context& ctx) {
2414 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
2415 specs_.width_ref, ctx);
2416 detail::handle_dynamic_spec<detail::precision_checker>(
2417 specs_.precision, specs_.precision_ref, ctx);
2418 }
2419
2420 public:
2421 template <typename ParseContext>
2422 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2423 format_str_ = ctx.begin();
2424 // Checks are deferred to formatting time when the argument type is known.
2425 detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
2426 return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
2427 }
2428
2429 template <typename T, typename FormatContext>
2430 auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
2431 handle_specs(ctx);
2432 detail::specs_checker<null_handler> checker(
2433 null_handler(), detail::mapped_type_constant<T, FormatContext>::value);
2434 checker.on_align(specs_.align);
2435 if (specs_.sign != sign::none) checker.on_sign(specs_.sign);
2436 if (specs_.alt) checker.on_hash();
2437 if (specs_.precision >= 0) checker.end_precision();
2438 return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
2439 }
2440 };
2441
2442 /**
2443 \rst
2444 Converts ``p`` to ``const void*`` for pointer formatting.
2445
2446 **Example**::
2447
2448 auto s = fmt::format("{}", fmt::ptr(p));
2449 \endrst
2450 */
2451 template <typename T> auto ptr(T p) -> const void* {
2452 static_assert(std::is_pointer<T>::value, "");
2453 return detail::bit_cast<const void*>(p);
2454 }
2455 template <typename T> auto ptr(const std::unique_ptr<T>& p) -> const void* {
2456 return p.get();
2457 }
2458 template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
2459 return p.get();
2460 }
2461
2462 class bytes {
2463 private:
2464 string_view data_;
2465 friend struct formatter<bytes>;
2466
2467 public:
2468 explicit bytes(string_view data) : data_(data) {}
2469 };
2470
2471 template <> struct formatter<bytes> {
2472 private:
2473 detail::dynamic_format_specs<char> specs_;
2474
2475 public:
2476 template <typename ParseContext>
2477 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2478 using handler_type = detail::dynamic_specs_handler<ParseContext>;
2479 detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
2480 detail::type::string_type);
2481 auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
2482 detail::check_string_type_spec(specs_.type, ctx.error_handler());
2483 return it;
2484 }
2485
2486 template <typename FormatContext>
2487 auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
2488 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
2489 specs_.width_ref, ctx);
2490 detail::handle_dynamic_spec<detail::precision_checker>(
2491 specs_.precision, specs_.precision_ref, ctx);
2492 return detail::write_bytes(ctx.out(), b.data_, specs_);
2493 }
2494 };
2495
2496 template <typename It, typename Sentinel, typename Char = char>
2497 struct join_view : detail::view {
2498 It begin;
2499 Sentinel end;
2500 basic_string_view<Char> sep;
2501
2502 join_view(It b, Sentinel e, basic_string_view<Char> s)
2503 : begin(b), end(e), sep(s) {}
2504 };
2505
2506 template <typename It, typename Sentinel, typename Char>
2507 using arg_join FMT_DEPRECATED_ALIAS = join_view<It, Sentinel, Char>;
2508
2509 template <typename It, typename Sentinel, typename Char>
2510 struct formatter<join_view<It, Sentinel, Char>, Char> {
2511 private:
2512 using value_type = typename std::iterator_traits<It>::value_type;
2513 using context = buffer_context<Char>;
2514 using mapper = detail::arg_mapper<context>;
2515
2516 template <typename T, FMT_ENABLE_IF(has_formatter<T, context>::value)>
2517 static auto map(const T& value) -> const T& {
2518 return value;
2519 }
2520 template <typename T, FMT_ENABLE_IF(!has_formatter<T, context>::value)>
2521 static auto map(const T& value) -> decltype(mapper().map(value)) {
2522 return mapper().map(value);
2523 }
2524
2525 using formatter_type =
2526 conditional_t<is_formattable<value_type, Char>::value,
2527 formatter<remove_cvref_t<decltype(map(
2528 std::declval<const value_type&>()))>,
2529 Char>,
2530 detail::fallback_formatter<value_type, Char>>;
2531
2532 formatter_type value_formatter_;
2533
2534 public:
2535 template <typename ParseContext>
2536 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2537 return value_formatter_.parse(ctx);
2538 }
2539
2540 template <typename FormatContext>
2541 auto format(const join_view<It, Sentinel, Char>& value, FormatContext& ctx)
2542 -> decltype(ctx.out()) {
2543 auto it = value.begin;
2544 auto out = ctx.out();
2545 if (it != value.end) {
2546 out = value_formatter_.format(map(*it++), ctx);
2547 while (it != value.end) {
2548 out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
2549 ctx.advance_to(out);
2550 out = value_formatter_.format(map(*it++), ctx);
2551 }
2552 }
2553 return out;
2554 }
2555 };
2556
2557 /**
2558 Returns an object that formats the iterator range `[begin, end)` with
2559 elements separated by `sep`.
2560 */
2561 template <typename It, typename Sentinel>
2562 auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
2563 return {begin, end, sep};
2564 }
2565
2566 /**
2567 \rst
2568 Returns an object that formats `range` with elements separated by `sep`.
2569
2570 **Example**::
2571
2572 std::vector<int> v = {1, 2, 3};
2573 fmt::print("{}", fmt::join(v, ", "));
2574 // Output: "1, 2, 3"
2575
2576 ``fmt::join`` applies passed format specifiers to the range elements::
2577
2578 fmt::print("{:02}", fmt::join(v, ", "));
2579 // Output: "01, 02, 03"
2580 \endrst
2581 */
2582 template <typename Range>
2583 auto join(Range&& range, string_view sep)
2584 -> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>> {
2585 return join(std::begin(range), std::end(range), sep);
2586 }
2587
2588 /**
2589 \rst
2590 Converts *value* to ``std::string`` using the default format for type *T*.
2591
2592 **Example**::
2593
2594 #include <fmt/format.h>
2595
2596 std::string answer = fmt::to_string(42);
2597 \endrst
2598 */
2599 template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
2600 inline auto to_string(const T& value) -> std::string {
2601 auto result = std::string();
2602 detail::write<char>(std::back_inserter(result), value);
2603 return result;
2604 }
2605
2606 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
2607 inline auto to_string(T value) -> std::string {
2608 // The buffer should be large enough to store the number including the sign
2609 // or "false" for bool.
2610 constexpr int max_size = detail::digits10<T>() + 2;
2611 char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
2612 char* begin = buffer;
2613 return std::string(begin, detail::write<char>(begin, value));
2614 }
2615
2616 template <typename Char, size_t SIZE>
2617 auto to_string(const basic_memory_buffer<Char, SIZE>& buf)
2618 -> std::basic_string<Char> {
2619 auto size = buf.size();
2620 detail::assume(size < std::basic_string<Char>().max_size());
2621 return std::basic_string<Char>(buf.data(), size);
2622 }
2623
2624 FMT_BEGIN_DETAIL_NAMESPACE
2625
2626 template <typename Char>
2627 void vformat_to(
2628 buffer<Char>& buf, basic_string_view<Char> fmt,
2629 basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args,
2630 locale_ref loc) {
2631 // workaround for msvc bug regarding name-lookup in module
2632 // link names into function scope
2633 using detail::arg_formatter;
2634 using detail::buffer_appender;
2635 using detail::custom_formatter;
2636 using detail::default_arg_formatter;
2637 using detail::get_arg;
2638 using detail::locale_ref;
2639 using detail::parse_format_specs;
2640 using detail::specs_checker;
2641 using detail::specs_handler;
2642 using detail::to_unsigned;
2643 using detail::type;
2644 using detail::write;
2645 auto out = buffer_appender<Char>(buf);
2646 if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
2647 auto arg = args.get(0);
2648 if (!arg) error_handler().on_error("argument not found");
2649 visit_format_arg(default_arg_formatter<Char>{out, args, loc}, arg);
2650 return;
2651 }
2652
2653 struct format_handler : error_handler {
2654 basic_format_parse_context<Char> parse_context;
2655 buffer_context<Char> context;
2656
2657 format_handler(buffer_appender<Char> out, basic_string_view<Char> str,
2658 basic_format_args<buffer_context<Char>> args, locale_ref loc)
2659 : parse_context(str), context(out, args, loc) {}
2660
2661 void on_text(const Char* begin, const Char* end) {
2662 auto text = basic_string_view<Char>(begin, to_unsigned(end - begin));
2663 context.advance_to(write<Char>(context.out(), text));
2664 }
2665
2666 FMT_CONSTEXPR auto on_arg_id() -> int {
2667 return parse_context.next_arg_id();
2668 }
2669 FMT_CONSTEXPR auto on_arg_id(int id) -> int {
2670 return parse_context.check_arg_id(id), id;
2671 }
2672 FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
2673 int arg_id = context.arg_id(id);
2674 if (arg_id < 0) on_error("argument not found");
2675 return arg_id;
2676 }
2677
2678 FMT_INLINE void on_replacement_field(int id, const Char*) {
2679 auto arg = get_arg(context, id);
2680 context.advance_to(visit_format_arg(
2681 default_arg_formatter<Char>{context.out(), context.args(),
2682 context.locale()},
2683 arg));
2684 }
2685
2686 auto on_format_specs(int id, const Char* begin, const Char* end)
2687 -> const Char* {
2688 auto arg = get_arg(context, id);
2689 if (arg.type() == type::custom_type) {
2690 parse_context.advance_to(parse_context.begin() +
2691 (begin - &*parse_context.begin()));
2692 visit_format_arg(custom_formatter<Char>{parse_context, context}, arg);
2693 return parse_context.begin();
2694 }
2695 auto specs = basic_format_specs<Char>();
2696 specs_checker<specs_handler<Char>> handler(
2697 specs_handler<Char>(specs, parse_context, context), arg.type());
2698 begin = parse_format_specs(begin, end, handler);
2699 if (begin == end || *begin != '}')
2700 on_error("missing '}' in format string");
2701 auto f = arg_formatter<Char>{context.out(), specs, context.locale()};
2702 context.advance_to(visit_format_arg(f, arg));
2703 return begin;
2704 }
2705 };
2706 detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
2707 }
2708
2709 #ifndef FMT_HEADER_ONLY
2710 extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
2711 -> thousands_sep_result<char>;
2712 extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
2713 -> thousands_sep_result<wchar_t>;
2714 extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
2715 extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
2716 extern template auto format_float<double>(double value, int precision,
2717 float_specs specs, buffer<char>& buf)
2718 -> int;
2719 extern template auto format_float<long double>(long double value, int precision,
2720 float_specs specs,
2721 buffer<char>& buf) -> int;
2722 void snprintf_float(float, int, float_specs, buffer<char>&) = delete;
2723 extern template auto snprintf_float<double>(double value, int precision,
2724 float_specs specs,
2725 buffer<char>& buf) -> int;
2726 extern template auto snprintf_float<long double>(long double value,
2727 int precision,
2728 float_specs specs,
2729 buffer<char>& buf) -> int;
2730 #endif // FMT_HEADER_ONLY
2731
2732 FMT_END_DETAIL_NAMESPACE
2733
2734 #if FMT_USE_USER_DEFINED_LITERALS
2735 inline namespace literals {
2736 /**
2737 \rst
2738 User-defined literal equivalent of :func:`fmt::arg`.
2739
2740 **Example**::
2741
2742 using namespace fmt::literals;
2743 fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
2744 \endrst
2745 */
2746 # if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
2747 template <detail_exported::fixed_string Str>
2748 constexpr auto operator""_a()
2749 -> detail::udl_arg<remove_cvref_t<decltype(Str.data[0])>,
2750 sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> {
2751 return {};
2752 }
2753 # else
2754 constexpr auto operator"" _a(const char* s, size_t) -> detail::udl_arg<char> {
2755 return {s};
2756 }
2757 # endif
2758
2759 /**
2760 \rst
2761 User-defined literal equivalent of :func:`fmt::format`.
2762
2763 **Example**::
2764
2765 using namespace fmt::literals;
2766 std::string message = "The answer is {}"_format(42);
2767 \endrst
2768 */
2769 constexpr auto operator"" _format(const char* s, size_t n)
2770 -> detail::udl_formatter<char> {
2771 return {{s, n}};
2772 }
2773 } // namespace literals
2774 #endif // FMT_USE_USER_DEFINED_LITERALS
2775
2776 template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
2777 inline auto vformat(const Locale& loc, string_view fmt, format_args args)
2778 -> std::string {
2779 return detail::vformat(loc, fmt, args);
2780 }
2781
2782 template <typename Locale, typename... T,
2783 FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
2784 inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
2785 -> std::string {
2786 return vformat(loc, string_view(fmt), fmt::make_format_args(args...));
2787 }
2788
2789 template <typename... T, size_t SIZE, typename Allocator>
2790 FMT_DEPRECATED auto format_to(basic_memory_buffer<char, SIZE, Allocator>& buf,
2791 format_string<T...> fmt, T&&... args)
2792 -> appender {
2793 detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...));
2794 return appender(buf);
2795 }
2796
2797 template <typename OutputIt, typename Locale,
2798 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
2799 detail::is_locale<Locale>::value)>
2800 auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
2801 format_args args) -> OutputIt {
2802 using detail::get_buffer;
2803 auto&& buf = get_buffer<char>(out);
2804 detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
2805 return detail::get_iterator(buf);
2806 }
2807
2808 template <typename OutputIt, typename Locale, typename... T,
2809 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
2810 detail::is_locale<Locale>::value)>
2811 FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
2812 format_string<T...> fmt, T&&... args) -> OutputIt {
2813 return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
2814 }
2815
2816 FMT_MODULE_EXPORT_END
2817 FMT_END_NAMESPACE
2818
2819 #ifdef FMT_DEPRECATED_INCLUDE_XCHAR
2820 # include "xchar.h"
2821 #endif
2822
2823 #ifdef FMT_HEADER_ONLY
2824 # define FMT_FUNC inline
2825 # include "format-inl.h"
2826 #else
2827 # define FMT_FUNC
2828 #endif
2829
2830 #endif // FMT_FORMAT_H_
2831