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


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:47:34