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 #define FMT_HEADER_ONLY // Added by diy for header-only usage
37
38 #include <algorithm>
39 #include <cassert>
40 #include <cmath>
41 #include <cstdint>
42 #include <cstring>
43 #include <iterator>
44 #include <limits>
45 #include <memory>
46 #include <stdexcept>
47
48 #include "core.h"
49
50 #ifdef __clang__
51 # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
52 #else
53 # define FMT_CLANG_VERSION 0
54 #endif
55
56 #ifdef __INTEL_COMPILER
57 # define FMT_ICC_VERSION __INTEL_COMPILER
58 #elif defined(__ICL)
59 # define FMT_ICC_VERSION __ICL
60 #else
61 # define FMT_ICC_VERSION 0
62 #endif
63
64 #ifdef __NVCC__
65 # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
66 #else
67 # define FMT_CUDA_VERSION 0
68 #endif
69
70 #ifdef __has_builtin
71 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
72 #else
73 # define FMT_HAS_BUILTIN(x) 0
74 #endif
75
76 #ifndef FMT_THROW
77 # if FMT_EXCEPTIONS
78 # if FMT_MSC_VER
79 FMT_BEGIN_NAMESPACE
80 namespace internal {
do_throw(const Exception & x)81 template <typename Exception> inline void do_throw(const Exception& x) {
82 // Silence unreachable code warnings in MSVC because these are nearly
83 // impossible to fix in a generic code.
84 volatile bool b = true;
85 if (b) throw x;
86 }
87 } // namespace internal
88 FMT_END_NAMESPACE
89 # define FMT_THROW(x) fmt::internal::do_throw(x)
90 # else
91 # define FMT_THROW(x) throw x
92 # endif
93 # else
94 # define FMT_THROW(x) \
95 do { \
96 static_cast<void>(sizeof(x)); \
97 assert(false); \
98 } while (false)
99 # endif
100 #endif
101
102 #ifndef FMT_USE_USER_DEFINED_LITERALS
103 // For Intel and NVIDIA compilers both they and the system gcc/msc support UDLs.
104 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
105 FMT_MSC_VER >= 1900) && \
106 (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || FMT_ICC_VERSION >= 1500 || \
107 FMT_CUDA_VERSION >= 700)
108 # define FMT_USE_USER_DEFINED_LITERALS 1
109 # else
110 # define FMT_USE_USER_DEFINED_LITERALS 0
111 # endif
112 #endif
113
114 #ifndef FMT_USE_UDL_TEMPLATE
115 // EDG front end based compilers (icc, nvcc) do not support UDL templates yet
116 // and GCC 9 warns about them.
117 # if FMT_USE_USER_DEFINED_LITERALS && FMT_ICC_VERSION == 0 && \
118 FMT_CUDA_VERSION == 0 && \
119 ((FMT_GCC_VERSION >= 600 && FMT_GCC_VERSION <= 900 && \
120 __cplusplus >= 201402L) || \
121 FMT_CLANG_VERSION >= 304)
122 # define FMT_USE_UDL_TEMPLATE 1
123 # else
124 # define FMT_USE_UDL_TEMPLATE 0
125 # endif
126 #endif
127
128 #ifdef FMT_USE_INT128
129 // Do nothing.
130 #elif defined(__SIZEOF_INT128__)
131 # define FMT_USE_INT128 1
132 #else
133 # define FMT_USE_INT128 0
134 #endif
135
136 // __builtin_clz is broken in clang with Microsoft CodeGen:
137 // https://github.com/fmtlib/fmt/issues/519
138 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER
139 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
140 #endif
141 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER
142 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
143 #endif
144
145 // Some compilers masquerade as both MSVC and GCC-likes or otherwise support
146 // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
147 // MSVC intrinsics if the clz and clzll builtins are not available.
148 #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED)
149 # include <intrin.h> // _BitScanReverse, _BitScanReverse64
150
151 FMT_BEGIN_NAMESPACE
152 namespace internal {
153 // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
154 # ifndef __clang__
155 # pragma intrinsic(_BitScanReverse)
156 # endif
clz(uint32_t x)157 inline uint32_t clz(uint32_t x) {
158 unsigned long r = 0;
159 _BitScanReverse(&r, x);
160
161 assert(x != 0);
162 // Static analysis complains about using uninitialized data
163 // "r", but the only way that can happen is if "x" is 0,
164 // which the callers guarantee to not happen.
165 # pragma warning(suppress : 6102)
166 return 31 - r;
167 }
168 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
169
170 # if defined(_WIN64) && !defined(__clang__)
171 # pragma intrinsic(_BitScanReverse64)
172 # endif
173
clzll(uint64_t x)174 inline uint32_t clzll(uint64_t x) {
175 unsigned long r = 0;
176 # ifdef _WIN64
177 _BitScanReverse64(&r, x);
178 # else
179 // Scan the high 32 bits.
180 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 - (r + 32);
181
182 // Scan the low 32 bits.
183 _BitScanReverse(&r, static_cast<uint32_t>(x));
184 # endif
185
186 assert(x != 0);
187 // Static analysis complains about using uninitialized data
188 // "r", but the only way that can happen is if "x" is 0,
189 // which the callers guarantee to not happen.
190 # pragma warning(suppress : 6102)
191 return 63 - r;
192 }
193 # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
194 } // namespace internal
195 FMT_END_NAMESPACE
196 #endif
197
198 FMT_BEGIN_NAMESPACE
199 namespace internal {
200
201 // A fallback implementation of uintptr_t for systems that lack it.
202 struct fallback_uintptr {
203 unsigned char value[sizeof(void*)];
204 };
205 #ifdef UINTPTR_MAX
206 using uintptr_t = ::uintptr_t;
207 #else
208 using uintptr_t = fallback_uintptr;
209 #endif
210
211 // An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't produce
212 // undefined behavior (e.g. due to type aliasing).
213 // Example: uint64_t d = bit_cast<uint64_t>(2.718);
214 template <typename Dest, typename Source>
bit_cast(const Source & source)215 inline Dest bit_cast(const Source& source) {
216 static_assert(sizeof(Dest) == sizeof(Source), "size mismatch");
217 Dest dest;
218 std::memcpy(&dest, &source, sizeof(dest));
219 return dest;
220 }
221
222 // An approximation of iterator_t for pre-C++20 systems.
223 template <typename T>
224 using iterator_t = decltype(std::begin(std::declval<T&>()));
225
226 // Detect the iterator category of *any* given type in a SFINAE-friendly way.
227 // Unfortunately, older implementations of std::iterator_traits are not safe
228 // for use in a SFINAE-context.
229 template <typename It, typename Enable = void>
230 struct iterator_category : std::false_type {};
231
232 template <typename T> struct iterator_category<T*> {
233 using type = std::random_access_iterator_tag;
234 };
235
236 template <typename It>
237 struct iterator_category<It, void_t<typename It::iterator_category>> {
238 using type = typename It::iterator_category;
239 };
240
241 // Detect if *any* given type models the OutputIterator concept.
242 template <typename It> class is_output_iterator {
243 // Check for mutability because all iterator categories derived from
244 // std::input_iterator_tag *may* also meet the requirements of an
245 // OutputIterator, thereby falling into the category of 'mutable iterators'
246 // [iterator.requirements.general] clause 4. The compiler reveals this
247 // property only at the point of *actually dereferencing* the iterator!
248 template <typename U>
249 static decltype(*(std::declval<U>())) test(std::input_iterator_tag);
250 template <typename U> static char& test(std::output_iterator_tag);
251 template <typename U> static const char& test(...);
252
253 using type = decltype(test<It>(typename iterator_category<It>::type{}));
254
255 public:
256 static const bool value = !std::is_const<remove_reference_t<type>>::value;
257 };
258
259 // A workaround for std::string not having mutable data() until C++17.
260 template <typename Char> inline Char* get_data(std::basic_string<Char>& s) {
261 return &s[0];
262 }
263 template <typename Container>
264 inline typename Container::value_type* get_data(Container& c) {
265 return c.data();
266 }
267
268 #ifdef _SECURE_SCL
269 // Make a checked iterator to avoid MSVC warnings.
270 template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
271 template <typename T> checked_ptr<T> make_checked(T* p, std::size_t size) {
272 return {p, size};
273 }
274 #else
275 template <typename T> using checked_ptr = T*;
276 template <typename T> inline T* make_checked(T* p, std::size_t) { return p; }
277 #endif
278
279 template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
280 inline checked_ptr<typename Container::value_type> reserve(
281 std::back_insert_iterator<Container>& it, std::size_t n) {
282 Container& c = get_container(it);
283 std::size_t size = c.size();
284 c.resize(size + n);
285 return make_checked(get_data(c) + size, n);
286 }
287
288 template <typename Iterator>
289 inline Iterator& reserve(Iterator& it, std::size_t) {
290 return it;
291 }
292
293 // An output iterator that counts the number of objects written to it and
294 // discards them.
295 template <typename T> class counting_iterator {
296 private:
297 std::size_t count_;
298 mutable T blackhole_;
299
300 public:
301 using iterator_category = std::output_iterator_tag;
302 using value_type = T;
303 using difference_type = std::ptrdiff_t;
304 using pointer = T*;
305 using reference = T&;
306 using _Unchecked_type = counting_iterator; // Mark iterator as checked.
307
308 counting_iterator() : count_(0) {}
309
310 std::size_t count() const { return count_; }
311
312 counting_iterator& operator++() {
313 ++count_;
314 return *this;
315 }
316
317 counting_iterator operator++(int) {
318 auto it = *this;
319 ++*this;
320 return it;
321 }
322
323 T& operator*() const { return blackhole_; }
324 };
325
326 template <typename OutputIt> class truncating_iterator_base {
327 protected:
328 OutputIt out_;
329 std::size_t limit_;
330 std::size_t count_;
331
332 truncating_iterator_base(OutputIt out, std::size_t limit)
333 : out_(out), limit_(limit), count_(0) {}
334
335 public:
336 using iterator_category = std::output_iterator_tag;
337 using difference_type = void;
338 using pointer = void;
339 using reference = void;
340 using _Unchecked_type =
341 truncating_iterator_base; // Mark iterator as checked.
342
343 OutputIt base() const { return out_; }
344 std::size_t count() const { return count_; }
345 };
346
347 // An output iterator that truncates the output and counts the number of objects
348 // written to it.
349 template <typename OutputIt,
350 typename Enable = typename std::is_void<
351 typename std::iterator_traits<OutputIt>::value_type>::type>
352 class truncating_iterator;
353
354 template <typename OutputIt>
355 class truncating_iterator<OutputIt, std::false_type>
356 : public truncating_iterator_base<OutputIt> {
357 using traits = std::iterator_traits<OutputIt>;
358
359 mutable typename traits::value_type blackhole_;
360
361 public:
362 using value_type = typename traits::value_type;
363
364 truncating_iterator(OutputIt out, std::size_t limit)
365 : truncating_iterator_base<OutputIt>(out, limit) {}
366
367 truncating_iterator& operator++() {
368 if (this->count_++ < this->limit_) ++this->out_;
369 return *this;
370 }
371
372 truncating_iterator operator++(int) {
373 auto it = *this;
374 ++*this;
375 return it;
376 }
377
378 value_type& operator*() const {
379 return this->count_ < this->limit_ ? *this->out_ : blackhole_;
380 }
381 };
382
383 template <typename OutputIt>
384 class truncating_iterator<OutputIt, std::true_type>
385 : public truncating_iterator_base<OutputIt> {
386 public:
387 using value_type = typename OutputIt::container_type::value_type;
388
389 truncating_iterator(OutputIt out, std::size_t limit)
390 : truncating_iterator_base<OutputIt>(out, limit) {}
391
392 truncating_iterator& operator=(value_type val) {
393 if (this->count_++ < this->limit_) this->out_ = val;
394 return *this;
395 }
396
397 truncating_iterator& operator++() { return *this; }
398 truncating_iterator& operator++(int) { return *this; }
399 truncating_iterator& operator*() { return *this; }
400 };
401
402 // A range with the specified output iterator and value type.
403 template <typename OutputIt, typename T = typename OutputIt::value_type>
404 class output_range {
405 private:
406 OutputIt it_;
407
408 public:
409 using value_type = T;
410 using iterator = OutputIt;
411 struct sentinel {};
412
413 explicit output_range(OutputIt it) : it_(it) {}
414 OutputIt begin() const { return it_; }
415 sentinel end() const { return {}; } // Sentinel is not used yet.
416 };
417
418 // A range with an iterator appending to a buffer.
419 template <typename T>
420 class buffer_range
421 : public output_range<std::back_insert_iterator<buffer<T>>, T> {
422 public:
423 using iterator = std::back_insert_iterator<buffer<T>>;
424 using output_range<iterator, T>::output_range;
425 buffer_range(buffer<T>& buf)
426 : output_range<iterator, T>(std::back_inserter(buf)) {}
427 };
428
429 template <typename Char>
430 inline size_t count_code_points(basic_string_view<Char> s) {
431 return s.size();
432 }
433
434 // Counts the number of code points in a UTF-8 string.
435 inline size_t count_code_points(basic_string_view<char8_t> s) {
436 const char8_t* data = s.data();
437 size_t num_code_points = 0;
438 for (size_t i = 0, size = s.size(); i != size; ++i) {
439 if ((data[i] & 0xc0) != 0x80) ++num_code_points;
440 }
441 return num_code_points;
442 }
443
444 inline char8_t to_char8_t(char c) { return static_cast<char8_t>(c); }
445
446 template <typename InputIt, typename OutChar>
447 using needs_conversion = bool_constant<
448 std::is_same<typename std::iterator_traits<InputIt>::value_type,
449 char>::value &&
450 std::is_same<OutChar, char8_t>::value>;
451
452 template <typename OutChar, typename InputIt, typename OutputIt,
453 FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)>
454 OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
455 return std::copy(begin, end, it);
456 }
457
458 template <typename OutChar, typename InputIt, typename OutputIt,
459 FMT_ENABLE_IF(needs_conversion<InputIt, OutChar>::value)>
460 OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
461 return std::transform(begin, end, it, to_char8_t);
462 }
463
464 #ifndef FMT_USE_GRISU
465 # define FMT_USE_GRISU 0
466 #endif
467
468 template <typename T> constexpr bool use_grisu() {
469 return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559 &&
470 sizeof(T) <= sizeof(double);
471 }
472
473 template <typename T>
474 template <typename U>
475 void buffer<T>::append(const U* begin, const U* end) {
476 std::size_t new_size = size_ + to_unsigned(end - begin);
477 reserve(new_size);
478 std::uninitialized_copy(begin, end, make_checked(ptr_, capacity_) + size_);
479 size_ = new_size;
480 }
481 } // namespace internal
482
483 // A UTF-8 string view.
484 class u8string_view : public basic_string_view<char8_t> {
485 public:
486 u8string_view(const char* s)
487 : basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s)) {}
488 u8string_view(const char* s, size_t count) FMT_NOEXCEPT
489 : basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s), count) {
490 }
491 };
492
493 #if FMT_USE_USER_DEFINED_LITERALS
494 inline namespace literals {
495 inline u8string_view operator"" _u(const char* s, std::size_t n) {
496 return {s, n};
497 }
498 } // namespace literals
499 #endif
500
501 // The number of characters to store in the basic_memory_buffer object itself
502 // to avoid dynamic memory allocation.
503 enum { inline_buffer_size = 500 };
504
505 /**
506 \rst
507 A dynamically growing memory buffer for trivially copyable/constructible types
508 with the first ``SIZE`` elements stored in the object itself.
509
510 You can use one of the following type aliases for common character types:
511
512 +----------------+------------------------------+
513 | Type | Definition |
514 +================+==============================+
515 | memory_buffer | basic_memory_buffer<char> |
516 +----------------+------------------------------+
517 | wmemory_buffer | basic_memory_buffer<wchar_t> |
518 +----------------+------------------------------+
519
520 **Example**::
521
522 fmt::memory_buffer out;
523 format_to(out, "The answer is {}.", 42);
524
525 This will append the following output to the ``out`` object:
526
527 .. code-block:: none
528
529 The answer is 42.
530
531 The output can be converted to an ``std::string`` with ``to_string(out)``.
532 \endrst
533 */
534 template <typename T, std::size_t SIZE = inline_buffer_size,
535 typename Allocator = std::allocator<T>>
536 class basic_memory_buffer : private Allocator, public internal::buffer<T> {
537 private:
538 T store_[SIZE];
539
540 // Deallocate memory allocated by the buffer.
541 void deallocate() {
542 T* data = this->data();
543 if (data != store_) Allocator::deallocate(data, this->capacity());
544 }
545
546 protected:
547 void grow(std::size_t size) FMT_OVERRIDE;
548
549 public:
550 using value_type = T;
551 using const_reference = const T&;
552
553 explicit basic_memory_buffer(const Allocator& alloc = Allocator())
554 : Allocator(alloc) {
555 this->set(store_, SIZE);
556 }
557 ~basic_memory_buffer() { deallocate(); }
558
559 private:
560 // Move data from other to this buffer.
561 void move(basic_memory_buffer& other) {
562 Allocator &this_alloc = *this, &other_alloc = other;
563 this_alloc = std::move(other_alloc);
564 T* data = other.data();
565 std::size_t size = other.size(), capacity = other.capacity();
566 if (data == other.store_) {
567 this->set(store_, capacity);
568 std::uninitialized_copy(other.store_, other.store_ + size,
569 internal::make_checked(store_, capacity));
570 } else {
571 this->set(data, capacity);
572 // Set pointer to the inline array so that delete is not called
573 // when deallocating.
574 other.set(other.store_, 0);
575 }
576 this->resize(size);
577 }
578
579 public:
580 /**
581 \rst
582 Constructs a :class:`fmt::basic_memory_buffer` object moving the content
583 of the other object to it.
584 \endrst
585 */
586 basic_memory_buffer(basic_memory_buffer&& other) { move(other); }
587
588 /**
589 \rst
590 Moves the content of the other ``basic_memory_buffer`` object to this one.
591 \endrst
592 */
593 basic_memory_buffer& operator=(basic_memory_buffer&& other) {
594 assert(this != &other);
595 deallocate();
596 move(other);
597 return *this;
598 }
599
600 // Returns a copy of the allocator associated with this buffer.
601 Allocator get_allocator() const { return *this; }
602 };
603
604 template <typename T, std::size_t SIZE, typename Allocator>
605 void basic_memory_buffer<T, SIZE, Allocator>::grow(std::size_t size) {
606 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
607 if (size > 1000) throw std::runtime_error("fuzz mode - won't grow that much");
608 #endif
609 std::size_t old_capacity = this->capacity();
610 std::size_t new_capacity = old_capacity + old_capacity / 2;
611 if (size > new_capacity) new_capacity = size;
612 T* old_data = this->data();
613 T* new_data = std::allocator_traits<Allocator>::allocate(*this, new_capacity);
614 // The following code doesn't throw, so the raw pointer above doesn't leak.
615 std::uninitialized_copy(old_data, old_data + this->size(),
616 internal::make_checked(new_data, new_capacity));
617 this->set(new_data, new_capacity);
618 // deallocate must not throw according to the standard, but even if it does,
619 // the buffer already uses the new storage and will deallocate it in
620 // destructor.
621 if (old_data != store_) Allocator::deallocate(old_data, old_capacity);
622 }
623
624 using memory_buffer = basic_memory_buffer<char>;
625 using wmemory_buffer = basic_memory_buffer<wchar_t>;
626
627 /** A formatting error such as invalid format string. */
628 class FMT_API format_error : public std::runtime_error {
629 public:
630 explicit format_error(const char* message) : std::runtime_error(message) {}
631 explicit format_error(const std::string& message)
632 : std::runtime_error(message) {}
633 ~format_error() FMT_NOEXCEPT;
634 };
635
636 namespace internal {
637
638 // Returns true if value is negative, false otherwise.
639 // Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
640 template <typename T, FMT_ENABLE_IF(std::numeric_limits<T>::is_signed)>
641 FMT_CONSTEXPR bool is_negative(T value) {
642 return value < 0;
643 }
644 template <typename T, FMT_ENABLE_IF(!std::numeric_limits<T>::is_signed)>
645 FMT_CONSTEXPR bool is_negative(T) {
646 return false;
647 }
648
649 // Smallest of uint32_t and uint64_t that is large enough to represent all
650 // values of T.
651 template <typename T>
652 using uint32_or_64_t =
653 conditional_t<std::numeric_limits<T>::digits <= 32, uint32_t, uint64_t>;
654
655 // Static data is placed in this class template for the header-only config.
656 template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
657 static const uint64_t powers_of_10_64[];
658 static const uint32_t zero_or_powers_of_10_32[];
659 static const uint64_t zero_or_powers_of_10_64[];
660 static const uint64_t pow10_significands[];
661 static const int16_t pow10_exponents[];
662 static const char digits[];
663 static const char hex_digits[];
664 static const char foreground_color[];
665 static const char background_color[];
666 static const char reset_color[5];
667 static const wchar_t wreset_color[5];
668 };
669
670 FMT_EXTERN template struct basic_data<void>;
671
672 // This is a struct rather than an alias to avoid shadowing warnings in gcc.
673 struct data : basic_data<> {};
674
675 #ifdef FMT_BUILTIN_CLZLL
676 // Returns the number of decimal digits in n. Leading zeros are not counted
677 // except for n == 0 in which case count_digits returns 1.
678 inline int count_digits(uint64_t n) {
679 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
680 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
681 int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
682 return t - (n < data::zero_or_powers_of_10_64[t]) + 1;
683 }
684 #else
685 // Fallback version of count_digits used when __builtin_clz is not available.
686 inline int count_digits(uint64_t n) {
687 int count = 1;
688 for (;;) {
689 // Integer division is slow so do it for a group of four digits instead
690 // of for every digit. The idea comes from the talk by Alexandrescu
691 // "Three Optimization Tips for C++". See speed-test for a comparison.
692 if (n < 10) return count;
693 if (n < 100) return count + 1;
694 if (n < 1000) return count + 2;
695 if (n < 10000) return count + 3;
696 n /= 10000u;
697 count += 4;
698 }
699 }
700 #endif
701
702 // Counts the number of digits in n. BITS = log2(radix).
703 template <unsigned BITS, typename UInt> inline int count_digits(UInt n) {
704 int num_digits = 0;
705 do {
706 ++num_digits;
707 } while ((n >>= BITS) != 0);
708 return num_digits;
709 }
710
711 template <> int count_digits<4>(internal::fallback_uintptr n);
712
713 #if FMT_HAS_CPP_ATTRIBUTE(always_inline)
714 # define FMT_ALWAYS_INLINE __attribute__((always_inline))
715 #else
716 # define FMT_ALWAYS_INLINE
717 #endif
718
719 template <typename Handler>
720 inline char* lg(uint32_t n, Handler h) FMT_ALWAYS_INLINE;
721
722 // Computes g = floor(log10(n)) and calls h.on<g>(n);
723 template <typename Handler> inline char* lg(uint32_t n, Handler h) {
724 return n < 100 ? n < 10 ? h.template on<0>(n) : h.template on<1>(n)
725 : n < 1000000
726 ? n < 10000 ? n < 1000 ? h.template on<2>(n)
727 : h.template on<3>(n)
728 : n < 100000 ? h.template on<4>(n)
729 : h.template on<5>(n)
730 : n < 100000000 ? n < 10000000 ? h.template on<6>(n)
731 : h.template on<7>(n)
732 : n < 1000000000 ? h.template on<8>(n)
733 : h.template on<9>(n);
734 }
735
736 // An lg handler that formats a decimal number.
737 // Usage: lg(n, decimal_formatter(buffer));
738 class decimal_formatter {
739 private:
740 char* buffer_;
741
742 void write_pair(unsigned N, uint32_t index) {
743 std::memcpy(buffer_ + N, data::digits + index * 2, 2);
744 }
745
746 public:
747 explicit decimal_formatter(char* buf) : buffer_(buf) {}
748
749 template <unsigned N> char* on(uint32_t u) {
750 if (N == 0) {
751 *buffer_ = static_cast<char>(u) + '0';
752 } else if (N == 1) {
753 write_pair(0, u);
754 } else {
755 // The idea of using 4.32 fixed-point numbers is based on
756 // https://github.com/jeaiii/itoa
757 unsigned n = N - 1;
758 unsigned a = n / 5 * n * 53 / 16;
759 uint64_t t =
760 ((1ULL << (32 + a)) / data::zero_or_powers_of_10_32[n] + 1 - n / 9);
761 t = ((t * u) >> a) + n / 5 * 4;
762 write_pair(0, t >> 32);
763 for (unsigned i = 2; i < N; i += 2) {
764 t = 100ULL * static_cast<uint32_t>(t);
765 write_pair(i, t >> 32);
766 }
767 if (N % 2 == 0) {
768 buffer_[N] =
769 static_cast<char>((10ULL * static_cast<uint32_t>(t)) >> 32) + '0';
770 }
771 }
772 return buffer_ += N + 1;
773 }
774 };
775
776 #ifdef FMT_BUILTIN_CLZ
777 // Optional version of count_digits for better performance on 32-bit platforms.
778 inline int count_digits(uint32_t n) {
779 int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
780 return t - (n < data::zero_or_powers_of_10_32[t]) + 1;
781 }
782 #endif
783
784 template <typename Char> FMT_API Char thousands_sep_impl(locale_ref loc);
785 template <typename Char> inline Char thousands_sep(locale_ref loc) {
786 return Char(thousands_sep_impl<char>(loc));
787 }
788 template <> inline wchar_t thousands_sep(locale_ref loc) {
789 return thousands_sep_impl<wchar_t>(loc);
790 }
791
792 template <typename Char> FMT_API Char decimal_point_impl(locale_ref loc);
793 template <typename Char> inline Char decimal_point(locale_ref loc) {
794 return Char(decimal_point_impl<char>(loc));
795 }
796 template <> inline wchar_t decimal_point(locale_ref loc) {
797 return decimal_point_impl<wchar_t>(loc);
798 }
799
800 // Formats a decimal unsigned integer value writing into buffer.
801 // add_thousands_sep is called after writing each char to add a thousands
802 // separator if necessary.
803 template <typename UInt, typename Char, typename F>
804 inline Char* format_decimal(Char* buffer, UInt value, int num_digits,
805 F add_thousands_sep) {
806 FMT_ASSERT(num_digits >= 0, "invalid digit count");
807 buffer += num_digits;
808 Char* end = buffer;
809 while (value >= 100) {
810 // Integer division is slow so do it for a group of two digits instead
811 // of for every digit. The idea comes from the talk by Alexandrescu
812 // "Three Optimization Tips for C++". See speed-test for a comparison.
813 unsigned index = static_cast<unsigned>((value % 100) * 2);
814 value /= 100;
815 *--buffer = static_cast<Char>(data::digits[index + 1]);
816 add_thousands_sep(buffer);
817 *--buffer = static_cast<Char>(data::digits[index]);
818 add_thousands_sep(buffer);
819 }
820 if (value < 10) {
821 *--buffer = static_cast<Char>('0' + value);
822 return end;
823 }
824 unsigned index = static_cast<unsigned>(value * 2);
825 *--buffer = static_cast<Char>(data::digits[index + 1]);
826 add_thousands_sep(buffer);
827 *--buffer = static_cast<Char>(data::digits[index]);
828 return end;
829 }
830
831 template <typename Char, typename UInt, typename Iterator, typename F>
832 inline Iterator format_decimal(Iterator out, UInt value, int num_digits,
833 F add_thousands_sep) {
834 FMT_ASSERT(num_digits >= 0, "invalid digit count");
835 // Buffer should be large enough to hold all digits (<= digits10 + 1).
836 enum { max_size = std::numeric_limits<UInt>::digits10 + 1 };
837 Char buffer[max_size + max_size / 3];
838 auto end = format_decimal(buffer, value, num_digits, add_thousands_sep);
839 return internal::copy_str<Char>(buffer, end, out);
840 }
841
842 template <typename Char, typename It, typename UInt>
843 inline It format_decimal(It out, UInt value, int num_digits) {
844 return format_decimal<Char>(out, value, num_digits, [](Char*) {});
845 }
846
847 template <unsigned BASE_BITS, typename Char, typename UInt>
848 inline Char* format_uint(Char* buffer, UInt value, int num_digits,
849 bool upper = false) {
850 buffer += num_digits;
851 Char* end = buffer;
852 do {
853 const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits;
854 unsigned digit = (value & ((1 << BASE_BITS) - 1));
855 *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
856 : digits[digit]);
857 } while ((value >>= BASE_BITS) != 0);
858 return end;
859 }
860
861 template <unsigned BASE_BITS, typename Char>
862 Char* format_uint(Char* buffer, internal::fallback_uintptr n, int num_digits,
863 bool = false) {
864 auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
865 int start = (num_digits + char_digits - 1) / char_digits - 1;
866 if (int start_digits = num_digits % char_digits) {
867 unsigned value = n.value[start--];
868 buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
869 }
870 for (; start >= 0; --start) {
871 unsigned value = n.value[start];
872 buffer += char_digits;
873 auto p = buffer;
874 for (int i = 0; i < char_digits; ++i) {
875 unsigned digit = (value & ((1 << BASE_BITS) - 1));
876 *--p = static_cast<Char>(data::hex_digits[digit]);
877 value >>= BASE_BITS;
878 }
879 }
880 return buffer;
881 }
882
883 template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
884 inline It format_uint(It out, UInt value, int num_digits, bool upper = false) {
885 // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
886 char buffer[std::numeric_limits<UInt>::digits / BASE_BITS + 1];
887 format_uint<BASE_BITS>(buffer, value, num_digits, upper);
888 return internal::copy_str<Char>(buffer, buffer + num_digits, out);
889 }
890
891 #ifndef _WIN32
892 # define FMT_USE_WINDOWS_H 0
893 #elif !defined(FMT_USE_WINDOWS_H)
894 # define FMT_USE_WINDOWS_H 1
895 #endif
896
897 // Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
898 // All the functionality that relies on it will be disabled too.
899 #if FMT_USE_WINDOWS_H
900 // A converter from UTF-8 to UTF-16.
901 // It is only provided for Windows since other systems support UTF-8 natively.
902 class utf8_to_utf16 {
903 private:
904 wmemory_buffer buffer_;
905
906 public:
907 FMT_API explicit utf8_to_utf16(string_view s);
908 operator wstring_view() const { return wstring_view(&buffer_[0], size()); }
909 size_t size() const { return buffer_.size() - 1; }
910 const wchar_t* c_str() const { return &buffer_[0]; }
911 std::wstring str() const { return std::wstring(&buffer_[0], size()); }
912 };
913
914 // A converter from UTF-16 to UTF-8.
915 // It is only provided for Windows since other systems support UTF-8 natively.
916 class utf16_to_utf8 {
917 private:
918 memory_buffer buffer_;
919
920 public:
921 utf16_to_utf8() {}
922 FMT_API explicit utf16_to_utf8(wstring_view s);
923 operator string_view() const { return string_view(&buffer_[0], size()); }
924 size_t size() const { return buffer_.size() - 1; }
925 const char* c_str() const { return &buffer_[0]; }
926 std::string str() const { return std::string(&buffer_[0], size()); }
927
928 // Performs conversion returning a system error code instead of
929 // throwing exception on conversion error. This method may still throw
930 // in case of memory allocation error.
931 FMT_API int convert(wstring_view s);
932 };
933
934 FMT_API void format_windows_error(fmt::internal::buffer<char>& out,
935 int error_code,
936 fmt::string_view message) FMT_NOEXCEPT;
937 #endif
938
939 template <typename T = void> struct null {};
940
941 // Workaround an array initialization issue in gcc 4.8.
942 template <typename Char> struct fill_t {
943 private:
944 Char data_[6];
945
946 public:
947 FMT_CONSTEXPR Char& operator[](size_t index) { return data_[index]; }
948 FMT_CONSTEXPR const Char& operator[](size_t index) const {
949 return data_[index];
950 }
951
952 static FMT_CONSTEXPR fill_t<Char> make() {
953 auto fill = fill_t<Char>();
954 fill[0] = Char(' ');
955 return fill;
956 }
957 };
958 } // namespace internal
959
960 // We cannot use enum classes as bit fields because of a gcc bug
961 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
962 namespace align {
963 enum type { none, left, right, center, numeric };
964 }
965 using align_t = align::type;
966
967 namespace sign {
968 enum type { none, minus, plus, space };
969 }
970 using sign_t = sign::type;
971
972 // Format specifiers for built-in and string types.
973 template <typename Char> struct basic_format_specs {
974 int width;
975 int precision;
976 char type;
977 align_t align : 4;
978 sign_t sign : 3;
979 bool alt : 1; // Alternate form ('#').
980 internal::fill_t<Char> fill;
981
982 constexpr basic_format_specs()
983 : width(0),
984 precision(-1),
985 type(0),
986 align(align::none),
987 sign(sign::none),
988 alt(false),
989 fill(internal::fill_t<Char>::make()) {}
990 };
991
992 using format_specs = basic_format_specs<char>;
993
994 namespace internal {
995
996 // Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
997 template <typename Char, typename It> It write_exponent(int exp, It it) {
998 FMT_ASSERT(-1000 < exp && exp < 1000, "exponent out of range");
999 if (exp < 0) {
1000 *it++ = static_cast<Char>('-');
1001 exp = -exp;
1002 } else {
1003 *it++ = static_cast<Char>('+');
1004 }
1005 if (exp >= 100) {
1006 *it++ = static_cast<Char>(static_cast<char>('0' + exp / 100));
1007 exp %= 100;
1008 }
1009 const char* d = data::digits + exp * 2;
1010 *it++ = static_cast<Char>(d[0]);
1011 *it++ = static_cast<Char>(d[1]);
1012 return it;
1013 }
1014
1015 struct gen_digits_params {
1016 int num_digits;
1017 bool fixed;
1018 bool upper;
1019 bool trailing_zeros;
1020 };
1021
1022 // The number is given as v = digits * pow(10, exp).
1023 template <typename Char, typename It>
1024 It grisu_prettify(const char* digits, int size, int exp, It it,
1025 gen_digits_params params, Char decimal_point) {
1026 // pow(10, full_exp - 1) <= v <= pow(10, full_exp).
1027 int full_exp = size + exp;
1028 if (!params.fixed) {
1029 // Insert a decimal point after the first digit and add an exponent.
1030 *it++ = static_cast<Char>(*digits);
1031 if (size > 1) *it++ = decimal_point;
1032 exp += size - 1;
1033 it = copy_str<Char>(digits + 1, digits + size, it);
1034 if (size < params.num_digits)
1035 it = std::fill_n(it, params.num_digits - size, static_cast<Char>('0'));
1036 *it++ = static_cast<Char>(params.upper ? 'E' : 'e');
1037 return write_exponent<Char>(exp, it);
1038 }
1039 if (size <= full_exp) {
1040 // 1234e7 -> 12340000000[.0+]
1041 it = copy_str<Char>(digits, digits + size, it);
1042 it = std::fill_n(it, full_exp - size, static_cast<Char>('0'));
1043 int num_zeros = (std::max)(params.num_digits - full_exp, 1);
1044 if (params.trailing_zeros) {
1045 *it++ = decimal_point;
1046 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1047 if (num_zeros > 1000)
1048 throw std::runtime_error("fuzz mode - avoiding excessive cpu use");
1049 #endif
1050 it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
1051 }
1052 } else if (full_exp > 0) {
1053 // 1234e-2 -> 12.34[0+]
1054 it = copy_str<Char>(digits, digits + full_exp, it);
1055 if (!params.trailing_zeros) {
1056 // Remove trailing zeros.
1057 while (size > full_exp && digits[size - 1] == '0') --size;
1058 if (size != full_exp) *it++ = decimal_point;
1059 return copy_str<Char>(digits + full_exp, digits + size, it);
1060 }
1061 *it++ = decimal_point;
1062 it = copy_str<Char>(digits + full_exp, digits + size, it);
1063 if (params.num_digits > size) {
1064 // Add trailing zeros.
1065 int num_zeros = params.num_digits - size;
1066 it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
1067 }
1068 } else {
1069 // 1234e-6 -> 0.001234
1070 *it++ = static_cast<Char>('0');
1071 int num_zeros = -full_exp;
1072 if (params.num_digits >= 0 && params.num_digits < num_zeros)
1073 num_zeros = params.num_digits;
1074 if (!params.trailing_zeros)
1075 while (size > 0 && digits[size - 1] == '0') --size;
1076 if (num_zeros != 0 || size != 0) {
1077 *it++ = decimal_point;
1078 it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
1079 it = copy_str<Char>(digits, digits + size, it);
1080 }
1081 }
1082 return it;
1083 }
1084
1085 namespace grisu_options {
1086 enum { fixed = 1, grisu3 = 2 };
1087 }
1088
1089 // Formats value using the Grisu algorithm:
1090 // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
1091 template <typename Double, FMT_ENABLE_IF(sizeof(Double) == sizeof(uint64_t))>
1092 FMT_API bool grisu_format(Double, buffer<char>&, int, unsigned, int&);
1093 template <typename Double, FMT_ENABLE_IF(sizeof(Double) != sizeof(uint64_t))>
1094 inline bool grisu_format(Double, buffer<char>&, int, unsigned, int&) {
1095 return false;
1096 }
1097
1098 struct sprintf_specs {
1099 int precision;
1100 char type;
1101 bool alt : 1;
1102
1103 template <typename Char>
1104 constexpr sprintf_specs(basic_format_specs<Char> specs)
1105 : precision(specs.precision), type(specs.type), alt(specs.alt) {}
1106
1107 constexpr bool has_precision() const { return precision >= 0; }
1108 };
1109
1110 template <typename Double>
1111 char* sprintf_format(Double, internal::buffer<char>&, sprintf_specs);
1112
1113 template <typename Handler>
1114 FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) {
1115 switch (spec) {
1116 case 0:
1117 case 'd':
1118 handler.on_dec();
1119 break;
1120 case 'x':
1121 case 'X':
1122 handler.on_hex();
1123 break;
1124 case 'b':
1125 case 'B':
1126 handler.on_bin();
1127 break;
1128 case 'o':
1129 handler.on_oct();
1130 break;
1131 case 'n':
1132 handler.on_num();
1133 break;
1134 default:
1135 handler.on_error();
1136 }
1137 }
1138
1139 template <typename Handler>
1140 FMT_CONSTEXPR void handle_float_type_spec(char spec, Handler&& handler) {
1141 switch (spec) {
1142 case 0:
1143 case 'g':
1144 case 'G':
1145 handler.on_general();
1146 break;
1147 case 'e':
1148 case 'E':
1149 handler.on_exp();
1150 break;
1151 case 'f':
1152 case 'F':
1153 handler.on_fixed();
1154 break;
1155 case '%':
1156 handler.on_percent();
1157 break;
1158 case 'a':
1159 case 'A':
1160 handler.on_hex();
1161 break;
1162 case 'n':
1163 handler.on_num();
1164 break;
1165 default:
1166 handler.on_error();
1167 break;
1168 }
1169 }
1170
1171 template <typename Char, typename Handler>
1172 FMT_CONSTEXPR void handle_char_specs(const basic_format_specs<Char>* specs,
1173 Handler&& handler) {
1174 if (!specs) return handler.on_char();
1175 if (specs->type && specs->type != 'c') return handler.on_int();
1176 if (specs->align == align::numeric || specs->sign != sign::none || specs->alt)
1177 handler.on_error("invalid format specifier for char");
1178 handler.on_char();
1179 }
1180
1181 template <typename Char, typename Handler>
1182 FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler&& handler) {
1183 if (spec == 0 || spec == 's')
1184 handler.on_string();
1185 else if (spec == 'p')
1186 handler.on_pointer();
1187 else
1188 handler.on_error("invalid type specifier");
1189 }
1190
1191 template <typename Char, typename ErrorHandler>
1192 FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler&& eh) {
1193 if (spec != 0 && spec != 's') eh.on_error("invalid type specifier");
1194 }
1195
1196 template <typename Char, typename ErrorHandler>
1197 FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler&& eh) {
1198 if (spec != 0 && spec != 'p') eh.on_error("invalid type specifier");
1199 }
1200
1201 template <typename ErrorHandler> class int_type_checker : private ErrorHandler {
1202 public:
1203 FMT_CONSTEXPR explicit int_type_checker(ErrorHandler eh) : ErrorHandler(eh) {}
1204
1205 FMT_CONSTEXPR void on_dec() {}
1206 FMT_CONSTEXPR void on_hex() {}
1207 FMT_CONSTEXPR void on_bin() {}
1208 FMT_CONSTEXPR void on_oct() {}
1209 FMT_CONSTEXPR void on_num() {}
1210
1211 FMT_CONSTEXPR void on_error() {
1212 ErrorHandler::on_error("invalid type specifier");
1213 }
1214 };
1215
1216 template <typename ErrorHandler>
1217 class float_type_checker : private ErrorHandler {
1218 public:
1219 FMT_CONSTEXPR explicit float_type_checker(ErrorHandler eh)
1220 : ErrorHandler(eh) {}
1221
1222 FMT_CONSTEXPR void on_general() {}
1223 FMT_CONSTEXPR void on_exp() {}
1224 FMT_CONSTEXPR void on_fixed() {}
1225 FMT_CONSTEXPR void on_percent() {}
1226 FMT_CONSTEXPR void on_hex() {}
1227 FMT_CONSTEXPR void on_num() {}
1228
1229 FMT_CONSTEXPR void on_error() {
1230 ErrorHandler::on_error("invalid type specifier");
1231 }
1232 };
1233
1234 template <typename ErrorHandler>
1235 class char_specs_checker : public ErrorHandler {
1236 private:
1237 char type_;
1238
1239 public:
1240 FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
1241 : ErrorHandler(eh), type_(type) {}
1242
1243 FMT_CONSTEXPR void on_int() {
1244 handle_int_type_spec(type_, int_type_checker<ErrorHandler>(*this));
1245 }
1246 FMT_CONSTEXPR void on_char() {}
1247 };
1248
1249 template <typename ErrorHandler>
1250 class cstring_type_checker : public ErrorHandler {
1251 public:
1252 FMT_CONSTEXPR explicit cstring_type_checker(ErrorHandler eh)
1253 : ErrorHandler(eh) {}
1254
1255 FMT_CONSTEXPR void on_string() {}
1256 FMT_CONSTEXPR void on_pointer() {}
1257 };
1258
1259 template <typename Context>
1260 void arg_map<Context>::init(const basic_format_args<Context>& args) {
1261 if (map_) return;
1262 map_ = new entry[internal::to_unsigned(args.max_size())];
1263 if (args.is_packed()) {
1264 for (int i = 0;; ++i) {
1265 internal::type arg_type = args.type(i);
1266 if (arg_type == internal::none_type) return;
1267 if (arg_type == internal::named_arg_type) push_back(args.values_[i]);
1268 }
1269 }
1270 for (int i = 0, n = args.max_size(); i < n; ++i) {
1271 auto type = args.args_[i].type_;
1272 if (type == internal::named_arg_type) push_back(args.args_[i].value_);
1273 }
1274 }
1275
1276 // This template provides operations for formatting and writing data into a
1277 // character range.
1278 template <typename Range> class basic_writer {
1279 public:
1280 using char_type = typename Range::value_type;
1281 using iterator = typename Range::iterator;
1282 using format_specs = basic_format_specs<char_type>;
1283
1284 private:
1285 iterator out_; // Output iterator.
1286 internal::locale_ref locale_;
1287
1288 // Attempts to reserve space for n extra characters in the output range.
1289 // Returns a pointer to the reserved range or a reference to out_.
1290 auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) {
1291 return internal::reserve(out_, n);
1292 }
1293
1294 template <typename F> struct padded_int_writer {
1295 size_t size_;
1296 string_view prefix;
1297 char_type fill;
1298 std::size_t padding;
1299 F f;
1300
1301 size_t size() const { return size_; }
1302 size_t width() const { return size_; }
1303
1304 template <typename It> void operator()(It&& it) const {
1305 if (prefix.size() != 0)
1306 it = internal::copy_str<char_type>(prefix.begin(), prefix.end(), it);
1307 it = std::fill_n(it, padding, fill);
1308 f(it);
1309 }
1310 };
1311
1312 // Writes an integer in the format
1313 // <left-padding><prefix><numeric-padding><digits><right-padding>
1314 // where <digits> are written by f(it).
1315 template <typename F>
1316 void write_int(int num_digits, string_view prefix, format_specs specs, F f) {
1317 std::size_t size = prefix.size() + internal::to_unsigned(num_digits);
1318 char_type fill = specs.fill[0];
1319 std::size_t padding = 0;
1320 if (specs.align == align::numeric) {
1321 auto unsiged_width = internal::to_unsigned(specs.width);
1322 if (unsiged_width > size) {
1323 padding = unsiged_width - size;
1324 size = unsiged_width;
1325 }
1326 } else if (specs.precision > num_digits) {
1327 size = prefix.size() + internal::to_unsigned(specs.precision);
1328 padding = internal::to_unsigned(specs.precision - num_digits);
1329 fill = static_cast<char_type>('0');
1330 }
1331 if (specs.align == align::none) specs.align = align::right;
1332 write_padded(specs, padded_int_writer<F>{size, prefix, fill, padding, f});
1333 }
1334
1335 // Writes a decimal integer.
1336 template <typename Int> void write_decimal(Int value) {
1337 auto abs_value = static_cast<uint32_or_64_t<Int>>(value);
1338 bool is_negative = internal::is_negative(value);
1339 if (is_negative) abs_value = 0 - abs_value;
1340 int num_digits = internal::count_digits(abs_value);
1341 auto&& it =
1342 reserve((is_negative ? 1 : 0) + static_cast<size_t>(num_digits));
1343 if (is_negative) *it++ = static_cast<char_type>('-');
1344 it = internal::format_decimal<char_type>(it, abs_value, num_digits);
1345 }
1346
1347 // The handle_int_type_spec handler that writes an integer.
1348 template <typename Int, typename Specs> struct int_writer {
1349 using unsigned_type = uint32_or_64_t<Int>;
1350
1351 basic_writer<Range>& writer;
1352 const Specs& specs;
1353 unsigned_type abs_value;
1354 char prefix[4];
1355 unsigned prefix_size;
1356
1357 string_view get_prefix() const { return string_view(prefix, prefix_size); }
1358
1359 int_writer(basic_writer<Range>& w, Int value, const Specs& s)
1360 : writer(w),
1361 specs(s),
1362 abs_value(static_cast<unsigned_type>(value)),
1363 prefix_size(0) {
1364 if (internal::is_negative(value)) {
1365 prefix[0] = '-';
1366 ++prefix_size;
1367 abs_value = 0 - abs_value;
1368 } else if (specs.sign != sign::none && specs.sign != sign::minus) {
1369 prefix[0] = specs.sign == sign::plus ? '+' : ' ';
1370 ++prefix_size;
1371 }
1372 }
1373
1374 struct dec_writer {
1375 unsigned_type abs_value;
1376 int num_digits;
1377
1378 template <typename It> void operator()(It&& it) const {
1379 it = internal::format_decimal<char_type>(it, abs_value, num_digits);
1380 }
1381 };
1382
1383 void on_dec() {
1384 int num_digits = internal::count_digits(abs_value);
1385 writer.write_int(num_digits, get_prefix(), specs,
1386 dec_writer{abs_value, num_digits});
1387 }
1388
1389 struct hex_writer {
1390 int_writer& self;
1391 int num_digits;
1392
1393 template <typename It> void operator()(It&& it) const {
1394 it = internal::format_uint<4, char_type>(it, self.abs_value, num_digits,
1395 self.specs.type != 'x');
1396 }
1397 };
1398
1399 void on_hex() {
1400 if (specs.alt) {
1401 prefix[prefix_size++] = '0';
1402 prefix[prefix_size++] = specs.type;
1403 }
1404 int num_digits = internal::count_digits<4>(abs_value);
1405 writer.write_int(num_digits, get_prefix(), specs,
1406 hex_writer{*this, num_digits});
1407 }
1408
1409 template <int BITS> struct bin_writer {
1410 unsigned_type abs_value;
1411 int num_digits;
1412
1413 template <typename It> void operator()(It&& it) const {
1414 it = internal::format_uint<BITS, char_type>(it, abs_value, num_digits);
1415 }
1416 };
1417
1418 void on_bin() {
1419 if (specs.alt) {
1420 prefix[prefix_size++] = '0';
1421 prefix[prefix_size++] = static_cast<char>(specs.type);
1422 }
1423 int num_digits = internal::count_digits<1>(abs_value);
1424 writer.write_int(num_digits, get_prefix(), specs,
1425 bin_writer<1>{abs_value, num_digits});
1426 }
1427
1428 void on_oct() {
1429 int num_digits = internal::count_digits<3>(abs_value);
1430 if (specs.alt && specs.precision <= num_digits) {
1431 // Octal prefix '0' is counted as a digit, so only add it if precision
1432 // is not greater than the number of digits.
1433 prefix[prefix_size++] = '0';
1434 }
1435 writer.write_int(num_digits, get_prefix(), specs,
1436 bin_writer<3>{abs_value, num_digits});
1437 }
1438
1439 enum { sep_size = 1 };
1440
1441 struct num_writer {
1442 unsigned_type abs_value;
1443 int size;
1444 char_type sep;
1445
1446 template <typename It> void operator()(It&& it) const {
1447 basic_string_view<char_type> s(&sep, sep_size);
1448 // Index of a decimal digit with the least significant digit having
1449 // index 0.
1450 unsigned digit_index = 0;
1451 it = internal::format_decimal<char_type>(
1452 it, abs_value, size, [s, &digit_index](char_type*& buffer) {
1453 if (++digit_index % 3 != 0) return;
1454 buffer -= s.size();
1455 std::uninitialized_copy(s.data(), s.data() + s.size(),
1456 internal::make_checked(buffer, s.size()));
1457 });
1458 }
1459 };
1460
1461 void on_num() {
1462 char_type sep = internal::thousands_sep<char_type>(writer.locale_);
1463 if (!sep) return on_dec();
1464 int num_digits = internal::count_digits(abs_value);
1465 int size = num_digits + sep_size * ((num_digits - 1) / 3);
1466 writer.write_int(size, get_prefix(), specs,
1467 num_writer{abs_value, size, sep});
1468 }
1469
1470 FMT_NORETURN void on_error() {
1471 FMT_THROW(format_error("invalid type specifier"));
1472 }
1473 };
1474
1475 enum { inf_size = 3 }; // This is an enum to workaround a bug in MSVC.
1476
1477 struct inf_or_nan_writer {
1478 char sign;
1479 bool as_percentage;
1480 const char* str;
1481
1482 size_t size() const {
1483 return static_cast<std::size_t>(inf_size + (sign ? 1 : 0) +
1484 (as_percentage ? 1 : 0));
1485 }
1486 size_t width() const { return size(); }
1487
1488 template <typename It> void operator()(It&& it) const {
1489 if (sign) *it++ = static_cast<char_type>(sign);
1490 it = internal::copy_str<char_type>(
1491 str, str + static_cast<std::size_t>(inf_size), it);
1492 if (as_percentage) *it++ = static_cast<char_type>('%');
1493 }
1494 };
1495
1496 struct double_writer {
1497 char sign;
1498 internal::buffer<char>& buffer;
1499 char* decimal_point_pos;
1500 char_type decimal_point;
1501
1502 size_t size() const { return buffer.size() + (sign ? 1 : 0); }
1503 size_t width() const { return size(); }
1504
1505 template <typename It> void operator()(It&& it) {
1506 if (sign) *it++ = static_cast<char_type>(sign);
1507 auto begin = buffer.begin();
1508 if (decimal_point_pos) {
1509 it = internal::copy_str<char_type>(begin, decimal_point_pos, it);
1510 *it++ = decimal_point;
1511 begin = decimal_point_pos + 1;
1512 }
1513 it = internal::copy_str<char_type>(begin, buffer.end(), it);
1514 }
1515 };
1516
1517 class grisu_writer {
1518 private:
1519 internal::buffer<char>& digits_;
1520 size_t size_;
1521 char sign_;
1522 int exp_;
1523 internal::gen_digits_params params_;
1524 char_type decimal_point_;
1525
1526 public:
1527 grisu_writer(char sign, internal::buffer<char>& digits, int exp,
1528 const internal::gen_digits_params& params,
1529 char_type decimal_point)
1530 : digits_(digits),
1531 sign_(sign),
1532 exp_(exp),
1533 params_(params),
1534 decimal_point_(decimal_point) {
1535 int num_digits = static_cast<int>(digits.size());
1536 int full_exp = num_digits + exp - 1;
1537 int precision = params.num_digits > 0 ? params.num_digits : 11;
1538 params_.fixed |= full_exp >= -4 && full_exp < precision;
1539 auto it = internal::grisu_prettify<char>(
1540 digits.data(), num_digits, exp, internal::counting_iterator<char>(),
1541 params_, '.');
1542 size_ = it.count();
1543 }
1544
1545 size_t size() const { return size_ + (sign_ ? 1 : 0); }
1546 size_t width() const { return size(); }
1547
1548 template <typename It> void operator()(It&& it) {
1549 if (sign_) *it++ = static_cast<char_type>(sign_);
1550 int num_digits = static_cast<int>(digits_.size());
1551 it = internal::grisu_prettify<char_type>(digits_.data(), num_digits, exp_,
1552 it, params_, decimal_point_);
1553 }
1554 };
1555
1556 template <typename Char> struct str_writer {
1557 const Char* s;
1558 size_t size_;
1559
1560 size_t size() const { return size_; }
1561 size_t width() const {
1562 return internal::count_code_points(basic_string_view<Char>(s, size_));
1563 }
1564
1565 template <typename It> void operator()(It&& it) const {
1566 it = internal::copy_str<char_type>(s, s + size_, it);
1567 }
1568 };
1569
1570 template <typename UIntPtr> struct pointer_writer {
1571 UIntPtr value;
1572 int num_digits;
1573
1574 size_t size() const { return to_unsigned(num_digits) + 2; }
1575 size_t width() const { return size(); }
1576
1577 template <typename It> void operator()(It&& it) const {
1578 *it++ = static_cast<char_type>('0');
1579 *it++ = static_cast<char_type>('x');
1580 it = internal::format_uint<4, char_type>(it, value, num_digits);
1581 }
1582 };
1583
1584 public:
1585 /** Constructs a ``basic_writer`` object. */
1586 explicit basic_writer(Range out,
1587 internal::locale_ref loc = internal::locale_ref())
1588 : out_(out.begin()), locale_(loc) {}
1589
1590 iterator out() const { return out_; }
1591
1592 // Writes a value in the format
1593 // <left-padding><value><right-padding>
1594 // where <value> is written by f(it).
1595 template <typename F> void write_padded(const format_specs& specs, F&& f) {
1596 // User-perceived width (in code points).
1597 unsigned width = to_unsigned(specs.width);
1598 size_t size = f.size(); // The number of code units.
1599 size_t num_code_points = width != 0 ? f.width() : size;
1600 if (width <= num_code_points) return f(reserve(size));
1601 auto&& it = reserve(width + (size - num_code_points));
1602 char_type fill = specs.fill[0];
1603 std::size_t padding = width - num_code_points;
1604 if (specs.align == align::right) {
1605 it = std::fill_n(it, padding, fill);
1606 f(it);
1607 } else if (specs.align == align::center) {
1608 std::size_t left_padding = padding / 2;
1609 it = std::fill_n(it, left_padding, fill);
1610 f(it);
1611 it = std::fill_n(it, padding - left_padding, fill);
1612 } else {
1613 f(it);
1614 it = std::fill_n(it, padding, fill);
1615 }
1616 }
1617
1618 void write(int value) { write_decimal(value); }
1619 void write(long value) { write_decimal(value); }
1620 void write(long long value) { write_decimal(value); }
1621
1622 void write(unsigned value) { write_decimal(value); }
1623 void write(unsigned long value) { write_decimal(value); }
1624 void write(unsigned long long value) { write_decimal(value); }
1625
1626 // Writes a formatted integer.
1627 template <typename T, typename Spec>
1628 void write_int(T value, const Spec& spec) {
1629 internal::handle_int_type_spec(spec.type,
1630 int_writer<T, Spec>(*this, value, spec));
1631 }
1632
1633 void write(double value, const format_specs& specs = format_specs()) {
1634 write_double(value, specs);
1635 }
1636
1637 /**
1638 \rst
1639 Formats *value* using the general format for floating-point numbers
1640 (``'g'``) and writes it to the buffer.
1641 \endrst
1642 */
1643 void write(long double value, const format_specs& specs = format_specs()) {
1644 write_double(value, specs);
1645 }
1646
1647 // Formats a floating-point number (double or long double).
1648 template <typename T, bool USE_GRISU = fmt::internal::use_grisu<T>()>
1649 void write_double(T value, const format_specs& specs);
1650
1651 /** Writes a character to the buffer. */
1652 void write(char value) {
1653 auto&& it = reserve(1);
1654 *it++ = value;
1655 }
1656
1657 template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char_type>::value)>
1658 void write(Char value) {
1659 auto&& it = reserve(1);
1660 *it++ = value;
1661 }
1662
1663 /**
1664 \rst
1665 Writes *value* to the buffer.
1666 \endrst
1667 */
1668 void write(string_view value) {
1669 auto&& it = reserve(value.size());
1670 it = internal::copy_str<char_type>(value.begin(), value.end(), it);
1671 }
1672 void write(wstring_view value) {
1673 static_assert(std::is_same<char_type, wchar_t>::value, "");
1674 auto&& it = reserve(value.size());
1675 it = std::copy(value.begin(), value.end(), it);
1676 }
1677
1678 // Writes a formatted string.
1679 template <typename Char>
1680 void write(const Char* s, std::size_t size, const format_specs& specs) {
1681 write_padded(specs, str_writer<Char>{s, size});
1682 }
1683
1684 template <typename Char>
1685 void write(basic_string_view<Char> s,
1686 const format_specs& specs = format_specs()) {
1687 const Char* data = s.data();
1688 std::size_t size = s.size();
1689 if (specs.precision >= 0 && internal::to_unsigned(specs.precision) < size)
1690 size = internal::to_unsigned(specs.precision);
1691 write(data, size, specs);
1692 }
1693
1694 template <typename UIntPtr>
1695 void write_pointer(UIntPtr value, const format_specs* specs) {
1696 int num_digits = internal::count_digits<4>(value);
1697 auto pw = pointer_writer<UIntPtr>{value, num_digits};
1698 if (!specs) return pw(reserve(to_unsigned(num_digits) + 2));
1699 format_specs specs_copy = *specs;
1700 if (specs_copy.align == align::none) specs_copy.align = align::right;
1701 write_padded(specs_copy, pw);
1702 }
1703 };
1704
1705 using writer = basic_writer<buffer_range<char>>;
1706
1707 template <typename Range, typename ErrorHandler = internal::error_handler>
1708 class arg_formatter_base {
1709 public:
1710 using char_type = typename Range::value_type;
1711 using iterator = typename Range::iterator;
1712 using format_specs = basic_format_specs<char_type>;
1713
1714 private:
1715 using writer_type = basic_writer<Range>;
1716 writer_type writer_;
1717 format_specs* specs_;
1718
1719 struct char_writer {
1720 char_type value;
1721
1722 size_t size() const { return 1; }
1723 size_t width() const { return 1; }
1724
1725 template <typename It> void operator()(It&& it) const { *it++ = value; }
1726 };
1727
1728 void write_char(char_type value) {
1729 if (specs_)
1730 writer_.write_padded(*specs_, char_writer{value});
1731 else
1732 writer_.write(value);
1733 }
1734
1735 void write_pointer(const void* p) {
1736 writer_.write_pointer(internal::bit_cast<internal::uintptr_t>(p), specs_);
1737 }
1738
1739 protected:
1740 writer_type& writer() { return writer_; }
1741 FMT_DEPRECATED format_specs* spec() { return specs_; }
1742 format_specs* specs() { return specs_; }
1743 iterator out() { return writer_.out(); }
1744
1745 void write(bool value) {
1746 string_view sv(value ? "true" : "false");
1747 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
1748 }
1749
1750 void write(const char_type* value) {
1751 if (!value) {
1752 FMT_THROW(format_error("string pointer is null"));
1753 } else {
1754 auto length = std::char_traits<char_type>::length(value);
1755 basic_string_view<char_type> sv(value, length);
1756 specs_ ? writer_.write(sv, *specs_) : writer_.write(sv);
1757 }
1758 }
1759
1760 public:
1761 arg_formatter_base(Range r, format_specs* s, locale_ref loc)
1762 : writer_(r, loc), specs_(s) {}
1763
1764 iterator operator()(monostate) {
1765 FMT_ASSERT(false, "invalid argument type");
1766 return out();
1767 }
1768
1769 template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
1770 iterator operator()(T value) {
1771 if (specs_)
1772 writer_.write_int(value, *specs_);
1773 else
1774 writer_.write(value);
1775 return out();
1776 }
1777
1778 iterator operator()(char_type value) {
1779 internal::handle_char_specs(
1780 specs_, char_spec_handler(*this, static_cast<char_type>(value)));
1781 return out();
1782 }
1783
1784 iterator operator()(bool value) {
1785 if (specs_ && specs_->type) return (*this)(value ? 1 : 0);
1786 write(value != 0);
1787 return out();
1788 }
1789
1790 template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
1791 iterator operator()(T value) {
1792 writer_.write_double(value, specs_ ? *specs_ : format_specs());
1793 return out();
1794 }
1795
1796 struct char_spec_handler : ErrorHandler {
1797 arg_formatter_base& formatter;
1798 char_type value;
1799
1800 char_spec_handler(arg_formatter_base& f, char_type val)
1801 : formatter(f), value(val) {}
1802
1803 void on_int() {
1804 if (formatter.specs_)
1805 formatter.writer_.write_int(value, *formatter.specs_);
1806 else
1807 formatter.writer_.write(value);
1808 }
1809 void on_char() { formatter.write_char(value); }
1810 };
1811
1812 struct cstring_spec_handler : internal::error_handler {
1813 arg_formatter_base& formatter;
1814 const char_type* value;
1815
1816 cstring_spec_handler(arg_formatter_base& f, const char_type* val)
1817 : formatter(f), value(val) {}
1818
1819 void on_string() { formatter.write(value); }
1820 void on_pointer() { formatter.write_pointer(value); }
1821 };
1822
1823 iterator operator()(const char_type* value) {
1824 if (!specs_) return write(value), out();
1825 internal::handle_cstring_type_spec(specs_->type,
1826 cstring_spec_handler(*this, value));
1827 return out();
1828 }
1829
1830 iterator operator()(basic_string_view<char_type> value) {
1831 if (specs_) {
1832 internal::check_string_type_spec(specs_->type, internal::error_handler());
1833 writer_.write(value, *specs_);
1834 } else {
1835 writer_.write(value);
1836 }
1837 return out();
1838 }
1839
1840 iterator operator()(const void* value) {
1841 if (specs_)
1842 check_pointer_type_spec(specs_->type, internal::error_handler());
1843 write_pointer(value);
1844 return out();
1845 }
1846 };
1847
1848 template <typename Char> FMT_CONSTEXPR bool is_name_start(Char c) {
1849 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
1850 }
1851
1852 // Parses the range [begin, end) as an unsigned integer. This function assumes
1853 // that the range is non-empty and the first character is a digit.
1854 template <typename Char, typename ErrorHandler>
1855 FMT_CONSTEXPR int parse_nonnegative_int(const Char*& begin, const Char* end,
1856 ErrorHandler&& eh) {
1857 assert(begin != end && '0' <= *begin && *begin <= '9');
1858 if (*begin == '0') {
1859 ++begin;
1860 return 0;
1861 }
1862 unsigned value = 0;
1863 // Convert to unsigned to prevent a warning.
1864 constexpr unsigned max_int = (std::numeric_limits<int>::max)();
1865 unsigned big = max_int / 10;
1866 do {
1867 // Check for overflow.
1868 if (value > big) {
1869 value = max_int + 1;
1870 break;
1871 }
1872 value = value * 10 + unsigned(*begin - '0');
1873 ++begin;
1874 } while (begin != end && '0' <= *begin && *begin <= '9');
1875 if (value > max_int) eh.on_error("number is too big");
1876 return static_cast<int>(value);
1877 }
1878
1879 template <typename Context> class custom_formatter {
1880 private:
1881 using char_type = typename Context::char_type;
1882
1883 basic_parse_context<char_type>& parse_ctx_;
1884 Context& ctx_;
1885
1886 public:
1887 explicit custom_formatter(basic_parse_context<char_type>& parse_ctx,
1888 Context& ctx)
1889 : parse_ctx_(parse_ctx), ctx_(ctx) {}
1890
1891 bool operator()(typename basic_format_arg<Context>::handle h) const {
1892 h.format(parse_ctx_, ctx_);
1893 return true;
1894 }
1895
1896 template <typename T> bool operator()(T) const { return false; }
1897 };
1898
1899 template <typename T>
1900 using is_integer =
1901 bool_constant<std::is_integral<T>::value && !std::is_same<T, bool>::value &&
1902 !std::is_same<T, char>::value &&
1903 !std::is_same<T, wchar_t>::value>;
1904
1905 template <typename ErrorHandler> class width_checker {
1906 public:
1907 explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}
1908
1909 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
1910 FMT_CONSTEXPR unsigned long long operator()(T value) {
1911 if (is_negative(value)) handler_.on_error("negative width");
1912 return static_cast<unsigned long long>(value);
1913 }
1914
1915 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
1916 FMT_CONSTEXPR unsigned long long operator()(T) {
1917 handler_.on_error("width is not integer");
1918 return 0;
1919 }
1920
1921 private:
1922 ErrorHandler& handler_;
1923 };
1924
1925 template <typename ErrorHandler> class precision_checker {
1926 public:
1927 explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}
1928
1929 template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
1930 FMT_CONSTEXPR unsigned long long operator()(T value) {
1931 if (is_negative(value)) handler_.on_error("negative precision");
1932 return static_cast<unsigned long long>(value);
1933 }
1934
1935 template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
1936 FMT_CONSTEXPR unsigned long long operator()(T) {
1937 handler_.on_error("precision is not integer");
1938 return 0;
1939 }
1940
1941 private:
1942 ErrorHandler& handler_;
1943 };
1944
1945 // A format specifier handler that sets fields in basic_format_specs.
1946 template <typename Char> class specs_setter {
1947 public:
1948 explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char>& specs)
1949 : specs_(specs) {}
1950
1951 FMT_CONSTEXPR specs_setter(const specs_setter& other)
1952 : specs_(other.specs_) {}
1953
1954 FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; }
1955 FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill[0] = fill; }
1956 FMT_CONSTEXPR void on_plus() { specs_.sign = sign::plus; }
1957 FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; }
1958 FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; }
1959 FMT_CONSTEXPR void on_hash() { specs_.alt = true; }
1960
1961 FMT_CONSTEXPR void on_zero() {
1962 specs_.align = align::numeric;
1963 specs_.fill[0] = Char('0');
1964 }
1965
1966 FMT_CONSTEXPR void on_width(int width) { specs_.width = width; }
1967 FMT_CONSTEXPR void on_precision(int precision) {
1968 specs_.precision = precision;
1969 }
1970 FMT_CONSTEXPR void end_precision() {}
1971
1972 FMT_CONSTEXPR void on_type(Char type) {
1973 specs_.type = static_cast<char>(type);
1974 }
1975
1976 protected:
1977 basic_format_specs<Char>& specs_;
1978 };
1979
1980 template <typename ErrorHandler> class numeric_specs_checker {
1981 public:
1982 FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, internal::type arg_type)
1983 : error_handler_(eh), arg_type_(arg_type) {}
1984
1985 FMT_CONSTEXPR void require_numeric_argument() {
1986 if (!is_arithmetic(arg_type_))
1987 error_handler_.on_error("format specifier requires numeric argument");
1988 }
1989
1990 FMT_CONSTEXPR void check_sign() {
1991 require_numeric_argument();
1992 if (is_integral(arg_type_) && arg_type_ != int_type &&
1993 arg_type_ != long_long_type && arg_type_ != internal::char_type) {
1994 error_handler_.on_error("format specifier requires signed argument");
1995 }
1996 }
1997
1998 FMT_CONSTEXPR void check_precision() {
1999 if (is_integral(arg_type_) || arg_type_ == internal::pointer_type)
2000 error_handler_.on_error("precision not allowed for this argument type");
2001 }
2002
2003 private:
2004 ErrorHandler& error_handler_;
2005 internal::type arg_type_;
2006 };
2007
2008 // A format specifier handler that checks if specifiers are consistent with the
2009 // argument type.
2010 template <typename Handler> class specs_checker : public Handler {
2011 public:
2012 FMT_CONSTEXPR specs_checker(const Handler& handler, internal::type arg_type)
2013 : Handler(handler), checker_(*this, arg_type) {}
2014
2015 FMT_CONSTEXPR specs_checker(const specs_checker& other)
2016 : Handler(other), checker_(*this, other.arg_type_) {}
2017
2018 FMT_CONSTEXPR void on_align(align_t align) {
2019 if (align == align::numeric) checker_.require_numeric_argument();
2020 Handler::on_align(align);
2021 }
2022
2023 FMT_CONSTEXPR void on_plus() {
2024 checker_.check_sign();
2025 Handler::on_plus();
2026 }
2027
2028 FMT_CONSTEXPR void on_minus() {
2029 checker_.check_sign();
2030 Handler::on_minus();
2031 }
2032
2033 FMT_CONSTEXPR void on_space() {
2034 checker_.check_sign();
2035 Handler::on_space();
2036 }
2037
2038 FMT_CONSTEXPR void on_hash() {
2039 checker_.require_numeric_argument();
2040 Handler::on_hash();
2041 }
2042
2043 FMT_CONSTEXPR void on_zero() {
2044 checker_.require_numeric_argument();
2045 Handler::on_zero();
2046 }
2047
2048 FMT_CONSTEXPR void end_precision() { checker_.check_precision(); }
2049
2050 private:
2051 numeric_specs_checker<Handler> checker_;
2052 };
2053
2054 template <template <typename> class Handler, typename T, typename FormatArg,
2055 typename ErrorHandler>
2056 FMT_CONSTEXPR void set_dynamic_spec(T& value, FormatArg arg, ErrorHandler eh) {
2057 unsigned long long big_value =
2058 visit_format_arg(Handler<ErrorHandler>(eh), arg);
2059 if (big_value > to_unsigned((std::numeric_limits<int>::max)()))
2060 eh.on_error("number is too big");
2061 value = static_cast<T>(big_value);
2062 }
2063
2064 struct auto_id {};
2065
2066 template <typename Context>
2067 FMT_CONSTEXPR typename Context::format_arg get_arg(Context& ctx, int id) {
2068 auto arg = ctx.arg(id);
2069 if (!arg) ctx.on_error("argument index out of range");
2070 return arg;
2071 }
2072
2073 // The standard format specifier handler with checking.
2074 template <typename ParseContext, typename Context>
2075 class specs_handler : public specs_setter<typename Context::char_type> {
2076 public:
2077 using char_type = typename Context::char_type;
2078
2079 FMT_CONSTEXPR specs_handler(basic_format_specs<char_type>& specs,
2080 ParseContext& parse_ctx, Context& ctx)
2081 : specs_setter<char_type>(specs),
2082 parse_context_(parse_ctx),
2083 context_(ctx) {}
2084
2085 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
2086 set_dynamic_spec<width_checker>(this->specs_.width, get_arg(arg_id),
2087 context_.error_handler());
2088 }
2089
2090 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
2091 set_dynamic_spec<precision_checker>(this->specs_.precision, get_arg(arg_id),
2092 context_.error_handler());
2093 }
2094
2095 void on_error(const char* message) { context_.on_error(message); }
2096
2097 private:
2098 // This is only needed for compatibility with gcc 4.4.
2099 using format_arg = typename Context::format_arg;
2100
2101 FMT_CONSTEXPR format_arg get_arg(auto_id) {
2102 return internal::get_arg(context_, parse_context_.next_arg_id());
2103 }
2104
2105 FMT_CONSTEXPR format_arg get_arg(int arg_id) {
2106 parse_context_.check_arg_id(arg_id);
2107 return internal::get_arg(context_, arg_id);
2108 }
2109
2110 FMT_CONSTEXPR format_arg get_arg(basic_string_view<char_type> arg_id) {
2111 parse_context_.check_arg_id(arg_id);
2112 return context_.arg(arg_id);
2113 }
2114
2115 ParseContext& parse_context_;
2116 Context& context_;
2117 };
2118
2119 struct string_view_metadata {
2120 FMT_CONSTEXPR string_view_metadata() : offset_(0u), size_(0u) {}
2121 template <typename Char>
2122 FMT_CONSTEXPR string_view_metadata(basic_string_view<Char> primary_string,
2123 basic_string_view<Char> view)
2124 : offset_(to_unsigned(view.data() - primary_string.data())),
2125 size_(view.size()) {}
2126 FMT_CONSTEXPR string_view_metadata(std::size_t offset, std::size_t size)
2127 : offset_(offset), size_(size) {}
2128 template <typename Char>
2129 FMT_CONSTEXPR basic_string_view<Char> to_view(const Char* str) const {
2130 return {str + offset_, size_};
2131 }
2132
2133 std::size_t offset_;
2134 std::size_t size_;
2135 };
2136
2137 enum class arg_id_kind { none, index, name };
2138
2139 // An argument reference.
2140 template <typename Char> struct arg_ref {
2141 FMT_CONSTEXPR arg_ref() : kind(arg_id_kind::none), val() {}
2142 FMT_CONSTEXPR explicit arg_ref(int index)
2143 : kind(arg_id_kind::index), val(index) {}
2144 FMT_CONSTEXPR explicit arg_ref(string_view_metadata name)
2145 : kind(arg_id_kind::name), val(name) {}
2146
2147 FMT_CONSTEXPR arg_ref& operator=(int idx) {
2148 kind = arg_id_kind::index;
2149 val.index = idx;
2150 return *this;
2151 }
2152
2153 arg_id_kind kind;
2154 union value {
2155 FMT_CONSTEXPR value() : index(0u) {}
2156 FMT_CONSTEXPR value(int id) : index(id) {}
2157 FMT_CONSTEXPR value(string_view_metadata n) : name(n) {}
2158
2159 int index;
2160 string_view_metadata name;
2161 } val;
2162 };
2163
2164 // Format specifiers with width and precision resolved at formatting rather
2165 // than parsing time to allow re-using the same parsed specifiers with
2166 // different sets of arguments (precompilation of format strings).
2167 template <typename Char>
2168 struct dynamic_format_specs : basic_format_specs<Char> {
2169 arg_ref<Char> width_ref;
2170 arg_ref<Char> precision_ref;
2171 };
2172
2173 // Format spec handler that saves references to arguments representing dynamic
2174 // width and precision to be resolved at formatting time.
2175 template <typename ParseContext>
2176 class dynamic_specs_handler
2177 : public specs_setter<typename ParseContext::char_type> {
2178 public:
2179 using char_type = typename ParseContext::char_type;
2180
2181 FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs<char_type>& specs,
2182 ParseContext& ctx)
2183 : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}
2184
2185 FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler& other)
2186 : specs_setter<char_type>(other),
2187 specs_(other.specs_),
2188 context_(other.context_) {}
2189
2190 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
2191 specs_.width_ref = make_arg_ref(arg_id);
2192 }
2193
2194 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
2195 specs_.precision_ref = make_arg_ref(arg_id);
2196 }
2197
2198 FMT_CONSTEXPR void on_error(const char* message) {
2199 context_.on_error(message);
2200 }
2201
2202 private:
2203 using arg_ref_type = arg_ref<char_type>;
2204
2205 FMT_CONSTEXPR arg_ref_type make_arg_ref(int arg_id) {
2206 context_.check_arg_id(arg_id);
2207 return arg_ref_type(arg_id);
2208 }
2209
2210 FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id) {
2211 return arg_ref_type(context_.next_arg_id());
2212 }
2213
2214 FMT_CONSTEXPR arg_ref_type make_arg_ref(basic_string_view<char_type> arg_id) {
2215 context_.check_arg_id(arg_id);
2216 basic_string_view<char_type> format_str(
2217 context_.begin(), to_unsigned(context_.end() - context_.begin()));
2218 const auto id_metadata = string_view_metadata(format_str, arg_id);
2219 return arg_ref_type(id_metadata);
2220 }
2221
2222 dynamic_format_specs<char_type>& specs_;
2223 ParseContext& context_;
2224 };
2225
2226 template <typename Char, typename IDHandler>
2227 FMT_CONSTEXPR const Char* parse_arg_id(const Char* begin, const Char* end,
2228 IDHandler&& handler) {
2229 assert(begin != end);
2230 Char c = *begin;
2231 if (c == '}' || c == ':') return handler(), begin;
2232 if (c >= '0' && c <= '9') {
2233 int index = parse_nonnegative_int(begin, end, handler);
2234 if (begin == end || (*begin != '}' && *begin != ':'))
2235 return handler.on_error("invalid format string"), begin;
2236 handler(index);
2237 return begin;
2238 }
2239 if (!is_name_start(c))
2240 return handler.on_error("invalid format string"), begin;
2241 auto it = begin;
2242 do {
2243 ++it;
2244 } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9')));
2245 handler(basic_string_view<Char>(begin, to_unsigned(it - begin)));
2246 return it;
2247 }
2248
2249 // Adapts SpecHandler to IDHandler API for dynamic width.
2250 template <typename SpecHandler, typename Char> struct width_adapter {
2251 explicit FMT_CONSTEXPR width_adapter(SpecHandler& h) : handler(h) {}
2252
2253 FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); }
2254 FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_width(id); }
2255 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
2256 handler.on_dynamic_width(id);
2257 }
2258
2259 FMT_CONSTEXPR void on_error(const char* message) {
2260 handler.on_error(message);
2261 }
2262
2263 SpecHandler& handler;
2264 };
2265
2266 // Adapts SpecHandler to IDHandler API for dynamic precision.
2267 template <typename SpecHandler, typename Char> struct precision_adapter {
2268 explicit FMT_CONSTEXPR precision_adapter(SpecHandler& h) : handler(h) {}
2269
2270 FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); }
2271 FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_precision(id); }
2272 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
2273 handler.on_dynamic_precision(id);
2274 }
2275
2276 FMT_CONSTEXPR void on_error(const char* message) {
2277 handler.on_error(message);
2278 }
2279
2280 SpecHandler& handler;
2281 };
2282
2283 // Parses fill and alignment.
2284 template <typename Char, typename Handler>
2285 FMT_CONSTEXPR const Char* parse_align(const Char* begin, const Char* end,
2286 Handler&& handler) {
2287 FMT_ASSERT(begin != end, "");
2288 auto align = align::none;
2289 int i = 0;
2290 if (begin + 1 != end) ++i;
2291 do {
2292 switch (static_cast<char>(begin[i])) {
2293 case '<':
2294 align = align::left;
2295 break;
2296 case '>':
2297 align = align::right;
2298 break;
2299 case '=':
2300 align = align::numeric;
2301 break;
2302 case '^':
2303 align = align::center;
2304 break;
2305 }
2306 if (align != align::none) {
2307 if (i > 0) {
2308 auto c = *begin;
2309 if (c == '{')
2310 return handler.on_error("invalid fill character '{'"), begin;
2311 begin += 2;
2312 handler.on_fill(c);
2313 } else
2314 ++begin;
2315 handler.on_align(align);
2316 break;
2317 }
2318 } while (i-- > 0);
2319 return begin;
2320 }
2321
2322 template <typename Char, typename Handler>
2323 FMT_CONSTEXPR const Char* parse_width(const Char* begin, const Char* end,
2324 Handler&& handler) {
2325 FMT_ASSERT(begin != end, "");
2326 if ('0' <= *begin && *begin <= '9') {
2327 handler.on_width(parse_nonnegative_int(begin, end, handler));
2328 } else if (*begin == '{') {
2329 ++begin;
2330 if (begin != end)
2331 begin = parse_arg_id(begin, end, width_adapter<Handler, Char>(handler));
2332 if (begin == end || *begin != '}')
2333 return handler.on_error("invalid format string"), begin;
2334 ++begin;
2335 }
2336 return begin;
2337 }
2338
2339 template <typename Char, typename Handler>
2340 FMT_CONSTEXPR const Char* parse_precision(const Char* begin, const Char* end,
2341 Handler&& handler) {
2342 ++begin;
2343 auto c = begin != end ? *begin : Char();
2344 if ('0' <= c && c <= '9') {
2345 handler.on_precision(parse_nonnegative_int(begin, end, handler));
2346 } else if (c == '{') {
2347 ++begin;
2348 if (begin != end) {
2349 begin =
2350 parse_arg_id(begin, end, precision_adapter<Handler, Char>(handler));
2351 }
2352 if (begin == end || *begin++ != '}')
2353 return handler.on_error("invalid format string"), begin;
2354 } else {
2355 return handler.on_error("missing precision specifier"), begin;
2356 }
2357 handler.end_precision();
2358 return begin;
2359 }
2360
2361 // Parses standard format specifiers and sends notifications about parsed
2362 // components to handler.
2363 template <typename Char, typename SpecHandler>
2364 FMT_CONSTEXPR const Char* parse_format_specs(const Char* begin, const Char* end,
2365 SpecHandler&& handler) {
2366 if (begin == end || *begin == '}') return begin;
2367
2368 begin = parse_align(begin, end, handler);
2369 if (begin == end) return begin;
2370
2371 // Parse sign.
2372 switch (static_cast<char>(*begin)) {
2373 case '+':
2374 handler.on_plus();
2375 ++begin;
2376 break;
2377 case '-':
2378 handler.on_minus();
2379 ++begin;
2380 break;
2381 case ' ':
2382 handler.on_space();
2383 ++begin;
2384 break;
2385 }
2386 if (begin == end) return begin;
2387
2388 if (*begin == '#') {
2389 handler.on_hash();
2390 if (++begin == end) return begin;
2391 }
2392
2393 // Parse zero flag.
2394 if (*begin == '0') {
2395 handler.on_zero();
2396 if (++begin == end) return begin;
2397 }
2398
2399 begin = parse_width(begin, end, handler);
2400 if (begin == end) return begin;
2401
2402 // Parse precision.
2403 if (*begin == '.') {
2404 begin = parse_precision(begin, end, handler);
2405 }
2406
2407 // Parse type.
2408 if (begin != end && *begin != '}') handler.on_type(*begin++);
2409 return begin;
2410 }
2411
2412 // Return the result via the out param to workaround gcc bug 77539.
2413 template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
2414 FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr& out) {
2415 for (out = first; out != last; ++out) {
2416 if (*out == value) return true;
2417 }
2418 return false;
2419 }
2420
2421 template <>
2422 inline bool find<false, char>(const char* first, const char* last, char value,
2423 const char*& out) {
2424 out = static_cast<const char*>(
2425 std::memchr(first, value, internal::to_unsigned(last - first)));
2426 return out != nullptr;
2427 }
2428
2429 template <typename Handler, typename Char> struct id_adapter {
2430 FMT_CONSTEXPR void operator()() { handler.on_arg_id(); }
2431 FMT_CONSTEXPR void operator()(int id) { handler.on_arg_id(id); }
2432 FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
2433 handler.on_arg_id(id);
2434 }
2435 FMT_CONSTEXPR void on_error(const char* message) {
2436 handler.on_error(message);
2437 }
2438 Handler& handler;
2439 };
2440
2441 template <bool IS_CONSTEXPR, typename Char, typename Handler>
2442 FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> format_str,
2443 Handler&& handler) {
2444 struct pfs_writer {
2445 FMT_CONSTEXPR void operator()(const Char* begin, const Char* end) {
2446 if (begin == end) return;
2447 for (;;) {
2448 const Char* p = nullptr;
2449 if (!find<IS_CONSTEXPR>(begin, end, '}', p))
2450 return handler_.on_text(begin, end);
2451 ++p;
2452 if (p == end || *p != '}')
2453 return handler_.on_error("unmatched '}' in format string");
2454 handler_.on_text(begin, p);
2455 begin = p + 1;
2456 }
2457 }
2458 Handler& handler_;
2459 } write{handler};
2460 auto begin = format_str.data();
2461 auto end = begin + format_str.size();
2462 while (begin != end) {
2463 // Doing two passes with memchr (one for '{' and another for '}') is up to
2464 // 2.5x faster than the naive one-pass implementation on big format strings.
2465 const Char* p = begin;
2466 if (*begin != '{' && !find<IS_CONSTEXPR>(begin, end, '{', p))
2467 return write(begin, end);
2468 write(begin, p);
2469 ++p;
2470 if (p == end) return handler.on_error("invalid format string");
2471 if (static_cast<char>(*p) == '}') {
2472 handler.on_arg_id();
2473 handler.on_replacement_field(p);
2474 } else if (*p == '{') {
2475 handler.on_text(p, p + 1);
2476 } else {
2477 p = parse_arg_id(p, end, id_adapter<Handler, Char>{handler});
2478 Char c = p != end ? *p : Char();
2479 if (c == '}') {
2480 handler.on_replacement_field(p);
2481 } else if (c == ':') {
2482 p = handler.on_format_specs(p + 1, end);
2483 if (p == end || *p != '}')
2484 return handler.on_error("unknown format specifier");
2485 } else {
2486 return handler.on_error("missing '}' in format string");
2487 }
2488 }
2489 begin = p + 1;
2490 }
2491 }
2492
2493 template <typename T, typename ParseContext>
2494 FMT_CONSTEXPR const typename ParseContext::char_type* parse_format_specs(
2495 ParseContext& ctx) {
2496 using char_type = typename ParseContext::char_type;
2497 using context = buffer_context<char_type>;
2498 using mapped_type =
2499 conditional_t<internal::mapped_type_constant<T, context>::value !=
2500 internal::custom_type,
2501 decltype(arg_mapper<context>().map(std::declval<T>())), T>;
2502 conditional_t<has_formatter<mapped_type, context>::value,
2503 formatter<mapped_type, char_type>,
2504 internal::fallback_formatter<T, char_type>>
2505 f;
2506 return f.parse(ctx);
2507 }
2508
2509 template <typename Char, typename ErrorHandler, typename... Args>
2510 class format_string_checker {
2511 public:
2512 explicit FMT_CONSTEXPR format_string_checker(
2513 basic_string_view<Char> format_str, ErrorHandler eh)
2514 : arg_id_((std::numeric_limits<unsigned>::max)()),
2515 context_(format_str, eh),
2516 parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
2517
2518 FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
2519
2520 FMT_CONSTEXPR void on_arg_id() {
2521 arg_id_ = context_.next_arg_id();
2522 check_arg_id();
2523 }
2524 FMT_CONSTEXPR void on_arg_id(int id) {
2525 arg_id_ = id;
2526 context_.check_arg_id(id);
2527 check_arg_id();
2528 }
2529 FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) {
2530 on_error("compile-time checks don't support named arguments");
2531 }
2532
2533 FMT_CONSTEXPR void on_replacement_field(const Char*) {}
2534
2535 FMT_CONSTEXPR const Char* on_format_specs(const Char* begin, const Char*) {
2536 advance_to(context_, begin);
2537 return arg_id_ < num_args ? parse_funcs_[arg_id_](context_) : begin;
2538 }
2539
2540 FMT_CONSTEXPR void on_error(const char* message) {
2541 context_.on_error(message);
2542 }
2543
2544 private:
2545 using parse_context_type = basic_parse_context<Char, ErrorHandler>;
2546 enum { num_args = sizeof...(Args) };
2547
2548 FMT_CONSTEXPR void check_arg_id() {
2549 if (arg_id_ >= num_args) context_.on_error("argument index out of range");
2550 }
2551
2552 // Format specifier parsing function.
2553 using parse_func = const Char* (*)(parse_context_type&);
2554
2555 unsigned arg_id_;
2556 parse_context_type context_;
2557 parse_func parse_funcs_[num_args > 0 ? num_args : 1];
2558 };
2559
2560 template <typename Char, typename ErrorHandler, typename... Args>
2561 FMT_CONSTEXPR bool do_check_format_string(basic_string_view<Char> s,
2562 ErrorHandler eh = ErrorHandler()) {
2563 format_string_checker<Char, ErrorHandler, Args...> checker(s, eh);
2564 parse_format_string<true>(s, checker);
2565 return true;
2566 }
2567
2568 template <typename... Args, typename S,
2569 enable_if_t<(is_compile_string<S>::value), int>>
2570 void check_format_string(S format_str) {
2571 FMT_CONSTEXPR_DECL bool invalid_format =
2572 internal::do_check_format_string<typename S::char_type,
2573 internal::error_handler, Args...>(
2574 to_string_view(format_str));
2575 (void)invalid_format;
2576 }
2577
2578 template <template <typename> class Handler, typename Spec, typename Context>
2579 void handle_dynamic_spec(Spec& value, arg_ref<typename Context::char_type> ref,
2580 Context& ctx,
2581 const typename Context::char_type* format_str) {
2582 switch (ref.kind) {
2583 case arg_id_kind::none:
2584 break;
2585 case arg_id_kind::index:
2586 internal::set_dynamic_spec<Handler>(value, ctx.arg(ref.val.index),
2587 ctx.error_handler());
2588 break;
2589 case arg_id_kind::name: {
2590 const auto arg_id = ref.val.name.to_view(format_str);
2591 internal::set_dynamic_spec<Handler>(value, ctx.arg(arg_id),
2592 ctx.error_handler());
2593 break;
2594 }
2595 }
2596 }
2597 } // namespace internal
2598
2599 template <typename Range>
2600 using basic_writer FMT_DEPRECATED_ALIAS = internal::basic_writer<Range>;
2601 using writer FMT_DEPRECATED_ALIAS = internal::writer;
2602 using wwriter FMT_DEPRECATED_ALIAS =
2603 internal::basic_writer<internal::buffer_range<wchar_t>>;
2604
2605 /** The default argument formatter. */
2606 template <typename Range>
2607 class arg_formatter : public internal::arg_formatter_base<Range> {
2608 private:
2609 using char_type = typename Range::value_type;
2610 using base = internal::arg_formatter_base<Range>;
2611 using context_type = basic_format_context<typename base::iterator, char_type>;
2612
2613 context_type& ctx_;
2614 basic_parse_context<char_type>* parse_ctx_;
2615
2616 public:
2617 using range = Range;
2618 using iterator = typename base::iterator;
2619 using format_specs = typename base::format_specs;
2620
2621 /**
2622 \rst
2623 Constructs an argument formatter object.
2624 *ctx* is a reference to the formatting context,
2625 *specs* contains format specifier information for standard argument types.
2626 \endrst
2627 */
2628 explicit arg_formatter(context_type& ctx,
2629 basic_parse_context<char_type>* parse_ctx = nullptr,
2630 format_specs* specs = nullptr)
2631 : base(Range(ctx.out()), specs, ctx.locale()),
2632 ctx_(ctx),
2633 parse_ctx_(parse_ctx) {}
2634
2635 using base::operator();
2636
2637 /** Formats an argument of a user-defined type. */
2638 iterator operator()(typename basic_format_arg<context_type>::handle handle) {
2639 handle.format(*parse_ctx_, ctx_);
2640 return this->out();
2641 }
2642 };
2643
2644 /**
2645 An error returned by an operating system or a language runtime,
2646 for example a file opening error.
2647 */
2648 class FMT_API system_error : public std::runtime_error {
2649 private:
2650 void init(int err_code, string_view format_str, format_args args);
2651
2652 protected:
2653 int error_code_;
2654
2655 system_error() : std::runtime_error(""), error_code_(0) {}
2656
2657 public:
2658 /**
2659 \rst
2660 Constructs a :class:`fmt::system_error` object with a description
2661 formatted with `fmt::format_system_error`. *message* and additional
2662 arguments passed into the constructor are formatted similarly to
2663 `fmt::format`.
2664
2665 **Example**::
2666
2667 // This throws a system_error with the description
2668 // cannot open file 'madeup': No such file or directory
2669 // or similar (system message may vary).
2670 const char *filename = "madeup";
2671 std::FILE *file = std::fopen(filename, "r");
2672 if (!file)
2673 throw fmt::system_error(errno, "cannot open file '{}'", filename);
2674 \endrst
2675 */
2676 template <typename... Args>
2677 system_error(int error_code, string_view message, const Args&... args)
2678 : std::runtime_error("") {
2679 init(error_code, message, make_format_args(args...));
2680 }
2681 ~system_error() FMT_NOEXCEPT;
2682
2683 int error_code() const { return error_code_; }
2684 };
2685
2686 /**
2687 \rst
2688 Formats an error returned by an operating system or a language runtime,
2689 for example a file opening error, and writes it to *out* in the following
2690 form:
2691
2692 .. parsed-literal::
2693 *<message>*: *<system-message>*
2694
2695 where *<message>* is the passed message and *<system-message>* is
2696 the system message corresponding to the error code.
2697 *error_code* is a system error code as given by ``errno``.
2698 If *error_code* is not a valid error code such as -1, the system message
2699 may look like "Unknown error -1" and is platform-dependent.
2700 \endrst
2701 */
2702 FMT_API void format_system_error(internal::buffer<char>& out, int error_code,
2703 fmt::string_view message) FMT_NOEXCEPT;
2704
2705 struct float_spec_handler {
2706 char type;
2707 bool upper;
2708 bool fixed;
2709 bool as_percentage;
2710 bool use_locale;
2711
2712 explicit float_spec_handler(char t)
2713 : type(t),
2714 upper(false),
2715 fixed(false),
2716 as_percentage(false),
2717 use_locale(false) {}
2718
2719 void on_general() {
2720 if (type == 'G') upper = true;
2721 }
2722
2723 void on_exp() {
2724 if (type == 'E') upper = true;
2725 }
2726
2727 void on_fixed() {
2728 fixed = true;
2729 if (type == 'F') upper = true;
2730 }
2731
2732 void on_percent() {
2733 fixed = true;
2734 as_percentage = true;
2735 }
2736
2737 void on_hex() {
2738 if (type == 'A') upper = true;
2739 }
2740
2741 void on_num() { use_locale = true; }
2742
2743 FMT_NORETURN void on_error() {
2744 FMT_THROW(format_error("invalid type specifier"));
2745 }
2746 };
2747
2748 template <typename Range>
2749 template <typename T, bool USE_GRISU>
2750 void internal::basic_writer<Range>::write_double(T value,
2751 const format_specs& specs) {
2752 // Check type.
2753 float_spec_handler handler(static_cast<char>(specs.type));
2754 internal::handle_float_type_spec(handler.type, handler);
2755
2756 char sign = 0;
2757 // Use signbit instead of value < 0 since the latter is always false for NaN.
2758 if (std::signbit(value)) {
2759 sign = '-';
2760 value = -value;
2761 } else if (specs.sign != sign::none) {
2762 if (specs.sign == sign::plus)
2763 sign = '+';
2764 else if (specs.sign == sign::space)
2765 sign = ' ';
2766 }
2767
2768 if (!std::isfinite(value)) {
2769 // Format infinity and NaN ourselves because sprintf's output is not
2770 // consistent across platforms.
2771 const char* str = std::isinf(value) ? (handler.upper ? "INF" : "inf")
2772 : (handler.upper ? "NAN" : "nan");
2773 return write_padded(specs,
2774 inf_or_nan_writer{sign, handler.as_percentage, str});
2775 }
2776
2777 if (handler.as_percentage) value *= 100;
2778
2779 memory_buffer buffer;
2780 int exp = 0;
2781 int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
2782 unsigned options = handler.fixed ? internal::grisu_options::fixed : 0;
2783 bool use_grisu = USE_GRISU &&
2784 (specs.type != 'a' && specs.type != 'A' &&
2785 specs.type != 'e' && specs.type != 'E') &&
2786 internal::grisu_format(static_cast<double>(value), buffer,
2787 precision, options, exp);
2788 char* decimal_point_pos = nullptr;
2789 if (!use_grisu)
2790 decimal_point_pos = internal::sprintf_format(value, buffer, specs);
2791
2792 if (handler.as_percentage) {
2793 buffer.push_back('%');
2794 --exp; // Adjust decimal place position.
2795 }
2796 format_specs as = specs;
2797 if (specs.align == align::numeric) {
2798 if (sign) {
2799 auto&& it = reserve(1);
2800 *it++ = static_cast<char_type>(sign);
2801 sign = 0;
2802 if (as.width) --as.width;
2803 }
2804 as.align = align::right;
2805 } else if (specs.align == align::none) {
2806 as.align = align::right;
2807 }
2808 char_type decimal_point = handler.use_locale
2809 ? internal::decimal_point<char_type>(locale_)
2810 : static_cast<char_type>('.');
2811 if (use_grisu) {
2812 auto params = internal::gen_digits_params();
2813 params.fixed = handler.fixed;
2814 params.num_digits = precision;
2815 params.trailing_zeros =
2816 (precision != 0 && (handler.fixed || !specs.type)) || specs.alt;
2817 write_padded(as, grisu_writer(sign, buffer, exp, params, decimal_point));
2818 } else {
2819 write_padded(as,
2820 double_writer{sign, buffer, decimal_point_pos, decimal_point});
2821 }
2822 }
2823
2824 // Reports a system error without throwing an exception.
2825 // Can be used to report errors from destructors.
2826 FMT_API void report_system_error(int error_code,
2827 string_view message) FMT_NOEXCEPT;
2828
2829 #if FMT_USE_WINDOWS_H
2830
2831 /** A Windows error. */
2832 class windows_error : public system_error {
2833 private:
2834 FMT_API void init(int error_code, string_view format_str, format_args args);
2835
2836 public:
2837 /**
2838 \rst
2839 Constructs a :class:`fmt::windows_error` object with the description
2840 of the form
2841
2842 .. parsed-literal::
2843 *<message>*: *<system-message>*
2844
2845 where *<message>* is the formatted message and *<system-message>* is the
2846 system message corresponding to the error code.
2847 *error_code* is a Windows error code as given by ``GetLastError``.
2848 If *error_code* is not a valid error code such as -1, the system message
2849 will look like "error -1".
2850
2851 **Example**::
2852
2853 // This throws a windows_error with the description
2854 // cannot open file 'madeup': The system cannot find the file specified.
2855 // or similar (system message may vary).
2856 const char *filename = "madeup";
2857 LPOFSTRUCT of = LPOFSTRUCT();
2858 HFILE file = OpenFile(filename, &of, OF_READ);
2859 if (file == HFILE_ERROR) {
2860 throw fmt::windows_error(GetLastError(),
2861 "cannot open file '{}'", filename);
2862 }
2863 \endrst
2864 */
2865 template <typename... Args>
2866 windows_error(int error_code, string_view message, const Args&... args) {
2867 init(error_code, message, make_format_args(args...));
2868 }
2869 };
2870
2871 // Reports a Windows error without throwing an exception.
2872 // Can be used to report errors from destructors.
2873 FMT_API void report_windows_error(int error_code,
2874 string_view message) FMT_NOEXCEPT;
2875
2876 #endif
2877
2878 /** Fast integer formatter. */
2879 class format_int {
2880 private:
2881 // Buffer should be large enough to hold all digits (digits10 + 1),
2882 // a sign and a null character.
2883 enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
2884 mutable char buffer_[buffer_size];
2885 char* str_;
2886
2887 // Formats value in reverse and returns a pointer to the beginning.
2888 char* format_decimal(unsigned long long value) {
2889 char* ptr = buffer_ + (buffer_size - 1); // Parens to workaround MSVC bug.
2890 while (value >= 100) {
2891 // Integer division is slow so do it for a group of two digits instead
2892 // of for every digit. The idea comes from the talk by Alexandrescu
2893 // "Three Optimization Tips for C++". See speed-test for a comparison.
2894 unsigned index = static_cast<unsigned>((value % 100) * 2);
2895 value /= 100;
2896 *--ptr = internal::data::digits[index + 1];
2897 *--ptr = internal::data::digits[index];
2898 }
2899 if (value < 10) {
2900 *--ptr = static_cast<char>('0' + value);
2901 return ptr;
2902 }
2903 unsigned index = static_cast<unsigned>(value * 2);
2904 *--ptr = internal::data::digits[index + 1];
2905 *--ptr = internal::data::digits[index];
2906 return ptr;
2907 }
2908
2909 void format_signed(long long value) {
2910 unsigned long long abs_value = static_cast<unsigned long long>(value);
2911 bool negative = value < 0;
2912 if (negative) abs_value = 0 - abs_value;
2913 str_ = format_decimal(abs_value);
2914 if (negative) *--str_ = '-';
2915 }
2916
2917 public:
2918 explicit format_int(int value) { format_signed(value); }
2919 explicit format_int(long value) { format_signed(value); }
2920 explicit format_int(long long value) { format_signed(value); }
2921 explicit format_int(unsigned value) : str_(format_decimal(value)) {}
2922 explicit format_int(unsigned long value) : str_(format_decimal(value)) {}
2923 explicit format_int(unsigned long long value) : str_(format_decimal(value)) {}
2924
2925 /** Returns the number of characters written to the output buffer. */
2926 std::size_t size() const {
2927 return internal::to_unsigned(buffer_ - str_ + buffer_size - 1);
2928 }
2929
2930 /**
2931 Returns a pointer to the output buffer content. No terminating null
2932 character is appended.
2933 */
2934 const char* data() const { return str_; }
2935
2936 /**
2937 Returns a pointer to the output buffer content with terminating null
2938 character appended.
2939 */
2940 const char* c_str() const {
2941 buffer_[buffer_size - 1] = '\0';
2942 return str_;
2943 }
2944
2945 /**
2946 \rst
2947 Returns the content of the output buffer as an ``std::string``.
2948 \endrst
2949 */
2950 std::string str() const { return std::string(str_, size()); }
2951 };
2952
2953 // A formatter specialization for the core types corresponding to internal::type
2954 // constants.
2955 template <typename T, typename Char>
2956 struct formatter<T, Char,
2957 enable_if_t<internal::type_constant<T, Char>::value !=
2958 internal::custom_type>> {
2959 FMT_CONSTEXPR formatter() : format_str_(nullptr) {}
2960
2961 // Parses format specifiers stopping either at the end of the range or at the
2962 // terminating '}'.
2963 template <typename ParseContext>
2964 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2965 format_str_ = ctx.begin();
2966 using handler_type = internal::dynamic_specs_handler<ParseContext>;
2967 auto type = internal::type_constant<T, Char>::value;
2968 internal::specs_checker<handler_type> handler(handler_type(specs_, ctx),
2969 type);
2970 auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
2971 auto eh = ctx.error_handler();
2972 switch (type) {
2973 case internal::none_type:
2974 case internal::named_arg_type:
2975 FMT_ASSERT(false, "invalid argument type");
2976 break;
2977 case internal::int_type:
2978 case internal::uint_type:
2979 case internal::long_long_type:
2980 case internal::ulong_long_type:
2981 case internal::bool_type:
2982 handle_int_type_spec(specs_.type,
2983 internal::int_type_checker<decltype(eh)>(eh));
2984 break;
2985 case internal::char_type:
2986 handle_char_specs(
2987 &specs_, internal::char_specs_checker<decltype(eh)>(specs_.type, eh));
2988 break;
2989 case internal::double_type:
2990 case internal::long_double_type:
2991 handle_float_type_spec(specs_.type,
2992 internal::float_type_checker<decltype(eh)>(eh));
2993 break;
2994 case internal::cstring_type:
2995 internal::handle_cstring_type_spec(
2996 specs_.type, internal::cstring_type_checker<decltype(eh)>(eh));
2997 break;
2998 case internal::string_type:
2999 internal::check_string_type_spec(specs_.type, eh);
3000 break;
3001 case internal::pointer_type:
3002 internal::check_pointer_type_spec(specs_.type, eh);
3003 break;
3004 case internal::custom_type:
3005 // Custom format specifiers should be checked in parse functions of
3006 // formatter specializations.
3007 break;
3008 }
3009 return it;
3010 }
3011
3012 template <typename FormatContext>
3013 auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3014 internal::handle_dynamic_spec<internal::width_checker>(
3015 specs_.width, specs_.width_ref, ctx, format_str_);
3016 internal::handle_dynamic_spec<internal::precision_checker>(
3017 specs_.precision, specs_.precision_ref, ctx, format_str_);
3018 using range_type =
3019 internal::output_range<typename FormatContext::iterator,
3020 typename FormatContext::char_type>;
3021 return visit_format_arg(arg_formatter<range_type>(ctx, nullptr, &specs_),
3022 internal::make_arg<FormatContext>(val));
3023 }
3024
3025 private:
3026 internal::dynamic_format_specs<Char> specs_;
3027 const Char* format_str_;
3028 };
3029
3030 #define FMT_FORMAT_AS(Type, Base) \
3031 template <typename Char> \
3032 struct formatter<Type, Char> : formatter<Base, Char> { \
3033 template <typename FormatContext> \
3034 auto format(const Type& val, FormatContext& ctx) -> decltype(ctx.out()) { \
3035 return formatter<Base, Char>::format(val, ctx); \
3036 } \
3037 }
3038
3039 FMT_FORMAT_AS(signed char, int);
3040 FMT_FORMAT_AS(unsigned char, unsigned);
3041 FMT_FORMAT_AS(short, int);
3042 FMT_FORMAT_AS(unsigned short, unsigned);
3043 FMT_FORMAT_AS(long, long long);
3044 FMT_FORMAT_AS(unsigned long, unsigned long long);
3045 FMT_FORMAT_AS(float, double);
3046 FMT_FORMAT_AS(Char*, const Char*);
3047 FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
3048 FMT_FORMAT_AS(std::nullptr_t, const void*);
3049 FMT_FORMAT_AS(internal::std_string_view<Char>, basic_string_view<Char>);
3050
3051 template <typename Char>
3052 struct formatter<void*, Char> : formatter<const void*, Char> {
3053 template <typename FormatContext>
3054 auto format(void* val, FormatContext& ctx) -> decltype(ctx.out()) {
3055 return formatter<const void*, Char>::format(val, ctx);
3056 }
3057 };
3058
3059 template <typename Char, size_t N>
3060 struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
3061 template <typename FormatContext>
3062 auto format(const Char* val, FormatContext& ctx) -> decltype(ctx.out()) {
3063 return formatter<basic_string_view<Char>, Char>::format(val, ctx);
3064 }
3065 };
3066
3067 // A formatter for types known only at run time such as variant alternatives.
3068 //
3069 // Usage:
3070 // using variant = std::variant<int, std::string>;
3071 // template <>
3072 // struct formatter<variant>: dynamic_formatter<> {
3073 // void format(buffer &buf, const variant &v, context &ctx) {
3074 // visit([&](const auto &val) { format(buf, val, ctx); }, v);
3075 // }
3076 // };
3077 template <typename Char = char> class dynamic_formatter {
3078 private:
3079 struct null_handler : internal::error_handler {
3080 void on_align(align_t) {}
3081 void on_plus() {}
3082 void on_minus() {}
3083 void on_space() {}
3084 void on_hash() {}
3085 };
3086
3087 public:
3088 template <typename ParseContext>
3089 auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3090 format_str_ = ctx.begin();
3091 // Checks are deferred to formatting time when the argument type is known.
3092 internal::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
3093 return parse_format_specs(ctx.begin(), ctx.end(), handler);
3094 }
3095
3096 template <typename T, typename FormatContext>
3097 auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
3098 handle_specs(ctx);
3099 internal::specs_checker<null_handler> checker(
3100 null_handler(),
3101 internal::mapped_type_constant<T, FormatContext>::value);
3102 checker.on_align(specs_.align);
3103 switch (specs_.sign) {
3104 case sign::none:
3105 break;
3106 case sign::plus:
3107 checker.on_plus();
3108 break;
3109 case sign::minus:
3110 checker.on_minus();
3111 break;
3112 case sign::space:
3113 checker.on_space();
3114 break;
3115 }
3116 if (specs_.alt) checker.on_hash();
3117 if (specs_.precision >= 0) checker.end_precision();
3118 using range = internal::output_range<typename FormatContext::iterator,
3119 typename FormatContext::char_type>;
3120 visit_format_arg(arg_formatter<range>(ctx, nullptr, &specs_),
3121 internal::make_arg<FormatContext>(val));
3122 return ctx.out();
3123 }
3124
3125 private:
3126 template <typename Context> void handle_specs(Context& ctx) {
3127 internal::handle_dynamic_spec<internal::width_checker>(
3128 specs_.width, specs_.width_ref, ctx, format_str_);
3129 internal::handle_dynamic_spec<internal::precision_checker>(
3130 specs_.precision, specs_.precision_ref, ctx, format_str_);
3131 }
3132
3133 internal::dynamic_format_specs<Char> specs_;
3134 const Char* format_str_;
3135 };
3136
3137 template <typename Range, typename Char>
3138 typename basic_format_context<Range, Char>::format_arg
3139 basic_format_context<Range, Char>::arg(basic_string_view<char_type> name) {
3140 map_.init(args_);
3141 format_arg arg = map_.find(name);
3142 if (arg.type() == internal::none_type) this->on_error("argument not found");
3143 return arg;
3144 }
3145
3146 template <typename Char, typename ErrorHandler>
3147 FMT_CONSTEXPR void advance_to(basic_parse_context<Char, ErrorHandler>& ctx,
3148 const Char* p) {
3149 ctx.advance_to(ctx.begin() + (p - &*ctx.begin()));
3150 }
3151
3152 template <typename ArgFormatter, typename Char, typename Context>
3153 struct format_handler : internal::error_handler {
3154 using range = typename ArgFormatter::range;
3155
3156 format_handler(range r, basic_string_view<Char> str,
3157 basic_format_args<Context> format_args,
3158 internal::locale_ref loc)
3159 : parse_context(str), context(r.begin(), format_args, loc) {}
3160
3161 void on_text(const Char* begin, const Char* end) {
3162 auto size = internal::to_unsigned(end - begin);
3163 auto out = context.out();
3164 auto&& it = internal::reserve(out, size);
3165 it = std::copy_n(begin, size, it);
3166 context.advance_to(out);
3167 }
3168
3169 void get_arg(int id) { arg = internal::get_arg(context, id); }
3170
3171 void on_arg_id() { get_arg(parse_context.next_arg_id()); }
3172 void on_arg_id(int id) {
3173 parse_context.check_arg_id(id);
3174 get_arg(id);
3175 }
3176 void on_arg_id(basic_string_view<Char> id) { arg = context.arg(id); }
3177
3178 void on_replacement_field(const Char* p) {
3179 advance_to(parse_context, p);
3180 internal::custom_formatter<Context> f(parse_context, context);
3181 if (!visit_format_arg(f, arg))
3182 context.advance_to(
3183 visit_format_arg(ArgFormatter(context, &parse_context), arg));
3184 }
3185
3186 const Char* on_format_specs(const Char* begin, const Char* end) {
3187 advance_to(parse_context, begin);
3188 internal::custom_formatter<Context> f(parse_context, context);
3189 if (visit_format_arg(f, arg)) return parse_context.begin();
3190 basic_format_specs<Char> specs;
3191 using internal::specs_handler;
3192 using parse_context_t = basic_parse_context<Char>;
3193 internal::specs_checker<specs_handler<parse_context_t, Context>> handler(
3194 specs_handler<parse_context_t, Context>(specs, parse_context, context),
3195 arg.type());
3196 begin = parse_format_specs(begin, end, handler);
3197 if (begin == end || *begin != '}') on_error("missing '}' in format string");
3198 advance_to(parse_context, begin);
3199 context.advance_to(
3200 visit_format_arg(ArgFormatter(context, &parse_context, &specs), arg));
3201 return begin;
3202 }
3203
3204 basic_parse_context<Char> parse_context;
3205 Context context;
3206 basic_format_arg<Context> arg;
3207 };
3208
3209 /** Formats arguments and writes the output to the range. */
3210 template <typename ArgFormatter, typename Char, typename Context>
3211 typename Context::iterator vformat_to(
3212 typename ArgFormatter::range out, basic_string_view<Char> format_str,
3213 basic_format_args<Context> args,
3214 internal::locale_ref loc = internal::locale_ref()) {
3215 format_handler<ArgFormatter, Char, Context> h(out, format_str, args, loc);
3216 internal::parse_format_string<false>(format_str, h);
3217 return h.context.out();
3218 }
3219
3220 // Casts ``p`` to ``const void*`` for pointer formatting.
3221 // Example:
3222 // auto s = format("{}", ptr(p));
3223 template <typename T> inline const void* ptr(const T* p) { return p; }
3224 template <typename T> inline const void* ptr(const std::unique_ptr<T>& p) {
3225 return p.get();
3226 }
3227 template <typename T> inline const void* ptr(const std::shared_ptr<T>& p) {
3228 return p.get();
3229 }
3230
3231 template <typename It, typename Char> struct arg_join : internal::view {
3232 It begin;
3233 It end;
3234 basic_string_view<Char> sep;
3235
3236 arg_join(It b, It e, basic_string_view<Char> s) : begin(b), end(e), sep(s) {}
3237 };
3238
3239 template <typename It, typename Char>
3240 struct formatter<arg_join<It, Char>, Char>
3241 : formatter<typename std::iterator_traits<It>::value_type, Char> {
3242 template <typename FormatContext>
3243 auto format(const arg_join<It, Char>& value, FormatContext& ctx)
3244 -> decltype(ctx.out()) {
3245 using base = formatter<typename std::iterator_traits<It>::value_type, Char>;
3246 auto it = value.begin;
3247 auto out = ctx.out();
3248 if (it != value.end) {
3249 out = base::format(*it++, ctx);
3250 while (it != value.end) {
3251 out = std::copy(value.sep.begin(), value.sep.end(), out);
3252 ctx.advance_to(out);
3253 out = base::format(*it++, ctx);
3254 }
3255 }
3256 return out;
3257 }
3258 };
3259
3260 /**
3261 Returns an object that formats the iterator range `[begin, end)` with elements
3262 separated by `sep`.
3263 */
3264 template <typename It>
3265 arg_join<It, char> join(It begin, It end, string_view sep) {
3266 return {begin, end, sep};
3267 }
3268
3269 template <typename It>
3270 arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) {
3271 return {begin, end, sep};
3272 }
3273
3274 /**
3275 \rst
3276 Returns an object that formats `range` with elements separated by `sep`.
3277
3278 **Example**::
3279
3280 std::vector<int> v = {1, 2, 3};
3281 fmt::print("{}", fmt::join(v, ", "));
3282 // Output: "1, 2, 3"
3283 \endrst
3284 */
3285 template <typename Range>
3286 arg_join<internal::iterator_t<const Range>, char> join(const Range& range,
3287 string_view sep) {
3288 return join(std::begin(range), std::end(range), sep);
3289 }
3290
3291 template <typename Range>
3292 arg_join<internal::iterator_t<const Range>, wchar_t> join(const Range& range,
3293 wstring_view sep) {
3294 return join(std::begin(range), std::end(range), sep);
3295 }
3296
3297 /**
3298 \rst
3299 Converts *value* to ``std::string`` using the default format for type *T*.
3300 It doesn't support user-defined types with custom formatters.
3301
3302 **Example**::
3303
3304 #include <fmt/format.h>
3305
3306 std::string answer = fmt::to_string(42);
3307 \endrst
3308 */
3309 template <typename T> inline std::string to_string(const T& value) {
3310 return format("{}", value);
3311 }
3312
3313 /**
3314 Converts *value* to ``std::wstring`` using the default format for type *T*.
3315 */
3316 template <typename T> inline std::wstring to_wstring(const T& value) {
3317 return format(L"{}", value);
3318 }
3319
3320 template <typename Char, std::size_t SIZE>
3321 std::basic_string<Char> to_string(const basic_memory_buffer<Char, SIZE>& buf) {
3322 return std::basic_string<Char>(buf.data(), buf.size());
3323 }
3324
3325 template <typename Char>
3326 typename buffer_context<Char>::iterator internal::vformat_to(
3327 internal::buffer<Char>& buf, basic_string_view<Char> format_str,
3328 basic_format_args<buffer_context<Char>> args) {
3329 using range = buffer_range<Char>;
3330 return vformat_to<arg_formatter<range>>(buf, to_string_view(format_str),
3331 args);
3332 }
3333
3334 template <typename S, typename Char = char_t<S>,
3335 FMT_ENABLE_IF(internal::is_string<S>::value)>
3336 inline typename buffer_context<Char>::iterator vformat_to(
3337 internal::buffer<Char>& buf, const S& format_str,
3338 basic_format_args<buffer_context<Char>> args) {
3339 return internal::vformat_to(buf, to_string_view(format_str), args);
3340 }
3341
3342 template <typename S, typename... Args, std::size_t SIZE = inline_buffer_size,
3343 typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
3344 inline typename buffer_context<Char>::iterator format_to(
3345 basic_memory_buffer<Char, SIZE>& buf, const S& format_str, Args&&... args) {
3346 internal::check_format_string<Args...>(format_str);
3347 using context = buffer_context<Char>;
3348 return internal::vformat_to(buf, to_string_view(format_str),
3349 {make_format_args<context>(args...)});
3350 }
3351
3352 template <typename OutputIt, typename Char = char>
3353 using format_context_t = basic_format_context<OutputIt, Char>;
3354
3355 template <typename OutputIt, typename Char = char>
3356 using format_args_t = basic_format_args<format_context_t<OutputIt, Char>>;
3357
3358 template <typename S, typename OutputIt, typename... Args,
3359 FMT_ENABLE_IF(
3360 internal::is_output_iterator<OutputIt>::value &&
3361 !internal::is_contiguous_back_insert_iterator<OutputIt>::value)>
3362 inline OutputIt vformat_to(OutputIt out, const S& format_str,
3363 format_args_t<OutputIt, char_t<S>> args) {
3364 using range = internal::output_range<OutputIt, char_t<S>>;
3365 return vformat_to<arg_formatter<range>>(range(out),
3366 to_string_view(format_str), args);
3367 }
3368
3369 /**
3370 \rst
3371 Formats arguments, writes the result to the output iterator ``out`` and returns
3372 the iterator past the end of the output range.
3373
3374 **Example**::
3375
3376 std::vector<char> out;
3377 fmt::format_to(std::back_inserter(out), "{}", 42);
3378 \endrst
3379 */
3380 template <typename OutputIt, typename S, typename... Args,
3381 FMT_ENABLE_IF(
3382 internal::is_output_iterator<OutputIt>::value &&
3383 !internal::is_contiguous_back_insert_iterator<OutputIt>::value &&
3384 internal::is_string<S>::value)>
3385 inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) {
3386 internal::check_format_string<Args...>(format_str);
3387 using context = format_context_t<OutputIt, char_t<S>>;
3388 return vformat_to(out, to_string_view(format_str),
3389 {make_format_args<context>(args...)});
3390 }
3391
3392 template <typename OutputIt> struct format_to_n_result {
3393 /** Iterator past the end of the output range. */
3394 OutputIt out;
3395 /** Total (not truncated) output size. */
3396 std::size_t size;
3397 };
3398
3399 template <typename OutputIt, typename Char = typename OutputIt::value_type>
3400 using format_to_n_context =
3401 format_context_t<fmt::internal::truncating_iterator<OutputIt>, Char>;
3402
3403 template <typename OutputIt, typename Char = typename OutputIt::value_type>
3404 using format_to_n_args = basic_format_args<format_to_n_context<OutputIt, Char>>;
3405
3406 template <typename OutputIt, typename Char, typename... Args>
3407 inline format_arg_store<format_to_n_context<OutputIt, Char>, Args...>
3408 make_format_to_n_args(const Args&... args) {
3409 return format_arg_store<format_to_n_context<OutputIt, Char>, Args...>(
3410 args...);
3411 }
3412
3413 template <typename OutputIt, typename Char, typename... Args,
3414 FMT_ENABLE_IF(internal::is_output_iterator<OutputIt>::value)>
3415 inline format_to_n_result<OutputIt> vformat_to_n(
3416 OutputIt out, std::size_t n, basic_string_view<Char> format_str,
3417 format_to_n_args<OutputIt, Char> args) {
3418 auto it = vformat_to(internal::truncating_iterator<OutputIt>(out, n),
3419 format_str, args);
3420 return {it.base(), it.count()};
3421 }
3422
3423 /**
3424 \rst
3425 Formats arguments, writes up to ``n`` characters of the result to the output
3426 iterator ``out`` and returns the total output size and the iterator past the
3427 end of the output range.
3428 \endrst
3429 */
3430 template <typename OutputIt, typename S, typename... Args,
3431 FMT_ENABLE_IF(internal::is_string<S>::value&&
3432 internal::is_output_iterator<OutputIt>::value)>
3433 inline format_to_n_result<OutputIt> format_to_n(OutputIt out, std::size_t n,
3434 const S& format_str,
3435 const Args&... args) {
3436 internal::check_format_string<Args...>(format_str);
3437 using context = format_to_n_context<OutputIt, char_t<S>>;
3438 return vformat_to_n(out, n, to_string_view(format_str),
3439 {make_format_args<context>(args...)});
3440 }
3441
3442 template <typename Char>
3443 inline std::basic_string<Char> internal::vformat(
3444 basic_string_view<Char> format_str,
3445 basic_format_args<buffer_context<Char>> args) {
3446 basic_memory_buffer<Char> buffer;
3447 internal::vformat_to(buffer, format_str, args);
3448 return fmt::to_string(buffer);
3449 }
3450
3451 /**
3452 Returns the number of characters in the output of
3453 ``format(format_str, args...)``.
3454 */
3455 template <typename... Args>
3456 inline std::size_t formatted_size(string_view format_str, const Args&... args) {
3457 auto it = format_to(internal::counting_iterator<char>(), format_str, args...);
3458 return it.count();
3459 }
3460
3461 #if FMT_USE_USER_DEFINED_LITERALS
3462 namespace internal {
3463
3464 # if FMT_USE_UDL_TEMPLATE
3465 template <typename Char, Char... CHARS> class udl_formatter {
3466 public:
3467 template <typename... Args>
3468 std::basic_string<Char> operator()(Args&&... args) const {
3469 FMT_CONSTEXPR_DECL Char s[] = {CHARS..., '\0'};
3470 FMT_CONSTEXPR_DECL bool invalid_format =
3471 do_check_format_string<Char, error_handler, Args...>(
3472 basic_string_view<Char>(s, sizeof...(CHARS)));
3473 (void)invalid_format;
3474 return format(s, std::forward<Args>(args)...);
3475 }
3476 };
3477 # else
3478 template <typename Char> struct udl_formatter {
3479 basic_string_view<Char> str;
3480
3481 template <typename... Args>
3482 std::basic_string<Char> operator()(Args&&... args) const {
3483 return format(str, std::forward<Args>(args)...);
3484 }
3485 };
3486 # endif // FMT_USE_UDL_TEMPLATE
3487
3488 template <typename Char> struct udl_arg {
3489 basic_string_view<Char> str;
3490
3491 template <typename T> named_arg<T, Char> operator=(T&& value) const {
3492 return {str, std::forward<T>(value)};
3493 }
3494 };
3495
3496 } // namespace internal
3497
3498 inline namespace literals {
3499 # if FMT_USE_UDL_TEMPLATE
3500 # pragma GCC diagnostic push
3501 # if FMT_CLANG_VERSION
3502 # pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template"
3503 # endif
3504 template <typename Char, Char... CHARS>
3505 FMT_CONSTEXPR internal::udl_formatter<Char, CHARS...> operator""_format() {
3506 return {};
3507 }
3508 # pragma GCC diagnostic pop
3509 # else
3510 /**
3511 \rst
3512 User-defined literal equivalent of :func:`fmt::format`.
3513
3514 **Example**::
3515
3516 using namespace fmt::literals;
3517 std::string message = "The answer is {}"_format(42);
3518 \endrst
3519 */
3520 FMT_CONSTEXPR internal::udl_formatter<char> operator"" _format(const char* s,
3521 std::size_t n) {
3522 return {{s, n}};
3523 }
3524 FMT_CONSTEXPR internal::udl_formatter<wchar_t> operator"" _format(
3525 const wchar_t* s, std::size_t n) {
3526 return {{s, n}};
3527 }
3528 # endif // FMT_USE_UDL_TEMPLATE
3529
3530 /**
3531 \rst
3532 User-defined literal equivalent of :func:`fmt::arg`.
3533
3534 **Example**::
3535
3536 using namespace fmt::literals;
3537 fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
3538 \endrst
3539 */
3540 FMT_CONSTEXPR internal::udl_arg<char> operator"" _a(const char* s,
3541 std::size_t n) {
3542 return {{s, n}};
3543 }
3544 FMT_CONSTEXPR internal::udl_arg<wchar_t> operator"" _a(const wchar_t* s,
3545 std::size_t n) {
3546 return {{s, n}};
3547 }
3548 } // namespace literals
3549 #endif // FMT_USE_USER_DEFINED_LITERALS
3550 FMT_END_NAMESPACE
3551
3552 /**
3553 \rst
3554 Constructs a compile-time format string.
3555
3556 **Example**::
3557
3558 // A compile-time error because 'd' is an invalid specifier for strings.
3559 std::string s = format(FMT_STRING("{:d}"), "foo");
3560 \endrst
3561 */
3562 #define FMT_STRING(s) \
3563 [] { \
3564 struct str : fmt::compile_string { \
3565 using char_type = typename std::remove_cv<std::remove_pointer< \
3566 typename std::decay<decltype(s)>::type>::type>::type; \
3567 FMT_CONSTEXPR operator fmt::basic_string_view<char_type>() const { \
3568 return {s, sizeof(s) / sizeof(char_type) - 1}; \
3569 } \
3570 } result; \
3571 /* Suppress Qt Creator warning about unused operator. */ \
3572 (void)static_cast<fmt::basic_string_view<typename str::char_type>>( \
3573 result); \
3574 return result; \
3575 }()
3576
3577 #if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS
3578 /**
3579 \rst
3580 Constructs a compile-time format string. This macro is disabled by default to
3581 prevent potential name collisions. To enable it define ``FMT_STRING_ALIAS`` to
3582 1 before including ``fmt/format.h``.
3583
3584 **Example**::
3585
3586 #define FMT_STRING_ALIAS 1
3587 #include <fmt/format.h>
3588 // A compile-time error because 'd' is an invalid specifier for strings.
3589 std::string s = format(fmt("{:d}"), "foo");
3590 \endrst
3591 */
3592 # define fmt(s) FMT_STRING(s)
3593 #endif
3594
3595 #ifdef FMT_HEADER_ONLY
3596 # define FMT_FUNC inline
3597 # include "format-inl.h"
3598 #else
3599 # define FMT_FUNC
3600 #endif
3601
3602 #endif // FMT_FORMAT_H_
3603