HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
core.h
Go to the documentation of this file.
1 // Formatting library for C++ - the core API for char/UTF-8
2 //
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7 
8 #ifndef FMT_CORE_H_
9 #define FMT_CORE_H_
10 
11 #include <cstdio> // std::FILE
12 #include <cstring>
13 #include <iterator>
14 #include <limits>
15 #include <string>
16 #include <type_traits>
17 
18 // The fmt library version in the form major * 10000 + minor * 100 + patch.
19 #define FMT_VERSION 80000
20 
21 #ifdef __clang__
22 # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
23 #else
24 # define FMT_CLANG_VERSION 0
25 #endif
26 
27 #if defined(__GNUC__) && !defined(__clang__)
28 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
29 # define FMT_GCC_PRAGMA(arg) _Pragma(arg)
30 #else
31 # define FMT_GCC_VERSION 0
32 # define FMT_GCC_PRAGMA(arg)
33 #endif
34 
35 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
36 # define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION
37 #else
38 # define FMT_HAS_GXX_CXX11 0
39 #endif
40 
41 #if defined(__INTEL_COMPILER)
42 # define FMT_ICC_VERSION __INTEL_COMPILER
43 #else
44 # define FMT_ICC_VERSION 0
45 #endif
46 
47 #ifdef __NVCC__
48 # define FMT_NVCC __NVCC__
49 #else
50 # define FMT_NVCC 0
51 #endif
52 
53 #ifdef _MSC_VER
54 # define FMT_MSC_VER _MSC_VER
55 # define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))
56 #else
57 # define FMT_MSC_VER 0
58 # define FMT_MSC_WARNING(...)
59 #endif
60 
61 #ifdef __has_feature
62 # define FMT_HAS_FEATURE(x) __has_feature(x)
63 #else
64 # define FMT_HAS_FEATURE(x) 0
65 #endif
66 
67 #if defined(__has_include) && !defined(__INTELLISENSE__) && \
68  (!FMT_ICC_VERSION || FMT_ICC_VERSION >= 1600)
69 # define FMT_HAS_INCLUDE(x) __has_include(x)
70 #else
71 # define FMT_HAS_INCLUDE(x) 0
72 #endif
73 
74 #ifdef __has_cpp_attribute
75 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
76 #else
77 # define FMT_HAS_CPP_ATTRIBUTE(x) 0
78 #endif
79 
80 #define FMT_HAS_CPP14_ATTRIBUTE(attribute) \
81  (__cplusplus >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute))
82 
83 #define FMT_HAS_CPP17_ATTRIBUTE(attribute) \
84  (__cplusplus >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))
85 
86 // Check if relaxed C++14 constexpr is supported.
87 // GCC doesn't allow throw in constexpr until version 6 (bug 67371).
88 #ifndef FMT_USE_CONSTEXPR
89 # define FMT_USE_CONSTEXPR \
90  (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \
91  (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \
92  !FMT_NVCC && !FMT_ICC_VERSION
93 #endif
94 #if FMT_USE_CONSTEXPR
95 # define FMT_CONSTEXPR constexpr
96 # define FMT_CONSTEXPR_DECL constexpr
97 #else
98 # define FMT_CONSTEXPR
99 # define FMT_CONSTEXPR_DECL
100 #endif
101 
102 // Check if constexpr std::char_traits<>::compare,length is supported.
103 #if defined(__GLIBCXX__)
104 # if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \
105  _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE.
106 # define FMT_CONSTEXPR_CHAR_TRAITS constexpr
107 # endif
108 #elif defined(_LIBCPP_VERSION) && __cplusplus >= 201703L && \
109  _LIBCPP_VERSION >= 4000
110 # define FMT_CONSTEXPR_CHAR_TRAITS constexpr
111 #elif FMT_MSC_VER >= 1914 && _MSVC_LANG >= 201703L
112 # define FMT_CONSTEXPR_CHAR_TRAITS constexpr
113 #endif
114 #ifndef FMT_CONSTEXPR_CHAR_TRAITS
115 # define FMT_CONSTEXPR_CHAR_TRAITS
116 #endif
117 
118 #ifndef FMT_OVERRIDE
119 # if FMT_HAS_FEATURE(cxx_override_control) || \
120  (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
121 # define FMT_OVERRIDE override
122 # else
123 # define FMT_OVERRIDE
124 # endif
125 #endif
126 
127 // Check if exceptions are disabled.
128 #ifndef FMT_EXCEPTIONS
129 # if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
130  FMT_MSC_VER && !_HAS_EXCEPTIONS
131 # define FMT_EXCEPTIONS 0
132 # else
133 # define FMT_EXCEPTIONS 1
134 # endif
135 #endif
136 
137 // Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
138 #ifndef FMT_USE_NOEXCEPT
139 # define FMT_USE_NOEXCEPT 0
140 #endif
141 
142 #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
143  (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
144 # define FMT_DETECTED_NOEXCEPT noexcept
145 # define FMT_HAS_CXX11_NOEXCEPT 1
146 #else
147 # define FMT_DETECTED_NOEXCEPT throw()
148 # define FMT_HAS_CXX11_NOEXCEPT 0
149 #endif
150 
151 #ifndef FMT_NOEXCEPT
152 # if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT
153 # define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
154 # else
155 # define FMT_NOEXCEPT
156 # endif
157 #endif
158 
159 // [[noreturn]] is disabled on MSVC and NVCC because of bogus unreachable code
160 // warnings.
161 #if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER && \
162  !FMT_NVCC
163 # define FMT_NORETURN [[noreturn]]
164 #else
165 # define FMT_NORETURN
166 #endif
167 
168 #ifndef FMT_MAYBE_UNUSED
169 # if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
170 # define FMT_MAYBE_UNUSED [[maybe_unused]]
171 # else
172 # define FMT_MAYBE_UNUSED
173 # endif
174 #endif
175 
176 #if __cplusplus == 201103L || __cplusplus == 201402L
177 # if defined(__INTEL_COMPILER) || defined(__PGI)
178 # define FMT_FALLTHROUGH
179 # elif defined(__clang__)
180 # define FMT_FALLTHROUGH [[clang::fallthrough]]
181 # elif FMT_GCC_VERSION >= 700 && \
182  (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
183 # define FMT_FALLTHROUGH [[gnu::fallthrough]]
184 # else
185 # define FMT_FALLTHROUGH
186 # endif
187 #elif FMT_HAS_CPP17_ATTRIBUTE(fallthrough) || \
188  (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
189 # define FMT_FALLTHROUGH [[fallthrough]]
190 #else
191 # define FMT_FALLTHROUGH
192 #endif
193 
194 #ifndef FMT_USE_FLOAT
195 # define FMT_USE_FLOAT 1
196 #endif
197 #ifndef FMT_USE_DOUBLE
198 # define FMT_USE_DOUBLE 1
199 #endif
200 #ifndef FMT_USE_LONG_DOUBLE
201 # define FMT_USE_LONG_DOUBLE 1
202 #endif
203 
204 #ifndef FMT_INLINE
205 # if FMT_GCC_VERSION || FMT_CLANG_VERSION
206 # define FMT_INLINE inline __attribute__((always_inline))
207 # else
208 # define FMT_INLINE inline
209 # endif
210 #endif
211 
212 #ifndef FMT_USE_INLINE_NAMESPACES
213 # if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \
214  (FMT_MSC_VER >= 1900 && (!defined(_MANAGED) || !_MANAGED))
215 # define FMT_USE_INLINE_NAMESPACES 1
216 # else
217 # define FMT_USE_INLINE_NAMESPACES 0
218 # endif
219 #endif
220 
221 #ifndef FMT_BEGIN_NAMESPACE
222 # if FMT_USE_INLINE_NAMESPACES
223 # define FMT_INLINE_NAMESPACE inline namespace
224 # define FMT_END_NAMESPACE \
225  } \
226  }
227 # else
228 # define FMT_INLINE_NAMESPACE namespace
229 # define FMT_END_NAMESPACE \
230  } \
231  using namespace v7; \
232  }
233 # endif
234 # define FMT_BEGIN_NAMESPACE \
235  namespace fmt { \
236  FMT_INLINE_NAMESPACE v7 {
237 #endif
238 
239 #ifndef FMT_MODULE_EXPORT
240 # define FMT_MODULE_EXPORT
241 # define FMT_MODULE_EXPORT_BEGIN
242 # define FMT_MODULE_EXPORT_END
243 # define FMT_BEGIN_DETAIL_NAMESPACE namespace detail {
244 # define FMT_END_DETAIL_NAMESPACE }
245 #endif
246 
247 #if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
248 # define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275)
249 # ifdef FMT_EXPORT
250 # define FMT_API __declspec(dllexport)
251 # elif defined(FMT_SHARED)
252 # define FMT_API __declspec(dllimport)
253 # endif
254 #else
255 # define FMT_CLASS_API
256 # if defined(FMT_EXPORT) || defined(FMT_SHARED)
257 # if defined(__GNUC__) || defined(__clang__)
258 # define FMT_API __attribute__((visibility("default")))
259 # endif
260 # endif
261 #endif
262 #ifndef FMT_API
263 # define FMT_API
264 #endif
265 
266 #if FMT_GCC_VERSION
267 # define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
268 #else
269 # define FMT_GCC_VISIBILITY_HIDDEN
270 #endif
271 
272 // libc++ supports string_view in pre-c++17.
273 #if (FMT_HAS_INCLUDE(<string_view>) && \
274  (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \
275  (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
276 # include <string_view>
277 # define FMT_USE_STRING_VIEW
278 #elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L
279 # include <experimental/string_view>
280 # define FMT_USE_EXPERIMENTAL_STRING_VIEW
281 #endif
282 
283 #ifndef FMT_UNICODE
284 # define FMT_UNICODE !FMT_MSC_VER
285 #endif
286 
287 #ifndef FMT_CONSTEVAL
288 # if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \
289  __cplusplus > 201703L) || \
290  (defined(__cpp_consteval) && \
291  !FMT_MSC_VER) // consteval is broken in MSVC.
292 # define FMT_CONSTEVAL consteval
293 # define FMT_HAS_CONSTEVAL
294 # else
295 # define FMT_CONSTEVAL
296 # endif
297 #endif
298 
299 #ifndef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
300 # if defined(__cpp_nontype_template_args) && \
301  ((FMT_GCC_VERSION >= 903 && __cplusplus >= 201709L) || \
302  __cpp_nontype_template_args >= 201911L)
303 # define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 1
304 # else
305 # define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 0
306 # endif
307 #endif
308 
309 // Enable minimal optimizations for more compact code in debug mode.
310 FMT_GCC_PRAGMA("GCC push_options")
311 #ifndef __OPTIMIZE__
312 FMT_GCC_PRAGMA("GCC optimize(\"Og\")")
313 #endif
314 
317 
318 // Implementations of enable_if_t and other metafunctions for older systems.
319 template <bool B, class T = void>
321 template <bool B, class T, class F>
323 template <bool B> using bool_constant = std::integral_constant<bool, B>;
324 template <typename T>
326 template <typename T>
327 using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
328 template <typename T> struct type_identity { using type = T; };
329 template <typename T> using type_identity_t = typename type_identity<T>::type;
330 
331 struct monostate {
332  constexpr monostate() {}
333 };
334 
335 // An enable_if helper to be used in template parameters which results in much
336 // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed
337 // to workaround a bug in MSVC 2019 (see #1140 and #1186).
338 #ifdef FMT_DOC
339 # define FMT_ENABLE_IF(...)
340 #else
341 # define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0
342 #endif
343 
345 
347 #ifdef __cpp_lib_is_constant_evaluated
349 #else
350  return false;
351 #endif
352 }
353 
354 // A function to suppress "conditional expression is constant" warnings.
355 template <typename T> constexpr auto const_check(T value) -> T { return value; }
356 
357 FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
358  const char* message);
359 
360 #ifndef FMT_ASSERT
361 # ifdef NDEBUG
362 // FMT_ASSERT is not empty to avoid -Werror=empty-body.
363 # define FMT_ASSERT(condition, message) ((void)0)
364 # else
365 # define FMT_ASSERT(condition, message) \
366  ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
367  ? (void)0 \
368  : ::fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
369 # endif
370 #endif
371 
372 #if defined(FMT_USE_STRING_VIEW)
373 template <typename Char> using std_string_view = std::basic_string_view<Char>;
374 #elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW)
375 template <typename Char>
376 using std_string_view = std::experimental::basic_string_view<Char>;
377 #else
378 template <typename T> struct std_string_view {};
379 #endif
380 
381 #ifdef FMT_USE_INT128
382 // Do nothing.
383 #elif defined(__SIZEOF_INT128__) && !FMT_NVCC && \
384  !(FMT_CLANG_VERSION && FMT_MSC_VER)
385 # define FMT_USE_INT128 1
386 using int128_t = __int128_t;
387 using uint128_t = __uint128_t;
388 template <typename T> inline auto convert_for_visit(T value) -> T {
389  return value;
390 }
391 #else
392 # define FMT_USE_INT128 0
393 #endif
394 #if !FMT_USE_INT128
395 enum class int128_t {};
396 enum class uint128_t {};
397 // Reduce template instantiations.
398 template <typename T> inline auto convert_for_visit(T) -> monostate {
399  return {};
400 }
401 #endif
402 
403 // Casts a nonnegative integer to unsigned.
404 template <typename Int>
407  FMT_ASSERT(value >= 0, "negative value");
408  return static_cast<typename std::make_unsigned<Int>::type>(value);
409 }
410 
411 FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5";
412 
413 constexpr auto is_utf8() -> bool {
414  // Avoid buggy sign extensions in MSVC's constant evaluation mode.
415  // https://developercommunity.visualstudio.com/t/C-difference-in-behavior-for-unsigned/1233612
416  using uchar = unsigned char;
417  return FMT_UNICODE || (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 &&
418  uchar(micro[1]) == 0xB5);
419 }
421 
422 /**
423  An implementation of ``std::basic_string_view`` for pre-C++17. It provides a
424  subset of the API. ``fmt::basic_string_view`` is used for format strings even
425  if ``std::string_view`` is available to prevent issues when a library is
426  compiled with a different ``-std`` option than the client code (which is not
427  recommended).
428  */
429 template <typename Char> class basic_string_view {
430  private:
431  const Char* data_;
432  size_t size_;
433 
434  public:
435  using value_type = Char;
436  using iterator = const Char*;
437 
438  constexpr basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {}
439 
440  /** Constructs a string reference object from a C string and a size. */
441  constexpr basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT
442  : data_(s),
443  size_(count) {}
444 
445  /**
446  \rst
447  Constructs a string reference object from a C string computing
448  the size with ``std::char_traits<Char>::length``.
449  \endrst
450  */
452  FMT_INLINE
453  basic_string_view(const Char* s) : data_(s) {
456  size_ = std::strlen(reinterpret_cast<const char*>(s));
457  else
459  }
460 
461  /** Constructs a string reference from a ``std::basic_string`` object. */
462  template <typename Traits, typename Alloc>
465  : data_(s.data()),
466  size_(s.size()) {}
467 
468  template <typename S, FMT_ENABLE_IF(std::is_same<
469  S, detail::std_string_view<Char>>::value)>
471  size_(s.size()) {}
472 
473  /** Returns a pointer to the string data. */
474  constexpr auto data() const -> const Char* { return data_; }
475 
476  /** Returns the string size. */
477  constexpr auto size() const -> size_t { return size_; }
478 
479  constexpr auto begin() const -> iterator { return data_; }
480  constexpr auto end() const -> iterator { return data_ + size_; }
481 
482  constexpr auto operator[](size_t pos) const -> const Char& {
483  return data_[pos];
484  }
485 
487  data_ += n;
488  size_ -= n;
489  }
490 
491  // Lexicographically compare this string reference to other.
493  size_t str_size = size_ < other.size_ ? size_ : other.size_;
494  int result = std::char_traits<Char>::compare(data_, other.data_, str_size);
495  if (result == 0)
496  result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
497  return result;
498  }
499 
501  basic_string_view rhs)
502  -> bool {
503  return lhs.compare(rhs) == 0;
504  }
505  friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {
506  return lhs.compare(rhs) != 0;
507  }
508  friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool {
509  return lhs.compare(rhs) < 0;
510  }
511  friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool {
512  return lhs.compare(rhs) <= 0;
513  }
514  friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool {
515  return lhs.compare(rhs) > 0;
516  }
517  friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool {
518  return lhs.compare(rhs) >= 0;
519  }
520 };
521 
523 
524 /** Specifies if ``T`` is a character type. Can be specialized by users. */
525 template <typename T> struct is_char : std::false_type {};
526 template <> struct is_char<char> : std::true_type {};
527 
528 /**
529  \rst
530  Returns a string view of `s`. In order to add custom string type support to
531  {fmt} provide an overload of `to_string_view` for it in the same namespace as
532  the type for the argument-dependent lookup to work.
533 
534  **Example**::
535 
536  namespace my_ns {
537  inline string_view to_string_view(const my_string& s) {
538  return {s.data(), s.length()};
539  }
540  }
541  std::string message = fmt::format(my_string("The answer is {}"), 42);
542  \endrst
543  */
546  return s;
547 }
548 
549 template <typename Char, typename Traits, typename Alloc>
552  return s;
553 }
554 
555 template <typename Char>
558  return s;
559 }
560 
561 template <typename Char,
562  FMT_ENABLE_IF(!std::is_empty<detail::std_string_view<Char>>::value)>
563 inline auto to_string_view(detail::std_string_view<Char> s)
565  return s;
566 }
567 
568 // A base class for compile-time strings. It is defined in the fmt namespace to
569 // make formatting functions visible via ADL, e.g. format(FMT_STRING("{}"), 42).
570 struct compile_string {};
571 
572 template <typename S>
573 struct is_compile_string : std::is_base_of<compile_string, S> {};
574 
576 constexpr auto to_string_view(const S& s)
579 }
580 
582 
583 void to_string_view(...);
585 
586 // Specifies whether S is a string type convertible to fmt::basic_string_view.
587 // It should be a constexpr function but MSVC 2017 fails to compile it in
588 // enable_if and MSVC 2015 fails to compile it as an alias template.
589 template <typename S>
590 struct is_string : std::is_class<decltype(to_string_view(std::declval<S>()))> {
591 };
592 
593 template <typename S, typename = void> struct char_t_impl {};
594 template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> {
595  using result = decltype(to_string_view(std::declval<S>()));
596  using type = typename result::value_type;
597 };
598 
599 // Reports a compile-time error if S is not a valid format string.
600 template <typename..., typename S, FMT_ENABLE_IF(!is_compile_string<S>::value)>
602 #ifdef FMT_ENFORCE_COMPILE_STRING
603  static_assert(is_compile_string<S>::value,
604  "FMT_ENFORCE_COMPILE_STRING requires all format strings to use "
605  "FMT_STRING.");
606 #endif
607 }
608 template <typename..., typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
609 void check_format_string(S);
610 
612  constexpr error_handler() = default;
613  constexpr error_handler(const error_handler&) = default;
614 
615  // This function is intentionally not constexpr to give a compile-time error.
616  FMT_NORETURN FMT_API void on_error(const char* message);
617 };
619 
620 /** String's character type. */
621 template <typename S> using char_t = typename detail::char_t_impl<S>::type;
622 
623 /**
624  \rst
625  Parsing context consisting of a format string range being parsed and an
626  argument counter for automatic indexing.
627  You can use the ```format_parse_context`` type alias for ``char`` instead.
628  \endrst
629  */
630 template <typename Char, typename ErrorHandler = detail::error_handler>
632  private:
633  basic_string_view<Char> format_str_;
634  int next_arg_id_;
635 
636  public:
637  using char_type = Char;
639 
640  explicit constexpr basic_format_parse_context(
641  basic_string_view<Char> format_str, ErrorHandler eh = {},
642  int next_arg_id = 0)
643  : ErrorHandler(eh), format_str_(format_str), next_arg_id_(next_arg_id) {}
644 
645  /**
646  Returns an iterator to the beginning of the format string range being
647  parsed.
648  */
649  constexpr auto begin() const FMT_NOEXCEPT -> iterator {
650  return format_str_.begin();
651  }
652 
653  /**
654  Returns an iterator past the end of the format string range being parsed.
655  */
656  constexpr auto end() const FMT_NOEXCEPT -> iterator {
657  return format_str_.end();
658  }
659 
660  /** Advances the begin iterator to ``it``. */
662  format_str_.remove_prefix(detail::to_unsigned(it - begin()));
663  }
664 
665  /**
666  Reports an error if using the manual argument indexing; otherwise returns
667  the next argument index and switches to the automatic indexing.
668  */
669  FMT_CONSTEXPR auto next_arg_id() -> int {
670  // Don't check if the argument id is valid to avoid overhead and because it
671  // will be checked during formatting anyway.
672  if (next_arg_id_ >= 0) return next_arg_id_++;
673  on_error("cannot switch from manual to automatic argument indexing");
674  return 0;
675  }
676 
677  /**
678  Reports an error if using the automatic argument indexing; otherwise
679  switches to the manual indexing.
680  */
682  if (next_arg_id_ > 0)
683  on_error("cannot switch from automatic to manual argument indexing");
684  else
685  next_arg_id_ = -1;
686  }
687 
689 
690  FMT_CONSTEXPR void on_error(const char* message) {
691  ErrorHandler::on_error(message);
692  }
693 
694  constexpr auto error_handler() const -> ErrorHandler { return *this; }
695 };
696 
698 
699 template <typename Context> class basic_format_arg;
700 template <typename Context> class basic_format_args;
701 template <typename Context> class dynamic_format_arg_store;
702 
703 // A formatter for objects of type T.
704 template <typename T, typename Char = char, typename Enable = void>
705 struct formatter {
706  // A deleted default constructor indicates a disabled formatter.
707  formatter() = delete;
708 };
709 
710 // Specifies if T has an enabled formatter specialization. A type can be
711 // formattable even if it doesn't have a formatter e.g. via a conversion.
712 template <typename T, typename Context>
713 using has_formatter =
714  std::is_constructible<typename Context::template formatter_type<T>>;
715 
716 // Checks whether T is a container with contiguous storage.
717 template <typename T> struct is_contiguous : std::false_type {};
718 template <typename Char>
719 struct is_contiguous<std::basic_string<Char>> : std::true_type {};
720 
721 class appender;
722 
724 
725 // Extracts a reference to the container from back_insert_iterator.
726 template <typename Container>
727 inline auto get_container(std::back_insert_iterator<Container> it)
728  -> Container& {
729  using bi_iterator = std::back_insert_iterator<Container>;
730  struct accessor : bi_iterator {
731  accessor(bi_iterator iter) : bi_iterator(iter) {}
732  using bi_iterator::container;
733  };
734  return *accessor(it).container;
735 }
736 
737 template <typename Char, typename InputIt, typename OutputIt>
738 FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out)
739  -> OutputIt {
740  while (begin != end) *out++ = static_cast<Char>(*begin++);
741  return out;
742 }
743 
745 FMT_CONSTEXPR auto copy_str(const Char* begin, const Char* end, Char* out)
746  -> Char* {
747  if (is_constant_evaluated())
748  return copy_str<Char, const Char*, Char*>(begin, end, out);
749  auto size = to_unsigned(end - begin);
750  memcpy(out, begin, size);
751  return out + size;
752 }
753 
754 /**
755  \rst
756  A contiguous memory buffer with an optional growing ability. It is an internal
757  class and shouldn't be used directly, only via `~fmt::basic_memory_buffer`.
758  \endrst
759  */
760 template <typename T> class buffer {
761  private:
762  T* ptr_;
763  size_t size_;
764  size_t capacity_;
765 
766  protected:
767  // Don't initialize ptr_ since it is not accessed to save a few cycles.
768  FMT_MSC_WARNING(suppress : 26495)
769  buffer(size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {}
770 
771  buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) FMT_NOEXCEPT
772  : ptr_(p),
773  size_(sz),
774  capacity_(cap) {}
775 
776  ~buffer() = default;
777  buffer(buffer&&) = default;
778 
779  /** Sets the buffer data and capacity. */
780  void set(T* buf_data, size_t buf_capacity) FMT_NOEXCEPT {
781  ptr_ = buf_data;
782  capacity_ = buf_capacity;
783  }
784 
785  /** Increases the buffer capacity to hold at least *capacity* elements. */
786  virtual void grow(size_t capacity) = 0;
787 
788  public:
789  using value_type = T;
790  using const_reference = const T&;
791 
792  buffer(const buffer&) = delete;
793  void operator=(const buffer&) = delete;
794 
795  auto begin() FMT_NOEXCEPT -> T* { return ptr_; }
796  auto end() FMT_NOEXCEPT -> T* { return ptr_ + size_; }
797 
798  auto begin() const FMT_NOEXCEPT -> const T* { return ptr_; }
799  auto end() const FMT_NOEXCEPT -> const T* { return ptr_ + size_; }
800 
801  /** Returns the size of this buffer. */
802  auto size() const FMT_NOEXCEPT -> size_t { return size_; }
803 
804  /** Returns the capacity of this buffer. */
805  auto capacity() const FMT_NOEXCEPT -> size_t { return capacity_; }
806 
807  /** Returns a pointer to the buffer data. */
808  auto data() FMT_NOEXCEPT -> T* { return ptr_; }
809 
810  /** Returns a pointer to the buffer data. */
811  auto data() const FMT_NOEXCEPT -> const T* { return ptr_; }
812 
813  /** Clears this buffer. */
814  void clear() { size_ = 0; }
815 
816  // Tries resizing the buffer to contain *count* elements. If T is a POD type
817  // the new elements may not be initialized.
818  void try_resize(size_t count) {
819  try_reserve(count);
820  size_ = count <= capacity_ ? count : capacity_;
821  }
822 
823  // Tries increasing the buffer capacity to *new_capacity*. It can increase the
824  // capacity by a smaller amount than requested but guarantees there is space
825  // for at least one additional element either by increasing the capacity or by
826  // flushing the buffer if it is full.
827  void try_reserve(size_t new_capacity) {
828  if (new_capacity > capacity_) grow(new_capacity);
829  }
830 
831  void push_back(const T& value) {
832  try_reserve(size_ + 1);
833  ptr_[size_++] = value;
834  }
835 
836  /** Appends data to the end of the buffer. */
837  template <typename U> void append(const U* begin, const U* end);
838 
839  template <typename I> auto operator[](I index) -> T& { return ptr_[index]; }
840  template <typename I> auto operator[](I index) const -> const T& {
841  return ptr_[index];
842  }
843 };
844 
846  explicit buffer_traits(size_t) {}
847  auto count() const -> size_t { return 0; }
848  auto limit(size_t size) -> size_t { return size; }
849 };
850 
852  private:
853  size_t count_ = 0;
854  size_t limit_;
855 
856  public:
857  explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
858  auto count() const -> size_t { return count_; }
859  auto limit(size_t size) -> size_t {
860  size_t n = limit_ > count_ ? limit_ - count_ : 0;
861  count_ += size;
862  return size < n ? size : n;
863  }
864 };
865 
866 // A buffer that writes to an output iterator when flushed.
867 template <typename OutputIt, typename T, typename Traits = buffer_traits>
868 class iterator_buffer final : public Traits, public buffer<T> {
869  private:
870  OutputIt out_;
871  enum { buffer_size = 256 };
872  T data_[buffer_size];
873 
874  protected:
875  void grow(size_t) final FMT_OVERRIDE {
876  if (this->size() == buffer_size) flush();
877  }
878 
879  void flush() {
880  auto size = this->size();
881  this->clear();
882  out_ = copy_str<T>(data_, data_ + this->limit(size), out_);
883  }
884 
885  public:
886  explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
887  : Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {}
889  : Traits(other), buffer<T>(data_, 0, buffer_size), out_(other.out_) {}
891 
892  auto out() -> OutputIt {
893  flush();
894  return out_;
895  }
896  auto count() const -> size_t { return Traits::count() + this->size(); }
897 };
898 
899 template <typename T> class iterator_buffer<T*, T> final : public buffer<T> {
900  protected:
901  void grow(size_t) final FMT_OVERRIDE {}
902 
903  public:
904  explicit iterator_buffer(T* out, size_t = 0) : buffer<T>(out, 0, ~size_t()) {}
905 
906  auto out() -> T* { return &*this->end(); }
907 };
908 
909 // A buffer that writes to a container with the contiguous storage.
910 template <typename Container>
911 class iterator_buffer<std::back_insert_iterator<Container>,
912  enable_if_t<is_contiguous<Container>::value,
913  typename Container::value_type>>
914  final : public buffer<typename Container::value_type> {
915  private:
916  Container& container_;
917 
918  protected:
919  void grow(size_t capacity) final FMT_OVERRIDE {
920  container_.resize(capacity);
921  this->set(&container_[0], capacity);
922  }
923 
924  public:
925  explicit iterator_buffer(Container& c)
926  : buffer<typename Container::value_type>(c.size()), container_(c) {}
927  explicit iterator_buffer(std::back_insert_iterator<Container> out, size_t = 0)
928  : iterator_buffer(get_container(out)) {}
929  auto out() -> std::back_insert_iterator<Container> {
930  return std::back_inserter(container_);
931  }
932 };
933 
934 // A buffer that counts the number of code units written discarding the output.
935 template <typename T = char> class counting_buffer final : public buffer<T> {
936  private:
937  enum { buffer_size = 256 };
938  T data_[buffer_size];
939  size_t count_ = 0;
940 
941  protected:
942  void grow(size_t) final FMT_OVERRIDE {
943  if (this->size() != buffer_size) return;
944  count_ += this->size();
945  this->clear();
946  }
947 
948  public:
949  counting_buffer() : buffer<T>(data_, 0, buffer_size) {}
950 
951  auto count() -> size_t { return count_ + this->size(); }
952 };
953 
954 template <typename T>
956  std::back_insert_iterator<buffer<T>>>;
957 
958 // Maps an output iterator to a buffer.
959 template <typename T, typename OutputIt>
961  return iterator_buffer<OutputIt, T>(out);
962 }
963 
964 template <typename Buffer>
965 auto get_iterator(Buffer& buf) -> decltype(buf.out()) {
966  return buf.out();
967 }
968 template <typename T> auto get_iterator(buffer<T>& buf) -> buffer_appender<T> {
969  return buffer_appender<T>(buf);
970 }
971 
972 template <typename T, typename Char = char, typename Enable = void>
974  fallback_formatter() = delete;
975 };
976 
977 // Specifies if T has an enabled fallback_formatter specialization.
978 template <typename T, typename Char>
980  std::is_constructible<fallback_formatter<T, Char>>;
981 
982 struct view {};
983 
984 template <typename Char, typename T> struct named_arg : view {
985  const Char* name;
986  const T& value;
987  named_arg(const Char* n, const T& v) : name(n), value(v) {}
988 };
989 
990 template <typename Char> struct named_arg_info {
991  const Char* name;
992  int id;
993 };
994 
995 template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
996 struct arg_data {
997  // args_[0].named_args points to named_args_ to avoid bloating format_args.
998  // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
999  T args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
1001 
1002  template <typename... U>
1003  arg_data(const U&... init) : args_{T(named_args_, NUM_NAMED_ARGS), init...} {}
1004  arg_data(const arg_data& other) = delete;
1005  auto args() const -> const T* { return args_ + 1; }
1007 };
1008 
1009 template <typename T, typename Char, size_t NUM_ARGS>
1010 struct arg_data<T, Char, NUM_ARGS, 0> {
1011  // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
1012  T args_[NUM_ARGS != 0 ? NUM_ARGS : +1];
1013 
1014  template <typename... U>
1015  FMT_CONSTEXPR FMT_INLINE arg_data(const U&... init) : args_{init...} {}
1016  FMT_CONSTEXPR FMT_INLINE auto args() const -> const T* { return args_; }
1017  FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t {
1018  return nullptr;
1019  }
1020 };
1021 
1022 template <typename Char>
1023 inline void init_named_args(named_arg_info<Char>*, int, int) {}
1024 
1025 template <typename T> struct is_named_arg : std::false_type {};
1026 template <typename T> struct is_statically_named_arg : std::false_type {};
1027 
1028 template <typename T, typename Char>
1029 struct is_named_arg<named_arg<Char, T>> : std::true_type {};
1030 
1031 template <typename Char, typename T, typename... Tail,
1033 void init_named_args(named_arg_info<Char>* named_args, int arg_count,
1034  int named_arg_count, const T&, const Tail&... args) {
1035  init_named_args(named_args, arg_count + 1, named_arg_count, args...);
1036 }
1037 
1038 template <typename Char, typename T, typename... Tail,
1040 void init_named_args(named_arg_info<Char>* named_args, int arg_count,
1041  int named_arg_count, const T& arg, const Tail&... args) {
1042  named_args[named_arg_count++] = {arg.name, arg_count};
1043  init_named_args(named_args, arg_count + 1, named_arg_count, args...);
1044 }
1045 
1046 template <typename... Args>
1047 FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int,
1048  const Args&...) {}
1049 
1050 template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
1051 template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
1052  return (B1 ? 1 : 0) + count<B2, Tail...>();
1053 }
1054 
1055 template <typename... Args> constexpr auto count_named_args() -> size_t {
1056  return count<is_named_arg<Args>::value...>();
1057 }
1058 
1059 enum class type {
1060  none_type,
1061  // Integer types should go first,
1062  int_type,
1063  uint_type,
1066  int128_type,
1067  uint128_type,
1068  bool_type,
1069  char_type,
1071  // followed by floating-point types.
1072  float_type,
1073  double_type,
1076  cstring_type,
1077  string_type,
1078  pointer_type,
1079  custom_type
1080 };
1081 
1082 // Maps core type T to the corresponding type enum constant.
1083 template <typename T, typename Char>
1084 struct type_constant : std::integral_constant<type, type::custom_type> {};
1085 
1086 #define FMT_TYPE_CONSTANT(Type, constant) \
1087  template <typename Char> \
1088  struct type_constant<Type, Char> \
1089  : std::integral_constant<type, type::constant> {}
1090 
1091 FMT_TYPE_CONSTANT(int, int_type);
1092 FMT_TYPE_CONSTANT(unsigned, uint_type);
1093 FMT_TYPE_CONSTANT(long long, long_long_type);
1094 FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);
1095 FMT_TYPE_CONSTANT(int128_t, int128_type);
1096 FMT_TYPE_CONSTANT(uint128_t, uint128_type);
1097 FMT_TYPE_CONSTANT(bool, bool_type);
1098 FMT_TYPE_CONSTANT(Char, char_type);
1099 FMT_TYPE_CONSTANT(float, float_type);
1100 FMT_TYPE_CONSTANT(double, double_type);
1101 FMT_TYPE_CONSTANT(long double, long_double_type);
1102 FMT_TYPE_CONSTANT(const Char*, cstring_type);
1104 FMT_TYPE_CONSTANT(const void*, pointer_type);
1105 
1106 constexpr bool is_integral_type(type t) {
1107  return t > type::none_type && t <= type::last_integer_type;
1108 }
1109 
1110 constexpr bool is_arithmetic_type(type t) {
1111  return t > type::none_type && t <= type::last_numeric_type;
1112 }
1113 
1114 template <typename Char> struct string_value {
1115  const Char* data;
1116  size_t size;
1117 };
1118 
1119 template <typename Char> struct named_arg_value {
1121  size_t size;
1122 };
1123 
1124 template <typename Context> struct custom_value {
1125  using parse_context = typename Context::parse_context_type;
1126  const void* value;
1127  void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx);
1128 };
1129 
1130 // A formatting argument value.
1131 template <typename Context> class value {
1132  public:
1133  using char_type = typename Context::char_type;
1134 
1135  union {
1138  unsigned uint_value;
1139  long long long_long_value;
1140  unsigned long long ulong_long_value;
1147  long double long_double_value;
1148  const void* pointer;
1152  };
1153 
1154  constexpr FMT_INLINE value() : no_value() {}
1155  constexpr FMT_INLINE value(int val) : int_value(val) {}
1156  constexpr FMT_INLINE value(unsigned val) : uint_value(val) {}
1157  constexpr FMT_INLINE value(long long val) : long_long_value(val) {}
1158  constexpr FMT_INLINE value(unsigned long long val) : ulong_long_value(val) {}
1161  FMT_INLINE value(float val) : float_value(val) {}
1162  FMT_INLINE value(double val) : double_value(val) {}
1163  FMT_INLINE value(long double val) : long_double_value(val) {}
1164  constexpr FMT_INLINE value(bool val) : bool_value(val) {}
1165  constexpr FMT_INLINE value(char_type val) : char_value(val) {}
1167  string.data = val;
1168  if (is_constant_evaluated()) string.size = {};
1169  }
1171  string.data = val.data();
1172  string.size = val.size();
1173  }
1174  FMT_INLINE value(const void* val) : pointer(val) {}
1176  : named_args{args, size} {}
1177 
1178  template <typename T> FMT_CONSTEXPR FMT_INLINE value(const T& val) {
1179  custom.value = &val;
1180  // Get the formatter type through the context to allow different contexts
1181  // have different extension points, e.g. `formatter<T>` for `format` and
1182  // `printf_formatter<T>` for `printf`.
1183  custom.format = format_custom_arg<
1185  typename Context::template formatter_type<T>,
1187  }
1188 
1189  private:
1190  // Formats an argument of a custom type, such as a user-defined class.
1191  template <typename T, typename Formatter>
1192  static void format_custom_arg(const void* arg,
1193  typename Context::parse_context_type& parse_ctx,
1194  Context& ctx) {
1195  Formatter f;
1196  parse_ctx.advance_to(f.parse(parse_ctx));
1197  ctx.advance_to(f.format(*static_cast<const T*>(arg), ctx));
1198  }
1199 };
1200 
1201 template <typename Context, typename T>
1203 
1204 // To minimize the number of types we need to deal with, long is translated
1205 // either to int or to long long depending on its size.
1206 enum { long_short = sizeof(long) == sizeof(int) };
1209 
1210 struct unformattable {};
1211 
1212 // Maps formatting arguments to core types.
1213 template <typename Context> struct arg_mapper {
1214  using char_type = typename Context::char_type;
1215 
1216  FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int { return val; }
1217  FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned {
1218  return val;
1219  }
1220  FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int { return val; }
1221  FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned {
1222  return val;
1223  }
1224  FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int { return val; }
1225  FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned { return val; }
1226  FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type { return val; }
1227  FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type {
1228  return val;
1229  }
1230  FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long { return val; }
1231  FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val)
1232  -> unsigned long long {
1233  return val;
1234  }
1237  FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool { return val; }
1238 
1241  static_assert(
1243  "mixing character types is disallowed");
1244  return val;
1245  }
1246 
1247  FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float { return val; }
1248  FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double { return val; }
1249  FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double {
1250  return val;
1251  }
1252 
1254  return val;
1255  }
1256  FMT_CONSTEXPR FMT_INLINE auto map(const char_type* val) -> const char_type* {
1257  return val;
1258  }
1260  FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1262  static_assert(std::is_same<char_type, char_t<T>>::value,
1263  "mixing character types is disallowed");
1264  return to_string_view(val);
1265  }
1266  template <typename T,
1267  FMT_ENABLE_IF(
1268  std::is_constructible<basic_string_view<char_type>, T>::value &&
1271  FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1274  }
1275  template <
1276  typename T,
1277  FMT_ENABLE_IF(
1278  std::is_constructible<std_string_view<char_type>, T>::value &&
1279  !std::is_constructible<basic_string_view<char_type>, T>::value &&
1282  FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1285  }
1286  FMT_CONSTEXPR FMT_INLINE auto map(const signed char* val) -> const char* {
1287  static_assert(std::is_same<char_type, char>::value, "invalid string type");
1288  return reinterpret_cast<const char*>(val);
1289  }
1290  FMT_CONSTEXPR FMT_INLINE auto map(const unsigned char* val) -> const char* {
1291  static_assert(std::is_same<char_type, char>::value, "invalid string type");
1292  return reinterpret_cast<const char*>(val);
1293  }
1294  FMT_CONSTEXPR FMT_INLINE auto map(signed char* val) -> const char* {
1295  const auto* const_val = val;
1296  return map(const_val);
1297  }
1298  FMT_CONSTEXPR FMT_INLINE auto map(unsigned char* val) -> const char* {
1299  const auto* const_val = val;
1300  return map(const_val);
1301  }
1302 
1303  FMT_CONSTEXPR FMT_INLINE auto map(void* val) -> const void* { return val; }
1304  FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* {
1305  return val;
1306  }
1307  FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void* {
1308  return val;
1309  }
1310 
1311  // We use SFINAE instead of a const T* parameter to avoid conflicting with
1312  // the C array overload.
1313  template <typename T>
1315  // Formatting of arbitrary pointers is disallowed. If you want to output
1316  // a pointer cast it to "void *" or "const void *". In particular, this
1317  // forbids formatting of "[const] volatile char *" which is printed as bool
1318  // by iostreams.
1319  static_assert(!sizeof(T), "formatting of non-void pointers is disallowed");
1320  return 0;
1321  }
1322 
1323  template <typename T, std::size_t N>
1324  FMT_CONSTEXPR FMT_INLINE auto map(const T (&values)[N]) -> const T (&)[N] {
1325  return values;
1326  }
1327 
1328  template <typename T,
1332  FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1333  -> decltype(std::declval<arg_mapper>().map(
1334  static_cast<typename std::underlying_type<T>::type>(val))) {
1335  return map(static_cast<typename std::underlying_type<T>::type>(val));
1336  }
1337  template <typename T,
1341  FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> const T& {
1342  return val;
1343  }
1344 
1347  -> decltype(std::declval<arg_mapper>().map(named_arg.value)) {
1348  return map(named_arg.value);
1349  }
1350 
1351  auto map(...) -> unformattable { return {}; }
1352 };
1353 
1354 // A type constant after applying arg_mapper<Context>.
1355 template <typename T, typename Context>
1356 using mapped_type_constant =
1357  type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())),
1358  typename Context::char_type>;
1359 
1360 enum { packed_arg_bits = 4 };
1361 // Maximum number of arguments with packed types.
1363 enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };
1364 enum : unsigned long long { has_named_args_bit = 1ULL << 62 };
1365 
1367 
1368 // An output iterator that appends to a buffer.
1369 // It is used to reduce symbol sizes for the common case.
1370 class appender : public std::back_insert_iterator<detail::buffer<char>> {
1371  using base = std::back_insert_iterator<detail::buffer<char>>;
1372 
1373  template <typename T>
1374  friend auto get_buffer(appender out) -> detail::buffer<char>& {
1375  return detail::get_container(out);
1376  }
1377 
1378  public:
1379  using std::back_insert_iterator<detail::buffer<char>>::back_insert_iterator;
1380  appender(base it) : base(it) {}
1381  using _Unchecked_type = appender; // Mark iterator as checked.
1382 
1383  auto operator++() -> appender& {
1384  base::operator++();
1385  return *this;
1386  }
1387 
1388  auto operator++(int) -> appender {
1389  auto tmp = *this;
1390  ++*this;
1391  return tmp;
1392  }
1393 };
1394 
1395 // A formatting argument. It is a trivially copyable/constructible type to
1396 // allow storage in basic_memory_buffer.
1397 template <typename Context> class basic_format_arg {
1398  private:
1399  detail::value<Context> value_;
1400  detail::type type_;
1401 
1402  template <typename ContextType, typename T>
1403  friend FMT_CONSTEXPR auto detail::make_arg(const T& value)
1405 
1406  template <typename Visitor, typename Ctx>
1407  friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis,
1408  const basic_format_arg<Ctx>& arg)
1409  -> decltype(vis(0));
1410 
1413 
1414  using char_type = typename Context::char_type;
1415 
1416  template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
1417  friend struct detail::arg_data;
1418 
1419  basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
1420  : value_(args, size) {}
1421 
1422  public:
1423  class handle {
1424  public:
1425  explicit handle(detail::custom_value<Context> custom) : custom_(custom) {}
1426 
1427  void format(typename Context::parse_context_type& parse_ctx,
1428  Context& ctx) const {
1429  custom_.format(custom_.value, parse_ctx, ctx);
1430  }
1431 
1432  private:
1433  detail::custom_value<Context> custom_;
1434  };
1435 
1436  constexpr basic_format_arg() : type_(detail::type::none_type) {}
1437 
1438  constexpr explicit operator bool() const FMT_NOEXCEPT {
1439  return type_ != detail::type::none_type;
1440  }
1441 
1442  auto type() const -> detail::type { return type_; }
1443 
1444  auto is_integral() const -> bool { return detail::is_integral_type(type_); }
1445  auto is_arithmetic() const -> bool {
1446  return detail::is_arithmetic_type(type_);
1447  }
1448 };
1449 
1450 /**
1451  \rst
1452  Visits an argument dispatching to the appropriate visit method based on
1453  the argument type. For example, if the argument type is ``double`` then
1454  ``vis(value)`` will be called with the value of type ``double``.
1455  \endrst
1456  */
1457 template <typename Visitor, typename Context>
1459  Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) {
1460  switch (arg.type_) {
1461  case detail::type::none_type:
1462  break;
1463  case detail::type::int_type:
1464  return vis(arg.value_.int_value);
1465  case detail::type::uint_type:
1466  return vis(arg.value_.uint_value);
1467  case detail::type::long_long_type:
1468  return vis(arg.value_.long_long_value);
1469  case detail::type::ulong_long_type:
1470  return vis(arg.value_.ulong_long_value);
1471  case detail::type::int128_type:
1472  return vis(detail::convert_for_visit(arg.value_.int128_value));
1473  case detail::type::uint128_type:
1474  return vis(detail::convert_for_visit(arg.value_.uint128_value));
1475  case detail::type::bool_type:
1476  return vis(arg.value_.bool_value);
1477  case detail::type::char_type:
1478  return vis(arg.value_.char_value);
1479  case detail::type::float_type:
1480  return vis(arg.value_.float_value);
1481  case detail::type::double_type:
1482  return vis(arg.value_.double_value);
1483  case detail::type::long_double_type:
1484  return vis(arg.value_.long_double_value);
1485  case detail::type::cstring_type:
1486  return vis(arg.value_.string.data);
1487  case detail::type::string_type:
1489  return vis(sv(arg.value_.string.data, arg.value_.string.size));
1490  case detail::type::pointer_type:
1491  return vis(arg.value_.pointer);
1492  case detail::type::custom_type:
1493  return vis(typename basic_format_arg<Context>::handle(arg.value_.custom));
1494  }
1495  return vis(monostate());
1496 }
1497 
1499 
1500 template <typename Char, typename InputIt>
1501 auto copy_str(InputIt begin, InputIt end, appender out) -> appender {
1502  get_container(out).append(begin, end);
1503  return out;
1504 }
1505 
1506 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
1507 // A workaround for gcc 4.8 to make void_t work in a SFINAE context.
1508 template <typename... Ts> struct void_t_impl { using type = void; };
1509 template <typename... Ts>
1510 using void_t = typename detail::void_t_impl<Ts...>::type;
1511 #else
1512 template <typename...> using void_t = void;
1513 #endif
1514 
1515 template <typename It, typename T, typename Enable = void>
1516 struct is_output_iterator : std::false_type {};
1517 
1518 template <typename It, typename T>
1520  It, T,
1522  decltype(*std::declval<It>() = std::declval<T>())>>
1523  : std::true_type {};
1524 
1525 template <typename OutputIt>
1526 struct is_back_insert_iterator : std::false_type {};
1527 template <typename Container>
1528 struct is_back_insert_iterator<std::back_insert_iterator<Container>>
1529  : std::true_type {};
1530 
1531 template <typename OutputIt>
1532 struct is_contiguous_back_insert_iterator : std::false_type {};
1533 template <typename Container>
1534 struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>>
1535  : is_contiguous<Container> {};
1536 template <>
1537 struct is_contiguous_back_insert_iterator<appender> : std::true_type {};
1538 
1539 // A type-erased reference to an std::locale to avoid heavy <locale> include.
1540 class locale_ref {
1541  private:
1542  const void* locale_; // A type-erased pointer to std::locale.
1543 
1544  public:
1545  constexpr locale_ref() : locale_(nullptr) {}
1546  template <typename Locale> explicit locale_ref(const Locale& loc);
1547 
1548  explicit operator bool() const FMT_NOEXCEPT { return locale_ != nullptr; }
1549 
1550  template <typename Locale> auto get() const -> Locale;
1551 };
1552 
1553 template <typename> constexpr auto encode_types() -> unsigned long long {
1554  return 0;
1555 }
1556 
1557 template <typename Context, typename Arg, typename... Args>
1558 constexpr auto encode_types() -> unsigned long long {
1559  return static_cast<unsigned>(mapped_type_constant<Arg, Context>::value) |
1560  (encode_types<Context, Args...>() << packed_arg_bits);
1561 }
1562 
1563 template <typename Context, typename T>
1567  arg.value_ = arg_mapper<Context>().map(value);
1568  return arg;
1569 }
1570 
1571 // The type template parameter is there to avoid an ODR violation when using
1572 // a fallback formatter in one translation unit and an implicit conversion in
1573 // another (not recommended).
1574 template <bool IS_PACKED, typename Context, type, typename T,
1575  FMT_ENABLE_IF(IS_PACKED)>
1577  const auto& arg = arg_mapper<Context>().map(val);
1578  static_assert(
1579  !std::is_same<decltype(arg), const unformattable&>::value,
1580  "Cannot format an argument. To make type T formattable provide a "
1581  "formatter<T> specialization: https://fmt.dev/latest/api.html#udt");
1582  return {arg};
1583 }
1584 
1585 template <bool IS_PACKED, typename Context, type, typename T,
1586  FMT_ENABLE_IF(!IS_PACKED)>
1587 inline auto make_arg(const T& value) -> basic_format_arg<Context> {
1588  return make_arg<Context>(value);
1589 }
1591 
1592 // Formatting context.
1593 template <typename OutputIt, typename Char> class basic_format_context {
1594  public:
1595  /** The character type for the output. */
1596  using char_type = Char;
1597 
1598  private:
1599  OutputIt out_;
1601  detail::locale_ref loc_;
1602 
1603  public:
1604  using iterator = OutputIt;
1607  template <typename T> using formatter_type = formatter<T, char_type>;
1608 
1610  basic_format_context(const basic_format_context&) = delete;
1611  void operator=(const basic_format_context&) = delete;
1612  /**
1613  Constructs a ``basic_format_context`` object. References to the arguments are
1614  stored in the object so make sure they have appropriate lifetimes.
1615  */
1617  OutputIt out, basic_format_args<basic_format_context> ctx_args,
1618  detail::locale_ref loc = detail::locale_ref())
1619  : out_(out), args_(ctx_args), loc_(loc) {}
1620 
1621  constexpr auto arg(int id) const -> format_arg { return args_.get(id); }
1623  return args_.get(name);
1624  }
1626  return args_.get_id(name);
1627  }
1629  return args_;
1630  }
1631 
1632  FMT_CONSTEXPR auto error_handler() -> detail::error_handler { return {}; }
1633  void on_error(const char* message) { error_handler().on_error(message); }
1634 
1635  // Returns an iterator to the beginning of the output range.
1636  FMT_CONSTEXPR auto out() -> iterator { return out_; }
1637 
1638  // Advances the begin iterator to ``it``.
1640  if (!detail::is_back_insert_iterator<iterator>()) out_ = it;
1641  }
1642 
1643  FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; }
1644 };
1645 
1646 template <typename Char>
1647 using buffer_context =
1650 
1651 // Workaround an alias issue: https://stackoverflow.com/q/62767544/471164.
1652 #define FMT_BUFFER_CONTEXT(Char) \
1653  basic_format_context<detail::buffer_appender<Char>, Char>
1654 
1655 template <typename T, typename Char = char>
1656 using is_formattable = bool_constant<
1657  !std::is_same<decltype(detail::arg_mapper<buffer_context<Char>>().map(
1658  std::declval<T>())),
1659  detail::unformattable>::value &&
1661 
1662 /**
1663  \rst
1664  An array of references to arguments. It can be implicitly converted into
1665  `~fmt::basic_format_args` for passing into type-erased formatting functions
1666  such as `~fmt::vformat`.
1667  \endrst
1668  */
1669 template <typename Context, typename... Args>
1672  // Workaround a GCC template argument substitution bug.
1674 #endif
1675 {
1676  private:
1677  static const size_t num_args = sizeof...(Args);
1678  static const size_t num_named_args = detail::count_named_args<Args...>();
1679  static const bool is_packed = num_args <= detail::max_packed_args;
1680 
1683 
1684  detail::arg_data<value_type, typename Context::char_type, num_args,
1685  num_named_args>
1686  data_;
1687 
1688  friend class basic_format_args<Context>;
1689 
1690  static constexpr unsigned long long desc =
1691  (is_packed ? detail::encode_types<Context, Args...>()
1692  : detail::is_unpacked_bit | num_args) |
1693  (num_named_args != 0
1694  ? static_cast<unsigned long long>(detail::has_named_args_bit)
1695  : 0);
1696 
1697  public:
1699  :
1701  basic_format_args<Context>(*this),
1702 #endif
1703  data_{detail::make_arg<
1704  is_packed, Context,
1706  detail::init_named_args(data_.named_args(), 0, 0, args...);
1707  }
1708 };
1709 
1710 /**
1711  \rst
1712  Constructs a `~fmt::format_arg_store` object that contains references to
1713  arguments and can be implicitly converted to `~fmt::format_args`. `Context`
1714  can be omitted in which case it defaults to `~fmt::context`.
1715  See `~fmt::arg` for lifetime considerations.
1716  \endrst
1717  */
1718 template <typename Context = format_context, typename... Args>
1719 constexpr auto make_format_args(const Args&... args)
1720  -> format_arg_store<Context, Args...> {
1721  return {args...};
1722 }
1723 
1724 /**
1725  \rst
1726  Returns a named argument to be used in a formatting function.
1727  It should only be used in a call to a formatting function or
1728  `dynamic_format_arg_store::push_back`.
1729 
1730  **Example**::
1731 
1732  fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23));
1733  \endrst
1734  */
1735 template <typename Char, typename T>
1736 inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
1737  static_assert(!detail::is_named_arg<T>(), "nested named arguments");
1738  return {name, arg};
1739 }
1740 
1741 /**
1742  \rst
1743  A view of a collection of formatting arguments. To avoid lifetime issues it
1744  should only be used as a parameter type in type-erased functions such as
1745  ``vformat``::
1746 
1747  void vlog(string_view format_str, format_args args); // OK
1748  format_args args = make_format_args(42); // Error: dangling reference
1749  \endrst
1750  */
1751 template <typename Context> class basic_format_args {
1752  public:
1753  using size_type = int;
1754  using format_arg = basic_format_arg<Context>;
1755 
1756  private:
1757  // A descriptor that contains information about formatting arguments.
1758  // If the number of arguments is less or equal to max_packed_args then
1759  // argument types are passed in the descriptor. This reduces binary code size
1760  // per formatting function call.
1761  unsigned long long desc_;
1762  union {
1763  // If is_packed() returns true then argument values are stored in values_;
1764  // otherwise they are stored in args_. This is done to improve cache
1765  // locality and reduce compiled code size since storing larger objects
1766  // may require more code (at least on x86-64) even if the same amount of
1767  // data is actually copied to stack. It saves ~10% on the bloat test.
1768  const detail::value<Context>* values_;
1770  };
1771 
1772  constexpr auto is_packed() const -> bool {
1773  return (desc_ & detail::is_unpacked_bit) == 0;
1774  }
1775  auto has_named_args() const -> bool {
1776  return (desc_ & detail::has_named_args_bit) != 0;
1777  }
1778 
1779  FMT_CONSTEXPR auto type(int index) const -> detail::type {
1780  int shift = index * detail::packed_arg_bits;
1781  unsigned int mask = (1 << detail::packed_arg_bits) - 1;
1782  return static_cast<detail::type>((desc_ >> shift) & mask);
1783  }
1784 
1785  constexpr FMT_INLINE basic_format_args(unsigned long long desc,
1786  const detail::value<Context>* values)
1787  : desc_(desc), values_(values) {}
1788  constexpr basic_format_args(unsigned long long desc, const format_arg* args)
1789  : desc_(desc), args_(args) {}
1790 
1791  public:
1792  constexpr basic_format_args() : desc_(0), args_(nullptr) {}
1793 
1794  /**
1795  \rst
1796  Constructs a `basic_format_args` object from `~fmt::format_arg_store`.
1797  \endrst
1798  */
1799  template <typename... Args>
1802  : basic_format_args(format_arg_store<Context, Args...>::desc,
1803  store.data_.args()) {}
1804 
1805  /**
1806  \rst
1807  Constructs a `basic_format_args` object from
1808  `~fmt::dynamic_format_arg_store`.
1809  \endrst
1810  */
1812  const dynamic_format_arg_store<Context>& store)
1813  : basic_format_args(store.get_types(), store.data()) {}
1814 
1815  /**
1816  \rst
1817  Constructs a `basic_format_args` object from a dynamic set of arguments.
1818  \endrst
1819  */
1820  constexpr basic_format_args(const format_arg* args, int count)
1821  : basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count),
1822  args) {}
1823 
1824  /** Returns the argument with the specified id. */
1825  FMT_CONSTEXPR auto get(int id) const -> format_arg {
1826  format_arg arg;
1827  if (!is_packed()) {
1828  if (id < max_size()) arg = args_[id];
1829  return arg;
1830  }
1831  if (id >= detail::max_packed_args) return arg;
1832  arg.type_ = type(id);
1833  if (arg.type_ == detail::type::none_type) return arg;
1834  arg.value_ = values_[id];
1835  return arg;
1836  }
1837 
1838  template <typename Char>
1840  int id = get_id(name);
1841  return id >= 0 ? get(id) : format_arg();
1842  }
1843 
1844  template <typename Char>
1845  auto get_id(basic_string_view<Char> name) const -> int {
1846  if (!has_named_args()) return -1;
1847  const auto& named_args =
1848  (is_packed() ? values_[-1] : args_[-1].value_).named_args;
1849  for (size_t i = 0; i < named_args.size; ++i) {
1850  if (named_args.data[i].name == name) return named_args.data[i].id;
1851  }
1852  return -1;
1853  }
1854 
1855  auto max_size() const -> int {
1856  unsigned long long max_packed = detail::max_packed_args;
1857  return static_cast<int>(is_packed() ? max_packed
1858  : desc_ & ~detail::is_unpacked_bit);
1859  }
1860 };
1861 
1862 /** An alias to ``basic_format_args<format_context>``. */
1863 // A separate type would result in shorter symbols but break ABI compatibility
1864 // between clang and gcc on ARM (#1919).
1866 
1867 // We cannot use enum classes as bit fields because of a gcc bug
1868 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
1869 namespace align {
1870 enum type { none, left, right, center, numeric };
1871 }
1873 namespace sign {
1874 enum type { none, minus, plus, space };
1875 }
1877 
1879 
1880 void throw_format_error(const char* message);
1881 
1882 // Workaround an array initialization issue in gcc 4.8.
1883 template <typename Char> struct fill_t {
1884  private:
1885  enum { max_size = 4 };
1886  Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)};
1887  unsigned char size_ = 1;
1888 
1889  public:
1891  auto size = s.size();
1892  if (size > max_size) return throw_format_error("invalid fill");
1893  for (size_t i = 0; i < size; ++i) data_[i] = s[i];
1894  size_ = static_cast<unsigned char>(size);
1895  }
1896 
1897  constexpr auto size() const -> size_t { return size_; }
1898  constexpr auto data() const -> const Char* { return data_; }
1899 
1900  FMT_CONSTEXPR auto operator[](size_t index) -> Char& { return data_[index]; }
1901  FMT_CONSTEXPR auto operator[](size_t index) const -> const Char& {
1902  return data_[index];
1903  }
1904 };
1906 
1907 // Format specifiers for built-in and string types.
1908 template <typename Char> struct basic_format_specs {
1909  int width;
1911  char type;
1914  bool alt : 1; // Alternate form ('#').
1915  bool localized : 1;
1916  detail::fill_t<Char> fill;
1917 
1919  : width(0),
1920  precision(-1),
1921  type(0),
1922  align(align::none),
1923  sign(sign::none),
1924  alt(false),
1925  localized(false) {}
1926 };
1927 
1929 
1931 
1932 enum class arg_id_kind { none, index, name };
1933 
1934 // An argument reference.
1935 template <typename Char> struct arg_ref {
1937 
1939  : kind(arg_id_kind::index), val(index) {}
1941  : kind(arg_id_kind::name), val(name) {}
1942 
1943  FMT_CONSTEXPR auto operator=(int idx) -> arg_ref& {
1945  val.index = idx;
1946  return *this;
1947  }
1948 
1950  union value {
1951  FMT_CONSTEXPR value(int id = 0) : index{id} {}
1953 
1954  int index;
1956  } val;
1957 };
1958 
1959 // Format specifiers with width and precision resolved at formatting rather
1960 // than parsing time to allow re-using the same parsed specifiers with
1961 // different sets of arguments (precompilation of format strings).
1962 template <typename Char>
1966 };
1967 
1968 struct auto_id {};
1969 
1970 // A format specifier handler that sets fields in basic_format_specs.
1971 template <typename Char> class specs_setter {
1972  protected:
1974 
1975  public:
1977  : specs_(specs) {}
1978 
1980  : specs_(other.specs_) {}
1981 
1982  FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; }
1984  specs_.fill = fill;
1985  }
1986  FMT_CONSTEXPR void on_sign(sign_t s) { specs_.sign = s; }
1987  FMT_CONSTEXPR void on_hash() { specs_.alt = true; }
1988  FMT_CONSTEXPR void on_localized() { specs_.localized = true; }
1989 
1991  if (specs_.align == align::none) specs_.align = align::numeric;
1992  specs_.fill[0] = Char('0');
1993  }
1994 
1995  FMT_CONSTEXPR void on_width(int width) { specs_.width = width; }
1997  specs_.precision = precision;
1998  }
2000 
2001  FMT_CONSTEXPR void on_type(Char type) {
2002  specs_.type = static_cast<char>(type);
2003  }
2004 };
2005 
2006 // Format spec handler that saves references to arguments representing dynamic
2007 // width and precision to be resolved at formatting time.
2008 template <typename ParseContext>
2010  : public specs_setter<typename ParseContext::char_type> {
2011  public:
2012  using char_type = typename ParseContext::char_type;
2013 
2015  ParseContext& ctx)
2016  : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}
2017 
2019  : specs_setter<char_type>(other),
2020  specs_(other.specs_),
2021  context_(other.context_) {}
2022 
2023  template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
2024  specs_.width_ref = make_arg_ref(arg_id);
2025  }
2026 
2027  template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
2028  specs_.precision_ref = make_arg_ref(arg_id);
2029  }
2030 
2031  FMT_CONSTEXPR void on_error(const char* message) {
2032  context_.on_error(message);
2033  }
2034 
2035  private:
2037  ParseContext& context_;
2038 
2039  using arg_ref_type = arg_ref<char_type>;
2040 
2041  FMT_CONSTEXPR auto make_arg_ref(int arg_id) -> arg_ref_type {
2042  context_.check_arg_id(arg_id);
2043  return arg_ref_type(arg_id);
2044  }
2045 
2046  FMT_CONSTEXPR auto make_arg_ref(auto_id) -> arg_ref_type {
2047  return arg_ref_type(context_.next_arg_id());
2048  }
2049 
2050  FMT_CONSTEXPR auto make_arg_ref(basic_string_view<char_type> arg_id)
2051  -> arg_ref_type {
2052  context_.check_arg_id(arg_id);
2053  basic_string_view<char_type> format_str(
2054  context_.begin(), to_unsigned(context_.end() - context_.begin()));
2055  return arg_ref_type(arg_id);
2056  }
2057 };
2058 
2059 template <typename Char> constexpr bool is_ascii_letter(Char c) {
2060  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
2061 }
2062 
2063 // Converts a character to ASCII. Returns a number > 127 on conversion failure.
2065 constexpr auto to_ascii(Char value) -> Char {
2066  return value;
2067 }
2069 constexpr auto to_ascii(Char value) ->
2071  return value;
2072 }
2073 
2074 template <typename Char>
2075 FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int {
2076  if (const_check(sizeof(Char) != 1)) return 1;
2077  constexpr char lengths[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2078  0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0};
2079  int len = lengths[static_cast<unsigned char>(*begin) >> 3];
2080 
2081  // Compute the pointer to the next character early so that the next
2082  // iteration can start working on the next character. Neither Clang
2083  // nor GCC figure out this reordering on their own.
2084  return len + !len;
2085 }
2086 
2087 // Return the result via the out param to workaround gcc bug 77539.
2088 template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
2089 FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool {
2090  for (out = first; out != last; ++out) {
2091  if (*out == value) return true;
2092  }
2093  return false;
2094 }
2095 
2096 template <>
2097 inline auto find<false, char>(const char* first, const char* last, char value,
2098  const char*& out) -> bool {
2099  out = static_cast<const char*>(
2100  std::memchr(first, value, to_unsigned(last - first)));
2101  return out != nullptr;
2102 }
2103 
2104 // Parses the range [begin, end) as an unsigned integer. This function assumes
2105 // that the range is non-empty and the first character is a digit.
2106 template <typename Char>
2107 FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
2108  int error_value) noexcept -> int {
2109  FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
2110  unsigned value = 0, prev = 0;
2111  auto p = begin;
2112  do {
2113  prev = value;
2114  value = value * 10 + unsigned(*p - '0');
2115  ++p;
2116  } while (p != end && '0' <= *p && *p <= '9');
2117  auto num_digits = p - begin;
2118  begin = p;
2119  if (num_digits <= std::numeric_limits<int>::digits10)
2120  return static_cast<int>(value);
2121  // Check for overflow.
2122  const unsigned max = to_unsigned((std::numeric_limits<int>::max)());
2123  return num_digits == std::numeric_limits<int>::digits10 + 1 &&
2124  prev * 10ull + unsigned(p[-1] - '0') <= max
2125  ? static_cast<int>(value)
2126  : error_value;
2127 }
2128 
2129 // Parses fill and alignment.
2130 template <typename Char, typename Handler>
2131 FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
2132  Handler&& handler) -> const Char* {
2133  FMT_ASSERT(begin != end, "");
2134  auto align = align::none;
2135  auto p = begin + code_point_length(begin);
2136  if (p >= end) p = begin;
2137  for (;;) {
2138  switch (to_ascii(*p)) {
2139  case '<':
2140  align = align::left;
2141  break;
2142  case '>':
2143  align = align::right;
2144  break;
2145  case '^':
2146  align = align::center;
2147  break;
2148  default:
2149  break;
2150  }
2151  if (align != align::none) {
2152  if (p != begin) {
2153  auto c = *begin;
2154  if (c == '{')
2155  return handler.on_error("invalid fill character '{'"), begin;
2156  handler.on_fill(basic_string_view<Char>(begin, to_unsigned(p - begin)));
2157  begin = p + 1;
2158  } else
2159  ++begin;
2160  handler.on_align(align);
2161  break;
2162  } else if (p == begin) {
2163  break;
2164  }
2165  p = begin;
2166  }
2167  return begin;
2168 }
2169 
2170 template <typename Char> FMT_CONSTEXPR bool is_name_start(Char c) {
2171  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
2172 }
2173 
2174 template <typename Char, typename IDHandler>
2175 FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end,
2176  IDHandler&& handler) -> const Char* {
2177  FMT_ASSERT(begin != end, "");
2178  Char c = *begin;
2179  if (c >= '0' && c <= '9') {
2180  int index = 0;
2181  if (c != '0')
2182  index =
2184  else
2185  ++begin;
2186  if (begin == end || (*begin != '}' && *begin != ':'))
2187  handler.on_error("invalid format string");
2188  else
2189  handler(index);
2190  return begin;
2191  }
2192  if (!is_name_start(c)) {
2193  handler.on_error("invalid format string");
2194  return begin;
2195  }
2196  auto it = begin;
2197  do {
2198  ++it;
2199  } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9')));
2201  return it;
2202 }
2203 
2204 template <typename Char, typename IDHandler>
2205 FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char* begin, const Char* end,
2206  IDHandler&& handler) -> const Char* {
2207  Char c = *begin;
2208  if (c != '}' && c != ':') return do_parse_arg_id(begin, end, handler);
2209  handler();
2210  return begin;
2211 }
2212 
2213 template <typename Char, typename Handler>
2214 FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end,
2215  Handler&& handler) -> const Char* {
2216  using detail::auto_id;
2217  struct width_adapter {
2218  Handler& handler;
2219 
2220  FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); }
2221  FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_width(id); }
2222  FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
2223  handler.on_dynamic_width(id);
2224  }
2225  FMT_CONSTEXPR void on_error(const char* message) {
2226  if (message) handler.on_error(message);
2227  }
2228  };
2229 
2230  FMT_ASSERT(begin != end, "");
2231  if ('0' <= *begin && *begin <= '9') {
2232  int width = parse_nonnegative_int(begin, end, -1);
2233  if (width != -1)
2234  handler.on_width(width);
2235  else
2236  handler.on_error("number is too big");
2237  } else if (*begin == '{') {
2238  ++begin;
2239  if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler});
2240  if (begin == end || *begin != '}')
2241  return handler.on_error("invalid format string"), begin;
2242  ++begin;
2243  }
2244  return begin;
2245 }
2246 
2247 template <typename Char, typename Handler>
2248 FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
2249  Handler&& handler) -> const Char* {
2250  using detail::auto_id;
2251  struct precision_adapter {
2252  Handler& handler;
2253 
2254  FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); }
2255  FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_precision(id); }
2256  FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
2257  handler.on_dynamic_precision(id);
2258  }
2259  FMT_CONSTEXPR void on_error(const char* message) {
2260  if (message) handler.on_error(message);
2261  }
2262  };
2263 
2264  ++begin;
2265  auto c = begin != end ? *begin : Char();
2266  if ('0' <= c && c <= '9') {
2268  if (precision != -1)
2269  handler.on_precision(precision);
2270  else
2271  handler.on_error("number is too big");
2272  } else if (c == '{') {
2273  ++begin;
2274  if (begin != end)
2275  begin = parse_arg_id(begin, end, precision_adapter{handler});
2276  if (begin == end || *begin++ != '}')
2277  return handler.on_error("invalid format string"), begin;
2278  } else {
2279  return handler.on_error("missing precision specifier"), begin;
2280  }
2281  handler.end_precision();
2282  return begin;
2283 }
2284 
2285 // Parses standard format specifiers and sends notifications about parsed
2286 // components to handler.
2287 template <typename Char, typename SpecHandler>
2289  const Char* end,
2290  SpecHandler&& handler)
2291  -> const Char* {
2292  if (begin + 1 < end && begin[1] == '}' && is_ascii_letter(*begin) &&
2293  *begin != 'L') {
2294  handler.on_type(*begin++);
2295  return begin;
2296  }
2297 
2298  if (begin == end) return begin;
2299 
2300  begin = parse_align(begin, end, handler);
2301  if (begin == end) return begin;
2302 
2303  // Parse sign.
2304  switch (to_ascii(*begin)) {
2305  case '+':
2306  handler.on_sign(sign::plus);
2307  ++begin;
2308  break;
2309  case '-':
2310  handler.on_sign(sign::minus);
2311  ++begin;
2312  break;
2313  case ' ':
2314  handler.on_sign(sign::space);
2315  ++begin;
2316  break;
2317  default:
2318  break;
2319  }
2320  if (begin == end) return begin;
2321 
2322  if (*begin == '#') {
2323  handler.on_hash();
2324  if (++begin == end) return begin;
2325  }
2326 
2327  // Parse zero flag.
2328  if (*begin == '0') {
2329  handler.on_zero();
2330  if (++begin == end) return begin;
2331  }
2332 
2333  begin = parse_width(begin, end, handler);
2334  if (begin == end) return begin;
2335 
2336  // Parse precision.
2337  if (*begin == '.') {
2338  begin = parse_precision(begin, end, handler);
2339  if (begin == end) return begin;
2340  }
2341 
2342  if (*begin == 'L') {
2343  handler.on_localized();
2344  ++begin;
2345  }
2346 
2347  // Parse type.
2348  if (begin != end && *begin != '}') handler.on_type(*begin++);
2349  return begin;
2350 }
2351 
2352 template <typename Char, typename Handler>
2353 FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end,
2354  Handler&& handler) -> const Char* {
2355  struct id_adapter {
2356  Handler& handler;
2357  int arg_id;
2358 
2359  FMT_CONSTEXPR void operator()() { arg_id = handler.on_arg_id(); }
2360  FMT_CONSTEXPR void operator()(int id) { arg_id = handler.on_arg_id(id); }
2361  FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
2362  arg_id = handler.on_arg_id(id);
2363  }
2364  FMT_CONSTEXPR void on_error(const char* message) {
2365  if (message) handler.on_error(message);
2366  }
2367  };
2368 
2369  ++begin;
2370  if (begin == end) return handler.on_error("invalid format string"), end;
2371  if (*begin == '}') {
2372  handler.on_replacement_field(handler.on_arg_id(), begin);
2373  } else if (*begin == '{') {
2374  handler.on_text(begin, begin + 1);
2375  } else {
2376  auto adapter = id_adapter{handler, 0};
2377  begin = parse_arg_id(begin, end, adapter);
2378  Char c = begin != end ? *begin : Char();
2379  if (c == '}') {
2380  handler.on_replacement_field(adapter.arg_id, begin);
2381  } else if (c == ':') {
2382  begin = handler.on_format_specs(adapter.arg_id, begin + 1, end);
2383  if (begin == end || *begin != '}')
2384  return handler.on_error("unknown format specifier"), end;
2385  } else {
2386  return handler.on_error("missing '}' in format string"), end;
2387  }
2388  }
2389  return begin + 1;
2390 }
2391 
2392 template <bool IS_CONSTEXPR, typename Char, typename Handler>
2394  basic_string_view<Char> format_str, Handler&& handler) {
2395  // this is most likely a name-lookup defect in msvc's modules implementation
2396  using detail::find;
2397 
2398  auto begin = format_str.data();
2399  auto end = begin + format_str.size();
2400  if (end - begin < 32) {
2401  // Use a simple loop instead of memchr for small strings.
2402  const Char* p = begin;
2403  while (p != end) {
2404  auto c = *p++;
2405  if (c == '{') {
2406  handler.on_text(begin, p - 1);
2407  begin = p = parse_replacement_field(p - 1, end, handler);
2408  } else if (c == '}') {
2409  if (p == end || *p != '}')
2410  return handler.on_error("unmatched '}' in format string");
2411  handler.on_text(begin, p);
2412  begin = ++p;
2413  }
2414  }
2415  handler.on_text(begin, end);
2416  return;
2417  }
2418  struct writer {
2419  FMT_CONSTEXPR void operator()(const Char* pbegin, const Char* pend) {
2420  if (pbegin == pend) return;
2421  for (;;) {
2422  const Char* p = nullptr;
2423  if (!find<IS_CONSTEXPR>(pbegin, pend, '}', p))
2424  return handler_.on_text(pbegin, pend);
2425  ++p;
2426  if (p == pend || *p != '}')
2427  return handler_.on_error("unmatched '}' in format string");
2428  handler_.on_text(pbegin, p);
2429  pbegin = p + 1;
2430  }
2431  }
2432  Handler& handler_;
2433  } write{handler};
2434  while (begin != end) {
2435  // Doing two passes with memchr (one for '{' and another for '}') is up to
2436  // 2.5x faster than the naive one-pass implementation on big format strings.
2437  const Char* p = begin;
2438  if (*begin != '{' && !find<IS_CONSTEXPR>(begin + 1, end, '{', p))
2439  return write(begin, end);
2440  write(begin, p);
2441  begin = parse_replacement_field(p, end, handler);
2442  }
2443 }
2444 
2445 template <typename T, typename ParseContext>
2446 FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx)
2447  -> decltype(ctx.begin()) {
2448  using char_type = typename ParseContext::char_type;
2449  using context = buffer_context<char_type>;
2450  using mapped_type = conditional_t<
2452  decltype(arg_mapper<context>().map(std::declval<const T&>())), T>;
2456  return f.parse(ctx);
2457 }
2458 
2459 // A parse context with extra argument id checks. It is only used at compile
2460 // time because adding checks at runtime would introduce substantial overhead
2461 // and would be redundant since argument ids are checked when arguments are
2462 // retrieved anyway.
2463 template <typename Char, typename ErrorHandler = error_handler>
2465  : public basic_format_parse_context<Char, ErrorHandler> {
2466  private:
2467  int num_args_;
2469 
2470  public:
2472  basic_string_view<Char> format_str,
2473  int num_args = (std::numeric_limits<int>::max)(), ErrorHandler eh = {})
2474  : base(format_str, eh), num_args_(num_args) {}
2475 
2476  FMT_CONSTEXPR auto next_arg_id() -> int {
2477  int id = base::next_arg_id();
2478  if (id >= num_args_) this->on_error("argument not found");
2479  return id;
2480  }
2481 
2483  base::check_arg_id(id);
2484  if (id >= num_args_) this->on_error("argument not found");
2485  }
2486  using base::check_arg_id;
2487 };
2488 
2489 template <typename ErrorHandler>
2491  switch (spec) {
2492  case 0:
2493  case 'd':
2494  case 'x':
2495  case 'X':
2496  case 'b':
2497  case 'B':
2498  case 'o':
2499  case 'c':
2500  break;
2501  default:
2502  eh.on_error("invalid type specifier");
2503  break;
2504  }
2505 }
2506 
2507 // Checks char specs and returns true if the type spec is char (and not int).
2508 template <typename Char, typename ErrorHandler = error_handler>
2510  ErrorHandler&& eh = {}) -> bool {
2511  if (specs.type && specs.type != 'c') {
2512  check_int_type_spec(specs.type, eh);
2513  return false;
2514  }
2515  if (specs.align == align::numeric || specs.sign != sign::none || specs.alt)
2516  eh.on_error("invalid format specifier for char");
2517  return true;
2518 }
2519 
2520 // A floating-point presentation format.
2521 enum class float_format : unsigned char {
2522  general, // General: exponent notation or fixed point based on magnitude.
2523  exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3.
2524  fixed, // Fixed point with the default precision of 6, e.g. 0.0012.
2525  hex
2526 };
2527 
2528 struct float_specs {
2532  bool upper : 1;
2533  bool locale : 1;
2534  bool binary32 : 1;
2535  bool use_grisu : 1;
2536  bool showpoint : 1;
2537 };
2538 
2539 template <typename ErrorHandler = error_handler, typename Char>
2541  ErrorHandler&& eh = {})
2542  -> float_specs {
2543  auto result = float_specs();
2544  result.showpoint = specs.alt;
2545  result.locale = specs.localized;
2546  switch (specs.type) {
2547  case 0:
2548  result.format = float_format::general;
2549  break;
2550  case 'G':
2551  result.upper = true;
2553  case 'g':
2554  result.format = float_format::general;
2555  break;
2556  case 'E':
2557  result.upper = true;
2559  case 'e':
2560  result.format = float_format::exp;
2561  result.showpoint |= specs.precision != 0;
2562  break;
2563  case 'F':
2564  result.upper = true;
2566  case 'f':
2567  result.format = float_format::fixed;
2568  result.showpoint |= specs.precision != 0;
2569  break;
2570  case 'A':
2571  result.upper = true;
2573  case 'a':
2574  result.format = float_format::hex;
2575  break;
2576  default:
2577  eh.on_error("invalid type specifier");
2578  break;
2579  }
2580  return result;
2581 }
2582 
2583 template <typename Char, typename ErrorHandler = error_handler>
2585  -> bool {
2586  if (spec == 0 || spec == 's') return true;
2587  if (spec != 'p') eh.on_error("invalid type specifier");
2588  return false;
2589 }
2590 
2591 template <typename Char, typename ErrorHandler>
2593  if (spec != 0 && spec != 's') eh.on_error("invalid type specifier");
2594 }
2595 
2596 template <typename Char, typename ErrorHandler>
2598  if (spec != 0 && spec != 'p') eh.on_error("invalid type specifier");
2599 }
2600 
2601 // A parse_format_specs handler that checks if specifiers are consistent with
2602 // the argument type.
2603 template <typename Handler> class specs_checker : public Handler {
2604  private:
2605  detail::type arg_type_;
2606 
2607  FMT_CONSTEXPR void require_numeric_argument() {
2608  if (!is_arithmetic_type(arg_type_))
2609  this->on_error("format specifier requires numeric argument");
2610  }
2611 
2612  public:
2613  FMT_CONSTEXPR specs_checker(const Handler& handler, detail::type arg_type)
2614  : Handler(handler), arg_type_(arg_type) {}
2615 
2617  if (align == align::numeric) require_numeric_argument();
2618  Handler::on_align(align);
2619  }
2620 
2622  require_numeric_argument();
2623  if (is_integral_type(arg_type_) && arg_type_ != type::int_type &&
2624  arg_type_ != type::long_long_type && arg_type_ != type::char_type) {
2625  this->on_error("format specifier requires signed argument");
2626  }
2627  Handler::on_sign(s);
2628  }
2629 
2631  require_numeric_argument();
2632  Handler::on_hash();
2633  }
2634 
2636  require_numeric_argument();
2637  Handler::on_localized();
2638  }
2639 
2641  require_numeric_argument();
2642  Handler::on_zero();
2643  }
2644 
2646  if (is_integral_type(arg_type_) || arg_type_ == type::pointer_type)
2647  this->on_error("precision not allowed for this argument type");
2648  }
2649 };
2650 
2651 constexpr int invalid_arg_index = -1;
2652 
2653 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
2654 template <int N, typename T, typename... Args, typename Char>
2655 constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
2656  if constexpr (detail::is_statically_named_arg<T>()) {
2657  if (name == T::name) return N;
2658  }
2659  if constexpr (sizeof...(Args) > 0)
2660  return get_arg_index_by_name<N + 1, Args...>(name);
2661  (void)name; // Workaround an MSVC bug about "unused" parameter.
2662  return invalid_arg_index;
2663 }
2664 #endif
2665 
2666 template <typename... Args, typename Char>
2668 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
2669  if constexpr (sizeof...(Args) > 0)
2670  return get_arg_index_by_name<0, Args...>(name);
2671 #endif
2672  (void)name;
2673  return invalid_arg_index;
2674 }
2675 
2676 template <typename Char, typename ErrorHandler, typename... Args>
2678  private:
2680  enum { num_args = sizeof...(Args) };
2681 
2682  // Format specifier parsing function.
2683  using parse_func = const Char* (*)(parse_context_type&);
2684 
2685  parse_context_type context_;
2686  parse_func parse_funcs_[num_args > 0 ? num_args : 1];
2687 
2688  public:
2690  basic_string_view<Char> format_str, ErrorHandler eh)
2691  : context_(format_str, num_args, eh),
2692  parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
2693 
2694  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
2695 
2696  FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); }
2697  FMT_CONSTEXPR auto on_arg_id(int id) -> int {
2698  return context_.check_arg_id(id), id;
2699  }
2701 #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
2702  auto index = get_arg_index_by_name<Args...>(id);
2703  if (index == invalid_arg_index) on_error("named argument is not found");
2704  return context_.check_arg_id(index), index;
2705 #else
2706  (void)id;
2707  on_error("compile-time checks for named arguments require C++20 support");
2708  return 0;
2709 #endif
2710  }
2711 
2712  FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
2713 
2714  FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char*)
2715  -> const Char* {
2716  context_.advance_to(context_.begin() + (begin - &*context_.begin()));
2717  // id >= 0 check is a workaround for gcc 10 bug (#2065).
2718  return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin;
2719  }
2720 
2721  FMT_CONSTEXPR void on_error(const char* message) {
2722  context_.on_error(message);
2723  }
2724 };
2725 
2726 template <typename... Args, typename S,
2728 void check_format_string(S format_str) {
2729  FMT_CONSTEXPR auto s = to_string_view(format_str);
2730  using checker = format_string_checker<typename S::char_type, error_handler,
2732  FMT_CONSTEXPR bool invalid_format =
2733  (parse_format_string<true>(s, checker(s, {})), true);
2734  (void)invalid_format;
2735 }
2736 
2737 template <typename Char>
2738 void vformat_to(
2741  detail::locale_ref loc = {});
2742 
2743 FMT_API void vprint_mojibake(std::FILE*, string_view, format_args);
2744 #ifndef _WIN32
2745 inline void vprint_mojibake(std::FILE*, string_view, format_args) {}
2746 #endif
2748 
2749 // A formatter specialization for the core types corresponding to detail::type
2750 // constants.
2751 template <typename T, typename Char>
2752 struct formatter<T, Char,
2754  detail::type::custom_type>> {
2755  private:
2756  detail::dynamic_format_specs<Char> specs_;
2757 
2758  public:
2759  // Parses format specifiers stopping either at the end of the range or at the
2760  // terminating '}'.
2761  template <typename ParseContext>
2762  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
2763  auto begin = ctx.begin(), end = ctx.end();
2764  if (begin == end) return begin;
2765  using handler_type = detail::dynamic_specs_handler<ParseContext>;
2767  auto checker =
2768  detail::specs_checker<handler_type>(handler_type(specs_, ctx), type);
2770  auto eh = ctx.error_handler();
2771  switch (type) {
2772  case detail::type::none_type:
2773  FMT_ASSERT(false, "invalid argument type");
2774  break;
2775  case detail::type::bool_type:
2776  if (!specs_.type || specs_.type == 's') break;
2778  case detail::type::int_type:
2779  case detail::type::uint_type:
2780  case detail::type::long_long_type:
2781  case detail::type::ulong_long_type:
2782  case detail::type::int128_type:
2783  case detail::type::uint128_type:
2784  detail::check_int_type_spec(specs_.type, eh);
2785  break;
2786  case detail::type::char_type:
2787  detail::check_char_specs(specs_, eh);
2788  break;
2789  case detail::type::float_type:
2791  detail::parse_float_type_spec(specs_, eh);
2792  else
2793  FMT_ASSERT(false, "float support disabled");
2794  break;
2795  case detail::type::double_type:
2797  detail::parse_float_type_spec(specs_, eh);
2798  else
2799  FMT_ASSERT(false, "double support disabled");
2800  break;
2801  case detail::type::long_double_type:
2803  detail::parse_float_type_spec(specs_, eh);
2804  else
2805  FMT_ASSERT(false, "long double support disabled");
2806  break;
2807  case detail::type::cstring_type:
2808  detail::check_cstring_type_spec(specs_.type, eh);
2809  break;
2810  case detail::type::string_type:
2811  detail::check_string_type_spec(specs_.type, eh);
2812  break;
2813  case detail::type::pointer_type:
2814  detail::check_pointer_type_spec(specs_.type, eh);
2815  break;
2816  case detail::type::custom_type:
2817  // Custom format specifiers are checked in parse functions of
2818  // formatter specializations.
2819  break;
2820  }
2821  return it;
2822  }
2823 
2824  template <typename FormatContext>
2825  FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
2826  -> decltype(ctx.out());
2827 };
2828 
2829 template <typename Char> struct basic_runtime { basic_string_view<Char> str; };
2830 
2831 template <typename Char, typename... Args> class basic_format_string {
2832  private:
2834 
2835  public:
2836  template <typename S,
2837  FMT_ENABLE_IF(
2838  std::is_convertible<const S&, basic_string_view<Char>>::value)>
2839  FMT_CONSTEVAL basic_format_string(const S& s) : str_(s) {
2840  static_assert(
2841  detail::count<
2842  (std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
2843  std::is_reference<Args>::value)...>() == 0,
2844  "passing views as lvalues is disallowed");
2845 #ifdef FMT_HAS_CONSTEVAL
2846  if constexpr (detail::count_named_args<Args...>() == 0) {
2847  using checker = detail::format_string_checker<Char, detail::error_handler,
2849  detail::parse_format_string<true>(str_, checker(s, {}));
2850  }
2851 #else
2852  detail::check_format_string<Args...>(s);
2853 #endif
2854  }
2856 
2857  FMT_INLINE operator basic_string_view<Char>() const { return str_; }
2858 };
2859 
2860 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
2861 // Workaround broken conversion on older gcc.
2862 template <typename... Args> using format_string = string_view;
2863 template <typename S> auto runtime(const S& s) -> basic_string_view<char_t<S>> {
2864  return s;
2865 }
2866 #else
2867 template <typename... Args>
2869 // Creates a runtime format string.
2870 template <typename S> auto runtime(const S& s) -> basic_runtime<char_t<S>> {
2871  return {{s}};
2872 }
2873 #endif
2874 
2876 
2877 /**
2878  \rst
2879  Formats ``args`` according to specifications in ``fmt`` and returns the result
2880  as a string.
2881 
2882  **Example**::
2883 
2884  #include <fmt/core.h>
2885  std::string message = fmt::format("The answer is {}", 42);
2886  \endrst
2887 */
2888 template <typename... T>
2890  return vformat(fmt, fmt::make_format_args(args...));
2891 }
2892 
2893 /** Formats a string and writes the output to ``out``. */
2894 template <typename OutputIt,
2896 auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt {
2897  using detail::get_buffer;
2898  auto&& buf = get_buffer<char>(out);
2899  detail::vformat_to(buf, string_view(fmt), args);
2900  return detail::get_iterator(buf);
2901 }
2902 
2903 /**
2904  \rst
2905  Formats ``args`` according to specifications in ``fmt``, writes the result to
2906  the output iterator ``out`` and returns the iterator past the end of the output
2907  range.
2908 
2909  **Example**::
2910 
2911  auto out = std::vector<char>();
2912  fmt::format_to(std::back_inserter(out), "{}", 42);
2913  \endrst
2914  */
2915 template <typename OutputIt, typename... T,
2917 FMT_INLINE auto format_to(OutputIt out, format_string<T...> fmt, T&&... args)
2918  -> OutputIt {
2919  return vformat_to(out, fmt, fmt::make_format_args(args...));
2920 }
2921 
2922 template <typename OutputIt> struct format_to_n_result {
2923  /** Iterator past the end of the output range. */
2924  OutputIt out;
2925  /** Total (not truncated) output size. */
2926  size_t size;
2927 };
2928 
2929 template <typename OutputIt, typename... T,
2931 auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args)
2933  using buffer =
2934  detail::iterator_buffer<OutputIt, char, detail::fixed_buffer_traits>;
2935  auto buf = buffer(out, n);
2936  detail::vformat_to(buf, fmt, args);
2937  return {buf.out(), buf.count()};
2938 }
2939 
2940 /**
2941  \rst
2942  Formats ``args`` according to specifications in ``fmt``, writes up to ``n``
2943  characters of the result to the output iterator ``out`` and returns the total
2944  (not truncated) output size and the iterator past the end of the output range.
2945  \endrst
2946  */
2947 template <typename OutputIt, typename... T,
2949 FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt,
2950  const T&... args) -> format_to_n_result<OutputIt> {
2951  return vformat_to_n(out, n, fmt, fmt::make_format_args(args...));
2952 }
2953 
2954 /** Returns the number of chars in the output of ``format(fmt, args...)``. */
2955 template <typename... T>
2956 FMT_INLINE auto formatted_size(format_string<T...> fmt, T&&... args) -> size_t {
2957  auto buf = detail::counting_buffer<>();
2959  return buf.count();
2960 }
2961 
2963 FMT_API void vprint(std::FILE* f, string_view fmt, format_args args);
2964 
2965 /**
2966  \rst
2967  Formats ``args`` according to specifications in ``fmt`` and writes the output
2968  to ``stdout``.
2969 
2970  **Example**::
2971 
2972  fmt::print("Elapsed time: {0:.2f} seconds", 1.23);
2973  \endrst
2974  */
2975 template <typename... T>
2977  const auto& vargs = fmt::make_format_args(args...);
2978  return detail::is_utf8() ? vprint(fmt, vargs)
2979  : detail::vprint_mojibake(stdout, fmt, vargs);
2980 }
2981 
2982 /**
2983  \rst
2984  Formats ``args`` according to specifications in ``fmt`` and writes the
2985  output to the file ``f``.
2986 
2987  **Example**::
2988 
2989  fmt::print(stderr, "Don't {}!", "panic");
2990  \endrst
2991  */
2992 template <typename... T>
2993 FMT_INLINE void print(std::FILE* f, format_string<T...> fmt, T&&... args) {
2994  const auto& vargs = fmt::make_format_args(args...);
2995  return detail::is_utf8() ? vprint(f, fmt, vargs)
2996  : detail::vprint_mojibake(f, fmt, vargs);
2997 }
2998 
3000 FMT_GCC_PRAGMA("GCC pop_options")
3002 
3003 #ifdef FMT_HEADER_ONLY
3004 # include "format.h"
3005 #endif
3006 #endif // FMT_CORE_H_
monostate no_value
Definition: core.h:1136
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition: core.h:405
#define FMT_MODULE_EXPORT_END
Definition: core.h:242
FMT_INLINE auto formatted_size(format_string< T...> fmt, T &&...args) -> size_t
Definition: core.h:2956
basic_string_view< Char > name
Definition: core.h:1955
GLint first
Definition: glcorearb.h:405
float_format
Definition: core.h:2521
auto data() FMT_NOEXCEPT-> T *
Definition: core.h:808
#define FMT_ENABLE_IF(...)
Definition: core.h:341
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
constexpr auto digits10() FMT_NOEXCEPT-> int
Definition: format.h:988
FMT_INLINE void check_format_string(const S &)
Definition: core.h:601
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
FMT_CONSTEXPR FMT_INLINE auto map(T val) -> char_type
Definition: core.h:1240
FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned
Definition: core.h:1221
named_arg_value< char_type > named_args
Definition: core.h:1151
decltype(to_string_view(std::declval< S >())) result
Definition: core.h:595
FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void *
Definition: core.h:1307
FMT_CONSTEXPR void on_localized()
Definition: core.h:2635
FMT_BEGIN_DETAIL_NAMESPACE constexpr FMT_INLINE auto is_constant_evaluated() FMT_NOEXCEPT-> bool
Definition: core.h:346
FMT_CONSTEXPR basic_string_view(const std::basic_string< Char, Traits, Alloc > &s) FMT_NOEXCEPT
Definition: core.h:463
FMT_API void vprint_mojibake(std::FILE *, string_view, format_args)
Definition: core.h:2745
FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler &other)
Definition: core.h:2018
auto operator[](I index) const -> const T &
Definition: core.h:840
FMT_CONSTEXPR auto operator[](size_t index) -> Char &
Definition: core.h:1900
const T & value
Definition: core.h:986
#define FMT_CONSTEVAL
Definition: core.h:295
#define FMT_NORETURN
Definition: core.h:165
FMT_INLINE value(uint128_t val)
Definition: core.h:1160
typename Context::char_type char_type
Definition: core.h:1133
std::is_constructible< fallback_formatter< T, Char >> has_fallback_formatter
Definition: core.h:980
#define FMT_FALLTHROUGH
Definition: core.h:191
FMT_API auto vformat(string_view fmt, format_args args) -> std::string
Definition: format-inl.h:2562
double double_value
Definition: core.h:1146
FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler) -> const Char *
Definition: core.h:2288
FMT_CONSTEXPR_CHAR_TRAITS friend auto operator==(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:500
#define FMT_BEGIN_DETAIL_NAMESPACE
Definition: core.h:243
void format(typename Context::parse_context_type &parse_ctx, Context &ctx) const
Definition: core.h:1427
bool locale
Definition: core.h:2533
FMT_CONSTEXPR void operator=(basic_string_view< Char > s)
Definition: core.h:1890
auto begin() const FMT_NOEXCEPT-> const T *
Definition: core.h:798
FMT_CONSTEXPR void check_arg_id(int id)
Definition: core.h:2482
constexpr auto data() const -> const Char *
Definition: core.h:1898
#define FMT_END_DETAIL_NAMESPACE
Definition: core.h:244
const void * pointer
Definition: core.h:1148
constexpr basic_format_specs()
Definition: core.h:1918
FMT_CONSTEXPR FMT_INLINE auto map(int128_t val) -> int128_t
Definition: core.h:1235
FMT_CONSTEXPR void end_precision()
Definition: core.h:2645
FMT_CONSTEXPR auto do_parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler) -> const Char *
Definition: core.h:2175
void
Definition: png.h:1083
FMT_CONSTEXPR auto arg_id(basic_string_view< char_type > name) -> int
Definition: core.h:1625
FMT_CONSTEXPR void on_width(int width)
Definition: core.h:1995
constexpr FMT_INLINE value(long long val)
Definition: core.h:1157
auto count() const -> size_t
Definition: core.h:896
FMT_CONSTEXPR void advance_to(iterator it)
Definition: core.h:661
iterator_buffer(T *out, size_t=0)
Definition: core.h:904
FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler &&eh)
Definition: core.h:2597
FMT_CONSTEXPR void on_align(align_t align)
Definition: core.h:1982
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:322
const GLdouble * v
Definition: glcorearb.h:837
auto limit(size_t size) -> size_t
Definition: core.h:848
basic_format_arg< Context > format_arg
Definition: core.h:1754
conditional_t< long_short, int, long long > long_type
Definition: core.h:1207
basic_format_context(basic_format_context &&)=default
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
FMT_CONSTEXPR FMT_INLINE auto map(signed char *val) -> const char *
Definition: core.h:1294
constexpr auto count_named_args() -> size_t
Definition: core.h:1055
float float_value
Definition: core.h:1145
void flush()
Definition: core.h:879
FMT_CONSTEXPR void on_hash()
Definition: core.h:2630
void grow(size_t) final FMT_OVERRIDE
Definition: core.h:901
virtual void grow(size_t capacity)=0
FMT_CONSTEXPR auto on_arg_id(basic_string_view< Char > id) -> int
Definition: core.h:2700
#define FMT_CONSTEXPR_CHAR_TRAITS
Definition: core.h:115
formatter()=delete
Definition: core.h:1968
constexpr bool is_ascii_letter(Char c)
Definition: core.h:2059
constexpr auto const_check(T value) -> T
Definition: core.h:355
FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double
Definition: core.h:1249
GLdouble s
Definition: glad.h:3009
FMT_CONSTEXPR_CHAR_TRAITS FMT_INLINE basic_string_view(const Char *s)
Definition: core.h:453
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T >>> buffer_appender
Definition: core.h:956
fallback_formatter()=delete
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
constexpr FMT_INLINE value(int val)
Definition: core.h:1155
bool binary32
Definition: core.h:2534
string_value< char_type > string
Definition: core.h:1149
FMT_CONSTEXPR arg_ref()
Definition: core.h:1936
T args_[1+(NUM_ARGS!=0?NUM_ARGS:+1)]
Definition: core.h:999
union arg_ref::value val
**But if you need a or simply need to know when the task has note that the like this
Definition: thread.h:617
constexpr auto end() const FMT_NOEXCEPT-> iterator
Definition: core.h:656
FMT_CONSTEXPR auto get(int id) const -> format_arg
Definition: core.h:1825
FMT_CONSTEXPR void on_localized()
Definition: core.h:1988
handle(detail::custom_value< Context > custom)
Definition: core.h:1425
FMT_CONSTEXPR arg_ref(basic_string_view< Char > name)
Definition: core.h:1940
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 void on_error(const char *message)
Definition: core.h:2721
**But if you need a result
Definition: thread.h:613
auto map(...) -> unformattable
Definition: core.h:1351
int int_value
Definition: core.h:1137
FMT_CONSTEXPR FMT_INLINE auto map(const T &val) -> basic_string_view< char_type >
Definition: core.h:1260
constexpr auto to_ascii(Char value) -> Char
Definition: core.h:2065
auto args() const -> const basic_format_args< basic_format_context > &
Definition: core.h:1628
constexpr FMT_INLINE basic_format_args(const dynamic_format_arg_store< Context > &store)
Definition: core.h:1811
auto count() const -> size_t
Definition: core.h:847
FMT_CONSTEXPR FMT_INLINE auto map(const T(&values)[N]) -> const T(&)[N]
Definition: core.h:1324
FMT_CONSTEXPR FMT_INLINE value(const T &val)
Definition: core.h:1178
typename std::remove_cv< remove_reference_t< T >>::type remove_cvref_t
Definition: core.h:327
appender(base it)
Definition: core.h:1380
align_t align
Definition: core.h:1912
auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) -> format_to_n_result< OutputIt >
Definition: core.h:2931
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1736
FMT_CONSTEXPR auto on_format_specs(int id, const Char *begin, const Char *) -> const Char *
Definition: core.h:2714
FMT_CONSTEXPR auto operator=(int idx) -> arg_ref &
Definition: core.h:1943
void vformat_to(buffer< Char > &buf, basic_string_view< Char > fmt, basic_format_args< FMT_BUFFER_CONTEXT(type_identity_t< Char >)> args, detail::locale_ref loc={})
PUGIXML_CHAR char_t
Definition: pugixml.hpp:125
constexpr auto size() const -> size_t
Definition: core.h:477
GLuint buffer
Definition: glcorearb.h:660
FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double
Definition: core.h:1248
friend FMT_CONSTEXPR auto visit_format_arg(Visitor &&vis, const basic_format_arg< Ctx > &arg) -> decltype(vis(0))
uint64 value_type
Definition: GA_PrimCompat.h:29
FMT_CONSTEXPR void on_error(const char *message)
Definition: core.h:690
FMT_CONSTEXPR auto operator[](size_t index) const -> const Char &
Definition: core.h:1901
FMT_CONSTEXPR FMT_INLINE auto map(const T &val) -> decltype(std::declval< arg_mapper >().map(static_cast< typename std::underlying_type< T >::type >(val)))
Definition: core.h:1332
named_arg_info< Char > named_args_[NUM_NAMED_ARGS]
Definition: core.h:1000
FMT_INLINE value(long double val)
Definition: core.h:1163
OutputIt out
Definition: core.h:2924
long double long_double_value
Definition: core.h:1147
auto operator[](I index) -> T &
Definition: core.h:839
constexpr auto is_utf8() -> bool
Definition: core.h:413
arg_id_kind kind
Definition: core.h:1949
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1262
FMT_CONSTEXPR void on_precision(int precision)
Definition: core.h:1996
FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long
Definition: core.h:1230
const Char * name
Definition: core.h:985
FMT_CONSTEXPR void on_zero()
Definition: core.h:2640
constexpr int invalid_arg_index
Definition: core.h:2651
void push_back(const T &value)
Definition: core.h:831
FMT_CONSTEXPR auto parse_precision(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2248
#define FMT_END_NAMESPACE
Definition: core.h:229
FMT_CONSTEXPR void on_fill(basic_string_view< Char > fill)
Definition: core.h:1983
size_t size
Definition: core.h:1121
FMT_CONSTEXPR auto on_arg_id(int id) -> int
Definition: core.h:2697
#define FMT_USE_DOUBLE
Definition: core.h:198
basic_string_view< char > string_view
Definition: core.h:522
basic_format_specs< Char > & specs_
Definition: core.h:1973
#define FMT_INLINE
Definition: core.h:208
buffer_context< char > format_context
Definition: core.h:1649
FMT_BEGIN_DETAIL_NAMESPACE void throw_format_error(const char *message)
Definition: format.h:810
FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned
Definition: core.h:1225
auto out() -> OutputIt
Definition: core.h:892
long long long_long_value
Definition: core.h:1139
void try_reserve(size_t new_capacity)
Definition: core.h:827
void clear()
Definition: core.h:814
auto get_id(basic_string_view< Char > name) const -> int
Definition: core.h:1845
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition: core.h:2027
constexpr auto size() const -> size_t
Definition: core.h:1897
constexpr auto error_handler() const -> ErrorHandler
Definition: core.h:694
auto get_iterator(Buffer &buf) -> decltype(buf.out())
Definition: core.h:965
FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition: core.h:738
auto args() const -> const T *
Definition: core.h:1005
GLdouble n
Definition: glcorearb.h:2008
const void * value
Definition: core.h:1126
FMT_CONSTEXPR auto map(T) -> enable_if_t< std::is_pointer< T >::value, int >
Definition: core.h:1314
FMT_CONSTEXPR auto parse_nonnegative_int(const Char *&begin, const Char *end, int error_value) noexcept-> int
Definition: core.h:2107
GLfloat f
Definition: glcorearb.h:1926
auto runtime(const S &s) -> basic_runtime< char_t< S >>
Definition: core.h:2870
constexpr auto data() const -> const Char *
Definition: core.h:474
class OCIOEXPORT Context
#define FMT_MSC_WARNING(...)
Definition: core.h:58
FMT_CONSTEXPR auto arg(basic_string_view< char_type > name) -> format_arg
Definition: core.h:1622
FMT_CONSTEXPR_CHAR_TRAITS auto compare(basic_string_view other) const -> int
Definition: core.h:492
FMT_NORETURN FMT_API void assert_fail(const char *file, int line, const char *message)
Definition: format-inl.h:34
Definition: core.h:760
constexpr error_handler()=default
FMT_INLINE value(int128_t val)
Definition: core.h:1159
Definition: core.h:1935
void operator=(const buffer &)=delete
constexpr FMT_INLINE basic_format_args(const format_arg_store< Context, Args...> &store)
Definition: core.h:1800
FMT_API void vprint(string_view fmt, format_args args)
Definition: format-inl.h:2615
typename Context::parse_context_type parse_context
Definition: core.h:1125
int128_t
Definition: core.h:395
const Char * name
Definition: core.h:991
FMT_CONSTEXPR FMT_INLINE format_arg_store(const Args &...args)
Definition: core.h:1698
FMT_CONSTEXPR auto error_handler() -> detail::error_handler
Definition: core.h:1632
FMT_CONSTEXPR void on_hash()
Definition: core.h:1987
basic_string_view< Char > str
Definition: core.h:2829
FMT_CONSTEXPR auto next_arg_id() -> int
Definition: core.h:669
auto data() const FMT_NOEXCEPT-> const T *
Definition: core.h:811
auto is_integral() const -> bool
Definition: core.h:1444
constexpr basic_format_arg()
Definition: core.h:1436
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:545
auto find< false, char >(const char *first, const char *last, char value, const char *&out) -> bool
Definition: core.h:2097
void grow(size_t) final FMT_OVERRIDE
Definition: core.h:875
auto out() -> T *
Definition: core.h:906
#define FMT_USE_FLOAT
Definition: core.h:195
constexpr auto operator[](size_t pos) const -> const Char &
Definition: core.h:482
constexpr auto arg(int id) const -> format_arg
Definition: core.h:1621
#define FMT_GCC_VERSION
Definition: core.h:31
GLuint GLuint end
Definition: glcorearb.h:475
constexpr auto count() -> size_t
Definition: core.h:1050
FMT_CONSTEXPR auto parse_replacement_field(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2353
friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:505
Char value_type
Definition: core.h:789
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
void void_t
Definition: core.h:1512
FMT_INLINE value(const named_arg_info< char_type > *args, size_t size)
Definition: core.h:1175
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:325
GLint GLuint mask
Definition: glcorearb.h:124
constexpr auto begin() const -> iterator
Definition: core.h:479
FMT_INLINE auto format(format_string< T...> fmt, T &&...args) -> std::string
Definition: core.h:2889
FMT_CONSTEXPR FMT_INLINE auto map(unsigned char *val) -> const char *
Definition: core.h:1298
type
Definition: core.h:1870
#define FMT_GCC_PRAGMA(arg)
Definition: core.h:32
FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type
Definition: core.h:1227
void set(T *buf_data, size_t buf_capacity) FMT_NOEXCEPT
Definition: core.h:780
FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int
Definition: core.h:1216
#define FMT_API
Definition: core.h:263
~iterator_buffer()
Definition: core.h:890
buffer_traits(size_t)
Definition: core.h:846
FMT_CONSTEXPR auto make_arg(const T &value) -> basic_format_arg< Context >
Definition: core.h:1564
FMT_CONSTEXPR void on_align(align_t align)
Definition: core.h:2616
auto capacity() const FMT_NOEXCEPT-> size_t
Definition: core.h:805
auto operator++() -> appender &
Definition: core.h:1383
auto is_arithmetic() const -> bool
Definition: core.h:1445
FMT_BEGIN_DETAIL_NAMESPACE auto get_container(std::back_insert_iterator< Container > it) -> Container &
Definition: core.h:727
GLuint id
Definition: glcorearb.h:655
#define FMT_BUFFER_CONTEXT(Char)
Definition: core.h:1652
auto operator++(int) -> appender
Definition: core.h:1388
void try_resize(size_t count)
Definition: core.h:818
detail::fill_t< Char > fill
Definition: core.h:1916
#define FMT_TYPE_CONSTANT(Type, constant)
Definition: core.h:1086
iterator_buffer(OutputIt out, size_t n=buffer_size)
Definition: core.h:886
#define FMT_USE_LONG_DOUBLE
Definition: core.h:201
conditional_t< long_short, unsigned, unsigned long long > ulong_type
Definition: core.h:1208
FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t
Definition: core.h:1017
FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler) -> const Char *
Definition: core.h:2205
bool use_grisu
Definition: core.h:2535
constexpr basic_string_view(const Char *s, size_t count) FMT_NOEXCEPT
Definition: core.h:441
FMT_CONSTEXPR FMT_INLINE auto map(const T &named_arg) -> decltype(std::declval< arg_mapper >().map(named_arg.value))
Definition: core.h:1346
GLuint const GLchar * name
Definition: glcorearb.h:786
IMATH_HOSTDEVICE constexpr int sign(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:33
#define FMT_UNICODE
Definition: core.h:284
FMT_CONSTEXPR FMT_INLINE void parse_format_string(basic_string_view< Char > format_str, Handler &&handler)
Definition: core.h:2393
sign_t sign
Definition: core.h:2531
FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool
Definition: core.h:1237
uint128_t uint128_value
Definition: core.h:1142
int precision
Definition: core.h:2529
FMT_CONSTEXPR void check_arg_id(basic_string_view< Char >)
Definition: core.h:688
constexpr auto make_format_args(const Args &...args) -> format_arg_store< Context, Args...>
Definition: core.h:1719
FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned
Definition: core.h:1217
constexpr basic_format_args()
Definition: core.h:1792
FMT_NORETURN FMT_API void on_error(const char *message)
Definition: format-inl.h:2553
FMT_INLINE value(float val)
Definition: core.h:1161
auto get_buffer(OutputIt out) -> iterator_buffer< OutputIt, T >
Definition: core.h:960
FMT_CONSTEXPR void on_zero()
Definition: core.h:1990
Definition: core.h:996
auto count() -> size_t
Definition: core.h:951
void advance_to(iterator it)
Definition: core.h:1639
basic_format_string(basic_runtime< Char > r)
Definition: core.h:2855
typename ParseContext::char_type char_type
Definition: core.h:2012
buffer(size_t sz) FMT_NOEXCEPT
Definition: core.h:769
GLdouble t
Definition: glad.h:2397
ErrorHandler() noexcept
Definition: errorhandler.h:54
FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string< T...> fmt, const T &...args) -> format_to_n_result< OutputIt >
Definition: core.h:2949
FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float
Definition: core.h:1247
FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs< char_type > &specs, ParseContext &ctx)
Definition: core.h:2014
FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view< Char > name) -> int
Definition: core.h:2667
auto begin() FMT_NOEXCEPT-> T *
Definition: core.h:795
arg_id_kind
Definition: core.h:1932
arg_ref< Char > width_ref
Definition: core.h:1964
friend auto get_buffer(appender out) -> detail::buffer< char > &
Definition: core.h:1374
GLenum GLint GLint * precision
Definition: glcorearb.h:1925
constexpr auto begin() const FMT_NOEXCEPT-> iterator
Definition: core.h:649
FMT_CONSTEXPR void end_precision()
Definition: core.h:1999
FMT_CONSTEXPR specs_checker(const Handler &handler, detail::type arg_type)
Definition: core.h:2613
counting_buffer()
Definition: core.h:949
arg_data(const U &...init)
Definition: core.h:1003
void on_error(const char *message)
Definition: core.h:1633
FMT_CONSTEXPR auto on_arg_id() -> int
Definition: core.h:2696
GLsizeiptr size
Definition: glcorearb.h:664
std::is_constructible< typename Context::template formatter_type< T >> has_formatter
Definition: core.h:714
friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:517
FMT_CONSTEVAL basic_format_string(const S &s)
Definition: core.h:2839
GLenum void ** pointer
Definition: glcorearb.h:810
unsigned long long ulong_long_value
Definition: core.h:1140
FMT_CONSTEXPR compile_parse_context(basic_string_view< Char > format_str, int num_args=(std::numeric_limits< int >::max)(), ErrorHandler eh={})
Definition: core.h:2471
iterator_buffer(iterator_buffer &&other)
Definition: core.h:888
void operator=(const basic_format_context &)=delete
const detail::value< Context > * values_
Definition: core.h:1768
auto max_size() const -> int
Definition: core.h:1855
FMT_CONSTEXPR FMT_INLINE arg_data(const U &...init)
Definition: core.h:1015
auto end() FMT_NOEXCEPT-> T *
Definition: core.h:796
#define FMT_CONSTEXPR
Definition: core.h:98
FMT_CONSTEXPR FMT_INLINE auto map(char_type *val) -> const char_type *
Definition: core.h:1253
constexpr monostate()
Definition: core.h:332
named_arg(const Char *n, const T &v)
Definition: core.h:987
FMT_CONSTEXPR void on_error(const char *message)
Definition: core.h:2031
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
constexpr FMT_INLINE value(unsigned val)
Definition: core.h:1156
friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:514
typename basic_string_view< Char >::iterator iterator
Definition: core.h:638
FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int
Definition: core.h:1224
typename type_identity< T >::type type_identity_t
Definition: core.h:329
constexpr locale_ref()
Definition: core.h:1545
void grow(size_t) final FMT_OVERRIDE
Definition: core.h:942
size_t size
Definition: core.h:1116
FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type
Definition: core.h:1226
GLuint index
Definition: glcorearb.h:786
FMT_CONSTEXPR FMT_INLINE auto args() const -> const T *
Definition: core.h:1016
bool_constant< !std::is_same< decltype(detail::arg_mapper< buffer_context< Char >>().map(std::declval< T >())), detail::unformattable >::value &&!detail::has_fallback_formatter< T, Char >::value > is_formattable
Definition: core.h:1660
uint128_t
Definition: core.h:396
FMT_CONSTEXPR auto parse_width(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2214
FMT_CONSTEXPR specs_setter(const specs_setter &other)
Definition: core.h:1979
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition: core.h:2023
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLuint GLfloat * val
Definition: glcorearb.h:1608
typename Context::char_type char_type
Definition: core.h:1214
const char * iterator
Definition: core.h:436
constexpr auto end() const -> iterator
Definition: core.h:480
GA_API const UT_StringHolder N
FMT_CONSTEXPR FMT_INLINE auto map(const signed char *val) -> const char *
Definition: core.h:1286
constexpr bool is_arithmetic_type(type t)
Definition: core.h:1110
FMT_CONSTEXPR auto code_point_length(const Char *begin) -> int
Definition: core.h:2075
FMT_INLINE auto format_to(OutputIt out, format_string< T...> fmt, T &&...args) -> OutputIt
Definition: core.h:2917
if(num_boxed_items<=0)
Definition: UT_RTreeImpl.h:697
constexpr auto encode_types() -> unsigned long long
Definition: core.h:1553
FMT_CONSTEXPR void on_replacement_field(int, const Char *)
Definition: core.h:2712
FMT_CONSTEXPR bool is_name_start(Char c)
Definition: core.h:2170
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
Definition: core.h:1458
FMT_CONSTEXPR void on_type(Char type)
Definition: core.h:2001
constexpr basic_format_args(const format_arg *args, int count)
Definition: core.h:1820
FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int
Definition: core.h:1220
FMT_CONSTEXPR format_string_checker(basic_string_view< Char > format_str, ErrorHandler eh)
Definition: core.h:2689
**If you just want to fire and args
Definition: thread.h:609
FMT_CONSTEXPR auto next_arg_id() -> int
Definition: core.h:2476
const format_arg * args_
Definition: core.h:1769
const Char * data
Definition: core.h:1115
GLint GLsizei width
Definition: glcorearb.h:103
auto type() const -> detail::type
Definition: core.h:1442
FMT_CONSTEXPR FMT_INLINE auto map(const unsigned char *val) -> const char *
Definition: core.h:1290
auto limit(size_t size) -> size_t
Definition: core.h:859
Definition: core.h:982
#define FMT_NOEXCEPT
Definition: core.h:153
Definition: core.h:1131
constexpr bool is_integral_type(type t)
Definition: core.h:1106
FMT_CONSTEXPR auto check_cstring_type_spec(Char spec, ErrorHandler &&eh={}) -> bool
Definition: core.h:2584
friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:511
bool showpoint
Definition: core.h:2536
FMT_CONSTEXPR FMT_INLINE auto map(const void *val) -> const void *
Definition: core.h:1304
FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val) -> unsigned long long
Definition: core.h:1231
auto end() const FMT_NOEXCEPT-> const T *
Definition: core.h:799
FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT
Definition: core.h:470
auto named_args() -> named_arg_info< Char > *
Definition: core.h:1006
#define FMT_ASSERT(condition, message)
Definition: core.h:365
FMT_INLINE value(const void *val)
Definition: core.h:1174
FMT_CONSTEXPR arg_ref(int index)
Definition: core.h:1938
char_type char_value
Definition: core.h:1144
GLboolean r
Definition: glcorearb.h:1222
#define FMT_BEGIN_NAMESPACE
Definition: core.h:234
auto count() const -> size_t
Definition: core.h:858
auto convert_for_visit(T) -> monostate
Definition: core.h:398
#define const
Definition: zconf.h:214
arg_ref< Char > precision_ref
Definition: core.h:1965
FMT_CONSTEXPR value(int id=0)
Definition: core.h:1951
Definition: core.h:1883
constexpr FMT_INLINE value(unsigned long long val)
Definition: core.h:1158
void append(const U *begin, const U *end)
Definition: format.h:577
FMT_CONSTEXPR auto out() -> iterator
Definition: core.h:1636
constexpr FMT_INLINE value(bool val)
Definition: core.h:1164
constexpr basic_string_view() FMT_NOEXCEPT
Definition: core.h:438
FMT_INLINE value(double val)
Definition: core.h:1162
FMT_CONSTEXPR void on_sign(sign_t s)
Definition: core.h:1986
#define FMT_OVERRIDE
Definition: core.h:123
auto size() const FMT_NOEXCEPT-> size_t
Definition: core.h:802
FMT_CONSTEXPR void check_arg_id(int)
Definition: core.h:681
FMT_CONSTEXPR auto locale() -> detail::locale_ref
Definition: core.h:1643
FMT_CONSTEXPR FMT_INLINE value(const char_type *val)
Definition: core.h:1166
void write(T &out, bool v)
Definition: ImfXdr.h:287
unsigned uint_value
Definition: core.h:1138
FMT_CONSTEXPR specs_setter(basic_format_specs< Char > &specs)
Definition: core.h:1976
#define FMT_MODULE_EXPORT_BEGIN
Definition: core.h:241
type
Definition: core.h:1059
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2976
FMT_CONSTEXPR FMT_INLINE auto map(const T &val) -> const T &
Definition: core.h:1341
friend struct detail::arg_data
Definition: core.h:1417
void init_named_args(named_arg_info< Char > *, int, int)
Definition: core.h:1023
FMT_CONSTEXPR void remove_prefix(size_t n)
Definition: core.h:486
~buffer()=default
std::integral_constant< bool, B > bool_constant
Definition: core.h:323
PXR_NAMESPACE_OPEN_SCOPE typedef unsigned char uchar
Definition: inttypes.h:58
bool bool_value
Definition: core.h:1143
FMT_CONSTEXPR FMT_INLINE auto map(void *val) -> const void *
Definition: core.h:1303
unsigned char uchar
Definition: SYS_Types.h:42
FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> float_specs
Definition: core.h:2540
const Char & const_reference
Definition: core.h:790
FMT_CONSTEXPR void on_text(const Char *, const Char *)
Definition: core.h:2694
FMT_CONSTEXPR FMT_INLINE auto map(uint128_t val) -> uint128_t
Definition: core.h:1236
constexpr FMT_INLINE value()
Definition: core.h:1154
Definition: core.h:525
type
Definition: core.h:1874
constexpr FMT_INLINE value(char_type val)
Definition: core.h:1165
constexpr basic_format_parse_context(basic_string_view< Char > format_str, ErrorHandler eh={}, int next_arg_id=0)
Definition: core.h:640
buffer(T *p=nullptr, size_t sz=0, size_t cap=0) FMT_NOEXCEPT
Definition: core.h:771
constexpr basic_format_context(OutputIt out, basic_format_args< basic_format_context > ctx_args, detail::locale_ref loc=detail::locale_ref())
Definition: core.h:1616
FMT_CONSTEXPR value(basic_string_view< Char > n)
Definition: core.h:1952
FMT_CONSTEXPR auto parse_align(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2131
GLint GLsizei count
Definition: glcorearb.h:405
FMT_CONSTEXPR FMT_INLINE value(basic_string_view< char_type > val)
Definition: core.h:1170
Definition: format.h:895
FMT_CONSTEXPR FMT_INLINE auto map(const char_type *val) -> const char_type *
Definition: core.h:1256
FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler &&eh)
Definition: core.h:2592
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> bool
Definition: core.h:2509
fixed_buffer_traits(size_t limit)
Definition: core.h:857
int128_t int128_value
Definition: core.h:1141
FMT_CONSTEXPR void on_sign(sign_t s)
Definition: core.h:2621
custom_value< Context > custom
Definition: core.h:1150
GLsizei GLenum GLenum GLuint GLenum GLsizei * lengths
Definition: glcorearb.h:2542
friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:508
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2089
FMT_CONSTEXPR void check_int_type_spec(char spec, ErrorHandler &&eh)
Definition: core.h:2490
bool upper
Definition: core.h:2532
const named_arg_info< Char > * data
Definition: core.h:1120
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:483