HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 implicit conversions that may change the sign of
70 // an integer; silencing it otherwise would require many explicit casts.
71 # pragma GCC diagnostic ignored "-Wsign-conversion"
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>
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:
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 
364 /** A formatting error such as invalid format string. */
365 class format_error : public std::runtime_error {
366  public:
367  explicit format_error(const char *message)
368  : std::runtime_error(message) {}
369 
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 
433 /**
434  \rst
435  A dynamically growing memory buffer for trivially copyable/constructible types
436  with the first ``SIZE`` elements stored in the object itself.
437 
438  You can use one of the following typedefs for common character types:
439 
440  +----------------+------------------------------+
441  | Type | Definition |
442  +================+==============================+
443  | memory_buffer | basic_memory_buffer<char> |
444  +----------------+------------------------------+
445  | wmemory_buffer | basic_memory_buffer<wchar_t> |
446  +----------------+------------------------------+
447 
448  **Example**::
449 
450  fmt::memory_buffer out;
451  format_to(out, "The answer is {}.", 42);
452 
453  This will append the following output to the ``out`` object:
454 
455  .. code-block:: none
456 
457  The answer is 42.
458 
459  The output can be converted to an ``std::string`` with ``to_string(out)``.
460  \endrst
461  */
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  explicit basic_memory_buffer(const Allocator &alloc = Allocator())
479  : Allocator(alloc) {
480  this->set(store_, SIZE);
481  }
482  ~basic_memory_buffer() { deallocate(); }
483 
484  private:
485  // Move data from other to this buffer.
486  void move(basic_memory_buffer &other) {
487  Allocator &this_alloc = *this, &other_alloc = other;
488  this_alloc = std::move(other_alloc);
489  T* data = other.data();
490  std::size_t size = other.size(), capacity = other.capacity();
491  if (data == other.store_) {
492  this->set(store_, capacity);
493  std::uninitialized_copy(other.store_, other.store_ + size,
494  internal::make_checked(store_, capacity));
495  } else {
496  this->set(data, capacity);
497  // Set pointer to the inline array so that delete is not called
498  // when deallocating.
499  other.set(other.store_, 0);
500  }
501  this->resize(size);
502  }
503 
504  public:
505  /**
506  \rst
507  Constructs a :class:`fmt::basic_memory_buffer` object moving the content
508  of the other object to it.
509  \endrst
510  */
512  move(other);
513  }
514 
515  /**
516  \rst
517  Moves the content of the other ``basic_memory_buffer`` object to this one.
518  \endrst
519  */
521  assert(this != &other);
522  deallocate();
523  move(other);
524  return *this;
525  }
526 
527  // Returns a copy of the allocator associated with this buffer.
528  Allocator get_allocator() const { return *this; }
529 };
530 
531 template <typename T, std::size_t SIZE, typename Allocator>
533  std::size_t old_capacity = this->capacity();
534  std::size_t new_capacity = old_capacity + old_capacity / 2;
535  if (size > new_capacity)
536  new_capacity = size;
537  T *old_data = this->data();
538  T *new_data = internal::allocate<Allocator>(*this, new_capacity);
539  // The following code doesn't throw, so the raw pointer above doesn't leak.
540  std::uninitialized_copy(old_data, old_data + this->size(),
541  internal::make_checked(new_data, new_capacity));
542  this->set(new_data, new_capacity);
543  // deallocate must not throw according to the standard, but even if it does,
544  // the buffer already uses the new storage and will deallocate it in
545  // destructor.
546  if (old_data != store_)
547  Allocator::deallocate(old_data, old_capacity);
548 }
549 
552 
553 namespace internal {
554 
555 template <typename Char>
556 struct char_traits;
557 
558 template <>
559 struct char_traits<char> {
560  // Formats a floating-point number.
561  template <typename T>
562  FMT_API static int format_float(char *buffer, std::size_t size,
563  const char *format, int precision, T value);
564 };
565 
566 template <>
567 struct char_traits<wchar_t> {
568  template <typename T>
569  FMT_API static int format_float(wchar_t *buffer, std::size_t size,
570  const wchar_t *format, int precision, T value);
571 };
572 
573 #if FMT_USE_EXTERN_TEMPLATES
574 extern template int char_traits<char>::format_float<double>(
575  char *buffer, std::size_t size, const char* format, int precision,
576  double value);
577 extern template int char_traits<char>::format_float<long double>(
578  char *buffer, std::size_t size, const char* format, int precision,
579  long double value);
580 
581 extern template int char_traits<wchar_t>::format_float<double>(
582  wchar_t *buffer, std::size_t size, const wchar_t* format, int precision,
583  double value);
584 extern template int char_traits<wchar_t>::format_float<long double>(
585  wchar_t *buffer, std::size_t size, const wchar_t* format, int precision,
586  long double value);
587 #endif
588 
589 template <typename Container>
590 inline typename std::enable_if<
593  reserve(std::back_insert_iterator<Container> &it, std::size_t n) {
594  Container &c = internal::get_container(it);
595  std::size_t size = c.size();
596  c.resize(size + n);
597  return make_checked(&c[size], n);
598 }
599 
600 template <typename Iterator>
601 inline Iterator &reserve(Iterator &it, std::size_t) { return it; }
602 
603 template <typename Char>
605 
606 template <typename Char>
608 
609 // An iterator that produces a null terminator on *end. This simplifies parsing
610 // and allows comparing the performance of processing a null-terminated string
611 // vs string_view.
612 template <typename Char>
614  public:
615  typedef std::ptrdiff_t difference_type;
616  typedef Char value_type;
617  typedef const Char* pointer;
618  typedef const Char& reference;
619  typedef std::random_access_iterator_tag iterator_category;
620 
621  null_terminating_iterator() : ptr_(0), end_(0) {}
622 
623  FMT_CONSTEXPR null_terminating_iterator(const Char *ptr, const Char *end)
624  : ptr_(ptr), end_(end) {}
625 
626  template <typename Range>
628  : ptr_(r.begin()), end_(r.end()) {}
629 
631  assert(ptr <= end_);
632  ptr_ = ptr;
633  return *this;
634  }
635 
636  FMT_CONSTEXPR Char operator*() const {
637  return ptr_ != end_ ? *ptr_ : Char();
638  }
639 
641  ++ptr_;
642  return *this;
643  }
644 
647  ++ptr_;
648  return result;
649  }
650 
652  --ptr_;
653  return *this;
654  }
655 
657  return null_terminating_iterator(ptr_ + n, end_);
658  }
659 
661  return null_terminating_iterator(ptr_ - n, end_);
662  }
663 
665  ptr_ += n;
666  return *this;
667  }
668 
670  null_terminating_iterator other) const {
671  return ptr_ - other.ptr_;
672  }
673 
675  return ptr_ != other.ptr_;
676  }
677 
679  return ptr_ >= other.ptr_;
680  }
681 
682  // This should be a friend specialization pointer_from<Char> but the latter
683  // doesn't compile by gcc 5.1 due to a compiler bug.
684  template <typename CharT>
685  friend FMT_CONSTEXPR_DECL const CharT *pointer_from(
687 
688  private:
689  const Char *ptr_;
690  const Char *end_;
691 };
692 
693 template <typename T>
694 FMT_CONSTEXPR const T *pointer_from(const T *p) { return p; }
695 
696 template <typename Char>
698  return it.ptr_;
699 }
700 
701 // An output iterator that counts the number of objects written to it and
702 // discards them.
703 template <typename T>
705  private:
706  std::size_t count_;
707  mutable T blackhole_;
708 
709  public:
710  typedef std::output_iterator_tag iterator_category;
711  typedef T value_type;
712  typedef std::ptrdiff_t difference_type;
713  typedef T* pointer;
714  typedef T& reference;
715  typedef counting_iterator _Unchecked_type; // Mark iterator as checked.
716 
717  counting_iterator(): count_(0) {}
718 
719  std::size_t count() const { return count_; }
720 
722  ++count_;
723  return *this;
724  }
725 
727  auto it = *this;
728  ++*this;
729  return it;
730  }
731 
732  T &operator*() const { return blackhole_; }
733 };
734 
735 template <typename OutputIt>
737  protected:
738  OutputIt out_;
739  std::size_t limit_;
740  std::size_t count_;
741 
742  truncating_iterator_base(OutputIt out, std::size_t limit)
743  : out_(out), limit_(limit), count_(0) {}
744 
745  public:
746  typedef std::output_iterator_tag iterator_category;
747  typedef void difference_type;
748  typedef void pointer;
749  typedef void reference;
750  typedef truncating_iterator_base _Unchecked_type; // Mark iterator as checked.
751 
752  OutputIt base() const { return out_; }
753  std::size_t count() const { return count_; }
754 };
755 
756 // An output iterator that truncates the output and counts the number of objects
757 // written to it.
758 template <typename OutputIt, typename Enable = typename std::is_void<
761 
762 template <typename OutputIt>
763 class truncating_iterator<OutputIt, std::false_type>:
764  public truncating_iterator_base<OutputIt> {
765  typedef std::iterator_traits<OutputIt> traits;
766 
767  mutable typename traits::value_type blackhole_;
768 
769  public:
770  typedef typename traits::value_type value_type;
771 
772  truncating_iterator(OutputIt out, std::size_t limit)
773  : truncating_iterator_base<OutputIt>(out, limit) {}
774 
776  if (this->count_++ < this->limit_)
777  ++this->out_;
778  return *this;
779  }
780 
782  auto it = *this;
783  ++*this;
784  return it;
785  }
786 
788  return this->count_ < this->limit_ ? *this->out_ : blackhole_;
789  }
790 };
791 
792 template <typename OutputIt>
793 class truncating_iterator<OutputIt, std::true_type>:
794  public truncating_iterator_base<OutputIt> {
795  public:
797 
798  truncating_iterator(OutputIt out, std::size_t limit)
799  : truncating_iterator_base<OutputIt>(out, limit) {}
800 
802  if (this->count_++ < this->limit_)
803  this->out_ = val;
804  return *this;
805  }
806 
807  truncating_iterator& operator++() { return *this; }
808  truncating_iterator& operator++(int) { return *this; }
809  truncating_iterator& operator*() { return *this; }
810 };
811 
812 // Returns true if value is negative, false otherwise.
813 // Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
814 template <typename T>
815 FMT_CONSTEXPR typename std::enable_if<
816  std::numeric_limits<T>::is_signed, bool>::type is_negative(T value) {
817  return value < 0;
818 }
819 template <typename T>
820 FMT_CONSTEXPR typename std::enable_if<
821  !std::numeric_limits<T>::is_signed, bool>::type is_negative(T) {
822  return false;
823 }
824 
825 template <typename T>
826 struct int_traits {
827  // Smallest of uint32_t and uint64_t that is large enough to represent
828  // all values of T.
829  typedef typename std::conditional<
830  std::numeric_limits<T>::digits <= 32, uint32_t, uint64_t>::type main_type;
831 };
832 
833 // Static data is placed in this class template to allow header-only
834 // configuration.
835 template <typename T = void>
837  static const uint32_t POWERS_OF_10_32[];
838  static const uint32_t ZERO_OR_POWERS_OF_10_32[];
839  static const uint64_t ZERO_OR_POWERS_OF_10_64[];
840  static const uint64_t POW10_SIGNIFICANDS[];
841  static const int16_t POW10_EXPONENTS[];
842  static const char DIGITS[];
843  static const char FOREGROUND_COLOR[];
844  static const char BACKGROUND_COLOR[];
845  static const char RESET_COLOR[];
846  static const wchar_t WRESET_COLOR[];
847 };
848 
849 #if FMT_USE_EXTERN_TEMPLATES
850 extern template struct basic_data<void>;
851 #endif
852 
854 
855 #ifdef FMT_BUILTIN_CLZLL
856 // Returns the number of decimal digits in n. Leading zeros are not counted
857 // except for n == 0 in which case count_digits returns 1.
858 inline unsigned count_digits(uint64_t n) {
859  // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
860  // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
861  int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
862  return to_unsigned(t) - (n < data::ZERO_OR_POWERS_OF_10_64[t]) + 1;
863 }
864 #else
865 // Fallback version of count_digits used when __builtin_clz is not available.
866 inline unsigned count_digits(uint64_t n) {
867  unsigned count = 1;
868  for (;;) {
869  // Integer division is slow so do it for a group of four digits instead
870  // of for every digit. The idea comes from the talk by Alexandrescu
871  // "Three Optimization Tips for C++". See speed-test for a comparison.
872  if (n < 10) return count;
873  if (n < 100) return count + 1;
874  if (n < 1000) return count + 2;
875  if (n < 10000) return count + 3;
876  n /= 10000u;
877  count += 4;
878  }
879 }
880 #endif
881 
882 template <typename Char>
883 inline size_t count_code_points(basic_string_view<Char> s) { return s.size(); }
884 
885 // Counts the number of code points in a UTF-8 string.
887 
888 inline char8_t to_char8_t(char c) { return static_cast<char8_t>(c); }
889 
890 template <typename InputIt, typename OutChar>
891 struct needs_conversion: std::integral_constant<bool,
892  std::is_same<
895 
896 template <typename OutChar, typename InputIt, typename OutputIt>
897 typename std::enable_if<
899  copy_str(InputIt begin, InputIt end, OutputIt it) {
900  return std::copy(begin, end, it);
901 }
902 
903 template <typename OutChar, typename InputIt, typename OutputIt>
904 typename std::enable_if<
906  copy_str(InputIt begin, InputIt end, OutputIt it) {
907  return std::transform(begin, end, it, to_char8_t);
908 }
909 
910 #if FMT_HAS_CPP_ATTRIBUTE(always_inline)
911 # define FMT_ALWAYS_INLINE __attribute__((always_inline))
912 #else
913 # define FMT_ALWAYS_INLINE
914 #endif
915 
916 template <typename Handler>
917 inline char *lg(uint32_t n, Handler h) FMT_ALWAYS_INLINE;
918 
919 // Computes g = floor(log10(n)) and calls h.on<g>(n);
920 template <typename Handler>
921 inline char *lg(uint32_t n, Handler h) {
922  return n < 100 ? n < 10 ? h.template on<0>(n) : h.template on<1>(n)
923  : n < 1000000
924  ? n < 10000 ? n < 1000 ? h.template on<2>(n)
925  : h.template on<3>(n)
926  : n < 100000 ? h.template on<4>(n)
927  : h.template on<5>(n)
928  : n < 100000000 ? n < 10000000 ? h.template on<6>(n)
929  : h.template on<7>(n)
930  : n < 1000000000 ? h.template on<8>(n)
931  : h.template on<9>(n);
932 }
933 
934 // An lg handler that formats a decimal number.
935 // Usage: lg(n, decimal_formatter(buffer));
937  private:
938  char *buffer_;
939 
940  void write_pair(unsigned N, uint32_t index) {
941  std::memcpy(buffer_ + N, data::DIGITS + index * 2, 2);
942  }
943 
944  public:
945  explicit decimal_formatter(char *buf) : buffer_(buf) {}
946 
947  template <unsigned N> char *on(uint32_t u) {
948  if (N == 0) {
949  *buffer_ = static_cast<char>(u) + '0';
950  } else if (N == 1) {
951  write_pair(0, u);
952  } else {
953  // The idea of using 4.32 fixed-point numbers is based on
954  // https://github.com/jeaiii/itoa
955  unsigned n = N - 1;
956  unsigned a = n / 5 * n * 53 / 16;
957  uint64_t t = ((1ULL << (32 + a)) /
958  data::ZERO_OR_POWERS_OF_10_32[n] + 1 - n / 9);
959  t = ((t * u) >> a) + n / 5 * 4;
960  write_pair(0, t >> 32);
961  for (unsigned i = 2; i < N; i += 2) {
962  t = 100ULL * static_cast<uint32_t>(t);
963  write_pair(i, t >> 32);
964  }
965  if (N % 2 == 0) {
966  buffer_[N] = static_cast<char>(
967  (10ULL * static_cast<uint32_t>(t)) >> 32) + '0';
968  }
969  }
970  return buffer_ += N + 1;
971  }
972 };
973 
974 // An lg handler that formats a decimal number with a terminating null.
976  public:
977  explicit decimal_formatter_null(char *buf) : decimal_formatter(buf) {}
978 
979  template <unsigned N> char *on(uint32_t u) {
980  char *buf = decimal_formatter::on<N>(u);
981  *buf = '\0';
982  return buf;
983  }
984 };
985 
986 #ifdef FMT_BUILTIN_CLZ
987 // Optional version of count_digits for better performance on 32-bit platforms.
988 inline unsigned count_digits(uint32_t n) {
989  int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
990  return to_unsigned(t) - (n < data::ZERO_OR_POWERS_OF_10_32[t]) + 1;
991 }
992 #endif
993 
994 // A functor that doesn't add a thousands separator.
996  typedef char char_type;
997 
998  template <typename Char>
999  void operator()(Char *) {}
1000 
1001  enum { size = 0 };
1002 };
1003 
1004 // A functor that adds a thousands separator.
1005 template <typename Char>
1007  private:
1009 
1010  // Index of a decimal digit with the least significant digit having index 0.
1011  unsigned digit_index_;
1012 
1013  public:
1014  typedef Char char_type;
1015 
1017  : sep_(sep), digit_index_(0) {}
1018 
1019  void operator()(Char *&buffer) {
1020  if (++digit_index_ % 3 != 0)
1021  return;
1022  buffer -= sep_.size();
1023  std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(),
1024  internal::make_checked(buffer, sep_.size()));
1025  }
1026 
1027  enum { size = 1 };
1028 };
1029 
1030 template <typename Char>
1031 FMT_API Char thousands_sep_impl(locale_ref loc);
1032 
1033 template <typename Char>
1034 inline Char thousands_sep(locale_ref loc) {
1035  return Char(thousands_sep_impl<char>(loc));
1036 }
1037 
1038 template <>
1039 inline wchar_t thousands_sep(locale_ref loc) {
1040  return thousands_sep_impl<wchar_t>(loc);
1041 }
1042 
1043 // Formats a decimal unsigned integer value writing into buffer.
1044 // thousands_sep is a functor that is called after writing each char to
1045 // add a thousands separator if necessary.
1046 template <typename UInt, typename Char, typename ThousandsSep>
1047 inline Char *format_decimal(Char *buffer, UInt value, unsigned num_digits,
1048  ThousandsSep thousands_sep) {
1049  buffer += num_digits;
1050  Char *end = buffer;
1051  while (value >= 100) {
1052  // Integer division is slow so do it for a group of two digits instead
1053  // of for every digit. The idea comes from the talk by Alexandrescu
1054  // "Three Optimization Tips for C++". See speed-test for a comparison.
1055  unsigned index = static_cast<unsigned>((value % 100) * 2);
1056  value /= 100;
1057  *--buffer = static_cast<Char>(data::DIGITS[index + 1]);
1058  thousands_sep(buffer);
1059  *--buffer = static_cast<Char>(data::DIGITS[index]);
1060  thousands_sep(buffer);
1061  }
1062  if (value < 10) {
1063  *--buffer = static_cast<Char>('0' + value);
1064  return end;
1065  }
1066  unsigned index = static_cast<unsigned>(value * 2);
1067  *--buffer = static_cast<Char>(data::DIGITS[index + 1]);
1068  thousands_sep(buffer);
1069  *--buffer = static_cast<Char>(data::DIGITS[index]);
1070  return end;
1071 }
1072 
1073 template <typename OutChar, typename UInt, typename Iterator,
1074  typename ThousandsSep>
1075 inline Iterator format_decimal(
1076  Iterator out, UInt value, unsigned num_digits, ThousandsSep sep) {
1077  typedef typename ThousandsSep::char_type char_type;
1078  // Buffer should be large enough to hold all digits (<= digits10 + 1).
1079  enum { max_size = std::numeric_limits<UInt>::digits10 + 1 };
1080  FMT_ASSERT(ThousandsSep::size <= 1, "invalid separator");
1081  char_type buffer[max_size + max_size / 3];
1082  auto end = format_decimal(buffer, value, num_digits, sep);
1083  return internal::copy_str<OutChar>(buffer, end, out);
1084 }
1085 
1086 template <typename OutChar, typename It, typename UInt>
1087 inline It format_decimal(It out, UInt value, unsigned num_digits) {
1088  return format_decimal<OutChar>(out, value, num_digits, no_thousands_sep());
1089 }
1090 
1091 template <unsigned BASE_BITS, typename Char, typename UInt>
1092 inline Char *format_uint(Char *buffer, UInt value, unsigned num_digits,
1093  bool upper = false) {
1094  buffer += num_digits;
1095  Char *end = buffer;
1096  do {
1097  const char *digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
1098  unsigned digit = (value & ((1 << BASE_BITS) - 1));
1099  *--buffer = static_cast<Char>(BASE_BITS < 4 ? '0' + digit : digits[digit]);
1100  } while ((value >>= BASE_BITS) != 0);
1101  return end;
1102 }
1103 
1104 template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
1105 inline It format_uint(It out, UInt value, unsigned num_digits,
1106  bool upper = false) {
1107  // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1)
1108  // and null.
1109  char buffer[std::numeric_limits<UInt>::digits / BASE_BITS + 2];
1110  format_uint<BASE_BITS>(buffer, value, num_digits, upper);
1111  return internal::copy_str<Char>(buffer, buffer + num_digits, out);
1112 }
1113 
1114 #ifndef _WIN32
1115 # define FMT_USE_WINDOWS_H 0
1116 #elif !defined(FMT_USE_WINDOWS_H)
1117 # define FMT_USE_WINDOWS_H 1
1118 #endif
1119 
1120 // Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
1121 // All the functionality that relies on it will be disabled too.
1122 #if FMT_USE_WINDOWS_H
1123 // A converter from UTF-8 to UTF-16.
1124 // It is only provided for Windows since other systems support UTF-8 natively.
1125 class utf8_to_utf16 {
1126  private:
1127  wmemory_buffer buffer_;
1128 
1129  public:
1130  FMT_API explicit utf8_to_utf16(string_view s);
1131  operator wstring_view() const { return wstring_view(&buffer_[0], size()); }
1132  size_t size() const { return buffer_.size() - 1; }
1133  const wchar_t *c_str() const { return &buffer_[0]; }
1134  std::wstring str() const { return std::wstring(&buffer_[0], size()); }
1135 };
1136 
1137 // A converter from UTF-16 to UTF-8.
1138 // It is only provided for Windows since other systems support UTF-8 natively.
1139 class utf16_to_utf8 {
1140  private:
1141  memory_buffer buffer_;
1142 
1143  public:
1144  utf16_to_utf8() {}
1145  FMT_API explicit utf16_to_utf8(wstring_view s);
1146  operator string_view() const { return string_view(&buffer_[0], size()); }
1147  size_t size() const { return buffer_.size() - 1; }
1148  const char *c_str() const { return &buffer_[0]; }
1149  std::string str() const { return std::string(&buffer_[0], size()); }
1150 
1151  // Performs conversion returning a system error code instead of
1152  // throwing exception on conversion error. This method may still throw
1153  // in case of memory allocation error.
1155 };
1156 
1157 FMT_API void format_windows_error(fmt::internal::buffer &out, int error_code,
1159 #endif
1160 
1161 template <typename T = void>
1162 struct null {};
1163 } // namespace internal
1164 
1167 };
1168 
1169 // Flags.
1170 enum { SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8 };
1171 
1172 // An alignment specifier.
1173 struct align_spec {
1174  unsigned width_;
1175  // Fill is always wchar_t and cast to char if necessary to avoid having
1176  // two specialization of AlignSpec and its subclasses.
1177  wchar_t fill_;
1179 
1180  FMT_CONSTEXPR align_spec() : width_(0), fill_(' '), align_(ALIGN_DEFAULT) {}
1181  FMT_CONSTEXPR unsigned width() const { return width_; }
1182  FMT_CONSTEXPR wchar_t fill() const { return fill_; }
1183  FMT_CONSTEXPR alignment align() const { return align_; }
1184 };
1185 
1188  uint_least8_t flags;
1189  char type;
1190 
1192  FMT_CONSTEXPR bool has(unsigned f) const { return (flags & f) != 0; }
1193 };
1194 
1195 // Format specifiers.
1196 template <typename Char>
1199 };
1200 
1202 
1203 template <typename Char, typename ErrorHandler>
1205  if (next_arg_id_ >= 0)
1206  return internal::to_unsigned(next_arg_id_++);
1207  on_error("cannot switch from manual to automatic argument indexing");
1208  return 0;
1209 }
1210 
1211 namespace internal {
1212 
1213 // Formats value using Grisu2 algorithm:
1214 // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
1215 template <typename Double>
1218 template <typename Double>
1220  grisu2_format(Double, buffer &, core_format_specs) { return false; }
1221 
1222 template <typename Double>
1224 
1225 template <typename Handler>
1226 FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler &&handler) {
1227  switch (spec) {
1228  case 0: case 'd':
1229  handler.on_dec();
1230  break;
1231  case 'x': case 'X':
1232  handler.on_hex();
1233  break;
1234  case 'b': case 'B':
1235  handler.on_bin();
1236  break;
1237  case 'o':
1238  handler.on_oct();
1239  break;
1240  case 'n':
1241  handler.on_num();
1242  break;
1243  default:
1244  handler.on_error();
1245  }
1246 }
1247 
1248 template <typename Handler>
1249 FMT_CONSTEXPR void handle_float_type_spec(char spec, Handler &&handler) {
1250  switch (spec) {
1251  case 0: case 'g': case 'G':
1252  handler.on_general();
1253  break;
1254  case 'e': case 'E':
1255  handler.on_exp();
1256  break;
1257  case 'f': case 'F':
1258  handler.on_fixed();
1259  break;
1260  case 'a': case 'A':
1261  handler.on_hex();
1262  break;
1263  default:
1264  handler.on_error();
1265  break;
1266  }
1267 }
1268 
1269 template <typename Char, typename Handler>
1271  const basic_format_specs<Char> *specs, Handler &&handler) {
1272  if (!specs) return handler.on_char();
1273  if (specs->type && specs->type != 'c') return handler.on_int();
1274  if (specs->align() == ALIGN_NUMERIC || specs->flags != 0)
1275  handler.on_error("invalid format specifier for char");
1276  handler.on_char();
1277 }
1278 
1279 template <typename Char, typename Handler>
1280 FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler &&handler) {
1281  if (spec == 0 || spec == 's')
1282  handler.on_string();
1283  else if (spec == 'p')
1284  handler.on_pointer();
1285  else
1286  handler.on_error("invalid type specifier");
1287 }
1288 
1289 template <typename Char, typename ErrorHandler>
1291  if (spec != 0 && spec != 's')
1292  eh.on_error("invalid type specifier");
1293 }
1294 
1295 template <typename Char, typename ErrorHandler>
1297  if (spec != 0 && spec != 'p')
1298  eh.on_error("invalid type specifier");
1299 }
1300 
1301 template <typename ErrorHandler>
1303  public:
1305 
1311 
1313  ErrorHandler::on_error("invalid type specifier");
1314  }
1315 };
1316 
1317 template <typename ErrorHandler>
1319  public:
1321  : ErrorHandler(eh) {}
1322 
1327 
1329  ErrorHandler::on_error("invalid type specifier");
1330  }
1331 };
1332 
1333 template <typename ErrorHandler>
1335  private:
1336  char type_;
1337 
1338  public:
1340  : ErrorHandler(eh), type_(type) {}
1341 
1344  }
1346 };
1347 
1348 template <typename ErrorHandler>
1350  public:
1352  : ErrorHandler(eh) {}
1353 
1356 };
1357 
1358 template <typename Context>
1360  if (map_)
1361  return;
1362  map_ = new entry[args.max_size()];
1363  bool use_values = args.type(max_packed_args - 1) == internal::none_type;
1364  if (use_values) {
1365  for (unsigned i = 0;/*nothing*/; ++i) {
1366  internal::type arg_type = args.type(i);
1367  switch (arg_type) {
1368  case internal::none_type:
1369  return;
1371  push_back(args.values_[i]);
1372  break;
1373  default:
1374  break; // Do nothing.
1375  }
1376  }
1377  }
1378  for (unsigned i = 0; ; ++i) {
1379  switch (args.args_[i].type_) {
1380  case internal::none_type:
1381  return;
1383  push_back(args.args_[i].value_);
1384  break;
1385  default:
1386  break; // Do nothing.
1387  }
1388  }
1389 }
1390 
1391 template <typename Range>
1393  public:
1394  typedef typename Range::value_type char_type;
1395  typedef decltype(internal::declval<Range>().begin()) iterator;
1397 
1398  private:
1399  typedef basic_writer<Range> writer_type;
1400  writer_type writer_;
1401  format_specs *specs_;
1402 
1403  struct char_writer {
1404  char_type value;
1405 
1406  size_t size() const { return 1; }
1407  size_t width() const { return 1; }
1408 
1409  template <typename It>
1410  void operator()(It &&it) const { *it++ = value; }
1411  };
1412 
1413  void write_char(char_type value) {
1414  if (specs_)
1415  writer_.write_padded(*specs_, char_writer{value});
1416  else
1417  writer_.write(value);
1418  }
1419 
1420  void write_pointer(const void *p) {
1421  format_specs specs = specs_ ? *specs_ : format_specs();
1422  specs.flags = HASH_FLAG;
1423  specs.type = 'x';
1424  writer_.write_int(reinterpret_cast<uintptr_t>(p), specs);
1425  }
1426 
1427  protected:
1428  writer_type &writer() { return writer_; }
1429  format_specs *spec() { return specs_; }
1430  iterator out() { return writer_.out(); }
1431 
1432  void write(bool value) {
1433  string_view sv(value ? "true" : "false");
1434  specs_ ? writer_.write_str(sv, *specs_) : writer_.write(sv);
1435  }
1436 
1437  void write(const char_type *value) {
1438  if (!value)
1439  FMT_THROW(format_error("string pointer is null"));
1442  specs_ ? writer_.write_str(sv, *specs_) : writer_.write(sv);
1443  }
1444 
1445  public:
1447  : writer_(r, loc), specs_(s) {}
1448 
1449  iterator operator()(monostate) {
1450  FMT_ASSERT(false, "invalid argument type");
1451  return out();
1452  }
1453 
1454  template <typename T>
1455  typename std::enable_if<
1457  iterator>::type operator()(T value) {
1458  // MSVC2013 fails to compile separate overloads for bool and char_type so
1459  // use std::is_same instead.
1461  if (specs_ && specs_->type)
1462  return (*this)(value ? 1 : 0);
1463  write(value != 0);
1464  } else if (std::is_same<T, char_type>::value) {
1466  specs_, char_spec_handler(*this, static_cast<char_type>(value)));
1467  } else {
1468  specs_ ? writer_.write_int(value, *specs_) : writer_.write(value);
1469  }
1470  return out();
1471  }
1472 
1473  template <typename T>
1475  operator()(T value) {
1476  writer_.write_double(value, specs_ ? *specs_ : format_specs());
1477  return out();
1478  }
1479 
1483 
1485  : formatter(f), value(val) {}
1486 
1487  void on_int() {
1488  if (formatter.specs_)
1489  formatter.writer_.write_int(value, *formatter.specs_);
1490  else
1491  formatter.writer_.write(value);
1492  }
1493  void on_char() { formatter.write_char(value); }
1494  };
1495 
1499 
1501  : formatter(f), value(val) {}
1502 
1503  void on_string() { formatter.write(value); }
1504  void on_pointer() { formatter.write_pointer(value); }
1505  };
1506 
1507  iterator operator()(const char_type *value) {
1508  if (!specs_) return write(value), out();
1510  specs_->type, cstring_spec_handler(*this, value));
1511  return out();
1512  }
1513 
1515  if (specs_) {
1517  specs_->type, internal::error_handler());
1518  writer_.write_str(value, *specs_);
1519  } else {
1520  writer_.write(value);
1521  }
1522  return out();
1523  }
1524 
1525  iterator operator()(const void *value) {
1526  if (specs_)
1528  write_pointer(value);
1529  return out();
1530  }
1531 };
1532 
1533 template <typename Char>
1535  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
1536 }
1537 
1538 // DEPRECATED: Parses the input as an unsigned integer. This function assumes
1539 // that the first character is a digit and presence of a non-digit character at
1540 // the end.
1541 // it: an iterator pointing to the beginning of the input range.
1542 template <typename Iterator, typename ErrorHandler>
1543 FMT_CONSTEXPR unsigned parse_nonnegative_int(Iterator &it, ErrorHandler &&eh) {
1544  assert('0' <= *it && *it <= '9');
1545  if (*it == '0') {
1546  ++it;
1547  return 0;
1548  }
1549  unsigned value = 0;
1550  // Convert to unsigned to prevent a warning.
1551  unsigned max_int = (std::numeric_limits<int>::max)();
1552  unsigned big = max_int / 10;
1553  do {
1554  // Check for overflow.
1555  if (value > big) {
1556  value = max_int + 1;
1557  break;
1558  }
1559  value = value * 10 + unsigned(*it - '0');
1560  // Workaround for MSVC "setup_exception stack overflow" error:
1561  auto next = it;
1562  ++next;
1563  it = next;
1564  } while ('0' <= *it && *it <= '9');
1565  if (value > max_int)
1566  eh.on_error("number is too big");
1567  return value;
1568 }
1569 
1570 // Parses the range [begin, end) as an unsigned integer. This function assumes
1571 // that the range is non-empty and the first character is a digit.
1572 template <typename Char, typename ErrorHandler>
1574  const Char *&begin, const Char *end, ErrorHandler &&eh) {
1575  assert(begin != end && '0' <= *begin && *begin <= '9');
1576  if (*begin == '0') {
1577  ++begin;
1578  return 0;
1579  }
1580  unsigned value = 0;
1581  // Convert to unsigned to prevent a warning.
1582  unsigned max_int = (std::numeric_limits<int>::max)();
1583  unsigned big = max_int / 10;
1584  do {
1585  // Check for overflow.
1586  if (value > big) {
1587  value = max_int + 1;
1588  break;
1589  }
1590  value = value * 10 + unsigned(*begin - '0');
1591  ++begin;
1592  } while (begin != end && '0' <= *begin && *begin <= '9');
1593  if (value > max_int)
1594  eh.on_error("number is too big");
1595  return value;
1596 }
1597 
1598 template <typename Char, typename Context>
1599 class custom_formatter: public function<bool> {
1600  private:
1601  Context &ctx_;
1602 
1603  public:
1604  explicit custom_formatter(Context &ctx): ctx_(ctx) {}
1605 
1607  h.format(ctx_);
1608  return true;
1609  }
1610 
1611  template <typename T>
1612  bool operator()(T) const { return false; }
1613 };
1614 
1615 template <typename T>
1616 struct is_integer {
1617  enum {
1620  };
1621 };
1622 
1623 template <typename ErrorHandler>
1624 class width_checker: public function<unsigned long long> {
1625  public:
1626  explicit FMT_CONSTEXPR width_checker(ErrorHandler &eh) : handler_(eh) {}
1627 
1628  template <typename T>
1630  typename std::enable_if<
1631  is_integer<T>::value, unsigned long long>::type operator()(T value) {
1632  if (is_negative(value))
1633  handler_.on_error("negative width");
1634  return static_cast<unsigned long long>(value);
1635  }
1636 
1637  template <typename T>
1638  FMT_CONSTEXPR typename std::enable_if<
1639  !is_integer<T>::value, unsigned long long>::type operator()(T) {
1640  handler_.on_error("width is not integer");
1641  return 0;
1642  }
1643 
1644  private:
1645  ErrorHandler &handler_;
1646 };
1647 
1648 template <typename ErrorHandler>
1649 class precision_checker: public function<unsigned long long> {
1650  public:
1651  explicit FMT_CONSTEXPR precision_checker(ErrorHandler &eh) : handler_(eh) {}
1652 
1653  template <typename T>
1654  FMT_CONSTEXPR typename std::enable_if<
1655  is_integer<T>::value, unsigned long long>::type operator()(T value) {
1656  if (is_negative(value))
1657  handler_.on_error("negative precision");
1658  return static_cast<unsigned long long>(value);
1659  }
1660 
1661  template <typename T>
1662  FMT_CONSTEXPR typename std::enable_if<
1663  !is_integer<T>::value, unsigned long long>::type operator()(T) {
1664  handler_.on_error("precision is not integer");
1665  return 0;
1666  }
1667 
1668  private:
1669  ErrorHandler &handler_;
1670 };
1671 
1672 // A format specifier handler that sets fields in basic_format_specs.
1673 template <typename Char>
1675  public:
1677  specs_(specs) {}
1678 
1679  FMT_CONSTEXPR specs_setter(const specs_setter &other): specs_(other.specs_) {}
1680 
1681  FMT_CONSTEXPR void on_align(alignment align) { specs_.align_ = align; }
1682  FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill_ = fill; }
1683  FMT_CONSTEXPR void on_plus() { specs_.flags |= SIGN_FLAG | PLUS_FLAG; }
1684  FMT_CONSTEXPR void on_minus() { specs_.flags |= MINUS_FLAG; }
1685  FMT_CONSTEXPR void on_space() { specs_.flags |= SIGN_FLAG; }
1686  FMT_CONSTEXPR void on_hash() { specs_.flags |= HASH_FLAG; }
1687 
1689  specs_.align_ = ALIGN_NUMERIC;
1690  specs_.fill_ = '0';
1691  }
1692 
1693  FMT_CONSTEXPR void on_width(unsigned width) { specs_.width_ = width; }
1695  specs_.precision = static_cast<int>(precision);
1696  }
1698 
1700  specs_.type = static_cast<char>(type);
1701  }
1702 
1703  protected:
1705 };
1706 
1707 // A format specifier handler that checks if specifiers are consistent with the
1708 // argument type.
1709 template <typename Handler>
1710 class specs_checker : public Handler {
1711  public:
1712  FMT_CONSTEXPR specs_checker(const Handler& handler, internal::type arg_type)
1713  : Handler(handler), arg_type_(arg_type) {}
1714 
1716  : Handler(other), arg_type_(other.arg_type_) {}
1717 
1719  if (align == ALIGN_NUMERIC)
1720  require_numeric_argument();
1721  Handler::on_align(align);
1722  }
1723 
1725  check_sign();
1726  Handler::on_plus();
1727  }
1728 
1730  check_sign();
1731  Handler::on_minus();
1732  }
1733 
1735  check_sign();
1736  Handler::on_space();
1737  }
1738 
1740  require_numeric_argument();
1741  Handler::on_hash();
1742  }
1743 
1745  require_numeric_argument();
1746  Handler::on_zero();
1747  }
1748 
1750  if (is_integral(arg_type_) || arg_type_ == pointer_type)
1751  this->on_error("precision not allowed for this argument type");
1752  }
1753 
1754  private:
1755  FMT_CONSTEXPR void require_numeric_argument() {
1756  if (!is_arithmetic(arg_type_))
1757  this->on_error("format specifier requires numeric argument");
1758  }
1759 
1760  FMT_CONSTEXPR void check_sign() {
1761  require_numeric_argument();
1762  if (is_integral(arg_type_) && arg_type_ != int_type &&
1763  arg_type_ != long_long_type && arg_type_ != internal::char_type) {
1764  this->on_error("format specifier requires signed argument");
1765  }
1766  }
1767 
1768  internal::type arg_type_;
1769 };
1770 
1771 template <template <typename> class Handler, typename T,
1772  typename Context, typename ErrorHandler>
1774  T &value, basic_format_arg<Context> arg, ErrorHandler eh) {
1775  unsigned long long big_value =
1776  visit_format_arg(Handler<ErrorHandler>(eh), arg);
1777  if (big_value > to_unsigned((std::numeric_limits<int>::max)()))
1778  eh.on_error("number is too big");
1779  value = static_cast<T>(big_value);
1780 }
1781 
1782 struct auto_id {};
1783 
1784 // The standard format specifier handler with checking.
1785 template <typename Context>
1786 class specs_handler: public specs_setter<typename Context::char_type> {
1787  public:
1788  typedef typename Context::char_type char_type;
1789 
1791  basic_format_specs<char_type> &specs, Context &ctx)
1792  : specs_setter<char_type>(specs), context_(ctx) {}
1793 
1794  template <typename Id>
1796  set_dynamic_spec<width_checker>(
1797  this->specs_.width_, get_arg(arg_id), context_.error_handler());
1798  }
1799 
1800  template <typename Id>
1802  set_dynamic_spec<precision_checker>(
1803  this->specs_.precision, get_arg(arg_id), context_.error_handler());
1804  }
1805 
1806  void on_error(const char *message) {
1807  context_.on_error(message);
1808  }
1809 
1810  private:
1812  return context_.next_arg();
1813  }
1814 
1815  template <typename Id>
1816  FMT_CONSTEXPR basic_format_arg<Context> get_arg(Id arg_id) {
1817  context_.parse_context().check_arg_id(arg_id);
1818  return context_.get_arg(arg_id);
1819  }
1820 
1821  Context &context_;
1822 };
1823 
1824 // An argument reference.
1825 template <typename Char>
1826 struct arg_ref {
1827  enum Kind { NONE, INDEX, NAME };
1828 
1829  FMT_CONSTEXPR arg_ref() : kind(NONE), index(0) {}
1830  FMT_CONSTEXPR explicit arg_ref(unsigned index) : kind(INDEX), index(index) {}
1831  explicit arg_ref(basic_string_view<Char> nm) : kind(NAME) {
1832  name = {nm.data(), nm.size()};
1833  }
1834 
1836  kind = INDEX;
1837  index = idx;
1838  return *this;
1839  }
1840 
1842  union {
1843  unsigned index;
1844  string_value<Char> name; // This is not string_view because of gcc 4.4.
1845  };
1846 };
1847 
1848 // Format specifiers with width and precision resolved at formatting rather
1849 // than parsing time to allow re-using the same parsed specifiers with
1850 // differents sets of arguments (precompilation of format strings).
1851 template <typename Char>
1855 };
1856 
1857 // Format spec handler that saves references to arguments representing dynamic
1858 // width and precision to be resolved at formatting time.
1859 template <typename ParseContext>
1861  public specs_setter<typename ParseContext::char_type> {
1862  public:
1864 
1866  dynamic_format_specs<char_type> &specs, ParseContext &ctx)
1867  : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}
1868 
1870  : specs_setter<char_type>(other),
1871  specs_(other.specs_), context_(other.context_) {}
1872 
1873  template <typename Id>
1875  specs_.width_ref = make_arg_ref(arg_id);
1876  }
1877 
1878  template <typename Id>
1880  specs_.precision_ref = make_arg_ref(arg_id);
1881  }
1882 
1883  FMT_CONSTEXPR void on_error(const char *message) {
1884  context_.on_error(message);
1885  }
1886 
1887  private:
1888  typedef arg_ref<char_type> arg_ref_type;
1889 
1890  template <typename Id>
1891  FMT_CONSTEXPR arg_ref_type make_arg_ref(Id arg_id) {
1892  context_.check_arg_id(arg_id);
1893  return arg_ref_type(arg_id);
1894  }
1895 
1896  FMT_CONSTEXPR arg_ref_type make_arg_ref(auto_id) {
1897  return arg_ref_type(context_.next_arg_id());
1898  }
1899 
1900  dynamic_format_specs<char_type> &specs_;
1901  ParseContext &context_;
1902 };
1903 
1904 template <typename Iterator, typename IDHandler>
1905 FMT_CONSTEXPR Iterator parse_arg_id(Iterator it, IDHandler &&handler) {
1907  char_type c = *it;
1908  if (c == '}' || c == ':') {
1909  handler();
1910  return it;
1911  }
1912  if (c >= '0' && c <= '9') {
1913  unsigned index = parse_nonnegative_int(it, handler);
1914  if (*it != '}' && *it != ':') {
1915  handler.on_error("invalid format string");
1916  return it;
1917  }
1918  handler(index);
1919  return it;
1920  }
1921  if (!is_name_start(c)) {
1922  handler.on_error("invalid format string");
1923  return it;
1924  }
1925  auto start = it;
1926  do {
1927  c = *++it;
1928  } while (is_name_start(c) || ('0' <= c && c <= '9'));
1930  pointer_from(start), to_unsigned(it - start)));
1931  return it;
1932 }
1933 
1934 template <typename Char, typename IDHandler>
1936  const Char *begin, const Char *end, IDHandler &&handler) {
1937  assert(begin != end);
1938  Char c = *begin;
1939  if (c == '}' || c == ':')
1940  return handler(), begin;
1941  if (c >= '0' && c <= '9') {
1942  unsigned index = parse_nonnegative_int(begin, end, handler);
1943  if (begin == end || (*begin != '}' && *begin != ':'))
1944  return handler.on_error("invalid format string"), begin;
1945  handler(index);
1946  return begin;
1947  }
1948  if (!is_name_start(c))
1949  return handler.on_error("invalid format string"), begin;
1950  auto it = begin;
1951  do {
1952  c = *++it;
1953  } while (it != end && (is_name_start(c) || ('0' <= c && c <= '9')));
1954  handler(basic_string_view<Char>(begin, to_unsigned(it - begin)));
1955  return it;
1956 }
1957 
1958 // Adapts SpecHandler to IDHandler API for dynamic width.
1959 template <typename SpecHandler, typename Char>
1961  explicit FMT_CONSTEXPR width_adapter(SpecHandler &h) : handler(h) {}
1962 
1963  FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); }
1964  FMT_CONSTEXPR void operator()(unsigned id) { handler.on_dynamic_width(id); }
1966  handler.on_dynamic_width(id);
1967  }
1968 
1969  FMT_CONSTEXPR void on_error(const char *message) {
1970  handler.on_error(message);
1971  }
1972 
1973  SpecHandler &handler;
1974 };
1975 
1976 // Adapts SpecHandler to IDHandler API for dynamic precision.
1977 template <typename SpecHandler, typename Char>
1979  explicit FMT_CONSTEXPR precision_adapter(SpecHandler &h) : handler(h) {}
1980 
1981  FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); }
1982  FMT_CONSTEXPR void operator()(unsigned id) {
1983  handler.on_dynamic_precision(id);
1984  }
1986  handler.on_dynamic_precision(id);
1987  }
1988 
1989  FMT_CONSTEXPR void on_error(const char *message) { handler.on_error(message); }
1990 
1991  SpecHandler &handler;
1992 };
1993 
1994 // Parses standard format specifiers and sends notifications about parsed
1995 // components to handler.
1996 // it: an iterator pointing to the beginning of a null-terminated range of
1997 // characters, possibly emulated via null_terminating_iterator, representing
1998 // format specifiers.
1999 template <typename Iterator, typename SpecHandler>
2000 FMT_CONSTEXPR Iterator parse_format_specs(Iterator it, SpecHandler &&handler) {
2002  char_type c = *it;
2003  if (c == '}' || !c)
2004  return it;
2005 
2006  // Parse fill and alignment.
2007  alignment align = ALIGN_DEFAULT;
2008  int i = 1;
2009  do {
2010  auto p = it + i;
2011  switch (static_cast<char>(*p)) {
2012  case '<':
2013  align = ALIGN_LEFT;
2014  break;
2015  case '>':
2016  align = ALIGN_RIGHT;
2017  break;
2018  case '=':
2019  align = ALIGN_NUMERIC;
2020  break;
2021  case '^':
2022  align = ALIGN_CENTER;
2023  break;
2024  }
2025  if (align != ALIGN_DEFAULT) {
2026  if (p != it) {
2027  if (c == '{') {
2028  handler.on_error("invalid fill character '{'");
2029  return it;
2030  }
2031  it += 2;
2032  handler.on_fill(c);
2033  } else ++it;
2034  handler.on_align(align);
2035  break;
2036  }
2037  } while (--i >= 0);
2038 
2039  // Parse sign.
2040  switch (static_cast<char>(*it)) {
2041  case '+':
2042  handler.on_plus();
2043  ++it;
2044  break;
2045  case '-':
2046  handler.on_minus();
2047  ++it;
2048  break;
2049  case ' ':
2050  handler.on_space();
2051  ++it;
2052  break;
2053  }
2054 
2055  if (*it == '#') {
2056  handler.on_hash();
2057  ++it;
2058  }
2059 
2060  // Parse zero flag.
2061  if (*it == '0') {
2062  handler.on_zero();
2063  ++it;
2064  }
2065 
2066  // Parse width.
2067  if ('0' <= *it && *it <= '9') {
2068  handler.on_width(parse_nonnegative_int(it, handler));
2069  } else if (*it == '{') {
2070  it = parse_arg_id(it + 1, width_adapter<SpecHandler, char_type>(handler));
2071  if (*it++ != '}') {
2072  handler.on_error("invalid format string");
2073  return it;
2074  }
2075  }
2076 
2077  // Parse precision.
2078  if (*it == '.') {
2079  ++it;
2080  if ('0' <= *it && *it <= '9') {
2081  handler.on_precision(parse_nonnegative_int(it, handler));
2082  } else if (*it == '{') {
2083  it = parse_arg_id(
2085  if (*it++ != '}') {
2086  handler.on_error("invalid format string");
2087  return it;
2088  }
2089  } else {
2090  handler.on_error("missing precision specifier");
2091  return it;
2092  }
2093  handler.end_precision();
2094  }
2095 
2096  // Parse type.
2097  if (*it != '}' && *it)
2098  handler.on_type(*it++);
2099  return it;
2100 }
2101 
2102 // Return the result via the out param to workaround gcc bug 77539.
2103 template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
2104 FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out) {
2105  for (out = first; out != last; ++out) {
2106  if (*out == value)
2107  return true;
2108  }
2109  return false;
2110 }
2111 
2112 template <>
2113 inline bool find<false, char>(
2114  const char *first, const char *last, char value, const char *&out) {
2115  out = static_cast<const char*>(std::memchr(first, value, last - first));
2116  return out != FMT_NULL;
2117 }
2118 
2119 template <typename Handler, typename Char>
2120 struct id_adapter {
2121  FMT_CONSTEXPR void operator()() { handler.on_arg_id(); }
2122  FMT_CONSTEXPR void operator()(unsigned id) { handler.on_arg_id(id); }
2124  handler.on_arg_id(id);
2125  }
2126  FMT_CONSTEXPR void on_error(const char *message) {
2127  handler.on_error(message);
2128  }
2129  Handler &handler;
2130 };
2131 
2132 template <bool IS_CONSTEXPR, typename Char, typename Handler>
2134  basic_string_view<Char> format_str, Handler &&handler) {
2135  struct writer {
2136  FMT_CONSTEXPR void operator()(const Char *begin, const Char *end) {
2137  if (begin == end) return;
2138  for (;;) {
2139  const Char *p = FMT_NULL;
2140  if (!find<IS_CONSTEXPR>(begin, end, '}', p))
2141  return handler_.on_text(begin, end);
2142  ++p;
2143  if (p == end || *p != '}')
2144  return handler_.on_error("unmatched '}' in format string");
2145  handler_.on_text(begin, p);
2146  begin = p + 1;
2147  }
2148  }
2149  Handler &handler_;
2150  } write{handler};
2151  auto begin = format_str.data();
2152  auto end = begin + format_str.size();
2153  while (begin != end) {
2154  // Doing two passes with memchr (one for '{' and another for '}') is up to
2155  // 2.5x faster than the naive one-pass implementation on big format strings.
2156  const Char *p = begin;
2157  if (*begin != '{' && !find<IS_CONSTEXPR>(begin, end, '{', p))
2158  return write(begin, end);
2159  write(begin, p);
2160  ++p;
2161  if (p == end)
2162  return handler.on_error("invalid format string");
2163  if (static_cast<char>(*p) == '}') {
2164  handler.on_arg_id();
2165  handler.on_replacement_field(p);
2166  } else if (*p == '{') {
2167  handler.on_text(p, p + 1);
2168  } else {
2169  p = parse_arg_id(p, end, id_adapter<Handler, Char>{handler});
2170  Char c = p != end ? *p : Char();
2171  if (c == '}') {
2172  handler.on_replacement_field(p);
2173  } else if (c == ':') {
2175  it = handler.on_format_specs(it);
2176  if (*it != '}')
2177  return handler.on_error("unknown format specifier");
2178  p = pointer_from(it);
2179  } else {
2180  return handler.on_error("missing '}' in format string");
2181  }
2182  }
2183  begin = p + 1;
2184  }
2185 }
2186 
2187 template <typename T, typename ParseContext>
2188 FMT_CONSTEXPR const typename ParseContext::char_type *
2189  parse_format_specs(ParseContext &ctx) {
2190  // GCC 7.2 requires initializer.
2192  return f.parse(ctx);
2193 }
2194 
2195 template <typename Char, typename ErrorHandler, typename... Args>
2197  public:
2199  basic_string_view<Char> format_str, ErrorHandler eh)
2200  : arg_id_(-1), context_(format_str, eh),
2201  parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
2202 
2204 
2205  FMT_CONSTEXPR void on_text(const Char *, const Char *) {}
2206 
2208  arg_id_ = context_.next_arg_id();
2209  check_arg_id();
2210  }
2211  FMT_CONSTEXPR void on_arg_id(unsigned id) {
2212  arg_id_ = id;
2213  context_.check_arg_id(id);
2214  check_arg_id();
2215  }
2217 
2218  FMT_CONSTEXPR void on_replacement_field(const Char *) {}
2219 
2221  auto p = pointer_from(it);
2222  context_.advance_to(p);
2223  return to_unsigned(arg_id_) < NUM_ARGS ?
2224  parse_funcs_[arg_id_](context_) : p;
2225  }
2226 
2227  FMT_CONSTEXPR void on_error(const char *message) {
2228  context_.on_error(message);
2229  }
2230 
2231  private:
2232  typedef basic_parse_context<Char, ErrorHandler> parse_context_type;
2233  enum { NUM_ARGS = sizeof...(Args) };
2234 
2235  FMT_CONSTEXPR void check_arg_id() {
2236  if (internal::to_unsigned(arg_id_) >= NUM_ARGS)
2237  context_.on_error("argument index out of range");
2238  }
2239 
2240  // Format specifier parsing function.
2241  typedef const Char *(*parse_func)(parse_context_type &);
2242 
2243  int arg_id_;
2244  parse_context_type context_;
2245  parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
2246 };
2247 
2248 template <typename Char, typename ErrorHandler, typename... Args>
2251  format_string_checker<Char, ErrorHandler, Args...> checker(s, eh);
2252  parse_format_string<true>(s, checker);
2253  return true;
2254 }
2255 
2256 template <typename... Args, typename S>
2258  check_format_string(S format_str) {
2259  typedef typename S::char_type char_t;
2261  char_t, internal::error_handler, Args...>(to_string_view(format_str));
2262  (void)invalid_format;
2263 }
2264 
2265 // Specifies whether to format T using the standard formatter.
2266 // It is not possible to use get_type in formatter specialization directly
2267 // because of a bug in MSVC.
2268 template <typename Context, typename T>
2269 struct format_type :
2270  std::integral_constant<bool, get_type<Context, T>::value != custom_type> {};
2271 
2272 template <template <typename> class Handler, typename Spec, typename Context>
2274  Spec &value, arg_ref<typename Context::char_type> ref, Context &ctx) {
2275  typedef typename Context::char_type char_type;
2276  switch (ref.kind) {
2278  break;
2280  internal::set_dynamic_spec<Handler>(
2281  value, ctx.get_arg(ref.index), ctx.error_handler());
2282  break;
2284  internal::set_dynamic_spec<Handler>(
2285  value, ctx.get_arg({ref.name.value, ref.name.size}),
2286  ctx.error_handler());
2287  break;
2288  }
2289 }
2290 } // namespace internal
2291 
2292 /** The default argument formatter. */
2293 template <typename Range>
2295  public internal::function<
2296  typename internal::arg_formatter_base<Range>::iterator>,
2297  public internal::arg_formatter_base<Range> {
2298  private:
2299  typedef typename Range::value_type char_type;
2302 
2303  context_type &ctx_;
2304 
2305  public:
2306  typedef Range range;
2307  typedef typename base::iterator iterator;
2309 
2310  /**
2311  \rst
2312  Constructs an argument formatter object.
2313  *ctx* is a reference to the formatting context,
2314  *spec* contains format specifier information for standard argument types.
2315  \endrst
2316  */
2318  : base(Range(ctx.out()), spec, ctx.locale()), ctx_(ctx) {}
2319 
2320  // Deprecated.
2322  : base(Range(ctx.out()), &spec), ctx_(ctx) {}
2323 
2324  using base::operator();
2325 
2326  /** Formats an argument of a user-defined type. */
2328  handle.format(ctx_);
2329  return this->out();
2330  }
2331 };
2332 
2333 /**
2334  An error returned by an operating system or a language runtime,
2335  for example a file opening error.
2336 */
2337 class system_error : public std::runtime_error {
2338  private:
2339  FMT_API void init(int err_code, string_view format_str, format_args args);
2340 
2341  protected:
2343 
2344  system_error() : std::runtime_error("") {}
2345 
2346  public:
2347  /**
2348  \rst
2349  Constructs a :class:`fmt::system_error` object with a description
2350  formatted with `fmt::format_system_error`. *message* and additional
2351  arguments passed into the constructor are formatted similarly to
2352  `fmt::format`.
2353 
2354  **Example**::
2355 
2356  // This throws a system_error with the description
2357  // cannot open file 'madeup': No such file or directory
2358  // or similar (system message may vary).
2359  const char *filename = "madeup";
2360  std::FILE *file = std::fopen(filename, "r");
2361  if (!file)
2362  throw fmt::system_error(errno, "cannot open file '{}'", filename);
2363  \endrst
2364  */
2365  template <typename... Args>
2366  system_error(int error_code, string_view message, const Args &... args)
2367  : std::runtime_error("") {
2368  init(error_code, message, make_format_args(args...));
2369  }
2370 
2371  int error_code() const { return error_code_; }
2372 };
2373 
2374 /**
2375  \rst
2376  Formats an error returned by an operating system or a language runtime,
2377  for example a file opening error, and writes it to *out* in the following
2378  form:
2379 
2380  .. parsed-literal::
2381  *<message>*: *<system-message>*
2382 
2383  where *<message>* is the passed message and *<system-message>* is
2384  the system message corresponding to the error code.
2385  *error_code* is a system error code as given by ``errno``.
2386  If *error_code* is not a valid error code such as -1, the system message
2387  may look like "Unknown error -1" and is platform-dependent.
2388  \endrst
2389  */
2390 FMT_API void format_system_error(internal::buffer &out, int error_code,
2392 
2393 /**
2394  This template provides operations for formatting and writing data into a
2395  character range.
2396  */
2397 template <typename Range>
2398 class basic_writer {
2399  public:
2400  typedef typename Range::value_type char_type;
2401  typedef decltype(internal::declval<Range>().begin()) iterator;
2403 
2404  private:
2405  iterator out_; // Output iterator.
2406  internal::locale_ref locale_;
2407 
2408  iterator out() const { return out_; }
2409 
2410  // Attempts to reserve space for n extra characters in the output range.
2411  // Returns a pointer to the reserved range or a reference to out_.
2412  auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) {
2413  return internal::reserve(out_, n);
2414  }
2415 
2416  // Writes a value in the format
2417  // <left-padding><value><right-padding>
2418  // where <value> is written by f(it).
2419  template <typename F>
2420  void write_padded(const align_spec &spec, F &&f);
2421 
2422  template <typename F>
2423  struct padded_int_writer {
2424  size_t size_;
2425  string_view prefix;
2426  char_type fill;
2427  std::size_t padding;
2428  F f;
2429 
2430  size_t size() const { return size_; }
2431  size_t width() const { return size_; }
2432 
2433  template <typename It>
2434  void operator()(It &&it) const {
2435  if (prefix.size() != 0)
2436  it = internal::copy_str<char_type>(prefix.begin(), prefix.end(), it);
2437  it = std::fill_n(it, padding, fill);
2438  f(it);
2439  }
2440  };
2441 
2442  // Writes an integer in the format
2443  // <left-padding><prefix><numeric-padding><digits><right-padding>
2444  // where <digits> are written by f(it).
2445  template <typename Spec, typename F>
2446  void write_int(unsigned num_digits, string_view prefix,
2447  const Spec &spec, F f) {
2448  std::size_t size = prefix.size() + num_digits;
2449  char_type fill = static_cast<char_type>(spec.fill());
2450  std::size_t padding = 0;
2451  if (spec.align() == ALIGN_NUMERIC) {
2452  if (spec.width() > size) {
2453  padding = spec.width() - size;
2454  size = spec.width();
2455  }
2456  } else if (spec.precision > static_cast<int>(num_digits)) {
2457  size = prefix.size() + internal::to_unsigned(spec.precision);
2458  padding = internal::to_unsigned(spec.precision) - num_digits;
2459  fill = static_cast<char_type>('0');
2460  }
2461  align_spec as = spec;
2462  if (spec.align() == ALIGN_DEFAULT)
2463  as.align_ = ALIGN_RIGHT;
2464  write_padded(as, padded_int_writer<F>{size, prefix, fill, padding, f});
2465  }
2466 
2467  // Writes a decimal integer.
2468  template <typename Int>
2469  void write_decimal(Int value) {
2470  typedef typename internal::int_traits<Int>::main_type main_type;
2471  main_type abs_value = static_cast<main_type>(value);
2472  bool is_negative = internal::is_negative(value);
2473  if (is_negative)
2474  abs_value = 0 - abs_value;
2475  unsigned num_digits = internal::count_digits(abs_value);
2476  auto &&it = reserve((is_negative ? 1 : 0) + num_digits);
2477  if (is_negative)
2478  *it++ = static_cast<char_type>('-');
2479  it = internal::format_decimal<char_type>(it, abs_value, num_digits);
2480  }
2481 
2482  // The handle_int_type_spec handler that writes an integer.
2483  template <typename Int, typename Spec>
2484  struct int_writer {
2485  typedef typename internal::int_traits<Int>::main_type unsigned_type;
2486 
2488  const Spec &spec;
2489  unsigned_type abs_value;
2490  char prefix[4];
2491  unsigned prefix_size;
2492 
2493  string_view get_prefix() const { return string_view(prefix, prefix_size); }
2494 
2495  // Counts the number of digits in abs_value. BITS = log2(radix).
2496  template <unsigned BITS>
2497  unsigned count_digits() const {
2498  unsigned_type n = abs_value;
2499  unsigned num_digits = 0;
2500  do {
2501  ++num_digits;
2502  } while ((n >>= BITS) != 0);
2503  return num_digits;
2504  }
2505 
2506  int_writer(basic_writer<Range> &w, Int value, const Spec &s)
2507  : writer(w), spec(s), abs_value(static_cast<unsigned_type>(value)),
2508  prefix_size(0) {
2509  if (internal::is_negative(value)) {
2510  prefix[0] = '-';
2511  ++prefix_size;
2512  abs_value = 0 - abs_value;
2513  } else if (spec.has(SIGN_FLAG)) {
2514  prefix[0] = spec.has(PLUS_FLAG) ? '+' : ' ';
2515  ++prefix_size;
2516  }
2517  }
2518 
2519  struct dec_writer {
2520  unsigned_type abs_value;
2521  unsigned num_digits;
2522 
2523  template <typename It>
2524  void operator()(It &&it) const {
2525  it = internal::format_decimal<char_type>(it, abs_value, num_digits);
2526  }
2527  };
2528 
2529  void on_dec() {
2530  unsigned num_digits = internal::count_digits(abs_value);
2531  writer.write_int(num_digits, get_prefix(), spec,
2532  dec_writer{abs_value, num_digits});
2533  }
2534 
2535  struct hex_writer {
2536  int_writer &self;
2537  unsigned num_digits;
2538 
2539  template <typename It>
2540  void operator()(It &&it) const {
2541  it = internal::format_uint<4, char_type>(
2542  it, self.abs_value, num_digits, self.spec.type != 'x');
2543  }
2544  };
2545 
2546  void on_hex() {
2547  if (spec.has(HASH_FLAG)) {
2548  prefix[prefix_size++] = '0';
2549  prefix[prefix_size++] = static_cast<char>(spec.type);
2550  }
2551  unsigned num_digits = count_digits<4>();
2552  writer.write_int(num_digits, get_prefix(), spec,
2553  hex_writer{*this, num_digits});
2554  }
2555 
2556  template <int BITS>
2557  struct bin_writer {
2558  unsigned_type abs_value;
2559  unsigned num_digits;
2560 
2561  template <typename It>
2562  void operator()(It &&it) const {
2563  it = internal::format_uint<BITS, char_type>(it, abs_value, num_digits);
2564  }
2565  };
2566 
2567  void on_bin() {
2568  if (spec.has(HASH_FLAG)) {
2569  prefix[prefix_size++] = '0';
2570  prefix[prefix_size++] = static_cast<char>(spec.type);
2571  }
2572  unsigned num_digits = count_digits<1>();
2573  writer.write_int(num_digits, get_prefix(), spec,
2574  bin_writer<1>{abs_value, num_digits});
2575  }
2576 
2577  void on_oct() {
2578  unsigned num_digits = count_digits<3>();
2579  if (spec.has(HASH_FLAG) &&
2580  spec.precision <= static_cast<int>(num_digits)) {
2581  // Octal prefix '0' is counted as a digit, so only add it if precision
2582  // is not greater than the number of digits.
2583  prefix[prefix_size++] = '0';
2584  }
2585  writer.write_int(num_digits, get_prefix(), spec,
2586  bin_writer<3>{abs_value, num_digits});
2587  }
2588 
2589  enum { SEP_SIZE = 1 };
2590 
2591  struct num_writer {
2592  unsigned_type abs_value;
2593  unsigned size;
2595 
2596  template <typename It>
2597  void operator()(It &&it) const {
2598  basic_string_view<char_type> s(&sep, SEP_SIZE);
2599  it = internal::format_decimal<char_type>(
2600  it, abs_value, size, internal::add_thousands_sep<char_type>(s));
2601  }
2602  };
2603 
2604  void on_num() {
2605  unsigned num_digits = internal::count_digits(abs_value);
2606  char_type sep = internal::thousands_sep<char_type>(writer.locale_);
2607  unsigned size = num_digits + SEP_SIZE * ((num_digits - 1) / 3);
2608  writer.write_int(size, get_prefix(), spec,
2609  num_writer{abs_value, size, sep});
2610  }
2611 
2612  void on_error() {
2613  FMT_THROW(format_error("invalid type specifier"));
2614  }
2615  };
2616 
2617  // Writes a formatted integer.
2618  template <typename T, typename Spec>
2619  void write_int(T value, const Spec &spec) {
2621  int_writer<T, Spec>(*this, value, spec));
2622  }
2623 
2624  enum {INF_SIZE = 3}; // This is an enum to workaround a bug in MSVC.
2625 
2626  struct inf_or_nan_writer {
2627  char sign;
2628  const char *str;
2629 
2630  size_t size() const {
2631  return static_cast<std::size_t>(INF_SIZE + (sign ? 1 : 0));
2632  }
2633  size_t width() const { return size(); }
2634 
2635  template <typename It>
2636  void operator()(It &&it) const {
2637  if (sign)
2638  *it++ = static_cast<char_type>(sign);
2639  it = internal::copy_str<char_type>(
2640  str, str + static_cast<std::size_t>(INF_SIZE), it);
2641  }
2642  };
2643 
2644  struct double_writer {
2645  size_t n;
2646  char sign;
2648 
2649  size_t size() const { return buffer.size() + (sign ? 1 : 0); }
2650  size_t width() const { return size(); }
2651 
2652  template <typename It>
2653  void operator()(It &&it) {
2654  if (sign) {
2655  *it++ = static_cast<char_type>(sign);
2656  --n;
2657  }
2658  it = internal::copy_str<char_type>(buffer.begin(), buffer.end(), it);
2659  }
2660  };
2661 
2662  // Formats a floating-point number (double or long double).
2663  template <typename T>
2664  void write_double(T value, const format_specs &spec);
2665 
2666  template <typename Char>
2667  struct str_writer {
2668  const Char *s;
2669  size_t size_;
2670 
2671  size_t size() const { return size_; }
2672  size_t width() const {
2674  }
2675 
2676  template <typename It>
2677  void operator()(It &&it) const {
2678  it = internal::copy_str<char_type>(s, s + size_, it);
2679  }
2680  };
2681 
2682  // Writes a formatted string.
2683  template <typename Char>
2684  void write_str(const Char *s, std::size_t size, const align_spec &spec) {
2685  write_padded(spec, str_writer<Char>{s, size});
2686  }
2687 
2688  template <typename Char>
2689  void write_str(basic_string_view<Char> str, const format_specs &spec);
2690 
2691  template <typename Char>
2693 
2694  public:
2695  /** Constructs a ``basic_writer`` object. */
2696  explicit basic_writer(
2698  : out_(out.begin()), locale_(loc) {}
2699 
2700  void write(int value) { write_decimal(value); }
2701  void write(long value) { write_decimal(value); }
2702  void write(long long value) { write_decimal(value); }
2703 
2704  void write(unsigned value) { write_decimal(value); }
2705  void write(unsigned long value) { write_decimal(value); }
2706  void write(unsigned long long value) { write_decimal(value); }
2707 
2708  /**
2709  \rst
2710  Formats *value* and writes it to the buffer.
2711  \endrst
2712  */
2713  template <typename T, typename FormatSpec, typename... FormatSpecs>
2715  write(T value, FormatSpec spec, FormatSpecs... specs) {
2716  format_specs s(spec, specs...);
2717  s.align_ = ALIGN_RIGHT;
2718  write_int(value, s);
2719  }
2720 
2721  void write(double value) {
2722  write_double(value, format_specs());
2723  }
2724 
2725  /**
2726  \rst
2727  Formats *value* using the general format for floating-point numbers
2728  (``'g'``) and writes it to the buffer.
2729  \endrst
2730  */
2731  void write(long double value) {
2732  write_double(value, format_specs());
2733  }
2734 
2735  /** Writes a character to the buffer. */
2736  void write(char value) {
2737  *reserve(1) = value;
2738  }
2739  void write(wchar_t value) {
2740  static_assert(std::is_same<char_type, wchar_t>::value, "");
2741  *reserve(1) = value;
2742  }
2743 
2744  /**
2745  \rst
2746  Writes *value* to the buffer.
2747  \endrst
2748  */
2749  void write(string_view value) {
2750  auto &&it = reserve(value.size());
2751  it = internal::copy_str<char_type>(value.begin(), value.end(), it);
2752  }
2753  void write(wstring_view value) {
2754  static_assert(std::is_same<char_type, wchar_t>::value, "");
2755  auto &&it = reserve(value.size());
2756  it = std::copy(value.begin(), value.end(), it);
2757  }
2758 
2759  template <typename... FormatSpecs>
2760  void write(basic_string_view<char_type> str, FormatSpecs... specs) {
2761  write_str(str, format_specs(specs...));
2762  }
2763 
2764  template <typename T>
2766  write(const T *p) {
2767  format_specs specs;
2768  specs.flags = HASH_FLAG;
2769  specs.type = 'x';
2770  write_int(reinterpret_cast<uintptr_t>(p), specs);
2771  }
2772 };
2773 
2774 template <typename Range>
2775 template <typename F>
2776 void basic_writer<Range>::write_padded(const align_spec &spec, F &&f) {
2777  unsigned width = spec.width(); // User-perceived width (in code points).
2778  size_t size = f.size(); // The number of code units.
2779  size_t num_code_points = width != 0 ? f.width() : size;
2780  if (width <= num_code_points)
2781  return f(reserve(size));
2782  auto &&it = reserve(width + (size - num_code_points));
2783  char_type fill = static_cast<char_type>(spec.fill());
2784  std::size_t padding = width - num_code_points;
2785  if (spec.align() == ALIGN_RIGHT) {
2786  it = std::fill_n(it, padding, fill);
2787  f(it);
2788  } else if (spec.align() == ALIGN_CENTER) {
2789  std::size_t left_padding = padding / 2;
2790  it = std::fill_n(it, left_padding, fill);
2791  f(it);
2792  it = std::fill_n(it, padding - left_padding, fill);
2793  } else {
2794  f(it);
2795  it = std::fill_n(it, padding, fill);
2796  }
2797 }
2798 
2799 template <typename Range>
2800 template <typename Char>
2802  basic_string_view<Char> s, const format_specs &spec) {
2803  const Char *data = s.data();
2804  std::size_t size = s.size();
2805  if (spec.precision >= 0 && internal::to_unsigned(spec.precision) < size)
2806  size = internal::to_unsigned(spec.precision);
2807  write_str(data, size, spec);
2808 }
2809 
2811  char type;
2812  bool upper;
2813 
2814  explicit float_spec_handler(char t) : type(t), upper(false) {}
2815 
2816  void on_general() {
2817  if (type == 'G')
2818  upper = true;
2819  else
2820  type = 'g';
2821  }
2822 
2823  void on_exp() {
2824  if (type == 'E')
2825  upper = true;
2826  }
2827 
2828  void on_fixed() {
2829  if (type == 'F') {
2830  upper = true;
2831 #if FMT_MSC_VER
2832  // MSVC's printf doesn't support 'F'.
2833  type = 'f';
2834 #endif
2835  }
2836  }
2837 
2838  void on_hex() {
2839  if (type == 'A')
2840  upper = true;
2841  }
2842 
2843  void on_error() {
2844  FMT_THROW(format_error("invalid type specifier"));
2845  }
2846 };
2847 
2848 template <typename Range>
2849 template <typename T>
2850 void basic_writer<Range>::write_double(T value, const format_specs &spec) {
2851  // Check type.
2852  float_spec_handler handler(static_cast<char>(spec.type));
2853  internal::handle_float_type_spec(handler.type, handler);
2854 
2855  char sign = 0;
2856  // Use signbit instead of value < 0 because the latter is always
2857  // false for NaN.
2858  if (std::signbit(value)) {
2859  sign = '-';
2860  value = -value;
2861  } else if (spec.has(SIGN_FLAG)) {
2862  sign = spec.has(PLUS_FLAG) ? '+' : ' ';
2863  }
2864 
2865  struct write_inf_or_nan_t {
2867  format_specs spec;
2868  char sign;
2869  void operator()(const char *str) const {
2870  writer.write_padded(spec, inf_or_nan_writer{sign, str});
2871  }
2872  } write_inf_or_nan = {*this, spec, sign};
2873 
2874  // Format NaN and ininity ourselves because sprintf's output is not consistent
2875  // across platforms.
2876  if (internal::fputil::isnotanumber(value))
2877  return write_inf_or_nan(handler.upper ? "NAN" : "nan");
2878  if (internal::fputil::isinfinity(value))
2879  return write_inf_or_nan(handler.upper ? "INF" : "inf");
2880 
2882  bool use_grisu = FMT_USE_GRISU && sizeof(T) <= sizeof(double) &&
2883  spec.type != 'a' && spec.type != 'A' &&
2884  internal::grisu2_format(static_cast<double>(value), buffer, spec);
2885  if (!use_grisu) {
2886  format_specs normalized_spec(spec);
2887  normalized_spec.type = handler.type;
2888  internal::sprintf_format(value, buffer, normalized_spec);
2889  }
2890  size_t n = buffer.size();
2891  align_spec as = spec;
2892  if (spec.align() == ALIGN_NUMERIC) {
2893  if (sign) {
2894  auto &&it = reserve(1);
2895  *it++ = static_cast<char_type>(sign);
2896  sign = 0;
2897  if (as.width_)
2898  --as.width_;
2899  }
2900  as.align_ = ALIGN_RIGHT;
2901  } else {
2902  if (spec.align() == ALIGN_DEFAULT)
2903  as.align_ = ALIGN_RIGHT;
2904  if (sign)
2905  ++n;
2906  }
2907  write_padded(as, double_writer{n, sign, buffer});
2908 }
2909 
2910 // Reports a system error without throwing an exception.
2911 // Can be used to report errors from destructors.
2912 FMT_API void report_system_error(int error_code,
2914 
2915 #if FMT_USE_WINDOWS_H
2916 
2917 /** A Windows error. */
2918 class windows_error : public system_error {
2919  private:
2920  FMT_API void init(int error_code, string_view format_str, format_args args);
2921 
2922  public:
2923  /**
2924  \rst
2925  Constructs a :class:`fmt::windows_error` object with the description
2926  of the form
2927 
2928  .. parsed-literal::
2929  *<message>*: *<system-message>*
2930 
2931  where *<message>* is the formatted message and *<system-message>* is the
2932  system message corresponding to the error code.
2933  *error_code* is a Windows error code as given by ``GetLastError``.
2934  If *error_code* is not a valid error code such as -1, the system message
2935  will look like "error -1".
2936 
2937  **Example**::
2938 
2939  // This throws a windows_error with the description
2940  // cannot open file 'madeup': The system cannot find the file specified.
2941  // or similar (system message may vary).
2942  const char *filename = "madeup";
2943  LPOFSTRUCT of = LPOFSTRUCT();
2944  HFILE file = OpenFile(filename, &of, OF_READ);
2945  if (file == HFILE_ERROR) {
2946  throw fmt::windows_error(GetLastError(),
2947  "cannot open file '{}'", filename);
2948  }
2949  \endrst
2950  */
2951  template <typename... Args>
2952  windows_error(int error_code, string_view message, const Args &... args) {
2953  init(error_code, message, make_format_args(args...));
2954  }
2955 };
2956 
2957 // Reports a Windows error without throwing an exception.
2958 // Can be used to report errors from destructors.
2959 FMT_API void report_windows_error(int error_code,
2961 
2962 #endif
2963 
2964 /** Fast integer formatter. */
2965 class format_int {
2966  private:
2967  // Buffer should be large enough to hold all digits (digits10 + 1),
2968  // a sign and a null character.
2969  enum {BUFFER_SIZE = std::numeric_limits<unsigned long long>::digits10 + 3};
2970  mutable char buffer_[BUFFER_SIZE];
2971  char *str_;
2972 
2973  // Formats value in reverse and returns a pointer to the beginning.
2974  char *format_decimal(unsigned long long value) {
2975  char *ptr = buffer_ + BUFFER_SIZE - 1;
2976  while (value >= 100) {
2977  // Integer division is slow so do it for a group of two digits instead
2978  // of for every digit. The idea comes from the talk by Alexandrescu
2979  // "Three Optimization Tips for C++". See speed-test for a comparison.
2980  unsigned index = static_cast<unsigned>((value % 100) * 2);
2981  value /= 100;
2982  *--ptr = internal::data::DIGITS[index + 1];
2983  *--ptr = internal::data::DIGITS[index];
2984  }
2985  if (value < 10) {
2986  *--ptr = static_cast<char>('0' + value);
2987  return ptr;
2988  }
2989  unsigned index = static_cast<unsigned>(value * 2);
2990  *--ptr = internal::data::DIGITS[index + 1];
2991  *--ptr = internal::data::DIGITS[index];
2992  return ptr;
2993  }
2994 
2995  void format_signed(long long value) {
2996  unsigned long long abs_value = static_cast<unsigned long long>(value);
2997  bool negative = value < 0;
2998  if (negative)
2999  abs_value = 0 - abs_value;
3000  str_ = format_decimal(abs_value);
3001  if (negative)
3002  *--str_ = '-';
3003  }
3004 
3005  public:
3006  explicit format_int(int value) { format_signed(value); }
3007  explicit format_int(long value) { format_signed(value); }
3008  explicit format_int(long long value) { format_signed(value); }
3009  explicit format_int(unsigned value) : str_(format_decimal(value)) {}
3010  explicit format_int(unsigned long value) : str_(format_decimal(value)) {}
3011  explicit format_int(unsigned long long value) : str_(format_decimal(value)) {}
3012 
3013  /** Returns the number of characters written to the output buffer. */
3014  std::size_t size() const {
3015  return internal::to_unsigned(buffer_ - str_ + BUFFER_SIZE - 1);
3016  }
3017 
3018  /**
3019  Returns a pointer to the output buffer content. No terminating null
3020  character is appended.
3021  */
3022  const char *data() const { return str_; }
3023 
3024  /**
3025  Returns a pointer to the output buffer content with terminating null
3026  character appended.
3027  */
3028  const char *c_str() const {
3029  buffer_[BUFFER_SIZE - 1] = '\0';
3030  return str_;
3031  }
3032 
3033  /**
3034  \rst
3035  Returns the content of the output buffer as an ``std::string``.
3036  \endrst
3037  */
3038  std::string str() const { return std::string(str_, size()); }
3039 };
3040 
3041 // Formats a decimal integer value writing into buffer and returns
3042 // a pointer to the end of the formatted string. This function doesn't
3043 // write a terminating null character.
3044 template <typename T>
3045 inline void format_decimal(char *&buffer, T value) {
3046  typedef typename internal::int_traits<T>::main_type main_type;
3047  main_type abs_value = static_cast<main_type>(value);
3048  if (internal::is_negative(value)) {
3049  *buffer++ = '-';
3050  abs_value = 0 - abs_value;
3051  }
3052  if (abs_value < 100) {
3053  if (abs_value < 10) {
3054  *buffer++ = static_cast<char>('0' + abs_value);
3055  return;
3056  }
3057  unsigned index = static_cast<unsigned>(abs_value * 2);
3058  *buffer++ = internal::data::DIGITS[index];
3059  *buffer++ = internal::data::DIGITS[index + 1];
3060  return;
3061  }
3062  unsigned num_digits = internal::count_digits(abs_value);
3063  internal::format_decimal<char>(buffer, abs_value, num_digits);
3064  buffer += num_digits;
3065 }
3066 
3067 // Formatter of objects of type T.
3068 template <typename T, typename Char>
3069 struct formatter<
3070  T, Char,
3071  typename std::enable_if<internal::format_type<
3072  typename buffer_context<Char>::type, T>::value>::type> {
3073 
3074  // Parses format specifiers stopping either at the end of the range or at the
3075  // terminating '}'.
3076  template <typename ParseContext>
3077  FMT_CONSTEXPR typename ParseContext::iterator parse(ParseContext &ctx) {
3079  typedef internal::dynamic_specs_handler<ParseContext> handler_type;
3080  auto type = internal::get_type<
3083  handler(handler_type(specs_, ctx), type);
3084  it = parse_format_specs(it, handler);
3085  auto type_spec = specs_.type;
3086  auto eh = ctx.error_handler();
3087  switch (type) {
3088  case internal::none_type:
3090  FMT_ASSERT(false, "invalid argument type");
3091  break;
3092  case internal::int_type:
3093  case internal::uint_type:
3096  case internal::bool_type:
3098  type_spec, internal::int_type_checker<decltype(eh)>(eh));
3099  break;
3100  case internal::char_type:
3102  &specs_,
3103  internal::char_specs_checker<decltype(eh)>(type_spec, eh));
3104  break;
3105  case internal::double_type:
3108  type_spec, internal::float_type_checker<decltype(eh)>(eh));
3109  break;
3112  type_spec, internal::cstring_type_checker<decltype(eh)>(eh));
3113  break;
3114  case internal::string_type:
3115  internal::check_string_type_spec(type_spec, eh);
3116  break;
3118  internal::check_pointer_type_spec(type_spec, eh);
3119  break;
3120  case internal::custom_type:
3121  // Custom format specifiers should be checked in parse functions of
3122  // formatter specializations.
3123  break;
3124  }
3125  return pointer_from(it);
3126  }
3127 
3128  template <typename FormatContext>
3129  auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out()) {
3130  internal::handle_dynamic_spec<internal::width_checker>(
3131  specs_.width_, specs_.width_ref, ctx);
3132  internal::handle_dynamic_spec<internal::precision_checker>(
3133  specs_.precision, specs_.precision_ref, ctx);
3134  typedef output_range<typename FormatContext::iterator,
3135  typename FormatContext::char_type> range_type;
3136  return visit_format_arg(arg_formatter<range_type>(ctx, &specs_),
3137  internal::make_arg<FormatContext>(val));
3138  }
3139 
3140  private:
3142 };
3143 
3144 // A formatter for types known only at run time such as variant alternatives.
3145 //
3146 // Usage:
3147 // typedef std::variant<int, std::string> variant;
3148 // template <>
3149 // struct formatter<variant>: dynamic_formatter<> {
3150 // void format(buffer &buf, const variant &v, context &ctx) {
3151 // visit([&](const auto &val) { format(buf, val, ctx); }, v);
3152 // }
3153 // };
3154 template <typename Char = char>
3156  private:
3157  struct null_handler: internal::error_handler {
3158  void on_align(alignment) {}
3159  void on_plus() {}
3160  void on_minus() {}
3161  void on_space() {}
3162  void on_hash() {}
3163  };
3164 
3165  public:
3166  template <typename ParseContext>
3167  auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
3169  // Checks are deferred to formatting time when the argument type is known.
3170  internal::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
3171  it = parse_format_specs(it, handler);
3172  return pointer_from(it);
3173  }
3174 
3175  template <typename T, typename FormatContext>
3176  auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out()) {
3177  handle_specs(ctx);
3180  checker.on_align(specs_.align());
3181  if (specs_.flags == 0); // Do nothing.
3182  else if (specs_.has(SIGN_FLAG))
3183  specs_.has(PLUS_FLAG) ? checker.on_plus() : checker.on_space();
3184  else if (specs_.has(MINUS_FLAG))
3185  checker.on_minus();
3186  else if (specs_.has(HASH_FLAG))
3187  checker.on_hash();
3188  if (specs_.precision != -1)
3189  checker.end_precision();
3190  typedef output_range<typename FormatContext::iterator,
3191  typename FormatContext::char_type> range;
3192  visit_format_arg(arg_formatter<range>(ctx, &specs_),
3193  internal::make_arg<FormatContext>(val));
3194  return ctx.out();
3195  }
3196 
3197  private:
3198  template <typename Context>
3199  void handle_specs(Context &ctx) {
3200  internal::handle_dynamic_spec<internal::width_checker>(
3201  specs_.width_, specs_.width_ref, ctx);
3202  internal::handle_dynamic_spec<internal::precision_checker>(
3203  specs_.precision, specs_.precision_ref, ctx);
3204  }
3205 
3207 };
3208 
3209 template <typename Range, typename Char>
3213  map_.init(this->args());
3214  format_arg arg = map_.find(name);
3215  if (arg.type() == internal::none_type)
3216  this->on_error("argument not found");
3217  return arg;
3218 }
3219 
3220 template <typename ArgFormatter, typename Char, typename Context>
3223  typedef typename ArgFormatter::range range;
3224 
3228  : context(r.begin(), str, format_args, loc) {}
3229 
3230  void on_text(const Char *begin, const Char *end) {
3231  auto size = internal::to_unsigned(end - begin);
3232  auto out = context.out();
3233  auto &&it = internal::reserve(out, size);
3234  it = std::copy_n(begin, size, it);
3235  context.advance_to(out);
3236  }
3237 
3238  void on_arg_id() { arg = context.next_arg(); }
3239  void on_arg_id(unsigned id) {
3240  context.parse_context().check_arg_id(id);
3241  arg = context.get_arg(id);
3242  }
3244  arg = context.get_arg(id);
3245  }
3246 
3247  void on_replacement_field(const Char *p) {
3248  context.parse_context().advance_to(p);
3250  if (!visit_format_arg(f, arg))
3251  context.advance_to(visit_format_arg(ArgFormatter(context), arg));
3252  }
3253 
3255  auto &parse_ctx = context.parse_context();
3256  parse_ctx.advance_to(pointer_from(it));
3258  if (visit_format_arg(f, arg))
3259  return iterator(parse_ctx);
3263  handler(specs_handler<Context>(specs, context), arg.type());
3264  it = parse_format_specs(it, handler);
3265  if (*it != '}')
3266  on_error("missing '}' in format string");
3267  parse_ctx.advance_to(pointer_from(it));
3268  context.advance_to(visit_format_arg(ArgFormatter(context, &specs), arg));
3269  return it;
3270  }
3271 
3272  Context context;
3274 };
3275 
3276 /** Formats arguments and writes the output to the range. */
3277 template <typename ArgFormatter, typename Char, typename Context>
3278 typename Context::iterator vformat_to(
3279  typename ArgFormatter::range out,
3280  basic_string_view<Char> format_str,
3283  format_handler<ArgFormatter, Char, Context> h(out, format_str, args, loc);
3284  internal::parse_format_string<false>(format_str, h);
3285  return h.context.out();
3286 }
3287 
3288 // Casts ``p`` to ``const void*`` for pointer formatting.
3289 // Example:
3290 // auto s = format("{}", ptr(p));
3291 template <typename T>
3292 inline const void *ptr(const T *p) { return p; }
3293 
3294 template <typename It, typename Char>
3295 struct arg_join {
3296  It begin;
3297  It end;
3299 
3301  : begin(begin), end(end), sep(sep) {}
3302 };
3303 
3304 template <typename It, typename Char>
3305 struct formatter<arg_join<It, Char>, Char>:
3306  formatter<typename std::iterator_traits<It>::value_type, Char> {
3307  template <typename FormatContext>
3308  auto format(const arg_join<It, Char> &value, FormatContext &ctx)
3309  -> decltype(ctx.out()) {
3311  auto it = value.begin;
3312  auto out = ctx.out();
3313  if (it != value.end) {
3314  out = base::format(*it++, ctx);
3315  while (it != value.end) {
3316  out = std::copy(value.sep.begin(), value.sep.end(), out);
3317  ctx.advance_to(out);
3318  out = base::format(*it++, ctx);
3319  }
3320  }
3321  return out;
3322  }
3323 };
3324 
3325 template <typename It>
3327  return arg_join<It, char>(begin, end, sep);
3328 }
3329 
3330 template <typename It>
3332  return arg_join<It, wchar_t>(begin, end, sep);
3333 }
3334 
3335 // The following causes ICE in gcc 4.4.
3336 #if FMT_USE_TRAILING_RETURN && (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 405)
3337 template <typename Range>
3338 auto join(const Range &range, string_view sep)
3340  return join(internal::begin(range), internal::end(range), sep);
3341 }
3342 
3343 template <typename Range>
3344 auto join(const Range &range, wstring_view sep)
3346  return join(internal::begin(range), internal::end(range), sep);
3347 }
3348 #endif
3349 
3350 /**
3351  \rst
3352  Converts *value* to ``std::string`` using the default format for type *T*.
3353  It doesn't support user-defined types with custom formatters.
3354 
3355  **Example**::
3356 
3357  #include <fmt/format.h>
3358 
3359  std::string answer = fmt::to_string(42);
3360  \endrst
3361  */
3362 template <typename T>
3363 std::string to_string(const T &value) {
3364  std::string str;
3366  writer(buf).write(value);
3367  return str;
3368 }
3369 
3370 /**
3371  Converts *value* to ``std::wstring`` using the default format for type *T*.
3372  */
3373 template <typename T>
3374 std::wstring to_wstring(const T &value) {
3375  std::wstring str;
3377  wwriter(buf).write(value);
3378  return str;
3379 }
3380 
3381 template <typename Char, std::size_t SIZE>
3382 std::basic_string<Char> to_string(const basic_memory_buffer<Char, SIZE> &buf) {
3383  return std::basic_string<Char>(buf.data(), buf.size());
3384 }
3385 
3386 template <typename Char>
3391  return vformat_to<arg_formatter<range>>(
3392  buf, to_string_view(format_str), args);
3393 }
3394 
3395 template <typename S, typename Char = FMT_CHAR(S)>
3397  internal::basic_buffer<Char> &buf, const S &format_str,
3399  return internal::vformat_to(buf, to_string_view(format_str), args);
3400 }
3401 
3402 template <
3403  typename S, typename... Args,
3404  std::size_t SIZE = inline_buffer_size,
3405  typename Char = typename internal::char_t<S>::type>
3407  basic_memory_buffer<Char, SIZE> &buf, const S &format_str,
3408  const Args &... args) {
3409  internal::check_format_string<Args...>(format_str);
3410  typedef typename buffer_context<Char>::type context;
3411  format_arg_store<context, Args...> as{args...};
3412  return internal::vformat_to(buf, to_string_view(format_str),
3414 }
3415 
3416 namespace internal {
3417 
3418 // Detect the iterator category of *any* given type in a SFINAE-friendly way.
3419 // Unfortunately, older implementations of std::iterator_traits are not safe
3420 // for use in a SFINAE-context.
3421 
3422 // the gist of C++17's void_t magic
3423 template<typename... Ts>
3424 struct void_ { typedef void type; };
3425 
3426 template <typename T, typename Enable = void>
3427 struct it_category : std::false_type {};
3428 
3429 template <typename T>
3430 struct it_category<T*> { typedef std::random_access_iterator_tag type; };
3431 
3432 template <typename T>
3433 struct it_category<T, typename void_<typename T::iterator_category>::type> {
3434  typedef typename T::iterator_category type;
3435 };
3436 
3437 // Detect if *any* given type models the OutputIterator concept.
3438 template <typename It>
3440  // Check for mutability because all iterator categories derived from
3441  // std::input_iterator_tag *may* also meet the requirements of an
3442  // OutputIterator, thereby falling into the category of 'mutable iterators'
3443  // [iterator.requirements.general] clause 4.
3444  // The compiler reveals this property only at the point of *actually
3445  // dereferencing* the iterator!
3446  template <typename U>
3447  static decltype(*(internal::declval<U>())) test(std::input_iterator_tag);
3448  template <typename U>
3449  static char& test(std::output_iterator_tag);
3450  template <typename U>
3451  static const char& test(...);
3452 
3453  typedef decltype(test<It>(typename it_category<It>::type{})) type;
3454  typedef typename std::remove_reference<type>::type result;
3455  public:
3456  static const bool value = !std::is_const<result>::value;
3457 };
3458 } // internal
3459 
3460 template <typename OutputIt, typename Char = char>
3461 //using format_context_t = basic_format_context<OutputIt, Char>;
3463 
3464 template <typename OutputIt, typename Char = char>
3465 //using format_args_t = basic_format_args<format_context_t<OutputIt, Char>>;
3467  typedef basic_format_args<
3469 };
3470 
3471 template <typename String, typename OutputIt, typename... Args>
3473  OutputIt>::type
3474  vformat_to(OutputIt out, const String &format_str,
3475  typename format_args_t<OutputIt, FMT_CHAR(String)>::type args) {
3477  return vformat_to<arg_formatter<range>>(range(out),
3478  to_string_view(format_str), args);
3479 }
3480 
3481 /**
3482  \rst
3483  Formats arguments, writes the result to the output iterator ``out`` and returns
3484  the iterator past the end of the output range.
3485 
3486  **Example**::
3487 
3488  std::vector<char> out;
3489  fmt::format_to(std::back_inserter(out), "{}", 42);
3490  \endrst
3491  */
3492 template <typename OutputIt, typename S, typename... Args>
3493 inline typename std::enable_if<
3496  format_to(OutputIt out, const S &format_str, const Args &... args) {
3497  internal::check_format_string<Args...>(format_str);
3499  format_arg_store<context, Args...> as{args...};
3500  return vformat_to(out, to_string_view(format_str),
3502 }
3503 
3504 template <typename OutputIt>
3506  /** Iterator past the end of the output range. */
3507  OutputIt out;
3508  /** Total (not truncated) output size. */
3509  std::size_t size;
3510 };
3511 
3512 template <typename OutputIt, typename Char = typename OutputIt::value_type>
3514  format_context_t<fmt::internal::truncating_iterator<OutputIt>, Char> {};
3515 
3516 template <typename OutputIt, typename Char = typename OutputIt::value_type>
3518  typedef basic_format_args<
3520 };
3521 
3522 template <typename OutputIt, typename Char, typename ...Args>
3523 inline format_arg_store<
3525  make_format_to_n_args(const Args &... args) {
3526  return format_arg_store<
3527  typename format_to_n_context<OutputIt, Char>::type, Args...>(args...);
3528 }
3529 
3530 template <typename OutputIt, typename Char, typename... Args>
3531 inline typename std::enable_if<
3534  OutputIt out, std::size_t n, basic_string_view<Char> format_str,
3537  auto it = vformat_to(It(out, n), format_str, args);
3538  return {it.base(), it.count()};
3539 }
3540 
3541 /**
3542  \rst
3543  Formats arguments, writes up to ``n`` characters of the result to the output
3544  iterator ``out`` and returns the total output size and the iterator past the
3545  end of the output range.
3546  \endrst
3547  */
3548 template <typename OutputIt, typename S, typename... Args>
3549 inline typename std::enable_if<
3553  format_to_n(OutputIt out, std::size_t n, const S &format_str,
3554  const Args &... args) {
3555  internal::check_format_string<Args...>(format_str);
3556  typedef FMT_CHAR(S) Char;
3558  typename format_to_n_context<OutputIt, Char>::type, Args...> as(args...);
3559  return vformat_to_n(out, n, to_string_view(format_str),
3561 }
3562 
3563 template <typename Char>
3564 inline std::basic_string<Char> internal::vformat(
3565  basic_string_view<Char> format_str,
3568  internal::vformat_to(buffer, format_str, args);
3569  return fmt::to_string(buffer);
3570 }
3571 
3572 /**
3573  Returns the number of characters in the output of
3574  ``format(format_str, args...)``.
3575  */
3576 template <typename... Args>
3577 inline std::size_t formatted_size(string_view format_str,
3578  const Args &... args) {
3579  auto it = format_to(internal::counting_iterator<char>(), format_str, args...);
3580  return it.count();
3581 }
3582 
3583 #if FMT_USE_USER_DEFINED_LITERALS
3584 namespace internal {
3585 
3586 # if FMT_UDL_TEMPLATE
3587 template <typename Char, Char... CHARS>
3588 class udl_formatter {
3589  public:
3590  template <typename... Args>
3591  std::basic_string<Char> operator()(const Args &... args) const {
3592  FMT_CONSTEXPR_DECL Char s[] = {CHARS..., '\0'};
3593  FMT_CONSTEXPR_DECL bool invalid_format =
3594  do_check_format_string<Char, error_handler, Args...>(
3595  basic_string_view<Char>(s, sizeof...(CHARS)));
3596  (void)invalid_format;
3597  return format(s, args...);
3598  }
3599 };
3600 # else
3601 template <typename Char>
3602 struct udl_formatter {
3603  const Char *str;
3604 
3605  template <typename... Args>
3606  auto operator()(Args &&... args) const
3607  -> decltype(format(str, std::forward<Args>(args)...)) {
3608  return format(str, std::forward<Args>(args)...);
3609  }
3610 };
3611 # endif // FMT_UDL_TEMPLATE
3612 
3613 template <typename Char>
3614 struct udl_arg {
3615  const Char *str;
3616 
3617  template <typename T>
3618  named_arg<T, Char> operator=(T &&value) const {
3619  return {str, std::forward<T>(value)};
3620  }
3621 };
3622 
3623 } // namespace internal
3624 
3625 inline namespace literals {
3626 
3627 # if FMT_UDL_TEMPLATE
3628 template <typename Char, Char... CHARS>
3629 FMT_CONSTEXPR internal::udl_formatter<Char, CHARS...> operator""_format() {
3630  return {};
3631 }
3632 # else
3633 /**
3634  \rst
3635  User-defined literal equivalent of :func:`fmt::format`.
3636 
3637  **Example**::
3638 
3639  using namespace fmt::literals;
3640  std::string message = "The answer is {}"_format(42);
3641  \endrst
3642  */
3643 inline internal::udl_formatter<char>
3644 operator"" _format(const char *s, std::size_t) { return {s}; }
3645 inline internal::udl_formatter<wchar_t>
3646 operator"" _format(const wchar_t *s, std::size_t) { return {s}; }
3647 # endif // FMT_UDL_TEMPLATE
3648 
3649 /**
3650  \rst
3651  User-defined literal equivalent of :func:`fmt::arg`.
3652 
3653  **Example**::
3654 
3655  using namespace fmt::literals;
3656  fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
3657  \endrst
3658  */
3659 inline internal::udl_arg<char>
3660 operator"" _a(const char *s, std::size_t) { return {s}; }
3661 inline internal::udl_arg<wchar_t>
3662 operator"" _a(const wchar_t *s, std::size_t) { return {s}; }
3663 } // inline namespace literals
3664 #endif // FMT_USE_USER_DEFINED_LITERALS
3666 
3667 #define FMT_STRING(s) [] { \
3668  typedef typename std::remove_cv<std::remove_pointer< \
3669  typename std::decay<decltype(s)>::type>::type>::type ct; \
3670  struct str : fmt::compile_string { \
3671  typedef ct char_type; \
3672  FMT_CONSTEXPR operator fmt::basic_string_view<ct>() const { \
3673  return {s, sizeof(s) / sizeof(ct) - 1}; \
3674  } \
3675  }; \
3676  return str{}; \
3677  }()
3678 
3679 #if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS
3680 /**
3681  \rst
3682  Constructs a compile-time format string. This macro is disabled by default to
3683  prevent potential name collisions. To enable it define ``FMT_STRING_ALIAS`` to
3684  1 before including ``fmt/format.h``.
3685 
3686  **Example**::
3687 
3688  #define FMT_STRING_ALIAS 1
3689  #include <fmt/format.h>
3690  // A compile-time error because 'd' is an invalid specifier for strings.
3691  std::string s = format(fmt("{:d}"), "foo");
3692  \endrst
3693  */
3694 # define fmt(s) FMT_STRING(s)
3695 #endif
3696 
3697 #ifdef FMT_HEADER_ONLY
3698 # define FMT_FUNC inline
3699 # include "format-inl.h"
3700 #else
3701 # define FMT_FUNC
3702 #endif
3703 
3704 // Restore warnings.
3705 #if FMT_GCC_VERSION >= 406 || FMT_CLANG_VERSION
3706 # pragma GCC diagnostic pop
3707 #endif
3708 
3709 #endif // FMT_FORMAT_H_
GLdouble s
Definition: glew.h:1390
float_spec_handler(char t)
Definition: format.h:2814
counting_iterator & operator++()
Definition: format.h:721
FMT_CONSTEXPR cstring_type_checker(ErrorHandler eh)
Definition: format.h:1351
int error_code() const
Definition: format.h:2371
vint4 max(const vint4 &a, const vint4 &b)
Definition: simd.h:4703
FMT_CONSTEXPR void on_error()
Definition: format.h:1312
system_error()
Definition: format.h:2344
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition: format.h:1879
void on_general()
Definition: format.h:2816
FMT_CONSTEXPR void on_align(alignment align)
Definition: format.h:1681
T value_type
Definition: format.h:343
GLenum GLint * range
Definition: glew.h:3500
bool operator()(typename basic_format_arg< Context >::handle h) const
Definition: format.h:1606
std::string str() const
Definition: format.h:3038
FMT_CONSTEXPR int_type_checker(ErrorHandler eh)
Definition: format.h:1304
FMT_CONSTEXPR null_terminating_iterator operator--()
Definition: format.h:651
base::format_specs format_specs
Definition: format.h:2308
cvex test(vector P=0;int unbound=3;export float s=0;export vector Cf=0;)
Definition: test.vfl:11
GLuint id
Definition: glew.h:1679
auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: format.h:3167
FMT_CONSTEXPR void on_string()
Definition: format.h:1354
GLsizeiptr size
Definition: glew.h:1681
FMT_CONSTEXPR void on_arg_id()
Definition: format.h:2207
wchar_t fill_
Definition: format.h:1177
Container & get_container(std::back_insert_iterator< Container > it)
Definition: core.h:311
FMT_CONSTEXPR specs_setter(basic_format_specs< Char > &specs)
Definition: format.h:1676
GLenum GLint ref
Definition: glew.h:1845
iterator operator()(basic_string_view< char_type > value)
Definition: format.h:1514
FMT_CONSTEXPR null_terminating_iterator(const Range &r)
Definition: format.h:627
GLuint const GLchar * name
Definition: glew.h:1814
basic_format_arg< Context > arg
Definition: format.h:3273
FMT_CONSTEXPR void on_error(const char *message)
Definition: format.h:2126
basic_memory_buffer< char > memory_buffer
Definition: format.h:550
auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3176
void operator()(It &&it) const
Definition: format.h:2524
truncating_iterator & operator=(value_type val)
Definition: format.h:801
FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler &&eh)
Definition: format.h:1296
FMT_CONSTEXPR void on_error(const char *message)
Definition: format.h:1883
FMT_CONSTEXPR void on_pointer()
Definition: format.h:1355
alignment align_
Definition: format.h:1178
iterator operator()(typename basic_format_arg< context_type >::handle handle)
Definition: format.h:2327
FMT_CONSTEXPR void end_precision()
Definition: format.h:1697
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
Definition: format.h:1651
void on_arg_id(basic_string_view< Char > id)
Definition: format.h:3243
FMT_CONSTEXPR std::enable_if< !std::numeric_limits< T >::is_signed, bool >::type is_negative(T)
Definition: format.h:821
bool operator>=(null_terminating_iterator other) const
Definition: format.h:678
void write(long value)
Definition: format.h:2701
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1252
FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin())
Definition: format.h:251
const Args & args
Definition: printf.h:628
FMT_CONSTEXPR void on_oct()
Definition: format.h:1309
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:90
basic_format_specs< Char > & specs_
Definition: format.h:1704
GLuint GLenum GLenum transform
Definition: glew.h:14742
GLuint index
Definition: glew.h:1814
void write(long double value)
Definition: format.h:2731
truncating_iterator(OutputIt out, std::size_t limit)
Definition: format.h:772
FMT_CONSTEXPR const Char * on_format_specs(iterator it)
Definition: format.h:2220
void write(char value)
Definition: format.h:2736
FMT_CONSTEXPR void on_type(Char type)
Definition: format.h:1699
ImageBuf OIIO_API fill(cspan< float > values, ROI roi, int nthreads=0)
GLuint const GLfloat * val
Definition: glew.h:2794
void grow(std::size_t size) FMT_OVERRIDE
Definition: format.h:532
It format_uint(It out, UInt value, unsigned num_digits, bool upper=false)
Definition: format.h:1105
internal::named_arg< T, char > arg(string_view name, const T &arg)
Definition: core.h:1393
FMT_CONSTEXPR void on_minus()
Definition: format.h:1729
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
void handle_dynamic_spec(Spec &value, arg_ref< typename Context::char_type > ref, Context &ctx)
Definition: format.h:2273
std::ptrdiff_t difference_type
Definition: format.h:712
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2864
unsigned count_digits(uint64_t n)
Definition: format.h:866
FMT_CONSTEXPR void on_zero()
Definition: format.h:1744
iterator operator()(const void *value)
Definition: format.h:1525
FMT_CONSTEXPR void handle_float_type_spec(char spec, Handler &&handler)
Definition: format.h:1249
ArgFormatter::range range
Definition: format.h:3223
arg_ref(basic_string_view< Char > nm)
Definition: format.h:1831
FMT_CONSTEXPR null_terminating_iterator operator++(int)
Definition: format.h:645
void write(unsigned long value)
Definition: format.h:2705
format_arg_store< typename format_to_n_context< OutputIt, Char >::type, Args...> make_format_to_n_args(const Args &...args)
Definition: format.h:3525
void on_error(const char *message)
Definition: format.h:1806
FMT_CONSTEXPR float_type_checker(ErrorHandler eh)
Definition: format.h:1320
Range::value_type char_type
Definition: format.h:1394
cstring_spec_handler(arg_formatter_base &f, const char_type *val)
Definition: format.h:1500
FMT_CONSTEXPR std::enable_if< is_integer< T >::value, unsigned long long >::type operator()(T value)
Definition: format.h:1655
FMT_CONSTEXPR bool is_name_start(Char c)
Definition: format.h:1534
GLsizei GLsizei GLchar * source
Definition: glew.h:1832
const GLint * first
Definition: glew.h:1528
GLint limit
Definition: glew.h:12988
FMT_CONSTEXPR specs_checker(const Handler &handler, internal::type arg_type)
Definition: format.h:1712
iterator operator()(monostate)
Definition: format.h:1449
FMT_CONSTEXPR core_format_specs()
Definition: format.h:1191
size_t count_code_points(basic_string_view< Char > s)
Definition: format.h:883
It end
Definition: format.h:3297
truncating_iterator(OutputIt out, std::size_t limit)
Definition: format.h:798
void on_arg_id()
Definition: format.h:3238
Allocator get_allocator() const
Definition: format.h:528
std::size_t count() const
Definition: format.h:719
std::enable_if< needs_conversion< InputIt, OutChar >::value, OutputIt >::type copy_str(InputIt begin, InputIt end, OutputIt it)
Definition: format.h:906
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glew.h:1254
void write(unsigned long long value)
Definition: format.h:2706
#define FMT_ALWAYS_INLINE
Definition: format.h:913
FMT_CONSTEXPR Char operator*() const
Definition: format.h:636
#define FMT_CONSTEXPR_DECL
Definition: core.h:70
FMT_CONSTEXPR void on_width(unsigned width)
Definition: format.h:1693
basic_writer< back_insert_range< internal::buffer > > writer
Definition: format.h:361
FMT_CONSTEXPR void operator()(unsigned id)
Definition: format.h:2122
Tto convert(const Tfrom &source)
Context::char_type char_type
Definition: format.h:1788
FMT_CONSTEXPR bool has(unsigned f) const
Definition: format.h:1192
ImageBuf OIIO_API checker(int width, int height, int depth, cspan< float > color1, cspan< float > color2, int xoffset, int yoffset, int zoffset, ROI roi, int nthreads=0)
FMT_CONSTEXPR T * end(T(&array)[N]) FMT_NOEXCEPT
Definition: format.h:259
basic_memory_buffer & operator=(basic_memory_buffer &&other)
Definition: format.h:520
FMT_CONSTEXPR void on_error(const char *message)
Definition: format.h:2227
basic_string_view< wchar_t > wstring_view
Definition: core.h:427
FMT_CONSTEXPR specs_checker(const specs_checker &other)
Definition: format.h:1715
FMT_CONSTEXPR void on_zero()
Definition: format.h:1688
format_arg_store< context, Args...> as
Definition: printf.h:632
FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler &other)
Definition: format.h:1869
basic_format_context< OutputIt, Char > type
Definition: format.h:3462
system_error(int error_code, string_view message, const Args &...args)
Definition: format.h:2366
FMT_CONSTEXPR null_terminating_iterator operator-(difference_type n)
Definition: format.h:660
FMT_CONSTEXPR null_terminating_iterator(const Char *ptr, const Char *end)
Definition: format.h:623
FMT_CONSTEXPR void on_arg_id(unsigned id)
Definition: format.h:2211
basic_data data
Definition: format.h:853
FMT_CONSTEXPR void operator()()
Definition: format.h:1981
std::size_t formatted_size(string_view format_str, const Args &...args)
Definition: format.h:3577
PUGIXML_CHAR char_t
Definition: pugixml.hpp:117
basic_format_specs< char > format_specs
Definition: format.h:1201
std::enable_if< sizeof(Double)!=sizeof(uint64_t), bool >::type grisu2_format(Double, buffer &, core_format_specs)
Definition: format.h:1220
FMT_API Char thousands_sep_impl(locale_ref loc)
Definition: format-inl.h:220
uint64 value_type
Definition: GA_PrimCompat.h:29
OutputIt out
Definition: format.h:3507
FMT_CONSTEXPR void handle_char_specs(const basic_format_specs< Char > *specs, Handler &&handler)
Definition: format.h:1270
FMT_CONSTEXPR void on_bin()
Definition: format.h:1308
u8string_view(const char *s)
Definition: format.h:415
Range range
Definition: format.h:2306
char * on(uint32_t u)
Definition: format.h:947
#define FMT_END_NAMESPACE
Definition: core.h:151
FMT_CONSTEXPR size_t size() const
Definition: core.h:387
FMT_CONSTEXPR void on_error(const char *message)
Definition: format.h:1989
string_value< Char > name
Definition: format.h:1844
FMT_CONSTEXPR void on_plus()
Definition: format.h:1683
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition: format.h:1874
#define FMT_THROW(x)
Definition: format.h:115
FMT_CONSTEXPR format_string_checker(basic_string_view< Char > format_str, ErrorHandler eh)
Definition: format.h:2198
std::enable_if<!is_compile_string< S >::value >::type check_format_string(const S &)
Definition: core.h:1354
void write(wstring_view value)
Definition: format.h:2753
Container::value_type value_type
Definition: format.h:355
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
Definition: format.h:1985
FMT_CONSTEXPR void on_replacement_field(const Char *)
Definition: format.h:2218
SpecHandler & handler
Definition: format.h:1991
format_int(unsigned long value)
Definition: format.h:3010
FMT_CONSTEXPR specs_setter(const specs_setter &other)
Definition: format.h:1679
FMT_CONSTEXPR void on_num()
Definition: format.h:1310
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh)
Definition: format.h:1290
FMT_CONSTEXPR void operator()(unsigned id)
Definition: format.h:1964
format_error(const std::string &message)
Definition: format.h:370
arg_formatter_base(Range r, format_specs *s, locale_ref loc)
Definition: format.h:1446
void write(long long value)
Definition: format.h:2702
const internal::value< Context > * values_
Definition: core.h:1212
std::enable_if< std::is_integral< T >::value||std::is_same< T, char_type >::value, iterator >::type operator()(T value)
Definition: format.h:1457
basic_format_args< typename format_context_t< OutputIt, Char >::type > type
Definition: format.h:3468
const_iterator end() const
Definition: string_view.h:152
FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler &&handler)
Definition: format.h:1226
std::enable_if< std::is_integral< T >::value, void >::type write(T value, FormatSpec spec, FormatSpecs...specs)
Definition: format.h:2715
T * data() FMT_NOEXCEPT
Definition: core.h:254
FMT_CONSTEXPR void on_general()
Definition: format.h:1323
Dest bit_cast(const Source &source)
Definition: format.h:242
FMT_CONSTEXPR void on_int()
Definition: format.h:1342
void advance_to(iterator it)
Definition: core.h:1033
FMT_CONSTEXPR void operator()()
Definition: format.h:1963
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:3387
FMT_CONSTEXPR void on_align(alignment align)
Definition: format.h:1718
FMT_CONSTEXPR auto end(const C &c) -> decltype(c.end())
Definition: format.h:257
counting_iterator operator++(int)
Definition: format.h:726
FMT_CONSTEXPR void operator()(unsigned id)
Definition: format.h:1982
#define FMT_USE_GRISU
Definition: format.h:165
GLclampf f
Definition: glew.h:3499
FMT_CONSTEXPR const Char * parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler)
Definition: format.h:1935
internal::null_terminating_iterator< Char > iterator
Definition: format.h:2203
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
size_type size() const
Definition: string_view.h:161
basic_writer< back_insert_range< internal::wbuffer > > wwriter
Definition: format.h:362
bool operator()(T) const
Definition: format.h:1612
FMT_CONSTEXPR std::enable_if< is_integer< T >::value, unsigned long long >::type operator()(T value)
Definition: format.h:1631
Iterator & reserve(Iterator &it, std::size_t)
Definition: format.h:601
FMT_CONSTEXPR const Char * data() const
Definition: core.h:384
dummy_int isinf(...)
Definition: format.h:276
char * on(uint32_t u)
Definition: format.h:979
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:593
ParseContext::char_type char_type
Definition: format.h:1863
arg_ref< Char > width_ref
Definition: format.h:1853
FMT_CONSTEXPR void on_arg_id(basic_string_view< Char >)
Definition: format.h:2216
FMT_CONSTEXPR bool is_arithmetic(type t)
Definition: core.h:543
GLuint buffer
Definition: glew.h:1680
void sprintf_format(Double value, internal::buffer &buffer, core_format_specs spec)
Definition: format-inl.h:763
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
void write(double value)
Definition: format.h:2721
FMT_CONSTEXPR void operator()()
Definition: format.h:2121
format_error(const char *message)
Definition: format.h:367
FMT_CONSTEXPR void on_error()
Definition: format.h:1328
FMT_CONSTEXPR void on_hex()
Definition: format.h:1307
std::basic_string< Char > vformat(basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
Definition: format.h:3564
format_arg get_arg(unsigned arg_id)
Definition: core.h:1112
unsigned max_size() const
Definition: core.h:1280
T & operator*() const
Definition: format.h:732
const char * c_str() const
Definition: format.h:3028
FMT_CONSTEXPR bool is_integral(type t)
Definition: core.h:538
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
FMT_CONSTEXPR T * begin(T(&array)[N]) FMT_NOEXCEPT
Definition: format.h:255
FMT_CONSTEXPR basic_format_specs()
Definition: format.h:1198
GLuint GLuint end
Definition: glew.h:1253
basic_string_view< char > string_view
Definition: core.h:426
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:1639
base::iterator iterator
Definition: format.h:2307
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
Definition: glew.h:2581
void
Definition: png.h:1083
truncating_iterator_base(OutputIt out, std::size_t limit)
Definition: format.h:742
internal::null_terminating_iterator< Char > iterator
Definition: format.h:3222
FMT_CONSTEXPR void on_error(const char *message)
Definition: format.h:1969
std::size_t size() const FMT_NOEXCEPT
Definition: core.h:248
std::enable_if< internal::is_string< S >::value &&internal::is_output_iterator< OutputIt >::value, format_to_n_result< OutputIt > >::type format_to_n(OutputIt out, std::size_t n, const S &format_str, const Args &...args)
Definition: format.h:3553
GLsizei n
Definition: glew.h:4040
const GLfloat * c
Definition: glew.h:16296
GLuint GLsizei GLsizei * length
Definition: glew.h:1825
const_iterator begin() const
Definition: string_view.h:151
std::size_t capacity() const FMT_NOEXCEPT
Definition: core.h:251
std::output_iterator_tag iterator_category
Definition: format.h:746
dummy_int _finite(...)
Definition: format.h:277
FMT_CONSTEXPR arg_ref(unsigned index)
Definition: format.h:1830
void on_arg_id(unsigned id)
Definition: format.h:3239
format_int(long long value)
Definition: format.h:3008
#define FMT_API
Definition: core.h:164
format_int(unsigned long long value)
Definition: format.h:3011
FMT_CONSTEXPR bool operator!=(null_terminating_iterator other) const
Definition: format.h:674
auto format(const arg_join< It, Char > &value, FormatContext &ctx) -> decltype(ctx.out())
Definition: format.h:3308
ImageBuf OIIO_API resize(const ImageBuf &src, string_view filtername="", float filterwidth=0.0f, ROI roi={}, int nthreads=0)
void write(const char_type *value)
Definition: format.h:1437
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
std::random_access_iterator_tag type
Definition: format.h:3430
void format_decimal(char *&buffer, T value)
Definition: format.h:3045
FMT_CONSTEXPR void on_fixed()
Definition: format.h:1325
Range::value_type char_type
Definition: format.h:2400
OutputIt iterator
Definition: format.h:342
FMT_CONSTEXPR void end_precision()
Definition: format.h:1749
FMT_CONSTEXPR difference_type operator-(null_terminating_iterator other) const
Definition: format.h:669
FMT_CONSTEXPR arg_ref & operator=(unsigned idx)
Definition: format.h:1835
void on_text(const Char *begin, const Char *end)
Definition: format.h:3230
void operator()(Char *)
Definition: format.h:999
FMT_CONSTEXPR void set_dynamic_spec(T &value, basic_format_arg< Context > arg, ErrorHandler eh)
Definition: format.h:1773
std::enable_if< std::is_same< T, void >::value >::type write(const T *p)
Definition: format.h:2766
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
FMT_CONSTEXPR void on_char()
Definition: format.h:1345
static const char DIGITS[]
Definition: format.h:842
char * lg(uint32_t n, Handler h) FMT_ALWAYS_INLINE
Definition: format.h:921
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:3533
int sign(T a)
Definition: ImathFun.h:63
void operator()(It &&it) const
Definition: format.h:2540
custom_formatter(Context &ctx)
Definition: format.h:1604
FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh)
Definition: format.h:1339
FMT_API size_t count_code_points(basic_string_view< char8_t > s)
Definition: format-inl.h:195
FMT_CONSTEXPR precision_adapter(SpecHandler &h)
Definition: format.h:1979
FMT_CONSTEXPR std::enable_if< !is_integer< T >::value, unsigned long long >::type operator()(T)
Definition: format.h:1663
FMT_CONSTEXPR void on_hash()
Definition: format.h:1686
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
internal::type type() const
Definition: core.h:811
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
Definition: format.h:1965
format_arg_store< Context, Args...> make_format_args(const Args &...args)
Definition: core.h:1193
FMT_CONSTEXPR void on_precision(unsigned precision)
Definition: format.h:1694
FMT_CONSTEXPR wchar_t fill() const
Definition: format.h:1182
FMT_CONSTEXPR width_adapter(SpecHandler &h)
Definition: format.h:1961
FMT_CONSTEXPR align_spec()
Definition: format.h:1180
std::random_access_iterator_tag iterator_category
Definition: format.h:619
iterator on_format_specs(iterator it)
Definition: format.h:3254
GLuint start
Definition: glew.h:1253
char8_t to_char8_t(char c)
Definition: format.h:888
std::wstring to_wstring(const T &value)
Definition: format.h:3374
It begin
Definition: format.h:3296
void write(unsigned value)
Definition: format.h:2704
#define FMT_CHAR(S)
Definition: core.h:1319
void write(wchar_t value)
Definition: format.h:2739
const char * data() const
Definition: format.h:3022
FMT_CONSTEXPR unsigned width() const
Definition: format.h:1181
FMT_CONSTEXPR const ParseContext::char_type * parse_format_specs(ParseContext &ctx)
Definition: format.h:2189
FMT_CONSTEXPR void handle_cstring_type_spec(Char spec, Handler &&handler)
Definition: format.h:1280
FMT_CONSTEXPR null_terminating_iterator & operator=(const Char *ptr)
Definition: format.h:630
std::numeric_limits< internal::dummy_int > fputil
Definition: format.h:272
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition: format.h:1795
buffer_context< Char >::type::iterator format_to(basic_memory_buffer< Char, SIZE > &buf, const S &format_str, const Args &...args)
Definition: format.h:3406
GLfloat GLfloat p
Definition: glew.h:16321
alignment
Definition: format.h:1165
T * make_checked(T *p, std::size_t)
Definition: format.h:389
Context::iterator vformat_to(typename ArgFormatter::range out, basic_string_view< Char > format_str, basic_format_args< Context > args, internal::locale_ref loc=internal::locale_ref())
Definition: format.h:3278
#define FMT_NULL
Definition: core.h:107
GLsizei const GLchar *const * string
Definition: glew.h:1844
OutputIt iterator
Definition: core.h:986
FMT_CONSTEXPR void on_minus()
Definition: format.h:1684
arg_join(It begin, It end, basic_string_view< Char > sep)
Definition: format.h:3300
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:816
FMT_CONSTEXPR void on_fill(Char fill)
Definition: format.h:1682
format_handler(range r, basic_string_view< Char > str, basic_format_args< Context > format_args, internal::locale_ref loc)
Definition: format.h:3225
std::string to_string(const T &value)
Definition: format.h:3363
uint_least8_t flags
Definition: format.h:1188
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
Definition: core.h:206
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition: format.h:1801
std::size_t count() const
Definition: format.h:753
#define FMT_CONSTEXPR
Definition: core.h:69
basic_printf_context_t< buffer >::type context
Definition: printf.h:631
FMT_CONSTEXPR void on_hex()
Definition: format.h:1326
basic_string_view< Char > sep
Definition: format.h:3298
iterator out()
Definition: core.h:1029
void operator()(It &&it) const
Definition: format.h:2597
const void * ptr(const T *p)
Definition: format.h:3292
FMT_CONSTEXPR void operator()(basic_string_view< Char > id)
Definition: format.h:2123
writer_type & writer()
Definition: format.h:1428
FMT_CONSTEXPR null_terminating_iterator operator+=(difference_type n)
Definition: format.h:664
int error_code_
Definition: format.h:2342
format_int(int value)
Definition: format.h:3006
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
Definition: format.h:2104
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
OIIO_API bool copy(string_view from, string_view to, std::string &err)
GLuint GLuint GLsizei count
Definition: glew.h:1253
Handler & handler
Definition: format.h:2129
SpecHandler & handler
Definition: format.h:1973
FMT_CONSTEXPR unsigned parse_nonnegative_int(const Char *&begin, const Char *end, ErrorHandler &&eh)
Definition: format.h:1573
void format(Context &ctx) const
Definition: core.h:799
void operator()(It &&it) const
Definition: format.h:2562
FMT_API void format_system_error(internal::buffer &out, int error_code, fmt::string_view message) FMT_NOEXCEPT
add_thousands_sep(basic_string_view< Char > sep)
Definition: format.h:1016
GA_API const UT_StringHolder N
basic_memory_buffer(basic_memory_buffer &&other)
Definition: format.h:511
Context context
Definition: format.h:3272
FMT_CONSTEXPR bool do_check_format_string(basic_string_view< Char > s, ErrorHandler eh=ErrorHandler())
Definition: format.h:2249
format_specs * spec()
Definition: format.h:1429
arg_ref< Char > precision_ref
Definition: format.h:1854
FMT_CONSTEXPR void on_space()
Definition: format.h:1734
format_int(unsigned value)
Definition: format.h:3009
const format_arg * args_
Definition: core.h:1213
counting_iterator _Unchecked_type
Definition: format.h:715
OutputIt begin() const
Definition: format.h:346
decimal_formatter(char *buf)
Definition: format.h:945
arg_join< It, char > join(It begin, It end, string_view sep)
Definition: format.h:3326
FMT_CONSTEXPR iterator end() const
Definition: core.h:390
FMT_CONSTEXPR void on_dec()
Definition: format.h:1306
T const_check(T value)
Definition: format.h:293
GLuint64EXT * result
Definition: glew.h:14007
arg_formatter(context_type &ctx, format_specs &spec)
Definition: format.h:2321
#define SIZE
Definition: simple.C:40
#define FMT_NOEXCEPT
Definition: core.h:138
ParseContext::iterator parse(ParseContext &)
GLenum array
Definition: glew.h:9066
std::enable_if< std::is_floating_point< T >::value, iterator >::type operator()(T value)
Definition: format.h:1475
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:715
if(rank==1) return rank
basic_memory_buffer(const Allocator &alloc=Allocator())
Definition: format.h:478
void write(bool value)
Definition: format.h:1432
FMT_CONSTEXPR void on_text(const Char *, const Char *)
Definition: format.h:2205
void write(string_view value)
Definition: format.h:2749
#define FMT_ASSERT(condition, message)
Definition: core.h:168
FMT_CONSTEXPR arg_ref()
Definition: format.h:1829
iterator operator()(const char_type *value)
Definition: format.h:1507
FMT_CONSTEXPR iterator begin() const
Definition: core.h:389
#define FMT_BEGIN_NAMESPACE
Definition: core.h:153
unsigned width_
Definition: format.h:1174
#define const
Definition: zconf.h:214
char8_t
Definition: format.h:407
FMT_CONSTEXPR void on_plus()
Definition: format.h:1724
FMT_CONSTEXPR void on_space()
Definition: format.h:1685
basic_string_view< Char > to_string_view(basic_string_view< Char > s)
Definition: core.h:453
basic_writer(Range out, internal::locale_ref loc=internal::locale_ref())
Definition: format.h:2696
#define FMT_OVERRIDE
Definition: core.h:88
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
Definition: format.h:1626
void on_replacement_field(const Char *p)
Definition: format.h:3247
void write(T &out, bool v)
Definition: ImfXdr.h:332
basic_format_args< typename format_to_n_context< OutputIt, Char >::type > type
Definition: format.h:3519
void operator()(Char *&buffer)
Definition: format.h:1019
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2580
FMT_CONSTEXPR specs_handler(basic_format_specs< char_type > &specs, Context &ctx)
Definition: format.h:1790
FMT_CONSTEXPR void parse_format_string(basic_string_view< Char > format_str, Handler &&handler)
Definition: format.h:2133
char8_t char_type
Definition: format.h:413
basic_parse_context< char_type > & parse_context()
Definition: core.h:1019
arg_formatter(context_type &ctx, format_specs *spec=FMT_NULL)
Definition: format.h:2317
char_spec_handler(arg_formatter_base &f, char_type val)
Definition: format.h:1484
GLenum GLint GLint * precision
Definition: glew.h:3500
FMT_CONSTEXPR void on_exp()
Definition: format.h:1324
GLsizei const GLfloat * value
Definition: glew.h:1849
std::size_t size
Definition: format.h:3509
FMT_CONSTEXPR unsigned next_arg_id()
Definition: format.h:1204
std::size_t size() const
Definition: format.h:3014
unsigned index
Definition: format.h:1843
basic_memory_buffer< wchar_t > wmemory_buffer
Definition: format.h:551
GLdouble GLdouble t
Definition: glew.h:1398
FMT_CONSTEXPR null_terminating_iterator operator+(difference_type n)
Definition: format.h:656
FMT_CONSTEXPR void on_hash()
Definition: format.h:1739
wchar_t thousands_sep(locale_ref loc)
Definition: format.h:1039
FMT_CONSTEXPR internal::result_of< Visitor(int)>::type visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg)
Definition: core.h:828
FMT_CONSTEXPR null_terminating_iterator operator++()
Definition: format.h:640
output_range(OutputIt it)
Definition: format.h:345
std::output_iterator_tag iterator_category
Definition: format.h:710
void write(int value)
Definition: format.h:2700
back_insert_range(Container &c)
Definition: format.h:357
back_insert_range(typename base::iterator it)
Definition: format.h:358
OutputIt::container_type::value_type value_type
Definition: format.h:796
FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs< char_type > &specs, ParseContext &ctx)
Definition: format.h:1865
dummy_int isnan(...)
Definition: format.h:278
FMT_API void report_system_error(int error_code, string_view message) FMT_NOEXCEPT
u8string_view(const char *s, size_t count) FMT_NOEXCEPT
Definition: format.h:417
void write(basic_string_view< char_type > str, FormatSpecs...specs)
Definition: format.h:2760
type
Definition: core.h:528
FMT_CONSTEXPR const Char * pointer_from(null_terminating_iterator< Char > it)
Definition: format.h:697
format_int(long value)
Definition: format.h:3007
bool find< false, char >(const char *first, const char *last, char value, const char *&out)
Definition: format.h:2113
truncating_iterator_base _Unchecked_type
Definition: format.h:750
FMT_CONSTEXPR alignment align() const
Definition: format.h:1183
void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT
Definition: core.h:230