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