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