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