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