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