WPILibC++ 2023.4.3
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 90100
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 || \
73 FMT_MSC_VERSION > 1900) && \
74 !defined(__INTELLISENSE__)
75# define FMT_HAS_INCLUDE(x) __has_include(x)
76#else
77# define FMT_HAS_INCLUDE(x) 0
78#endif
79
80#ifdef __has_cpp_attribute
81# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
82#else
83# define FMT_HAS_CPP_ATTRIBUTE(x) 0
84#endif
85
86#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \
87 (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute))
88
89#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \
90 (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))
91
92// Check if relaxed C++14 constexpr is supported.
93// GCC doesn't allow throw in constexpr until version 6 (bug 67371).
94#ifndef FMT_USE_CONSTEXPR
95# if (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912 || \
96 (FMT_GCC_VERSION >= 600 && FMT_CPLUSPLUS >= 201402L)) && \
97 !FMT_ICC_VERSION && !defined(__NVCC__)
98# define FMT_USE_CONSTEXPR 1
99# else
100# define FMT_USE_CONSTEXPR 0
101# endif
102#endif
103#if FMT_USE_CONSTEXPR
104# define FMT_CONSTEXPR constexpr
105#else
106# define FMT_CONSTEXPR
107#endif
108
109#if ((FMT_CPLUSPLUS >= 202002L) && \
110 (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE > 9)) || \
111 (FMT_CPLUSPLUS >= 201709L && FMT_GCC_VERSION >= 1002)
112# define FMT_CONSTEXPR20 constexpr
113#else
114# define FMT_CONSTEXPR20
115#endif
116
117// Check if constexpr std::char_traits<>::{compare,length} are supported.
118#if defined(__GLIBCXX__)
119# if FMT_CPLUSPLUS >= 201703L && defined(_GLIBCXX_RELEASE) && \
120 _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE.
121# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
122# endif
123#elif defined(_LIBCPP_VERSION) && FMT_CPLUSPLUS >= 201703L && \
124 _LIBCPP_VERSION >= 4000
125# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
126#elif FMT_MSC_VERSION >= 1914 && FMT_CPLUSPLUS >= 201703L
127# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
128#endif
129#ifndef FMT_CONSTEXPR_CHAR_TRAITS
130# define FMT_CONSTEXPR_CHAR_TRAITS
131#endif
132
133// Check if exceptions are disabled.
134#ifndef FMT_EXCEPTIONS
135# if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
136 (FMT_MSC_VERSION && !_HAS_EXCEPTIONS)
137# define FMT_EXCEPTIONS 0
138# else
139# define FMT_EXCEPTIONS 1
140# endif
141#endif
142
143#ifndef FMT_DEPRECATED
144# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VERSION >= 1900
145# define FMT_DEPRECATED [[deprecated]]
146# else
147# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
148# define FMT_DEPRECATED __attribute__((deprecated))
149# elif FMT_MSC_VERSION
150# define FMT_DEPRECATED __declspec(deprecated)
151# else
152# define FMT_DEPRECATED /* deprecated */
153# endif
154# endif
155#endif
156
157// [[noreturn]] is disabled on MSVC and NVCC because of bogus unreachable code
158// warnings.
159#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && \
160 !defined(__NVCC__)
161# define FMT_NORETURN [[noreturn]]
162#else
163# define FMT_NORETURN
164#endif
165
166#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
167# define FMT_FALLTHROUGH [[fallthrough]]
168#elif defined(__clang__)
169# define FMT_FALLTHROUGH [[clang::fallthrough]]
170#elif FMT_GCC_VERSION >= 700 && \
171 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
172# define FMT_FALLTHROUGH [[gnu::fallthrough]]
173#else
174# define FMT_FALLTHROUGH
175#endif
176
177#ifndef FMT_NODISCARD
178# if FMT_HAS_CPP17_ATTRIBUTE(nodiscard)
179# define FMT_NODISCARD [[nodiscard]]
180# else
181# define FMT_NODISCARD
182# endif
183#endif
184
185#ifndef FMT_USE_FLOAT
186# define FMT_USE_FLOAT 1
187#endif
188#ifndef FMT_USE_DOUBLE
189# define FMT_USE_DOUBLE 1
190#endif
191#ifndef FMT_USE_LONG_DOUBLE
192# define FMT_USE_LONG_DOUBLE 1
193#endif
194
195#ifndef FMT_INLINE
196# if FMT_GCC_VERSION || FMT_CLANG_VERSION
197# define FMT_INLINE inline __attribute__((always_inline))
198# else
199# define FMT_INLINE inline
200# endif
201#endif
202
203// An inline std::forward replacement.
204#define FMT_FORWARD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
205
206#ifdef _MSC_VER
207# define FMT_UNCHECKED_ITERATOR(It) \
208 using _Unchecked_type = It // Mark iterator as checked.
209#else
210# define FMT_UNCHECKED_ITERATOR(It) using unchecked_type = It
211#endif
212
213#ifndef FMT_BEGIN_NAMESPACE
214# define FMT_BEGIN_NAMESPACE \
215 namespace fmt { \
216 inline namespace v9 {
217# define FMT_END_NAMESPACE \
218 } \
219 }
220#endif
221
222#ifndef FMT_MODULE_EXPORT
223# define FMT_MODULE_EXPORT
224# define FMT_MODULE_EXPORT_BEGIN
225# define FMT_MODULE_EXPORT_END
226# define FMT_BEGIN_DETAIL_NAMESPACE namespace detail {
227# define FMT_END_DETAIL_NAMESPACE }
228#endif
229
230#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
231# define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275)
232# ifdef FMT_EXPORT
233# define FMT_API __declspec(dllexport)
234# elif defined(FMT_SHARED)
235# define FMT_API __declspec(dllimport)
236# endif
237#else
238# define FMT_CLASS_API
239# if defined(FMT_EXPORT) || defined(FMT_SHARED)
240# if defined(__GNUC__) || defined(__clang__)
241# define FMT_API __attribute__((visibility("default")))
242# endif
243# endif
244#endif
245#ifndef FMT_API
246# define FMT_API
247#endif
248
249// libc++ supports string_view in pre-c++17.
250#if FMT_HAS_INCLUDE(<string_view>) && \
251 (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION))
252# include <string_view>
253# define FMT_USE_STRING_VIEW
254#elif FMT_HAS_INCLUDE("experimental/string_view") && FMT_CPLUSPLUS >= 201402L
255# include <experimental/string_view>
256# define FMT_USE_EXPERIMENTAL_STRING_VIEW
257#endif
258
259#ifndef FMT_UNICODE
260# define FMT_UNICODE !FMT_MSC_VERSION
261#endif
262
263#ifndef FMT_CONSTEVAL
264# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \
265 FMT_CPLUSPLUS >= 202002L && !defined(__apple_build_version__)) || \
266 (defined(__cpp_consteval) && \
267 (!FMT_MSC_VERSION || _MSC_FULL_VER >= 193030704))
268// consteval is broken in MSVC before VS2022 and Apple clang 13.
269# define FMT_CONSTEVAL consteval
270# define FMT_HAS_CONSTEVAL
271# else
272# define FMT_CONSTEVAL
273# endif
274#endif
275
276#ifndef FMT_USE_NONTYPE_TEMPLATE_ARGS
277# if defined(__cpp_nontype_template_args) && \
278 ((FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L) || \
279 __cpp_nontype_template_args >= 201911L) && \
280 !defined(__NVCOMPILER)
281# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
282# else
283# define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
284# endif
285#endif
286
287// Enable minimal optimizations for more compact code in debug mode.
288FMT_GCC_PRAGMA("GCC push_options")
289#if !defined(__OPTIMIZE__) && !defined(__NVCOMPILER)
290FMT_GCC_PRAGMA("GCC optimize(\"Og\")")
291#endif
292
295
296// Implementations of enable_if_t and other metafunctions for older systems.
297template <bool B, typename T = void>
299template <bool B, typename T, typename F>
301template <bool B> using bool_constant = std::integral_constant<bool, B>;
302template <typename T>
304template <typename T>
306template <typename T>
307using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
308template <typename T> struct type_identity { using type = T; };
309template <typename T> using type_identity_t = typename type_identity<T>::type;
310template <typename T>
312
313template <typename...> struct disjunction : std::false_type {};
314template <typename P> struct disjunction<P> : P {};
315template <typename P1, typename... Pn>
316struct disjunction<P1, Pn...>
317 : conditional_t<bool(P1::value), P1, disjunction<Pn...>> {};
318
319template <typename...> struct conjunction : std::true_type {};
320template <typename P> struct conjunction<P> : P {};
321template <typename P1, typename... Pn>
322struct conjunction<P1, Pn...>
323 : conditional_t<bool(P1::value), conjunction<Pn...>, P1> {};
324
325struct monostate {
326 constexpr monostate() {}
327};
328
329// An enable_if helper to be used in template parameters which results in much
330// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed
331// to workaround a bug in MSVC 2019 (see #1140 and #1186).
332#ifdef FMT_DOC
333# define FMT_ENABLE_IF(...)
334#else
335# define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0
336#endif
337
339
340// Suppresses "unused variable" warnings with the method described in
341// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
342// (void)var does not work on many Intel compilers.
343template <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {}
344
346 bool default_value = false) noexcept -> bool {
347#ifdef __cpp_lib_is_constant_evaluated
348 ignore_unused(default_value);
350#else
351 return default_value;
352#endif
353}
354
355// Suppresses "conditional expression is constant" warnings.
356template <typename T> constexpr FMT_INLINE auto const_check(T value) -> T {
357 return value;
358}
359
360FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
361 const char* message);
362
363#ifndef FMT_ASSERT
364# ifdef NDEBUG
365// FMT_ASSERT is not empty to avoid -Wempty-body.
366# define FMT_ASSERT(condition, message) \
367 ::fmt::detail::ignore_unused((condition), (message))
368# else
369# define FMT_ASSERT(condition, message) \
370 ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
371 ? (void)0 \
372 : ::fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
373# endif
374#endif
375
376#if defined(FMT_USE_STRING_VIEW)
377template <typename Char> using std_string_view = std::basic_string_view<Char>;
378#elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW)
379template <typename Char>
380using std_string_view = std::experimental::basic_string_view<Char>;
381#else
382template <typename T> struct std_string_view {};
383#endif
384
385#ifdef FMT_USE_INT128
386// Do nothing.
387#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \
388 !(FMT_CLANG_VERSION && FMT_MSC_VERSION)
389# define FMT_USE_INT128 1
390using int128_opt = __int128_t; // An optional native 128-bit integer.
391using uint128_opt = __uint128_t;
392template <typename T> inline auto convert_for_visit(T value) -> T {
393 return value;
394}
395#else
396# define FMT_USE_INT128 0
397#endif
398#if !FMT_USE_INT128
399enum class int128_opt {};
400enum class uint128_opt {};
401// Reduce template instantiations.
402template <typename T> auto convert_for_visit(T) -> monostate { return {}; }
403#endif
404
405// Casts a nonnegative integer to unsigned.
406template <typename Int>
409 FMT_ASSERT(std::is_unsigned<Int>::value || value >= 0, "negative value");
410 return static_cast<typename std::make_unsigned<Int>::type>(value);
411}
412
413FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5";
414
415constexpr auto is_utf8() -> bool {
416 // Avoid buggy sign extensions in MSVC's constant evaluation mode (#2297).
417 using uchar = unsigned char;
418 return FMT_UNICODE || (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 &&
419 uchar(micro[1]) == 0xB5);
420}
422
423/**
424 An implementation of ``std::basic_string_view`` for pre-C++17. It provides a
425 subset of the API. ``fmt::basic_string_view`` is used for format strings even
426 if ``std::string_view`` is available to prevent issues when a library is
427 compiled with a different ``-std`` option than the client code (which is not
428 recommended).
429 */
430template <typename Char> class basic_string_view {
431 private:
432 const Char* data_;
433 size_t size_;
434
435 public:
436 using value_type = Char;
437 using iterator = const Char*;
438
439 constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
440
441 /** Constructs a string reference object from a C string and a size. */
442 constexpr basic_string_view(const Char* s, size_t count) noexcept
443 : data_(s), size_(count) {}
444
445 /**
446 \rst
447 Constructs a string reference object from a C string computing
448 the size with ``std::char_traits<Char>::length``.
449 \endrst
450 */
453 basic_string_view(const Char* s)
454 : data_(s),
455 size_(detail::const_check(std::is_same<Char, char>::value &&
457 ? std::strlen(reinterpret_cast<const char*>(s))
458 : std::char_traits<Char>::length(s)) {}
459
460 /** Constructs a string reference from a ``std::basic_string`` object. */
461 template <typename Traits, typename Alloc>
463 const std::basic_string<Char, Traits, Alloc>& s) noexcept
464 : data_(s.data()), size_(s.size()) {}
465
466 template <typename S, FMT_ENABLE_IF(std::is_same<
467 S, detail::std_string_view<Char>>::value)>
469 : data_(s.data()), size_(s.size()) {}
470
471 /** Returns a pointer to the string data. */
472 constexpr auto data() const noexcept -> const Char* { return data_; }
473
474 /** Returns the string size. */
475 constexpr auto size() const noexcept -> size_t { return size_; }
476
477 constexpr auto begin() const noexcept -> iterator { return data_; }
478 constexpr auto end() const noexcept -> iterator { return data_ + size_; }
479
480 constexpr auto operator[](size_t pos) const noexcept -> const Char& {
481 return data_[pos];
482 }
483
484 FMT_CONSTEXPR void remove_prefix(size_t n) noexcept {
485 data_ += n;
486 size_ -= n;
487 }
488
489 // Lexicographically compare this string reference to other.
491 size_t str_size = size_ < other.size_ ? size_ : other.size_;
492 int result = std::char_traits<Char>::compare(data_, other.data_, str_size);
493 if (result == 0)
494 result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
495 return result;
496 }
497
500 -> bool {
501 return lhs.compare(rhs) == 0;
502 }
503 friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {
504 return lhs.compare(rhs) != 0;
505 }
506 friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool {
507 return lhs.compare(rhs) < 0;
508 }
509 friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool {
510 return lhs.compare(rhs) <= 0;
511 }
512 friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool {
513 return lhs.compare(rhs) > 0;
514 }
515 friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool {
516 return lhs.compare(rhs) >= 0;
517 }
518};
519
521
522/** Specifies if ``T`` is a character type. Can be specialized by users. */
523template <typename T> struct is_char : std::false_type {};
524template <> struct is_char<char> : std::true_type {};
525
527
528// A base class for compile-time strings.
530
531template <typename S>
532struct is_compile_string : std::is_base_of<compile_string, S> {};
533
534// Returns a string view of `s`.
535template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
537 return s;
538}
539template <typename Char, typename Traits, typename Alloc>
540inline auto to_string_view(const std::basic_string<Char, Traits, Alloc>& s)
542 return s;
543}
544template <typename Char>
547 return s;
548}
549template <typename Char,
552 return s;
553}
554template <typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
555constexpr auto to_string_view(const S& s)
558}
560
561// Specifies whether S is a string type convertible to fmt::basic_string_view.
562// It should be a constexpr function but MSVC 2017 fails to compile it in
563// enable_if and MSVC 2015 fails to compile it as an alias template.
564// ADL invocation of to_string_view is DEPRECATED!
565template <typename S>
566struct is_string : std::is_class<decltype(to_string_view(std::declval<S>()))> {
567};
568
569template <typename S, typename = void> struct char_t_impl {};
570template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> {
571 using result = decltype(to_string_view(std::declval<S>()));
572 using type = typename result::value_type;
573};
574
575enum class type {
576 none_type,
577 // Integer types should go first,
578 int_type,
579 uint_type,
584 bool_type,
585 char_type,
587 // followed by floating-point types.
596};
597
598// Maps core type T to the corresponding type enum constant.
599template <typename T, typename Char>
600struct type_constant : std::integral_constant<type, type::custom_type> {};
601
602#define FMT_TYPE_CONSTANT(Type, constant) \
603 template <typename Char> \
604 struct type_constant<Type, Char> \
605 : std::integral_constant<type, type::constant> {}
606
607FMT_TYPE_CONSTANT(int, int_type);
608FMT_TYPE_CONSTANT(unsigned, uint_type);
609FMT_TYPE_CONSTANT(long long, long_long_type);
610FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);
613FMT_TYPE_CONSTANT(bool, bool_type);
614FMT_TYPE_CONSTANT(Char, char_type);
615FMT_TYPE_CONSTANT(float, float_type);
616FMT_TYPE_CONSTANT(double, double_type);
617FMT_TYPE_CONSTANT(long double, long_double_type);
618FMT_TYPE_CONSTANT(const Char*, cstring_type);
620FMT_TYPE_CONSTANT(const void*, pointer_type);
621
622constexpr bool is_integral_type(type t) {
623 return t > type::none_type && t <= type::last_integer_type;
624}
625
626constexpr bool is_arithmetic_type(type t) {
627 return t > type::none_type && t <= type::last_numeric_type;
628}
629
630FMT_NORETURN FMT_API void throw_format_error(const char* message);
631
633 constexpr error_handler() = default;
634 constexpr error_handler(const error_handler&) = default;
635
636 // This function is intentionally not constexpr to give a compile-time error.
637 FMT_NORETURN void on_error(const char* message) {
638 throw_format_error(message);
639 }
640};
642
643/** String's character type. */
644template <typename S> using char_t = typename detail::char_t_impl<S>::type;
645
646/**
647 \rst
648 Parsing context consisting of a format string range being parsed and an
649 argument counter for automatic indexing.
650 You can use the ``format_parse_context`` type alias for ``char`` instead.
651 \endrst
652 */
653template <typename Char, typename ErrorHandler = detail::error_handler>
654class basic_format_parse_context : private ErrorHandler {
655 private:
656 basic_string_view<Char> format_str_;
657 int next_arg_id_;
658
659 FMT_CONSTEXPR void do_check_arg_id(int id);
660
661 public:
662 using char_type = Char;
664
665 explicit constexpr basic_format_parse_context(
666 basic_string_view<Char> format_str, ErrorHandler eh = {},
667 int next_arg_id = 0)
668 : ErrorHandler(eh), format_str_(format_str), next_arg_id_(next_arg_id) {}
669
670 /**
671 Returns an iterator to the beginning of the format string range being
672 parsed.
673 */
674 constexpr auto begin() const noexcept -> iterator {
675 return format_str_.begin();
676 }
677
678 /**
679 Returns an iterator past the end of the format string range being parsed.
680 */
681 constexpr auto end() const noexcept -> iterator { return format_str_.end(); }
682
683 /** Advances the begin iterator to ``it``. */
685 format_str_.remove_prefix(detail::to_unsigned(it - begin()));
686 }
687
688 /**
689 Reports an error if using the manual argument indexing; otherwise returns
690 the next argument index and switches to the automatic indexing.
691 */
693 if (next_arg_id_ < 0) {
694 on_error("cannot switch from manual to automatic argument indexing");
695 return 0;
696 }
697 int id = next_arg_id_++;
698 do_check_arg_id(id);
699 return id;
700 }
701
702 /**
703 Reports an error if using the automatic argument indexing; otherwise
704 switches to the manual indexing.
705 */
707 if (next_arg_id_ > 0) {
708 on_error("cannot switch from automatic to manual argument indexing");
709 return;
710 }
711 next_arg_id_ = -1;
712 do_check_arg_id(id);
713 }
716
717 FMT_CONSTEXPR void on_error(const char* message) {
718 ErrorHandler::on_error(message);
719 }
720
721 constexpr auto error_handler() const -> ErrorHandler { return *this; }
722};
723
725
727// A parse context with extra data used only in compile-time checks.
728template <typename Char, typename ErrorHandler = detail::error_handler>
730 : public basic_format_parse_context<Char, ErrorHandler> {
731 private:
732 int num_args_;
733 const type* types_;
735
736 public:
738 basic_string_view<Char> format_str, int num_args, const type* types,
739 ErrorHandler eh = {}, int next_arg_id = 0)
740 : base(format_str, eh, next_arg_id), num_args_(num_args), types_(types) {}
741
742 constexpr auto num_args() const -> int { return num_args_; }
743 constexpr auto arg_type(int id) const -> type { return types_[id]; }
744
746 int id = base::next_arg_id();
747 if (id >= num_args_) this->on_error("argument not found");
748 return id;
749 }
750
753 if (id >= num_args_) this->on_error("argument not found");
754 }
755 using base::check_arg_id;
756
758 if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id]))
759 this->on_error("width/precision is not integer");
760 }
761};
763
764template <typename Char, typename ErrorHandler>
765FMT_CONSTEXPR void
767 // Argument id is only checked at compile-time during parsing because
768 // formatting has its own validation.
770 using context = detail::compile_parse_context<Char, ErrorHandler>;
771 if (id >= static_cast<context*>(this)->num_args())
772 on_error("argument not found");
773 }
774}
775
776template <typename Char, typename ErrorHandler>
777FMT_CONSTEXPR void
780 using context = detail::compile_parse_context<Char, ErrorHandler>;
781 static_cast<context*>(this)->check_dynamic_spec(arg_id);
782 }
783}
784
785template <typename Context> class basic_format_arg;
786template <typename Context> class basic_format_args;
787template <typename Context> class dynamic_format_arg_store;
788
789// A formatter for objects of type T.
790template <typename T, typename Char = char, typename Enable = void>
791struct formatter {
792 // A deleted default constructor indicates a disabled formatter.
793 formatter() = delete;
794};
795
796// Specifies if T has an enabled formatter specialization. A type can be
797// formattable even if it doesn't have a formatter e.g. via a conversion.
798template <typename T, typename Context>
800 std::is_constructible<typename Context::template formatter_type<T>>;
801
802// Checks whether T is a container with contiguous storage.
803template <typename T> struct is_contiguous : std::false_type {};
804template <typename Char>
805struct is_contiguous<std::basic_string<Char>> : std::true_type {};
806
807class appender;
808
810
811template <typename Context, typename T>
812constexpr auto has_const_formatter_impl(T*)
813 -> decltype(typename Context::template formatter_type<T>().format(
814 std::declval<const T&>(), std::declval<Context&>()),
815 true) {
816 return true;
817}
818template <typename Context>
819constexpr auto has_const_formatter_impl(...) -> bool {
820 return false;
821}
822template <typename T, typename Context>
823constexpr auto has_const_formatter() -> bool {
824 return has_const_formatter_impl<Context>(static_cast<T*>(nullptr));
825}
826
827// Extracts a reference to the container from back_insert_iterator.
828template <typename Container>
829inline auto get_container(std::back_insert_iterator<Container> it)
830 -> Container& {
831 using base = std::back_insert_iterator<Container>;
832 struct accessor : base {
833 accessor(base b) : base(b) {}
834 using base::container;
835 };
836 return *accessor(it).container;
837}
838
839template <typename Char, typename InputIt, typename OutputIt>
840FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out)
841 -> OutputIt {
842 while (begin != end) *out++ = static_cast<Char>(*begin++);
843 return out;
844}
845
846template <typename Char, typename T, typename U,
849FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* {
850 if (is_constant_evaluated()) return copy_str<Char, T*, U*>(begin, end, out);
851 auto size = to_unsigned(end - begin);
852 memcpy(out, begin, size * sizeof(U));
853 return out + size;
854}
855
856/**
857 \rst
858 A contiguous memory buffer with an optional growing ability. It is an internal
859 class and shouldn't be used directly, only via `~fmt::basic_memory_buffer`.
860 \endrst
861 */
862template <typename T> class buffer {
863 private:
864 T* ptr_;
865 size_t size_;
866 size_t capacity_;
867
868 protected:
869 // Don't initialize ptr_ since it is not accessed to save a few cycles.
870 FMT_MSC_WARNING(suppress : 26495)
871 buffer(size_t sz) noexcept : size_(sz), capacity_(sz) {}
872
873 FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) noexcept
874 : ptr_(p), size_(sz), capacity_(cap) {}
875
877 buffer(buffer&&) = default;
878
879 /** Sets the buffer data and capacity. */
880 FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept {
881 ptr_ = buf_data;
882 capacity_ = buf_capacity;
883 }
884
885 /** Increases the buffer capacity to hold at least *capacity* elements. */
886 virtual FMT_CONSTEXPR20 void grow(size_t capacity) = 0;
887
888 public:
889 using value_type = T;
890 using const_reference = const T&;
891
892 buffer(const buffer&) = delete;
893 void operator=(const buffer&) = delete;
894
895 auto begin() noexcept -> T* { return ptr_; }
896 auto end() noexcept -> T* { return ptr_ + size_; }
897
898 auto begin() const noexcept -> const T* { return ptr_; }
899 auto end() const noexcept -> const T* { return ptr_ + size_; }
900
901 /** Returns the size of this buffer. */
902 constexpr auto size() const noexcept -> size_t { return size_; }
903
904 /** Returns the capacity of this buffer. */
905 constexpr auto capacity() const noexcept -> size_t { return capacity_; }
906
907 /** Returns a pointer to the buffer data. */
908 FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; }
909
910 /** Returns a pointer to the buffer data. */
911 FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; }
912
913 /** Clears this buffer. */
914 void clear() { size_ = 0; }
915
916 // Tries resizing the buffer to contain *count* elements. If T is a POD type
917 // the new elements may not be initialized.
920 size_ = count <= capacity_ ? count : capacity_;
921 }
922
923 // Tries increasing the buffer capacity to *new_capacity*. It can increase the
924 // capacity by a smaller amount than requested but guarantees there is space
925 // for at least one additional element either by increasing the capacity or by
926 // flushing the buffer if it is full.
927 FMT_CONSTEXPR20 void try_reserve(size_t new_capacity) {
928 if (new_capacity > capacity_) grow(new_capacity);
929 }
930
932 try_reserve(size_ + 1);
933 ptr_[size_++] = value;
934 }
935
936 /** Appends data to the end of the buffer. */
937 template <typename U> void append(const U* begin, const U* end);
938
939 template <typename Idx> FMT_CONSTEXPR auto operator[](Idx index) -> T& {
940 return ptr_[index];
941 }
942 template <typename Idx>
943 FMT_CONSTEXPR auto operator[](Idx index) const -> const T& {
944 return ptr_[index];
945 }
946};
947
949 explicit buffer_traits(size_t) {}
950 auto count() const -> size_t { return 0; }
951 auto limit(size_t size) -> size_t { return size; }
952};
953
955 private:
956 size_t count_ = 0;
957 size_t limit_;
958
959 public:
960 explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
961 auto count() const -> size_t { return count_; }
962 auto limit(size_t size) -> size_t {
963 size_t n = limit_ > count_ ? limit_ - count_ : 0;
964 count_ += size;
965 return size < n ? size : n;
966 }
967};
968
969// A buffer that writes to an output iterator when flushed.
970template <typename OutputIt, typename T, typename Traits = buffer_traits>
971class iterator_buffer final : public Traits, public buffer<T> {
972 private:
973 OutputIt out_;
974 enum { buffer_size = 256 };
975 T data_[buffer_size];
976
977 protected:
978 FMT_CONSTEXPR20 void grow(size_t) override {
979 if (this->size() == buffer_size) flush();
980 }
981
982 void flush() {
983 auto size = this->size();
984 this->clear();
985 out_ = copy_str<T>(data_, data_ + this->limit(size), out_);
986 }
987
988 public:
989 explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
990 : Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {}
992 : Traits(other), buffer<T>(data_, 0, buffer_size), out_(other.out_) {}
994
995 auto out() -> OutputIt {
996 flush();
997 return out_;
998 }
999 auto count() const -> size_t { return Traits::count() + this->size(); }
1000};
1001
1002template <typename T>
1004 : public fixed_buffer_traits,
1005 public buffer<T> {
1006 private:
1007 T* out_;
1008 enum { buffer_size = 256 };
1009 T data_[buffer_size];
1010
1011 protected:
1012 FMT_CONSTEXPR20 void grow(size_t) override {
1013 if (this->size() == this->capacity()) flush();
1014 }
1015
1016 void flush() {
1017 size_t n = this->limit(this->size());
1018 if (this->data() == out_) {
1019 out_ += n;
1020 this->set(data_, buffer_size);
1021 }
1022 this->clear();
1023 }
1024
1025 public:
1026 explicit iterator_buffer(T* out, size_t n = buffer_size)
1027 : fixed_buffer_traits(n), buffer<T>(out, 0, n), out_(out) {}
1029 : fixed_buffer_traits(other),
1030 buffer<T>(std::move(other)),
1031 out_(other.out_) {
1032 if (this->data() != out_) {
1033 this->set(data_, buffer_size);
1034 this->clear();
1035 }
1036 }
1038
1039 auto out() -> T* {
1040 flush();
1041 return out_;
1042 }
1043 auto count() const -> size_t {
1044 return fixed_buffer_traits::count() + this->size();
1045 }
1046};
1047
1048template <typename T> class iterator_buffer<T*, T> final : public buffer<T> {
1049 protected:
1050 FMT_CONSTEXPR20 void grow(size_t) override {}
1051
1052 public:
1053 explicit iterator_buffer(T* out, size_t = 0) : buffer<T>(out, 0, ~size_t()) {}
1054
1055 auto out() -> T* { return &*this->end(); }
1056};
1057
1058// A buffer that writes to a container with the contiguous storage.
1059template <typename Container>
1060class iterator_buffer<std::back_insert_iterator<Container>,
1061 enable_if_t<is_contiguous<Container>::value,
1062 typename Container::value_type>>
1063 final : public buffer<typename Container::value_type> {
1064 private:
1065 Container& container_;
1066
1067 protected:
1068 FMT_CONSTEXPR20 void grow(size_t capacity) override {
1069 container_.resize(capacity);
1070 this->set(&container_[0], capacity);
1071 }
1072
1073 public:
1074 explicit iterator_buffer(Container& c)
1075 : buffer<typename Container::value_type>(c.size()), container_(c) {}
1076 explicit iterator_buffer(std::back_insert_iterator<Container> out, size_t = 0)
1078
1079 auto out() -> std::back_insert_iterator<Container> {
1080 return std::back_inserter(container_);
1081 }
1082};
1083
1084// A buffer that counts the number of code units written discarding the output.
1085template <typename T = char> class counting_buffer final : public buffer<T> {
1086 private:
1087 enum { buffer_size = 256 };
1088 T data_[buffer_size];
1089 size_t count_ = 0;
1090
1091 protected:
1092 FMT_CONSTEXPR20 void grow(size_t) override {
1093 if (this->size() != buffer_size) return;
1094 count_ += this->size();
1095 this->clear();
1096 }
1097
1098 public:
1099 counting_buffer() : buffer<T>(data_, 0, buffer_size) {}
1100
1101 auto count() -> size_t { return count_ + this->size(); }
1102};
1103
1104template <typename T>
1106 std::back_insert_iterator<buffer<T>>>;
1107
1108// Maps an output iterator to a buffer.
1109template <typename T, typename OutputIt>
1111 return iterator_buffer<OutputIt, T>(out);
1112}
1113
1114template <typename Buffer>
1115auto get_iterator(Buffer& buf) -> decltype(buf.out()) {
1116 return buf.out();
1117}
1118template <typename T> auto get_iterator(buffer<T>& buf) -> buffer_appender<T> {
1119 return buffer_appender<T>(buf);
1120}
1121
1122template <typename T, typename Char = char, typename Enable = void>
1125};
1126
1127// Specifies if T has an enabled fallback_formatter specialization.
1128template <typename T, typename Char>
1130#ifdef FMT_DEPRECATED_OSTREAM
1131 std::is_constructible<fallback_formatter<T, Char>>;
1132#else
1133 std::false_type;
1134#endif
1135
1136struct view {};
1137
1138template <typename Char, typename T> struct named_arg : view {
1139 const Char* name;
1140 const T& value;
1141 named_arg(const Char* n, const T& v) : name(n), value(v) {}
1142};
1143
1144template <typename Char> struct named_arg_info {
1145 const Char* name;
1146 int id;
1147};
1148
1149template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
1150struct arg_data {
1151 // args_[0].named_args points to named_args_ to avoid bloating format_args.
1152 // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
1153 T args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
1155
1156 template <typename... U>
1157 arg_data(const U&... init) : args_{T(named_args_, NUM_NAMED_ARGS), init...} {}
1158 arg_data(const arg_data& other) = delete;
1159 auto args() const -> const T* { return args_ + 1; }
1161};
1162
1163template <typename T, typename Char, size_t NUM_ARGS>
1164struct arg_data<T, Char, NUM_ARGS, 0> {
1165 // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
1166 T args_[NUM_ARGS != 0 ? NUM_ARGS : +1];
1167
1168 template <typename... U>
1169 FMT_CONSTEXPR FMT_INLINE arg_data(const U&... init) : args_{init...} {}
1170 FMT_CONSTEXPR FMT_INLINE auto args() const -> const T* { return args_; }
1171 FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t {
1172 return nullptr;
1173 }
1174};
1175
1176template <typename Char>
1177inline void init_named_args(named_arg_info<Char>*, int, int) {}
1178
1179template <typename T> struct is_named_arg : std::false_type {};
1180template <typename T> struct is_statically_named_arg : std::false_type {};
1181
1182template <typename T, typename Char>
1183struct is_named_arg<named_arg<Char, T>> : std::true_type {};
1184
1185template <typename Char, typename T, typename... Tail,
1187void init_named_args(named_arg_info<Char>* named_args, int arg_count,
1188 int named_arg_count, const T&, const Tail&... args) {
1189 init_named_args(named_args, arg_count + 1, named_arg_count, args...);
1190}
1191
1192template <typename Char, typename T, typename... Tail,
1194void init_named_args(named_arg_info<Char>* named_args, int arg_count,
1195 int named_arg_count, const T& arg, const Tail&... args) {
1196 named_args[named_arg_count++] = {arg.name, arg_count};
1197 init_named_args(named_args, arg_count + 1, named_arg_count, args...);
1198}
1199
1200template <typename... Args>
1201FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int,
1202 const Args&...) {}
1203
1204template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
1205template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
1206 return (B1 ? 1 : 0) + count<B2, Tail...>();
1207}
1208
1209template <typename... Args> constexpr auto count_named_args() -> size_t {
1210 return count<is_named_arg<Args>::value...>();
1211}
1212
1213template <typename... Args>
1214constexpr auto count_statically_named_args() -> size_t {
1215 return count<is_statically_named_arg<Args>::value...>();
1216}
1217
1222
1223template <typename Char> struct string_value {
1224 const Char* data;
1225 size_t size;
1226};
1227
1228template <typename Char> struct named_arg_value {
1230 size_t size;
1231};
1232
1233template <typename Context> struct custom_value {
1234 using parse_context = typename Context::parse_context_type;
1235 void* value;
1236 void (*format)(void* arg, parse_context& parse_ctx, Context& ctx);
1237};
1238
1239// A formatting argument value.
1240template <typename Context> class value {
1241 public:
1242 using char_type = typename Context::char_type;
1243
1244 union {
1247 unsigned uint_value;
1249 unsigned long long ulong_long_value;
1257 const void* pointer;
1261 };
1262
1263 constexpr FMT_INLINE value() : no_value() {}
1264 constexpr FMT_INLINE value(int val) : int_value(val) {}
1265 constexpr FMT_INLINE value(unsigned val) : uint_value(val) {}
1266 constexpr FMT_INLINE value(long long val) : long_long_value(val) {}
1267 constexpr FMT_INLINE value(unsigned long long val) : ulong_long_value(val) {}
1270 constexpr FMT_INLINE value(float val) : float_value(val) {}
1271 constexpr FMT_INLINE value(double val) : double_value(val) {}
1272 FMT_INLINE value(long double val) : long_double_value(val) {}
1273 constexpr FMT_INLINE value(bool val) : bool_value(val) {}
1274 constexpr FMT_INLINE value(char_type val) : char_value(val) {}
1276 string.data = val;
1277 if (is_constant_evaluated()) string.size = {};
1278 }
1280 string.data = val.data();
1281 string.size = val.size();
1282 }
1283 FMT_INLINE value(const void* val) : pointer(val) {}
1285 : named_args{args, size} {}
1286
1287 template <typename T> FMT_CONSTEXPR FMT_INLINE value(T& val) {
1288 using value_type = remove_cvref_t<T>;
1289 custom.value = const_cast<value_type*>(&val);
1290 // Get the formatter type through the context to allow different contexts
1291 // have different extension points, e.g. `formatter<T>` for `format` and
1292 // `printf_formatter<T>` for `printf`.
1293 custom.format = format_custom_arg<
1294 value_type,
1296 typename Context::template formatter_type<value_type>,
1298 }
1303
1304 private:
1305 // Formats an argument of a custom type, such as a user-defined class.
1306 template <typename T, typename Formatter>
1307 static void format_custom_arg(void* arg,
1308 typename Context::parse_context_type& parse_ctx,
1309 Context& ctx) {
1310 auto f = Formatter();
1311 parse_ctx.advance_to(f.parse(parse_ctx));
1312 using qualified_type =
1314 ctx.advance_to(f.format(*static_cast<qualified_type*>(arg), ctx));
1315 }
1316};
1317
1318template <typename Context, typename T>
1320
1321// To minimize the number of types we need to deal with, long is translated
1322// either to int or to long long depending on its size.
1323enum { long_short = sizeof(long) == sizeof(int) };
1326
1327#ifdef __cpp_lib_byte
1328inline auto format_as(std::byte b) -> unsigned char {
1329 return static_cast<unsigned char>(b);
1330}
1331#endif
1332
1333template <typename T> struct has_format_as {
1334 template <typename U, typename V = decltype(format_as(U())),
1335 FMT_ENABLE_IF(std::is_enum<U>::value&& std::is_integral<V>::value)>
1336 static auto check(U*) -> std::true_type;
1337 static auto check(...) -> std::false_type;
1338
1339 enum { value = decltype(check(static_cast<T*>(nullptr)))::value };
1340};
1341
1342// Maps formatting arguments to core types.
1343// arg_mapper reports errors by returning unformattable instead of using
1344// static_assert because it's used in the is_formattable trait.
1345template <typename Context> struct arg_mapper {
1346 using char_type = typename Context::char_type;
1347
1348 FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int { return val; }
1349 FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned {
1350 return val;
1351 }
1352 FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int { return val; }
1353 FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned {
1354 return val;
1355 }
1356 FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int { return val; }
1357 FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned { return val; }
1358 FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type { return val; }
1359 FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type {
1360 return val;
1361 }
1362 FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long { return val; }
1363 FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val)
1364 -> unsigned long long {
1365 return val;
1366 }
1368 return val;
1369 }
1371 return val;
1372 }
1373 FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool { return val; }
1374
1375 template <typename T, FMT_ENABLE_IF(std::is_same<T, char>::value ||
1376 std::is_same<T, char_type>::value)>
1378 return val;
1379 }
1380 template <typename T, enable_if_t<(std::is_same<T, wchar_t>::value ||
1381#ifdef __cpp_char8_t
1382 std::is_same<T, char8_t>::value ||
1383#endif
1384 std::is_same<T, char16_t>::value ||
1385 std::is_same<T, char32_t>::value) &&
1386 !std::is_same<T, char_type>::value,
1387 int> = 0>
1389 return {};
1390 }
1391
1392 FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float { return val; }
1393 FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double { return val; }
1394 FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double {
1395 return val;
1396 }
1397
1399 return val;
1400 }
1401 FMT_CONSTEXPR FMT_INLINE auto map(const char_type* val) -> const char_type* {
1402 return val;
1403 }
1404 template <typename T,
1405 FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value &&
1406 std::is_same<char_type, char_t<T>>::value)>
1407 FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1409 return to_string_view(val);
1410 }
1411 template <typename T,
1412 FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value &&
1413 !std::is_same<char_type, char_t<T>>::value)>
1415 return {};
1416 }
1417 template <typename T,
1419 std::is_convertible<T, basic_string_view<char_type>>::value &&
1422 FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1424 return basic_string_view<char_type>(val);
1425 }
1426 template <typename T,
1428 std::is_convertible<T, std_string_view<char_type>>::value &&
1429 !std::is_convertible<T, basic_string_view<char_type>>::value &&
1432 FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1434 return std_string_view<char_type>(val);
1435 }
1436
1437 FMT_CONSTEXPR FMT_INLINE auto map(void* val) -> const void* { return val; }
1438 FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* {
1439 return val;
1440 }
1441 FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void* {
1442 return val;
1443 }
1444
1445 // We use SFINAE instead of a const T* parameter to avoid conflicting with
1446 // the C array overload.
1447 template <
1448 typename T,
1450 std::is_pointer<T>::value || std::is_member_pointer<T>::value ||
1451 std::is_function<typename std::remove_pointer<T>::type>::value ||
1452 (std::is_convertible<const T&, const void*>::value &&
1453 !std::is_convertible<const T&, const char_type*>::value &&
1456 return {};
1457 }
1458
1459 template <typename T, std::size_t N,
1460 FMT_ENABLE_IF(!std::is_same<T, wchar_t>::value)>
1461 FMT_CONSTEXPR FMT_INLINE auto map(const T (&values)[N]) -> const T (&)[N] {
1462 return values;
1463 }
1464
1465 template <typename T,
1467 std::is_enum<T>::value&& std::is_convertible<T, int>::value &&
1471 -> decltype(std::declval<arg_mapper>().map(
1472 static_cast<underlying_t<T>>(val))) {
1473 return map(static_cast<underlying_t<T>>(val));
1474 }
1475
1476 template <typename T, FMT_ENABLE_IF(has_format_as<T>::value &&
1477 !has_formatter<T, Context>::value)>
1478 FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1479 -> decltype(std::declval<arg_mapper>().map(format_as(T()))) {
1480 return map(format_as(val));
1481 }
1482
1483 template <typename T, typename U = remove_cvref_t<T>>
1485 : bool_constant<has_const_formatter<U, Context>() ||
1486 !std::is_const<remove_reference_t<T>>::value ||
1487 has_fallback_formatter<U, char_type>::value> {};
1488
1489#if (FMT_MSC_VERSION != 0 && FMT_MSC_VERSION < 1910) || \
1490 FMT_ICC_VERSION != 0 || defined(__NVCC__)
1491 // Workaround a bug in MSVC and Intel (Issue 2746).
1492 template <typename T> FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
1493 return val;
1494 }
1495#else
1496 template <typename T, FMT_ENABLE_IF(formattable<T>::value)>
1497 FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
1498 return val;
1499 }
1500 template <typename T, FMT_ENABLE_IF(!formattable<T>::value)>
1502 return {};
1503 }
1504#endif
1505
1506 template <typename T, typename U = remove_cvref_t<T>,
1507 FMT_ENABLE_IF(!is_string<U>::value && !is_char<U>::value &&
1508 !std::is_array<U>::value &&
1509 !std::is_pointer<U>::value &&
1510 !has_format_as<U>::value &&
1511 (has_formatter<U, Context>::value ||
1512 has_fallback_formatter<U, char_type>::value))>
1514 -> decltype(this->do_map(std::forward<T>(val))) {
1515 return do_map(std::forward<T>(val));
1516 }
1517
1518 template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
1520 -> decltype(std::declval<arg_mapper>().map(named_arg.value)) {
1521 return map(named_arg.value);
1522 }
1523
1524 auto map(...) -> unformattable { return {}; }
1525};
1526
1527// A type constant after applying arg_mapper<Context>.
1528template <typename T, typename Context>
1530 type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())),
1531 typename Context::char_type>;
1532
1533enum { packed_arg_bits = 4 };
1534// Maximum number of arguments with packed types.
1536enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };
1537enum : unsigned long long { has_named_args_bit = 1ULL << 62 };
1538
1540
1541// An output iterator that appends to a buffer.
1542// It is used to reduce symbol sizes for the common case.
1543class appender : public std::back_insert_iterator<detail::buffer<char>> {
1544 using base = std::back_insert_iterator<detail::buffer<char>>;
1545
1546 template <typename T>
1547 friend auto get_buffer(appender out) -> detail::buffer<char>& {
1548 return detail::get_container(out);
1549 }
1550
1551 public:
1552 using std::back_insert_iterator<detail::buffer<char>>::back_insert_iterator;
1553 appender(base it) noexcept : base(it) {}
1555
1556 auto operator++() noexcept -> appender& { return *this; }
1557 auto operator++(int) noexcept -> appender { return *this; }
1558};
1559
1560// A formatting argument. It is a trivially copyable/constructible type to
1561// allow storage in basic_memory_buffer.
1562template <typename Context> class basic_format_arg {
1563 private:
1564 detail::value<Context> value_;
1565 detail::type type_;
1566
1567 template <typename ContextType, typename T>
1570
1571 template <typename Visitor, typename Ctx>
1572 friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis,
1574 -> decltype(vis(0));
1575
1576 friend class basic_format_args<Context>;
1577 friend class dynamic_format_arg_store<Context>;
1578
1579 using char_type = typename Context::char_type;
1580
1581 template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
1582 friend struct detail::arg_data;
1583
1584 basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
1585 : value_(args, size) {}
1586
1587 public:
1588 class handle {
1589 public:
1590 explicit handle(detail::custom_value<Context> custom) : custom_(custom) {}
1591
1592 void format(typename Context::parse_context_type& parse_ctx,
1593 Context& ctx) const {
1594 custom_.format(custom_.value, parse_ctx, ctx);
1595 }
1596
1597 private:
1598 detail::custom_value<Context> custom_;
1599 };
1600
1601 constexpr basic_format_arg() : type_(detail::type::none_type) {}
1602
1603 constexpr explicit operator bool() const noexcept {
1604 return type_ != detail::type::none_type;
1605 }
1606
1607 auto type() const -> detail::type { return type_; }
1608
1609 auto is_integral() const -> bool { return detail::is_integral_type(type_); }
1610 auto is_arithmetic() const -> bool {
1611 return detail::is_arithmetic_type(type_);
1612 }
1613};
1614
1615/**
1616 \rst
1617 Visits an argument dispatching to the appropriate visit method based on
1618 the argument type. For example, if the argument type is ``double`` then
1619 ``vis(value)`` will be called with the value of type ``double``.
1620 \endrst
1621 */
1622template <typename Visitor, typename Context>
1624 Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) {
1625 switch (arg.type_) {
1626 case detail::type::none_type:
1627 break;
1628 case detail::type::int_type:
1629 return vis(arg.value_.int_value);
1630 case detail::type::uint_type:
1631 return vis(arg.value_.uint_value);
1632 case detail::type::long_long_type:
1633 return vis(arg.value_.long_long_value);
1634 case detail::type::ulong_long_type:
1635 return vis(arg.value_.ulong_long_value);
1636 case detail::type::int128_type:
1637 return vis(detail::convert_for_visit(arg.value_.int128_value));
1638 case detail::type::uint128_type:
1639 return vis(detail::convert_for_visit(arg.value_.uint128_value));
1640 case detail::type::bool_type:
1641 return vis(arg.value_.bool_value);
1642 case detail::type::char_type:
1643 return vis(arg.value_.char_value);
1644 case detail::type::float_type:
1645 return vis(arg.value_.float_value);
1646 case detail::type::double_type:
1647 return vis(arg.value_.double_value);
1648 case detail::type::long_double_type:
1649 return vis(arg.value_.long_double_value);
1650 case detail::type::cstring_type:
1651 return vis(arg.value_.string.data);
1652 case detail::type::string_type:
1654 return vis(sv(arg.value_.string.data, arg.value_.string.size));
1655 case detail::type::pointer_type:
1656 return vis(arg.value_.pointer);
1657 case detail::type::custom_type:
1658 return vis(typename basic_format_arg<Context>::handle(arg.value_.custom));
1659 }
1660 return vis(monostate());
1661}
1662
1664
1665template <typename Char, typename InputIt>
1666auto copy_str(InputIt begin, InputIt end, appender out) -> appender {
1667 get_container(out).append(begin, end);
1668 return out;
1669}
1670
1671template <typename Char, typename R, typename OutputIt>
1672FMT_CONSTEXPR auto copy_str(R&& rng, OutputIt out) -> OutputIt {
1673 return detail::copy_str<Char>(rng.begin(), rng.end(), out);
1674}
1675
1676#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
1677// A workaround for gcc 4.8 to make void_t work in a SFINAE context.
1678template <typename... Ts> struct void_t_impl { using type = void; };
1679template <typename... Ts>
1680using void_t = typename detail::void_t_impl<Ts...>::type;
1681#else
1682template <typename...> using void_t = void;
1683#endif
1684
1685template <typename It, typename T, typename Enable = void>
1686struct is_output_iterator : std::false_type {};
1687
1688template <typename It, typename T>
1690 It, T,
1692 decltype(*std::declval<It>() = std::declval<T>())>>
1693 : std::true_type {};
1694
1695template <typename OutputIt>
1696struct is_back_insert_iterator : std::false_type {};
1697template <typename Container>
1699 : std::true_type {};
1700
1701template <typename OutputIt>
1702struct is_contiguous_back_insert_iterator : std::false_type {};
1703template <typename Container>
1704struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>>
1705 : is_contiguous<Container> {};
1706template <>
1708
1709// A type-erased reference to an std::locale to avoid a heavy <locale> include.
1711 private:
1712 const void* locale_; // A type-erased pointer to std::locale.
1713
1714 public:
1715 constexpr locale_ref() : locale_(nullptr) {}
1716 template <typename Locale> explicit locale_ref(const Locale& loc);
1717
1718 explicit operator bool() const noexcept { return locale_ != nullptr; }
1719
1720 template <typename Locale> auto get() const -> Locale;
1721};
1722
1723template <typename> constexpr auto encode_types() -> unsigned long long {
1724 return 0;
1725}
1726
1727template <typename Context, typename Arg, typename... Args>
1728constexpr auto encode_types() -> unsigned long long {
1729 return static_cast<unsigned>(mapped_type_constant<Arg, Context>::value) |
1730 (encode_types<Context, Args...>() << packed_arg_bits);
1731}
1732
1733template <typename Context, typename T>
1735 const auto& arg = arg_mapper<Context>().map(FMT_FORWARD(val));
1736
1737 constexpr bool formattable_char =
1738 !std::is_same<decltype(arg), const unformattable_char&>::value;
1739 static_assert(formattable_char, "Mixing character types is disallowed.");
1740
1741 constexpr bool formattable_const =
1742 !std::is_same<decltype(arg), const unformattable_const&>::value;
1743 static_assert(formattable_const, "Cannot format a const argument.");
1744
1745 // Formatting of arbitrary pointers is disallowed. If you want to output
1746 // a pointer cast it to "void *" or "const void *". In particular, this
1747 // forbids formatting of "[const] volatile char *" which is printed as bool
1748 // by iostreams.
1749 constexpr bool formattable_pointer =
1750 !std::is_same<decltype(arg), const unformattable_pointer&>::value;
1751 static_assert(formattable_pointer,
1752 "Formatting of non-void pointers is disallowed.");
1753
1754 constexpr bool formattable =
1755 !std::is_same<decltype(arg), const unformattable&>::value;
1756 static_assert(
1757 formattable,
1758 "Cannot format an argument. To make type T formattable provide a "
1759 "formatter<T> specialization: https://fmt.dev/latest/api.html#udt");
1760 return {arg};
1761}
1762
1763template <typename Context, typename T>
1767 arg.value_ = make_value<Context>(value);
1768 return arg;
1769}
1770
1771// The type template parameter is there to avoid an ODR violation when using
1772// a fallback formatter in one translation unit and an implicit conversion in
1773// another (not recommended).
1774template <bool IS_PACKED, typename Context, type, typename T,
1775 FMT_ENABLE_IF(IS_PACKED)>
1777 return make_value<Context>(val);
1778}
1779
1780template <bool IS_PACKED, typename Context, type, typename T,
1781 FMT_ENABLE_IF(!IS_PACKED)>
1783 return make_arg<Context>(value);
1784}
1786
1787// Formatting context.
1788template <typename OutputIt, typename Char> class basic_format_context {
1789 public:
1790 /** The character type for the output. */
1791 using char_type = Char;
1792
1793 private:
1794 OutputIt out_;
1796 detail::locale_ref loc_;
1797
1798 public:
1799 using iterator = OutputIt;
1802 template <typename T> using formatter_type = formatter<T, char_type>;
1803
1806 void operator=(const basic_format_context&) = delete;
1807 /**
1808 Constructs a ``basic_format_context`` object. References to the arguments are
1809 stored in the object so make sure they have appropriate lifetimes.
1810 */
1812 OutputIt out, basic_format_args<basic_format_context> ctx_args,
1813 detail::locale_ref loc = detail::locale_ref())
1814 : out_(out), args_(ctx_args), loc_(loc) {}
1815
1816 constexpr auto arg(int id) const -> format_arg { return args_.get(id); }
1818 return args_.get(name);
1819 }
1821 return args_.get_id(name);
1822 }
1824 return args_;
1825 }
1826
1827 FMT_CONSTEXPR auto error_handler() -> detail::error_handler { return {}; }
1828 void on_error(const char* message) { error_handler().on_error(message); }
1829
1830 // Returns an iterator to the beginning of the output range.
1831 FMT_CONSTEXPR auto out() -> iterator { return out_; }
1832
1833 // Advances the begin iterator to ``it``.
1835 if (!detail::is_back_insert_iterator<iterator>()) out_ = it;
1836 }
1837
1838 FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; }
1839};
1840
1841template <typename Char>
1845
1846// Workaround an alias issue: https://stackoverflow.com/q/62767544/471164.
1847#define FMT_BUFFER_CONTEXT(Char) \
1848 basic_format_context<detail::buffer_appender<Char>, Char>
1849
1850template <typename T, typename Char = char>
1852 !std::is_base_of<detail::unformattable,
1853 decltype(detail::arg_mapper<buffer_context<Char>>().map(
1854 std::declval<T>()))>::value &&
1855 !detail::has_fallback_formatter<T, Char>::value>;
1856
1857/**
1858 \rst
1859 An array of references to arguments. It can be implicitly converted into
1860 `~fmt::basic_format_args` for passing into type-erased formatting functions
1861 such as `~fmt::vformat`.
1862 \endrst
1863 */
1864template <typename Context, typename... Args>
1867 // Workaround a GCC template argument substitution bug.
1869#endif
1870{
1871 private:
1872 static const size_t num_args = sizeof...(Args);
1873 static const size_t num_named_args = detail::count_named_args<Args...>();
1874 static const bool is_packed = num_args <= detail::max_packed_args;
1875
1878
1879 detail::arg_data<value_type, typename Context::char_type, num_args,
1880 num_named_args>
1881 data_;
1882
1883 friend class basic_format_args<Context>;
1884
1885 static constexpr unsigned long long desc =
1886 (is_packed ? detail::encode_types<Context, Args...>()
1887 : detail::is_unpacked_bit | num_args) |
1888 (num_named_args != 0
1889 ? static_cast<unsigned long long>(detail::has_named_args_bit)
1890 : 0);
1891
1892 public:
1893 template <typename... T>
1895 :
1897 basic_format_args<Context>(*this),
1898#endif
1899 data_{detail::make_arg<
1900 is_packed, Context,
1902 FMT_FORWARD(args))...} {
1903 detail::init_named_args(data_.named_args(), 0, 0, args...);
1904 }
1905};
1906
1907/**
1908 \rst
1909 Constructs a `~fmt::format_arg_store` object that contains references to
1910 arguments and can be implicitly converted to `~fmt::format_args`. `Context`
1911 can be omitted in which case it defaults to `~fmt::context`.
1912 See `~fmt::arg` for lifetime considerations.
1913 \endrst
1914 */
1915template <typename Context = format_context, typename... Args>
1916constexpr auto make_format_args(Args&&... args)
1918 return {FMT_FORWARD(args)...};
1919}
1920
1921/**
1922 \rst
1923 Returns a named argument to be used in a formatting function.
1924 It should only be used in a call to a formatting function or
1925 `dynamic_format_arg_store::push_back`.
1926
1927 **Example**::
1928
1929 fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23));
1930 \endrst
1931 */
1932template <typename Char, typename T>
1933inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
1934 static_assert(!detail::is_named_arg<T>(), "nested named arguments");
1935 return {name, arg};
1936}
1937
1938/**
1939 \rst
1940 A view of a collection of formatting arguments. To avoid lifetime issues it
1941 should only be used as a parameter type in type-erased functions such as
1942 ``vformat``::
1943
1944 void vlog(string_view format_str, format_args args); // OK
1945 format_args args = make_format_args(42); // Error: dangling reference
1946 \endrst
1947 */
1948template <typename Context> class basic_format_args {
1949 public:
1950 using size_type = int;
1952
1953 private:
1954 // A descriptor that contains information about formatting arguments.
1955 // If the number of arguments is less or equal to max_packed_args then
1956 // argument types are passed in the descriptor. This reduces binary code size
1957 // per formatting function call.
1958 unsigned long long desc_;
1959 union {
1960 // If is_packed() returns true then argument values are stored in values_;
1961 // otherwise they are stored in args_. This is done to improve cache
1962 // locality and reduce compiled code size since storing larger objects
1963 // may require more code (at least on x86-64) even if the same amount of
1964 // data is actually copied to stack. It saves ~10% on the bloat test.
1965 const detail::value<Context>* values_;
1967 };
1968
1969 constexpr auto is_packed() const -> bool {
1970 return (desc_ & detail::is_unpacked_bit) == 0;
1971 }
1972 auto has_named_args() const -> bool {
1973 return (desc_ & detail::has_named_args_bit) != 0;
1974 }
1975
1976 FMT_CONSTEXPR auto type(int index) const -> detail::type {
1977 int shift = index * detail::packed_arg_bits;
1978 unsigned int mask = (1 << detail::packed_arg_bits) - 1;
1979 return static_cast<detail::type>((desc_ >> shift) & mask);
1980 }
1981
1982 constexpr FMT_INLINE basic_format_args(unsigned long long desc,
1983 const detail::value<Context>* values)
1984 : desc_(desc), values_(values) {}
1985 constexpr basic_format_args(unsigned long long desc, const format_arg* args)
1986 : desc_(desc), args_(args) {}
1987
1988 public:
1989 constexpr basic_format_args() : desc_(0), args_(nullptr) {}
1990
1991 /**
1992 \rst
1993 Constructs a `basic_format_args` object from `~fmt::format_arg_store`.
1994 \endrst
1995 */
1996 template <typename... Args>
1999 : basic_format_args(format_arg_store<Context, Args...>::desc,
2000 store.data_.args()) {}
2001
2002 /**
2003 \rst
2004 Constructs a `basic_format_args` object from
2005 `~fmt::dynamic_format_arg_store`.
2006 \endrst
2007 */
2010 : basic_format_args(store.get_types(), store.data()) {}
2011
2012 /**
2013 \rst
2014 Constructs a `basic_format_args` object from a dynamic set of arguments.
2015 \endrst
2016 */
2017 constexpr basic_format_args(const format_arg* args, int count)
2019 args) {}
2020
2021 /** Returns the argument with the specified id. */
2022 FMT_CONSTEXPR auto get(int id) const -> format_arg {
2024 if (!is_packed()) {
2025 if (id < max_size()) arg = args_[id];
2026 return arg;
2027 }
2028 if (id >= detail::max_packed_args) return arg;
2029 arg.type_ = type(id);
2030 if (arg.type_ == detail::type::none_type) return arg;
2031 arg.value_ = values_[id];
2032 return arg;
2033 }
2034
2035 template <typename Char>
2037 int id = get_id(name);
2038 return id >= 0 ? get(id) : format_arg();
2039 }
2040
2041 template <typename Char>
2043 if (!has_named_args()) return -1;
2044 const auto& named_args =
2045 (is_packed() ? values_[-1] : args_[-1].value_).named_args;
2046 for (size_t i = 0; i < named_args.size; ++i) {
2047 if (named_args.data[i].name == name) return named_args.data[i].id;
2048 }
2049 return -1;
2050 }
2051
2052 auto max_size() const -> int {
2053 unsigned long long max_packed = detail::max_packed_args;
2054 return static_cast<int>(is_packed() ? max_packed
2055 : desc_ & ~detail::is_unpacked_bit);
2056 }
2057};
2058
2059/** An alias to ``basic_format_args<format_context>``. */
2060// A separate type would result in shorter symbols but break ABI compatibility
2061// between clang and gcc on ARM (#1919).
2063
2064// We cannot use enum classes as bit fields because of a gcc bug, so we put them
2065// in namespaces instead (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414).
2066// Additionally, if an underlying type is specified, older gcc incorrectly warns
2067// that the type is too small. Both bugs are fixed in gcc 9.3.
2068#if FMT_GCC_VERSION && FMT_GCC_VERSION < 903
2069# define FMT_ENUM_UNDERLYING_TYPE(type)
2070#else
2071# define FMT_ENUM_UNDERLYING_TYPE(type) : type
2072#endif
2073namespace align {
2074enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char){none, left, right, center,
2075 numeric};
2076}
2078namespace sign {
2079enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char){none, minus, plus, space};
2080}
2082
2084
2085// Workaround an array initialization issue in gcc 4.8.
2086template <typename Char> struct fill_t {
2087 private:
2088 enum { max_size = 4 };
2089 Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)};
2090 unsigned char size_ = 1;
2091
2092 public:
2094 auto size = s.size();
2095 if (size > max_size) return throw_format_error("invalid fill");
2096 for (size_t i = 0; i < size; ++i) data_[i] = s[i];
2097 size_ = static_cast<unsigned char>(size);
2098 }
2099
2100 constexpr auto size() const -> size_t { return size_; }
2101 constexpr auto data() const -> const Char* { return data_; }
2102
2103 FMT_CONSTEXPR auto operator[](size_t index) -> Char& { return data_[index]; }
2104 FMT_CONSTEXPR auto operator[](size_t index) const -> const Char& {
2105 return data_[index];
2106 }
2107};
2109
2110enum class presentation_type : unsigned char {
2111 none,
2112 // Integer types should go first,
2113 dec, // 'd'
2114 oct, // 'o'
2115 hex_lower, // 'x'
2116 hex_upper, // 'X'
2117 bin_lower, // 'b'
2118 bin_upper, // 'B'
2119 hexfloat_lower, // 'a'
2120 hexfloat_upper, // 'A'
2121 exp_lower, // 'e'
2122 exp_upper, // 'E'
2123 fixed_lower, // 'f'
2124 fixed_upper, // 'F'
2125 general_lower, // 'g'
2126 general_upper, // 'G'
2127 chr, // 'c'
2128 string, // 's'
2129 pointer, // 'p'
2130 debug // '?'
2131};
2132
2133// Format specifiers for built-in and string types.
2134template <typename Char> struct basic_format_specs {
2140 bool alt : 1; // Alternate form ('#').
2141 bool localized : 1;
2142 detail::fill_t<Char> fill;
2143
2145 : width(0),
2146 precision(-1),
2148 align(align::none),
2149 sign(sign::none),
2150 alt(false),
2151 localized(false) {}
2152};
2153
2155
2157
2158enum class arg_id_kind { none, index, name };
2159
2160// An argument reference.
2161template <typename Char> struct arg_ref {
2163
2165 : kind(arg_id_kind::index), val(index) {}
2167 : kind(arg_id_kind::name), val(name) {}
2168
2169 FMT_CONSTEXPR auto operator=(int idx) -> arg_ref& {
2170 kind = arg_id_kind::index;
2171 val.index = idx;
2172 return *this;
2173 }
2174
2176 union value {
2177 FMT_CONSTEXPR value(int id = 0) : index{id} {}
2179
2182 } val;
2183};
2184
2185// Format specifiers with width and precision resolved at formatting rather
2186// than parsing time to allow re-using the same parsed specifiers with
2187// different sets of arguments (precompilation of format strings).
2188template <typename Char>
2192};
2193
2194struct auto_id {};
2195
2196// A format specifier handler that sets fields in basic_format_specs.
2197template <typename Char> class specs_setter {
2198 protected:
2200
2201 public:
2203 : specs_(specs) {}
2204
2206 : specs_(other.specs_) {}
2207
2210 specs_.fill = fill;
2211 }
2212 FMT_CONSTEXPR void on_sign(sign_t s) { specs_.sign = s; }
2213 FMT_CONSTEXPR void on_hash() { specs_.alt = true; }
2214 FMT_CONSTEXPR void on_localized() { specs_.localized = true; }
2215
2217 if (specs_.align == align::none) specs_.align = align::numeric;
2218 specs_.fill[0] = Char('0');
2219 }
2220
2221 FMT_CONSTEXPR void on_width(int width) { specs_.width = width; }
2222 FMT_CONSTEXPR void on_precision(int precision) {
2223 specs_.precision = precision;
2224 }
2226
2228};
2229
2230// Format spec handler that saves references to arguments representing dynamic
2231// width and precision to be resolved at formatting time.
2232template <typename ParseContext>
2234 : public specs_setter<typename ParseContext::char_type> {
2235 public:
2236 using char_type = typename ParseContext::char_type;
2237
2239 ParseContext& ctx)
2240 : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}
2241
2243 : specs_setter<char_type>(other),
2244 specs_(other.specs_),
2245 context_(other.context_) {}
2246
2247 template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
2248 specs_.width_ref = make_arg_ref(arg_id);
2249 }
2250
2251 template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
2252 specs_.precision_ref = make_arg_ref(arg_id);
2253 }
2254
2255 FMT_CONSTEXPR void on_error(const char* message) {
2256 context_.on_error(message);
2257 }
2258
2259 private:
2261 ParseContext& context_;
2262
2263 using arg_ref_type = arg_ref<char_type>;
2264
2265 FMT_CONSTEXPR auto make_arg_ref(int arg_id) -> arg_ref_type {
2266 context_.check_arg_id(arg_id);
2267 context_.check_dynamic_spec(arg_id);
2268 return arg_ref_type(arg_id);
2269 }
2270
2271 FMT_CONSTEXPR auto make_arg_ref(auto_id) -> arg_ref_type {
2272 int arg_id = context_.next_arg_id();
2273 context_.check_dynamic_spec(arg_id);
2274 return arg_ref_type(arg_id);
2275 }
2276
2277 FMT_CONSTEXPR auto make_arg_ref(basic_string_view<char_type> arg_id)
2278 -> arg_ref_type {
2279 context_.check_arg_id(arg_id);
2281 context_.begin(), to_unsigned(context_.end() - context_.begin()));
2282 return arg_ref_type(arg_id);
2283 }
2284};
2285
2286template <typename Char> constexpr bool is_ascii_letter(Char c) {
2287 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
2288}
2289
2290// Converts a character to ASCII. Returns a number > 127 on conversion failure.
2291template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
2292constexpr auto to_ascii(Char c) -> Char {
2293 return c;
2294}
2295template <typename Char, FMT_ENABLE_IF(std::is_enum<Char>::value)>
2296constexpr auto to_ascii(Char c) -> underlying_t<Char> {
2297 return c;
2298}
2299
2300FMT_CONSTEXPR inline auto code_point_length_impl(char c) -> int {
2301 return "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4"
2302 [static_cast<unsigned char>(c) >> 3];
2303}
2304
2305template <typename Char>
2306FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int {
2307 if (const_check(sizeof(Char) != 1)) return 1;
2308 int len = code_point_length_impl(static_cast<char>(*begin));
2309
2310 // Compute the pointer to the next character early so that the next
2311 // iteration can start working on the next character. Neither Clang
2312 // nor GCC figure out this reordering on their own.
2313 return len + !len;
2314}
2315
2316// Return the result via the out param to workaround gcc bug 77539.
2317template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
2318FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool {
2319 for (out = first; out != last; ++out) {
2320 if (*out == value) return true;
2321 }
2322 return false;
2323}
2324
2325template <>
2326inline auto find<false, char>(const char* first, const char* last, char value,
2327 const char*& out) -> bool {
2328 out = static_cast<const char*>(
2329 std::memchr(first, value, to_unsigned(last - first)));
2330 return out != nullptr;
2331}
2332
2333// Parses the range [begin, end) as an unsigned integer. This function assumes
2334// that the range is non-empty and the first character is a digit.
2335template <typename Char>
2336FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
2337 int error_value) noexcept -> int {
2338 FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
2339 unsigned value = 0, prev = 0;
2340 auto p = begin;
2341 do {
2342 prev = value;
2343 value = value * 10 + unsigned(*p - '0');
2344 ++p;
2345 } while (p != end && '0' <= *p && *p <= '9');
2346 auto num_digits = p - begin;
2347 begin = p;
2348 if (num_digits <= std::numeric_limits<int>::digits10)
2349 return static_cast<int>(value);
2350 // Check for overflow.
2351 const unsigned max = to_unsigned((std::numeric_limits<int>::max)());
2352 return num_digits == std::numeric_limits<int>::digits10 + 1 &&
2353 prev * 10ull + unsigned(p[-1] - '0') <= max
2354 ? static_cast<int>(value)
2355 : error_value;
2356}
2357
2358// Parses fill and alignment.
2359template <typename Char, typename Handler>
2360FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
2361 Handler&& handler) -> const Char* {
2362 FMT_ASSERT(begin != end, "");
2363 auto align = align::none;
2364 auto p = begin + code_point_length(begin);
2365 if (end - p <= 0) p = begin;
2366 for (;;) {
2367 switch (to_ascii(*p)) {
2368 case '<':
2369 align = align::left;
2370 break;
2371 case '>':
2372 align = align::right;
2373 break;
2374 case '^':
2375 align = align::center;
2376 break;
2377 default:
2378 break;
2379 }
2380 if (align != align::none) {
2381 if (p != begin) {
2382 auto c = *begin;
2383 if (c == '{')
2384 return handler.on_error("invalid fill character '{'"), begin;
2385 handler.on_fill(basic_string_view<Char>(begin, to_unsigned(p - begin)));
2386 begin = p + 1;
2387 } else
2388 ++begin;
2389 handler.on_align(align);
2390 break;
2391 } else if (p == begin) {
2392 break;
2393 }
2394 p = begin;
2395 }
2396 return begin;
2397}
2398
2399template <typename Char> FMT_CONSTEXPR bool is_name_start(Char c) {
2400 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
2401}
2402
2403template <typename Char, typename IDHandler>
2404FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end,
2405 IDHandler&& handler) -> const Char* {
2406 FMT_ASSERT(begin != end, "");
2407 Char c = *begin;
2408 if (c >= '0' && c <= '9') {
2409 int index = 0;
2410 if (c != '0')
2411 index =
2413 else
2414 ++begin;
2415 if (begin == end || (*begin != '}' && *begin != ':'))
2416 handler.on_error("invalid format string");
2417 else
2418 handler(index);
2419 return begin;
2420 }
2421 if (!is_name_start(c)) {
2422 handler.on_error("invalid format string");
2423 return begin;
2424 }
2425 auto it = begin;
2426 do {
2427 ++it;
2428 } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9')));
2430 return it;
2431}
2432
2433template <typename Char, typename IDHandler>
2434FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char* begin, const Char* end,
2435 IDHandler&& handler) -> const Char* {
2436 Char c = *begin;
2437 if (c != '}' && c != ':') return do_parse_arg_id(begin, end, handler);
2438 handler();
2439 return begin;
2440}
2441
2442template <typename Char, typename Handler>
2443FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end,
2444 Handler&& handler) -> const Char* {
2445 using detail::auto_id;
2446 struct width_adapter {
2447 Handler& handler;
2448
2449 FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); }
2450 FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_width(id); }
2452 handler.on_dynamic_width(id);
2453 }
2454 FMT_CONSTEXPR void on_error(const char* message) {
2455 if (message) handler.on_error(message);
2456 }
2457 };
2458
2459 FMT_ASSERT(begin != end, "");
2460 if ('0' <= *begin && *begin <= '9') {
2461 int width = parse_nonnegative_int(begin, end, -1);
2462 if (width != -1)
2463 handler.on_width(width);
2464 else
2465 handler.on_error("number is too big");
2466 } else if (*begin == '{') {
2467 ++begin;
2468 if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler});
2469 if (begin == end || *begin != '}')
2470 return handler.on_error("invalid format string"), begin;
2471 ++begin;
2472 }
2473 return begin;
2474}
2475
2476template <typename Char, typename Handler>
2477FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
2478 Handler&& handler) -> const Char* {
2479 using detail::auto_id;
2480 struct precision_adapter {
2481 Handler& handler;
2482
2483 FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); }
2484 FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_precision(id); }
2486 handler.on_dynamic_precision(id);
2487 }
2488 FMT_CONSTEXPR void on_error(const char* message) {
2489 if (message) handler.on_error(message);
2490 }
2491 };
2492
2493 ++begin;
2494 auto c = begin != end ? *begin : Char();
2495 if ('0' <= c && c <= '9') {
2496 auto precision = parse_nonnegative_int(begin, end, -1);
2497 if (precision != -1)
2498 handler.on_precision(precision);
2499 else
2500 handler.on_error("number is too big");
2501 } else if (c == '{') {
2502 ++begin;
2503 if (begin != end)
2504 begin = parse_arg_id(begin, end, precision_adapter{handler});
2505 if (begin == end || *begin++ != '}')
2506 return handler.on_error("invalid format string"), begin;
2507 } else {
2508 return handler.on_error("missing precision specifier"), begin;
2509 }
2510 handler.end_precision();
2511 return begin;
2512}
2513
2514template <typename Char>
2516 switch (to_ascii(type)) {
2517 case 'd':
2519 case 'o':
2521 case 'x':
2523 case 'X':
2525 case 'b':
2527 case 'B':
2529 case 'a':
2531 case 'A':
2533 case 'e':
2535 case 'E':
2537 case 'f':
2539 case 'F':
2541 case 'g':
2543 case 'G':
2545 case 'c':
2547 case 's':
2549 case 'p':
2551 case '?':
2553 default:
2555 }
2556}
2557
2558// Parses standard format specifiers and sends notifications about parsed
2559// components to handler.
2560template <typename Char, typename SpecHandler>
2562 const Char* end,
2563 SpecHandler&& handler)
2564 -> const Char* {
2565 if (1 < end - begin && begin[1] == '}' && is_ascii_letter(*begin) &&
2566 *begin != 'L') {
2569 handler.on_error("invalid type specifier");
2570 handler.on_type(type);
2571 return begin;
2572 }
2573
2574 if (begin == end) return begin;
2575
2576 begin = parse_align(begin, end, handler);
2577 if (begin == end) return begin;
2578
2579 // Parse sign.
2580 switch (to_ascii(*begin)) {
2581 case '+':
2582 handler.on_sign(sign::plus);
2583 ++begin;
2584 break;
2585 case '-':
2586 handler.on_sign(sign::minus);
2587 ++begin;
2588 break;
2589 case ' ':
2590 handler.on_sign(sign::space);
2591 ++begin;
2592 break;
2593 default:
2594 break;
2595 }
2596 if (begin == end) return begin;
2597
2598 if (*begin == '#') {
2599 handler.on_hash();
2600 if (++begin == end) return begin;
2601 }
2602
2603 // Parse zero flag.
2604 if (*begin == '0') {
2605 handler.on_zero();
2606 if (++begin == end) return begin;
2607 }
2608
2609 begin = parse_width(begin, end, handler);
2610 if (begin == end) return begin;
2611
2612 // Parse precision.
2613 if (*begin == '.') {
2614 begin = parse_precision(begin, end, handler);
2615 if (begin == end) return begin;
2616 }
2617
2618 if (*begin == 'L') {
2619 handler.on_localized();
2620 ++begin;
2621 }
2622
2623 // Parse type.
2624 if (begin != end && *begin != '}') {
2627 handler.on_error("invalid type specifier");
2628 handler.on_type(type);
2629 }
2630 return begin;
2631}
2632
2633template <typename Char, typename Handler>
2634FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end,
2635 Handler&& handler) -> const Char* {
2636 struct id_adapter {
2637 Handler& handler;
2638 int arg_id;
2639
2640 FMT_CONSTEXPR void operator()() { arg_id = handler.on_arg_id(); }
2641 FMT_CONSTEXPR void operator()(int id) { arg_id = handler.on_arg_id(id); }
2643 arg_id = handler.on_arg_id(id);
2644 }
2645 FMT_CONSTEXPR void on_error(const char* message) {
2646 if (message) handler.on_error(message);
2647 }
2648 };
2649
2650 ++begin;
2651 if (begin == end) return handler.on_error("invalid format string"), end;
2652 if (*begin == '}') {
2653 handler.on_replacement_field(handler.on_arg_id(), begin);
2654 } else if (*begin == '{') {
2655 handler.on_text(begin, begin + 1);
2656 } else {
2657 auto adapter = id_adapter{handler, 0};
2658 begin = parse_arg_id(begin, end, adapter);
2659 Char c = begin != end ? *begin : Char();
2660 if (c == '}') {
2661 handler.on_replacement_field(adapter.arg_id, begin);
2662 } else if (c == ':') {
2663 begin = handler.on_format_specs(adapter.arg_id, begin + 1, end);
2664 if (begin == end || *begin != '}')
2665 return handler.on_error("unknown format specifier"), end;
2666 } else {
2667 return handler.on_error("missing '}' in format string"), end;
2668 }
2669 }
2670 return begin + 1;
2671}
2672
2673template <bool IS_CONSTEXPR, typename Char, typename Handler>
2675 basic_string_view<Char> format_str, Handler&& handler) {
2676 // Workaround a name-lookup bug in MSVC's modules implementation.
2677 using detail::find;
2678
2679 auto begin = format_str.data();
2680 auto end = begin + format_str.size();
2681 if (end - begin < 32) {
2682 // Use a simple loop instead of memchr for small strings.
2683 const Char* p = begin;
2684 while (p != end) {
2685 auto c = *p++;
2686 if (c == '{') {
2687 handler.on_text(begin, p - 1);
2688 begin = p = parse_replacement_field(p - 1, end, handler);
2689 } else if (c == '}') {
2690 if (p == end || *p != '}')
2691 return handler.on_error("unmatched '}' in format string");
2692 handler.on_text(begin, p);
2693 begin = ++p;
2694 }
2695 }
2696 handler.on_text(begin, end);
2697 return;
2698 }
2699 struct writer {
2700 FMT_CONSTEXPR void operator()(const Char* from, const Char* to) {
2701 if (from == to) return;
2702 for (;;) {
2703 const Char* p = nullptr;
2704 if (!find<IS_CONSTEXPR>(from, to, Char('}'), p))
2705 return handler_.on_text(from, to);
2706 ++p;
2707 if (p == to || *p != '}')
2708 return handler_.on_error("unmatched '}' in format string");
2709 handler_.on_text(from, p);
2710 from = p + 1;
2711 }
2712 }
2713 Handler& handler_;
2714 } write = {handler};
2715 while (begin != end) {
2716 // Doing two passes with memchr (one for '{' and another for '}') is up to
2717 // 2.5x faster than the naive one-pass implementation on big format strings.
2718 const Char* p = begin;
2719 if (*begin != '{' && !find<IS_CONSTEXPR>(begin + 1, end, Char('{'), p))
2720 return write(begin, end);
2721 write(begin, p);
2722 begin = parse_replacement_field(p, end, handler);
2723 }
2724}
2725
2726template <typename T, bool = is_named_arg<T>::value> struct strip_named_arg {
2727 using type = T;
2728};
2729template <typename T> struct strip_named_arg<T, true> {
2730 using type = remove_cvref_t<decltype(T::value)>;
2731};
2732
2733template <typename T, typename ParseContext>
2734FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx)
2735 -> decltype(ctx.begin()) {
2736 using char_type = typename ParseContext::char_type;
2737 using context = buffer_context<char_type>;
2738 using stripped_type = typename strip_named_arg<T>::type;
2739 using mapped_type = conditional_t<
2741 decltype(arg_mapper<context>().map(std::declval<const T&>())),
2742 stripped_type>;
2746 return f.parse(ctx);
2747}
2748
2749template <typename ErrorHandler>
2751 ErrorHandler&& eh) {
2753 eh.on_error("invalid type specifier");
2754}
2755
2756// Checks char specs and returns true if the type spec is char (and not int).
2757template <typename Char, typename ErrorHandler = error_handler>
2759 ErrorHandler&& eh = {}) -> bool {
2760 if (specs.type != presentation_type::none &&
2761 specs.type != presentation_type::chr &&
2762 specs.type != presentation_type::debug) {
2763 check_int_type_spec(specs.type, eh);
2764 return false;
2765 }
2766 if (specs.align == align::numeric || specs.sign != sign::none || specs.alt)
2767 eh.on_error("invalid format specifier for char");
2768 return true;
2769}
2770
2771// A floating-point presentation format.
2772enum class float_format : unsigned char {
2773 general, // General: exponent notation or fixed point based on magnitude.
2774 exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3.
2775 fixed, // Fixed point with the default precision of 6, e.g. 0.0012.
2776 hex
2777};
2778
2783 bool upper : 1;
2784 bool locale : 1;
2785 bool binary32 : 1;
2786 bool showpoint : 1;
2787};
2788
2789template <typename ErrorHandler = error_handler, typename Char>
2791 ErrorHandler&& eh = {})
2792 -> float_specs {
2793 auto result = float_specs();
2794 result.showpoint = specs.alt;
2795 result.locale = specs.localized;
2796 switch (specs.type) {
2799 break;
2801 result.upper = true;
2805 break;
2807 result.upper = true;
2810 result.format = float_format::exp;
2811 result.showpoint |= specs.precision != 0;
2812 break;
2814 result.upper = true;
2817 result.format = float_format::fixed;
2818 result.showpoint |= specs.precision != 0;
2819 break;
2821 result.upper = true;
2824 result.format = float_format::hex;
2825 break;
2826 default:
2827 eh.on_error("invalid type specifier");
2828 break;
2829 }
2830 return result;
2831}
2832
2833template <typename ErrorHandler = error_handler>
2835 ErrorHandler&& eh = {}) -> bool {
2838 return true;
2839 if (type != presentation_type::pointer) eh.on_error("invalid type specifier");
2840 return false;
2841}
2842
2843template <typename ErrorHandler = error_handler>
2845 ErrorHandler&& eh = {}) {
2848 eh.on_error("invalid type specifier");
2849}
2850
2851template <typename ErrorHandler>
2853 ErrorHandler&& eh) {
2855 eh.on_error("invalid type specifier");
2856}
2857
2858// A parse_format_specs handler that checks if specifiers are consistent with
2859// the argument type.
2860template <typename Handler> class specs_checker : public Handler {
2861 private:
2862 detail::type arg_type_;
2863
2864 FMT_CONSTEXPR void require_numeric_argument() {
2865 if (!is_arithmetic_type(arg_type_))
2866 this->on_error("format specifier requires numeric argument");
2867 }
2868
2869 public:
2870 FMT_CONSTEXPR specs_checker(const Handler& handler, detail::type arg_type)
2871 : Handler(handler), arg_type_(arg_type) {}
2872
2874 if (align == align::numeric) require_numeric_argument();
2875 Handler::on_align(align);
2876 }
2877
2879 require_numeric_argument();
2880 if (is_integral_type(arg_type_) && arg_type_ != type::int_type &&
2881 arg_type_ != type::long_long_type && arg_type_ != type::int128_type &&
2882 arg_type_ != type::char_type) {
2883 this->on_error("format specifier requires signed argument");
2884 }
2885 Handler::on_sign(s);
2886 }
2887
2889 require_numeric_argument();
2890 Handler::on_hash();
2891 }
2892
2894 require_numeric_argument();
2895 Handler::on_localized();
2896 }
2897
2899 require_numeric_argument();
2900 Handler::on_zero();
2901 }
2902
2904 if (is_integral_type(arg_type_) || arg_type_ == type::pointer_type)
2905 this->on_error("precision not allowed for this argument type");
2906 }
2907};
2908
2909constexpr int invalid_arg_index = -1;
2910
2911#if FMT_USE_NONTYPE_TEMPLATE_ARGS
2912template <int N, typename T, typename... Args, typename Char>
2913constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
2914 if constexpr (detail::is_statically_named_arg<T>()) {
2915 if (name == T::name) return N;
2916 }
2917 if constexpr (sizeof...(Args) > 0)
2918 return get_arg_index_by_name<N + 1, Args...>(name);
2919 (void)name; // Workaround an MSVC bug about "unused" parameter.
2920 return invalid_arg_index;
2921}
2922#endif
2923
2924template <typename... Args, typename Char>
2926#if FMT_USE_NONTYPE_TEMPLATE_ARGS
2927 if constexpr (sizeof...(Args) > 0)
2928 return get_arg_index_by_name<0, Args...>(name);
2929#endif
2930 (void)name;
2931 return invalid_arg_index;
2932}
2933
2934template <typename Char, typename ErrorHandler, typename... Args>
2936 private:
2937 // In the future basic_format_parse_context will replace compile_parse_context
2938 // here and will use is_constant_evaluated and downcasting to access the data
2939 // needed for compile-time checks: https://godbolt.org/z/GvWzcTjh1.
2941 static constexpr int num_args = sizeof...(Args);
2942
2943 // Format specifier parsing function.
2944 using parse_func = const Char* (*)(parse_context_type&);
2945
2946 parse_context_type context_;
2947 parse_func parse_funcs_[num_args > 0 ? static_cast<size_t>(num_args) : 1];
2948 type types_[num_args > 0 ? static_cast<size_t>(num_args) : 1];
2949
2950 public:
2952 basic_string_view<Char> format_str, ErrorHandler eh)
2953 : context_(format_str, num_args, types_, eh),
2954 parse_funcs_{&parse_format_specs<Args, parse_context_type>...},
2955 types_{ // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
2957 basic_format_context<Char*, Char>>::value...} {
2958 }
2959
2960 FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
2961
2962 FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); }
2963 FMT_CONSTEXPR auto on_arg_id(int id) -> int {
2964 return context_.check_arg_id(id), id;
2965 }
2967#if FMT_USE_NONTYPE_TEMPLATE_ARGS
2968 auto index = get_arg_index_by_name<Args...>(id);
2969 if (index == invalid_arg_index) on_error("named argument is not found");
2970 return context_.check_arg_id(index), index;
2971#else
2972 (void)id;
2973 on_error("compile-time checks for named arguments require C++20 support");
2974 return 0;
2975#endif
2976 }
2977
2978 FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
2979
2980 FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char*)
2981 -> const Char* {
2982 context_.advance_to(context_.begin() + (begin - &*context_.begin()));
2983 // id >= 0 check is a workaround for gcc 10 bug (#2065).
2984 return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin;
2985 }
2986
2987 FMT_CONSTEXPR void on_error(const char* message) {
2988 context_.on_error(message);
2989 }
2990};
2991
2992// Reports a compile-time error if S is not a valid format string.
2993template <typename..., typename S, FMT_ENABLE_IF(!is_compile_string<S>::value)>
2995#ifdef FMT_ENFORCE_COMPILE_STRING
2996 static_assert(is_compile_string<S>::value,
2997 "FMT_ENFORCE_COMPILE_STRING requires all format strings to use "
2998 "FMT_STRING.");
2999#endif
3000}
3001template <typename... Args, typename S,
3003void check_format_string(S format_str) {
3005 using checker = format_string_checker<typename S::char_type, error_handler,
3007 FMT_CONSTEXPR bool invalid_format =
3008 (parse_format_string<true>(s, checker(s, {})), true);
3009 ignore_unused(invalid_format);
3010}
3011
3012template <typename Char>
3013void vformat_to(
3016 locale_ref loc = {});
3017
3019#ifndef _WIN32
3020inline void vprint_mojibake(std::FILE*, string_view, format_args) {}
3021#endif
3023
3024// A formatter specialization for the core types corresponding to detail::type
3025// constants.
3026template <typename T, typename Char>
3027struct formatter<T, Char,
3029 detail::type::custom_type>> {
3030 private:
3031 detail::dynamic_format_specs<Char> specs_;
3032
3033 public:
3034 // Parses format specifiers stopping either at the end of the range or at the
3035 // terminating '}'.
3036 template <typename ParseContext>
3037 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
3038 auto begin = ctx.begin(), end = ctx.end();
3039 if (begin == end) return begin;
3040 using handler_type = detail::dynamic_specs_handler<ParseContext>;
3041 auto type = detail::type_constant<T, Char>::value;
3042 auto checker =
3043 detail::specs_checker<handler_type>(handler_type(specs_, ctx), type);
3044 auto it = detail::parse_format_specs(begin, end, checker);
3045 auto eh = ctx.error_handler();
3046 switch (type) {
3047 case detail::type::none_type:
3048 FMT_ASSERT(false, "invalid argument type");
3049 break;
3050 case detail::type::bool_type:
3051 if (specs_.type == presentation_type::none ||
3052 specs_.type == presentation_type::string) {
3053 break;
3054 }
3056 case detail::type::int_type:
3057 case detail::type::uint_type:
3058 case detail::type::long_long_type:
3059 case detail::type::ulong_long_type:
3060 case detail::type::int128_type:
3061 case detail::type::uint128_type:
3062 detail::check_int_type_spec(specs_.type, eh);
3063 break;
3064 case detail::type::char_type:
3065 detail::check_char_specs(specs_, eh);
3066 break;
3067 case detail::type::float_type:
3070 else
3071 FMT_ASSERT(false, "float support disabled");
3072 break;
3073 case detail::type::double_type:
3076 else
3077 FMT_ASSERT(false, "double support disabled");
3078 break;
3079 case detail::type::long_double_type:
3082 else
3083 FMT_ASSERT(false, "long double support disabled");
3084 break;
3085 case detail::type::cstring_type:
3086 detail::check_cstring_type_spec(specs_.type, eh);
3087 break;
3088 case detail::type::string_type:
3089 detail::check_string_type_spec(specs_.type, eh);
3090 break;
3091 case detail::type::pointer_type:
3092 detail::check_pointer_type_spec(specs_.type, eh);
3093 break;
3094 case detail::type::custom_type:
3095 // Custom format specifiers are checked in parse functions of
3096 // formatter specializations.
3097 break;
3098 }
3099 return it;
3100 }
3101
3102 template <detail::type U = detail::type_constant<T, Char>::value,
3103 enable_if_t<(U == detail::type::string_type ||
3104 U == detail::type::cstring_type ||
3105 U == detail::type::char_type),
3106 int> = 0>
3108 specs_.type = presentation_type::debug;
3109 }
3110
3111 template <typename FormatContext>
3112 FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
3113 -> decltype(ctx.out());
3114};
3115
3116#define FMT_FORMAT_AS(Type, Base) \
3117 template <typename Char> \
3118 struct formatter<Type, Char> : formatter<Base, Char> { \
3119 template <typename FormatContext> \
3120 auto format(Type const& val, FormatContext& ctx) const \
3121 -> decltype(ctx.out()) { \
3122 return formatter<Base, Char>::format(static_cast<Base>(val), ctx); \
3123 } \
3124 }
3125
3126FMT_FORMAT_AS(signed char, int);
3127FMT_FORMAT_AS(unsigned char, unsigned);
3128FMT_FORMAT_AS(short, int);
3129FMT_FORMAT_AS(unsigned short, unsigned);
3130FMT_FORMAT_AS(long, long long);
3131FMT_FORMAT_AS(unsigned long, unsigned long long);
3132FMT_FORMAT_AS(Char*, const Char*);
3133FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
3134FMT_FORMAT_AS(std::nullptr_t, const void*);
3135FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
3136
3137template <typename Char> struct basic_runtime { basic_string_view<Char> str; };
3138
3139/** A compile-time format string. */
3140template <typename Char, typename... Args> class basic_format_string {
3141 private:
3143
3144 public:
3145 template <typename S,
3147 std::is_convertible<const S&, basic_string_view<Char>>::value)>
3149 static_assert(
3151 (std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
3152 std::is_reference<Args>::value)...>() == 0,
3153 "passing views as lvalues is disallowed");
3154#ifdef FMT_HAS_CONSTEVAL
3155 if constexpr (detail::count_named_args<Args...>() ==
3156 detail::count_statically_named_args<Args...>()) {
3157 using checker = detail::format_string_checker<Char, detail::error_handler,
3159 detail::parse_format_string<true>(str_, checker(s, {}));
3160 }
3161#else
3162 detail::check_format_string<Args...>(s);
3163#endif
3164 }
3166
3167 FMT_INLINE operator basic_string_view<Char>() const { return str_; }
3168};
3169
3170#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
3171// Workaround broken conversion on older gcc.
3172template <typename...> using format_string = string_view;
3173inline auto runtime(string_view s) -> string_view { return s; }
3174#else
3175template <typename... Args>
3177/**
3178 \rst
3179 Creates a runtime format string.
3180
3181 **Example**::
3182
3183 // Check format string at runtime instead of compile-time.
3184 fmt::print(fmt::runtime("{:d}"), "I am not a number");
3185 \endrst
3186 */
3187inline auto runtime(string_view s) -> basic_runtime<char> { return {{s}}; }
3188#endif
3189
3190FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
3191
3192/**
3193 \rst
3194 Formats ``args`` according to specifications in ``fmt`` and returns the result
3195 as a string.
3196
3197 **Example**::
3198
3199 #include <fmt/core.h>
3200 std::string message = fmt::format("The answer is {}.", 42);
3201 \endrst
3202*/
3203template <typename... T>
3205 -> std::string {
3206 return vformat(fmt, fmt::make_format_args(args...));
3207}
3208
3209/** Formats a string and writes the output to ``out``. */
3210template <typename OutputIt,
3211 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
3212auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt {
3213 using detail::get_buffer;
3214 auto&& buf = get_buffer<char>(out);
3215 detail::vformat_to(buf, fmt, args, {});
3216 return detail::get_iterator(buf);
3217}
3218
3219/**
3220 \rst
3221 Formats ``args`` according to specifications in ``fmt``, writes the result to
3222 the output iterator ``out`` and returns the iterator past the end of the output
3223 range. `format_to` does not append a terminating null character.
3224
3225 **Example**::
3226
3227 auto out = std::vector<char>();
3228 fmt::format_to(std::back_inserter(out), "{}", 42);
3229 \endrst
3230 */
3231template <typename OutputIt, typename... T,
3232 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
3233FMT_INLINE auto format_to(OutputIt out, format_string<T...> fmt, T&&... args)
3234 -> OutputIt {
3235 return vformat_to(out, fmt, fmt::make_format_args(args...));
3236}
3237
3238template <typename OutputIt> struct format_to_n_result {
3239 /** Iterator past the end of the output range. */
3240 OutputIt out;
3241 /** Total (not truncated) output size. */
3242 size_t size;
3243};
3244
3245template <typename OutputIt, typename... T,
3246 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
3247auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args)
3249 using traits = detail::fixed_buffer_traits;
3250 auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
3251 detail::vformat_to(buf, fmt, args, {});
3252 return {buf.out(), buf.count()};
3253}
3254
3255/**
3256 \rst
3257 Formats ``args`` according to specifications in ``fmt``, writes up to ``n``
3258 characters of the result to the output iterator ``out`` and returns the total
3259 (not truncated) output size and the iterator past the end of the output range.
3260 `format_to_n` does not append a terminating null character.
3261 \endrst
3262 */
3263template <typename OutputIt, typename... T,
3264 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
3265FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt,
3266 T&&... args) -> format_to_n_result<OutputIt> {
3267 return vformat_to_n(out, n, fmt, fmt::make_format_args(args...));
3268}
3269
3270/** Returns the number of chars in the output of ``format(fmt, args...)``. */
3271template <typename... T>
3273 T&&... args) -> size_t {
3274 auto buf = detail::counting_buffer<>();
3275 detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...), {});
3276 return buf.count();
3277}
3278
3279FMT_API void vprint(string_view fmt, format_args args);
3280FMT_API void vprint(std::FILE* f, string_view fmt, format_args args);
3281
3282/**
3283 \rst
3284 Formats ``args`` according to specifications in ``fmt`` and writes the output
3285 to ``stdout``.
3286
3287 **Example**::
3288
3289 fmt::print("Elapsed time: {0:.2f} seconds", 1.23);
3290 \endrst
3291 */
3292template <typename... T>
3293FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
3294 const auto& vargs = fmt::make_format_args(args...);
3295 return detail::is_utf8() ? vprint(fmt, vargs)
3296 : detail::vprint_mojibake(stdout, fmt, vargs);
3297}
3298
3299/**
3300 \rst
3301 Formats ``args`` according to specifications in ``fmt`` and writes the
3302 output to the file ``f``.
3303
3304 **Example**::
3305
3306 fmt::print(stderr, "Don't {}!", "panic");
3307 \endrst
3308 */
3309template <typename... T>
3310FMT_INLINE void print(std::FILE* f, format_string<T...> fmt, T&&... args) {
3311 const auto& vargs = fmt::make_format_args(args...);
3312 return detail::is_utf8() ? vprint(f, fmt, vargs)
3313 : detail::vprint_mojibake(f, fmt, vargs);
3314}
3315
3317FMT_GCC_PRAGMA("GCC pop_options")
3319
3320#ifdef FMT_HEADER_ONLY
3321# include "format.h"
3322#endif
3323#endif // FMT_CORE_H_
internal::enable_if< internal::valid_indexed_view_overload< RowIndices, ColIndices >::value &&internal::traits< typenameEIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::ReturnAsIndexedView, typenameEIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::type operator()(const RowIndices &rowIndices, const ColIndices &colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
Definition: IndexedViewMethods.h:73
you may not use this file except in compliance with the License You may obtain a copy of the License at software distributed under the License is distributed on an AS IS WITHOUT WARRANTIES OR CONDITIONS OF ANY either express or implied See the License for the specific language governing permissions and limitations under the License LLVM Exceptions to the Apache License As an if
Definition: ThirdPartyNotices.txt:292
then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file
Definition: ThirdPartyNotices.txt:195
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source including but not limited to compiled object generated and conversions to other media types Work shall mean the work of whether in Source or Object made available under the as indicated by a copyright notice that is included in or attached to the whether in Source or Object that is based or other modifications as a an original work of authorship For the purposes of this Derivative Works shall not include works that remain separable from
Definition: ThirdPartyNotices.txt:131
Definition: core.h:1543
appender(base it) noexcept
Definition: core.h:1553
auto operator++() noexcept -> appender &
Definition: core.h:1556
auto operator++(int) noexcept -> appender
Definition: core.h:1557
FMT_UNCHECKED_ITERATOR(appender)
friend auto get_buffer(appender out) -> detail::buffer< char > &
Definition: core.h:1547
Definition: core.h:1588
void format(typename Context::parse_context_type &parse_ctx, Context &ctx) const
Definition: core.h:1592
handle(detail::custom_value< Context > custom)
Definition: core.h:1590
Definition: core.h:1562
constexpr basic_format_arg()
Definition: core.h:1601
auto type() const -> detail::type
Definition: core.h:1607
friend struct detail::arg_data
Definition: core.h:1582
friend FMT_CONSTEXPR auto visit_format_arg(Visitor &&vis, const basic_format_arg< Ctx > &arg) -> decltype(vis(0))
auto is_arithmetic() const -> bool
Definition: core.h:1610
auto is_integral() const -> bool
Definition: core.h:1609
\rst A view of a collection of formatting arguments.
Definition: core.h:1948
constexpr basic_format_args()
Definition: core.h:1989
const format_arg * args_
Definition: core.h:1966
constexpr basic_format_args(const format_arg *args, int count)
\rst Constructs a basic_format_args object from a dynamic set of arguments.
Definition: core.h:2017
FMT_CONSTEXPR auto get(int id) const -> format_arg
Returns the argument with the specified id.
Definition: core.h:2022
const detail::value< Context > * values_
Definition: core.h:1965
constexpr FMT_INLINE basic_format_args(const dynamic_format_arg_store< Context > &store)
\rst Constructs a basic_format_args object from ~fmtdynamic_format_arg_store.
Definition: core.h:2008
int size_type
Definition: core.h:1950
auto max_size() const -> int
Definition: core.h:2052
auto get(basic_string_view< Char > name) const -> format_arg
Definition: core.h:2036
constexpr FMT_INLINE basic_format_args(const format_arg_store< Context, Args... > &store)
\rst Constructs a basic_format_args object from ~fmtformat_arg_store.
Definition: core.h:1997
auto get_id(basic_string_view< Char > name) const -> int
Definition: core.h:2042
Definition: core.h:1788
basic_format_context(const basic_format_context &)=delete
OutputIt iterator
Definition: core.h:1799
FMT_CONSTEXPR auto locale() -> detail::locale_ref
Definition: core.h:1838
FMT_CONSTEXPR auto out() -> iterator
Definition: core.h:1831
FMT_CONSTEXPR auto arg(basic_string_view< char_type > name) -> format_arg
Definition: core.h:1817
Char char_type
The character type for the output.
Definition: core.h:1791
FMT_CONSTEXPR auto arg_id(basic_string_view< char_type > name) -> int
Definition: core.h:1820
void on_error(const char *message)
Definition: core.h:1828
FMT_CONSTEXPR auto error_handler() -> detail::error_handler
Definition: core.h:1827
constexpr auto arg(int id) const -> format_arg
Definition: core.h:1816
auto args() const -> const basic_format_args< basic_format_context > &
Definition: core.h:1823
void advance_to(iterator it)
Definition: core.h:1834
constexpr basic_format_context(OutputIt out, basic_format_args< basic_format_context > ctx_args, detail::locale_ref loc=detail::locale_ref())
Constructs a basic_format_context object.
Definition: core.h:1811
basic_format_context(basic_format_context &&)=default
void operator=(const basic_format_context &)=delete
\rst Parsing context consisting of a format string range being parsed and an argument counter for aut...
Definition: core.h:654
FMT_CONSTEXPR void check_dynamic_spec(int arg_id)
FMT_CONSTEXPR void check_arg_id(basic_string_view< Char >)
Definition: core.h:714
constexpr auto error_handler() const -> ErrorHandler
Definition: core.h:721
FMT_CONSTEXPR void on_error(const char *message)
Definition: core.h:717
FMT_CONSTEXPR void check_arg_id(int id)
Reports an error if using the automatic argument indexing; otherwise switches to the manual indexing.
Definition: core.h:706
constexpr auto end() const noexcept -> iterator
Returns an iterator past the end of the format string range being parsed.
Definition: core.h:681
Char char_type
Definition: core.h:662
typename basic_string_view< Char >::iterator iterator
Definition: core.h:663
FMT_CONSTEXPR auto next_arg_id() -> int
Reports an error if using the manual argument indexing; otherwise returns the next argument index and...
Definition: core.h:692
FMT_CONSTEXPR void advance_to(iterator it)
Advances the begin iterator to it.
Definition: core.h:684
constexpr auto begin() const noexcept -> iterator
Returns an iterator to the beginning of the format string range being parsed.
Definition: core.h:674
constexpr basic_format_parse_context(basic_string_view< Char > format_str, ErrorHandler eh={}, int next_arg_id=0)
Definition: core.h:665
A compile-time format string.
Definition: core.h:3140
FMT_CONSTEVAL FMT_INLINE basic_format_string(const S &s)
Definition: core.h:3148
basic_format_string(basic_runtime< Char > r)
Definition: core.h:3165
An implementation of std::basic_string_view for pre-C++17.
Definition: core.h:430
FMT_CONSTEXPR basic_string_view(const std::basic_string< Char, Traits, Alloc > &s) noexcept
Constructs a string reference from a std::basic_string object.
Definition: core.h:462
constexpr auto end() const noexcept -> iterator
Definition: core.h:478
const Char * iterator
Definition: core.h:437
constexpr auto size() const noexcept -> size_t
Returns the string size.
Definition: core.h:475
constexpr auto data() const noexcept -> const Char *
Returns a pointer to the string data.
Definition: core.h:472
FMT_CONSTEXPR_CHAR_TRAITS friend auto operator==(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:498
friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:512
constexpr auto begin() const noexcept -> iterator
Definition: core.h:477
friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:506
Char value_type
Definition: core.h:436
FMT_CONSTEXPR basic_string_view(S s) noexcept
Definition: core.h:468
friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:509
FMT_CONSTEXPR void remove_prefix(size_t n) noexcept
Definition: core.h:484
FMT_CONSTEXPR_CHAR_TRAITS FMT_INLINE basic_string_view(const Char *s)
\rst Constructs a string reference object from a C string computing the size with std::char_traits<Ch...
Definition: core.h:453
friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:503
constexpr auto operator[](size_t pos) const noexcept -> const Char &
Definition: core.h:480
constexpr basic_string_view(const Char *s, size_t count) noexcept
Constructs a string reference object from a C string and a size.
Definition: core.h:442
constexpr basic_string_view() noexcept
Definition: core.h:439
friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool
Definition: core.h:515
FMT_CONSTEXPR_CHAR_TRAITS auto compare(basic_string_view other) const -> int
Definition: core.h:490
\rst A contiguous memory buffer with an optional growing ability.
Definition: core.h:862
constexpr auto capacity() const noexcept -> size_t
Returns the capacity of this buffer.
Definition: core.h:905
void append(const U *begin, const U *end)
Appends data to the end of the buffer.
FMT_CONSTEXPR20 ~buffer()=default
auto end() noexcept -> T *
Definition: core.h:896
FMT_CONSTEXPR20 void try_reserve(size_t new_capacity)
Definition: core.h:927
buffer(const buffer &)=delete
void clear()
Clears this buffer.
Definition: core.h:914
FMT_CONSTEXPR20 void push_back(const T &value)
Definition: core.h:931
FMT_CONSTEXPR auto data() noexcept -> T *
Returns a pointer to the buffer data.
Definition: core.h:908
auto begin() const noexcept -> const T *
Definition: core.h:898
FMT_CONSTEXPR auto operator[](Idx index) -> T &
Definition: core.h:939
const T & const_reference
Definition: core.h:890
virtual FMT_CONSTEXPR20 void grow(size_t capacity)=0
Increases the buffer capacity to hold at least capacity elements.
T value_type
Definition: core.h:889
auto end() const noexcept -> const T *
Definition: core.h:899
FMT_CONSTEXPR auto operator[](Idx index) const -> const T &
Definition: core.h:943
FMT_CONSTEXPR20 buffer(T *p=nullptr, size_t sz=0, size_t cap=0) noexcept
Definition: core.h:873
FMT_CONSTEXPR20 void try_resize(size_t count)
Definition: core.h:918
FMT_CONSTEXPR auto data() const noexcept -> const T *
Returns a pointer to the buffer data.
Definition: core.h:911
void operator=(const buffer &)=delete
FMT_CONSTEXPR void set(T *buf_data, size_t buf_capacity) noexcept
Sets the buffer data and capacity.
Definition: core.h:880
constexpr auto size() const noexcept -> size_t
Returns the size of this buffer.
Definition: core.h:902
buffer(buffer &&)=default
auto begin() noexcept -> T *
Definition: core.h:895
Definition: core.h:730
constexpr auto num_args() const -> int
Definition: core.h:742
FMT_CONSTEXPR void check_arg_id(int id)
Definition: core.h:751
FMT_CONSTEXPR void check_dynamic_spec(int arg_id)
Definition: core.h:757
FMT_CONSTEXPR compile_parse_context(basic_string_view< Char > format_str, int num_args, const type *types, ErrorHandler eh={}, int next_arg_id=0)
Definition: core.h:737
FMT_CONSTEXPR auto next_arg_id() -> int
Definition: core.h:745
constexpr auto arg_type(int id) const -> type
Definition: core.h:743
Definition: core.h:1085
FMT_CONSTEXPR20 void grow(size_t) override
Increases the buffer capacity to hold at least capacity elements.
Definition: core.h:1092
auto count() -> size_t
Definition: core.h:1101
counting_buffer()
Definition: core.h:1099
\rst A dynamic version of fmt::format_arg_store.
Definition: args.h:79
Definition: core.h:2234
typename ParseContext::char_type char_type
Definition: core.h:2236
FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler &other)
Definition: core.h:2242
FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs< char_type > &specs, ParseContext &ctx)
Definition: core.h:2238
FMT_CONSTEXPR void on_dynamic_precision(Id arg_id)
Definition: core.h:2251
FMT_CONSTEXPR void on_error(const char *message)
Definition: core.h:2255
FMT_CONSTEXPR void on_dynamic_width(Id arg_id)
Definition: core.h:2247
Definition: core.h:954
fixed_buffer_traits(size_t limit)
Definition: core.h:960
auto limit(size_t size) -> size_t
Definition: core.h:962
auto count() const -> size_t
Definition: core.h:961
\rst An array of references to arguments.
Definition: core.h:1870
FMT_CONSTEXPR FMT_INLINE format_arg_store(T &&... args)
Definition: core.h:1894
Definition: core.h:2935
FMT_CONSTEXPR void on_error(const char *message)
Definition: core.h:2987
FMT_CONSTEXPR format_string_checker(basic_string_view< Char > format_str, ErrorHandler eh)
Definition: core.h:2951
FMT_CONSTEXPR void on_text(const Char *, const Char *)
Definition: core.h:2960
FMT_CONSTEXPR auto on_format_specs(int id, const Char *begin, const Char *) -> const Char *
Definition: core.h:2980
FMT_CONSTEXPR auto on_arg_id(int id) -> int
Definition: core.h:2963
FMT_CONSTEXPR void on_replacement_field(int, const Char *)
Definition: core.h:2978
FMT_CONSTEXPR auto on_arg_id(basic_string_view< Char > id) -> int
Definition: core.h:2966
FMT_CONSTEXPR auto on_arg_id() -> int
Definition: core.h:2962
iterator_buffer(T *out, size_t n=buffer_size)
Definition: core.h:1026
auto count() const -> size_t
Definition: core.h:1043
auto out() -> T *
Definition: core.h:1039
FMT_CONSTEXPR20 void grow(size_t) override
Increases the buffer capacity to hold at least capacity elements.
Definition: core.h:1012
iterator_buffer(iterator_buffer &&other)
Definition: core.h:1028
iterator_buffer(T *out, size_t=0)
Definition: core.h:1053
auto out() -> T *
Definition: core.h:1055
FMT_CONSTEXPR20 void grow(size_t) override
Increases the buffer capacity to hold at least capacity elements.
Definition: core.h:1050
FMT_CONSTEXPR20 void grow(size_t capacity) override
Increases the buffer capacity to hold at least capacity elements.
Definition: core.h:1068
Definition: core.h:971
auto out() -> OutputIt
Definition: core.h:995
iterator_buffer(OutputIt out, size_t n=buffer_size)
Definition: core.h:989
auto count() const -> size_t
Definition: core.h:999
void flush()
Definition: core.h:982
iterator_buffer(iterator_buffer &&other)
Definition: core.h:991
FMT_CONSTEXPR20 void grow(size_t) override
Increases the buffer capacity to hold at least capacity elements.
Definition: core.h:978
~iterator_buffer()
Definition: core.h:993
Definition: core.h:1710
constexpr locale_ref()
Definition: core.h:1715
auto get() const -> Locale
Definition: core.h:2860
FMT_CONSTEXPR void end_precision()
Definition: core.h:2903
FMT_CONSTEXPR void on_zero()
Definition: core.h:2898
FMT_CONSTEXPR specs_checker(const Handler &handler, detail::type arg_type)
Definition: core.h:2870
FMT_CONSTEXPR void on_align(align_t align)
Definition: core.h:2873
FMT_CONSTEXPR void on_hash()
Definition: core.h:2888
FMT_CONSTEXPR void on_sign(sign_t s)
Definition: core.h:2878
FMT_CONSTEXPR void on_localized()
Definition: core.h:2893
Definition: core.h:2197
FMT_CONSTEXPR void on_sign(sign_t s)
Definition: core.h:2212
basic_format_specs< Char > & specs_
Definition: core.h:2199
FMT_CONSTEXPR void on_precision(int precision)
Definition: core.h:2222
FMT_CONSTEXPR specs_setter(basic_format_specs< Char > &specs)
Definition: core.h:2202
FMT_CONSTEXPR void on_hash()
Definition: core.h:2213
FMT_CONSTEXPR void on_zero()
Definition: core.h:2216
FMT_CONSTEXPR void on_localized()
Definition: core.h:2214
FMT_CONSTEXPR specs_setter(const specs_setter &other)
Definition: core.h:2205
FMT_CONSTEXPR void on_width(int width)
Definition: core.h:2221
FMT_CONSTEXPR void end_precision()
Definition: core.h:2225
FMT_CONSTEXPR void on_align(align_t align)
Definition: core.h:2208
FMT_CONSTEXPR void on_type(presentation_type type)
Definition: core.h:2227
FMT_CONSTEXPR void on_fill(basic_string_view< Char > fill)
Definition: core.h:2209
Definition: core.h:1240
FMT_CONSTEXPR FMT_INLINE value(const char_type *val)
Definition: core.h:1275
long double long_double_value
Definition: core.h:1256
value(unformattable_pointer)
constexpr FMT_INLINE value(char_type val)
Definition: core.h:1274
long long long_long_value
Definition: core.h:1248
const void * pointer
Definition: core.h:1257
constexpr FMT_INLINE value()
Definition: core.h:1263
value(unformattable_char)
constexpr FMT_INLINE value(bool val)
Definition: core.h:1273
constexpr FMT_INLINE value(int val)
Definition: core.h:1264
constexpr FMT_INLINE value(float val)
Definition: core.h:1270
constexpr FMT_INLINE value(unsigned long long val)
Definition: core.h:1267
FMT_INLINE value(const named_arg_info< char_type > *args, size_t size)
Definition: core.h:1284
value(unformattable)
constexpr FMT_INLINE value(unsigned val)
Definition: core.h:1265
constexpr FMT_INLINE value(long long val)
Definition: core.h:1266
value(unformattable_const)
bool bool_value
Definition: core.h:1252
monostate no_value
Definition: core.h:1245
constexpr FMT_INLINE value(double val)
Definition: core.h:1271
unsigned long long ulong_long_value
Definition: core.h:1249
FMT_INLINE value(uint128_opt val)
Definition: core.h:1269
char_type char_value
Definition: core.h:1253
int128_opt int128_value
Definition: core.h:1250
float float_value
Definition: core.h:1254
typename Context::char_type char_type
Definition: core.h:1242
int int_value
Definition: core.h:1246
FMT_INLINE value(long double val)
Definition: core.h:1272
FMT_INLINE value(const void *val)
Definition: core.h:1283
unsigned uint_value
Definition: core.h:1247
FMT_CONSTEXPR FMT_INLINE value(basic_string_view< char_type > val)
Definition: core.h:1279
FMT_CONSTEXPR FMT_INLINE value(T &val)
Definition: core.h:1287
custom_value< Context > custom
Definition: core.h:1259
named_arg_value< char_type > named_args
Definition: core.h:1260
uint128_opt uint128_value
Definition: core.h:1251
string_value< char_type > string
Definition: core.h:1258
FMT_INLINE value(int128_opt val)
Definition: core.h:1268
double double_value
Definition: core.h:1255
FMT_CONSTEXPR bool is_name_start(Char c)
Definition: core.h:2399
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:298
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2318
constexpr FMT_INLINE auto const_check(T value) -> T
Definition: core.h:356
#define FMT_ASSERT(condition, message)
Definition: core.h:369
FMT_NODISCARD FMT_INLINE auto format(format_string< T... > fmt, T &&... args) -> std::string
\rst Formats args according to specifications in fmt and returns the result as a string.
Definition: core.h:3204
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
\rst Visits an argument dispatching to the appropriate visit method based on the argument type.
Definition: core.h:1623
FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out) -> OutputIt
Definition: core.h:840
FMT_CONSTEXPR auto make_arg(T &&value) -> basic_format_arg< Context >
Definition: core.h:1764
FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char *begin, const Char *end, SpecHandler &&handler) -> const Char *
Definition: core.h:2561
FMT_CONSTEXPR auto code_point_length(const Char *begin) -> int
Definition: core.h:2306
#define FMT_ENUM_UNDERLYING_TYPE(type)
Definition: core.h:2071
std::integral_constant< bool, B > bool_constant
Definition: core.h:301
FMT_NODISCARD FMT_INLINE auto formatted_size(format_string< T... > fmt, T &&... args) -> size_t
Returns the number of chars in the output of format(fmt, args...).
Definition: core.h:3272
#define FMT_FORMAT_AS(Type, Base)
Definition: core.h:3116
#define FMT_USE_LONG_DOUBLE
Definition: core.h:192
#define FMT_FORWARD(...)
Definition: core.h:204
#define FMT_CONSTEVAL
Definition: core.h:272
#define FMT_TYPE_CONSTANT(Type, constant)
Definition: core.h:602
constexpr bool is_ascii_letter(Char c)
Definition: core.h:2286
basic_string_view< char > string_view
Definition: core.h:520
FMT_CONSTEXPR auto parse_replacement_field(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2634
FMT_CONSTEXPR auto code_point_length_impl(char c) -> int
Definition: core.h:2300
#define FMT_UNICODE
Definition: core.h:260
align::type align_t
Definition: core.h:2077
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
\rst Returns a named argument to be used in a formatting function.
Definition: core.h:1933
conditional_t< long_short, unsigned, unsigned long long > ulong_type
Definition: core.h:1325
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> bool
Definition: core.h:2758
typename std::remove_const< T >::type remove_const_t
Definition: core.h:305
#define FMT_FALLTHROUGH
Definition: core.h:174
#define FMT_NODISCARD
Definition: core.h:181
void init_named_args(named_arg_info< Char > *, int, int)
Definition: core.h:1177
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:303
uint128_opt
Definition: core.h:400
typename detail::char_t_impl< S >::type char_t
String's character type.
Definition: core.h:644
#define FMT_END_DETAIL_NAMESPACE
Definition: core.h:227
buffer_context< char > format_context
Definition: core.h:1844
@ is_unpacked_bit
Definition: core.h:1536
#define FMT_MODULE_EXPORT_BEGIN
Definition: core.h:224
FMT_API void vprint(string_view fmt, format_args args)
Definition: format-inl.h:1524
#define FMT_USE_FLOAT
Definition: core.h:186
auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) -> format_to_n_result< OutputIt >
Definition: core.h:3247
FMT_CONSTEXPR auto parse_precision(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2477
FMT_CONSTEXPR FMT_INLINE auto make_value(T &&val) -> value< Context >
Definition: core.h:1734
FMT_API void vprint_mojibake(std::FILE *, string_view, format_args)
Definition: core.h:3020
FMT_CONSTEXPR void check_string_type_spec(presentation_type type, ErrorHandler &&eh={})
Definition: core.h:2844
#define FMT_GCC_VERSION
Definition: core.h:32
constexpr auto count() -> size_t
Definition: core.h:1204
std::false_type has_fallback_formatter
Definition: core.h:1133
FMT_CONSTEXPR auto parse_presentation_type(Char type) -> presentation_type
Definition: core.h:2515
constexpr auto to_ascii(Char c) -> Char
Definition: core.h:2292
FMT_INLINE void print(format_string< T... > fmt, T &&... args)
\rst Formats args according to specifications in fmt and writes the output to stdout.
Definition: core.h:3293
constexpr auto count_named_args() -> size_t
Definition: core.h:1209
int128_opt
Definition: core.h:399
constexpr auto make_format_args(Args &&... args) -> format_arg_store< Context, remove_cvref_t< Args >... >
\rst Constructs a ~fmtformat_arg_store object that contains references to arguments and can be implic...
Definition: core.h:1916
#define FMT_GCC_PRAGMA(arg)
Definition: core.h:40
#define FMT_CONSTEXPR
Definition: core.h:106
FMT_CONSTEXPR FMT_INLINE void parse_format_string(basic_string_view< Char > format_str, Handler &&handler)
Definition: core.h:2674
@ has_named_args_bit
Definition: core.h:1537
std::is_constructible< typename Context::template formatter_type< T > > has_formatter
Definition: core.h:800
FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type, ErrorHandler &&eh)
Definition: core.h:2852
FMT_CONSTEXPR auto parse_width(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2443
type
Definition: core.h:575
@ int_type
@ custom_type
@ uint_type
@ uint128_type
@ string_type
@ bool_type
@ none_type
@ last_numeric_type
@ long_double_type
@ cstring_type
@ ulong_long_type
@ double_type
@ char_type
@ long_long_type
@ pointer_type
@ last_integer_type
@ int128_type
@ float_type
constexpr bool is_integral_type(type t)
Definition: core.h:622
arg_id_kind
Definition: core.h:2158
float_format
Definition: core.h:2772
FMT_NORETURN FMT_API void assert_fail(const char *file, int line, const char *message)
FMT_CONSTEXPR void check_int_type_spec(presentation_type type, ErrorHandler &&eh)
Definition: core.h:2750
bool_constant< !std::is_base_of< detail::unformattable, decltype(detail::arg_mapper< buffer_context< Char > >().map(std::declval< T >()))>::value &&!detail::has_fallback_formatter< T, Char >::value > is_formattable
Definition: core.h:1855
#define FMT_BEGIN_NAMESPACE
Definition: core.h:214
#define FMT_DEPRECATED
Definition: core.h:152
conditional_t< long_short, int, long long > long_type
Definition: core.h:1324
FMT_CONSTEXPR auto do_parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler) -> const Char *
Definition: core.h:2404
#define FMT_BEGIN_DETAIL_NAMESPACE
Definition: core.h:226
#define FMT_API
Definition: core.h:246
FMT_INLINE void check_format_string(const S &)
Definition: core.h:2994
@ long_short
Definition: core.h:1323
void vformat_to(buffer< Char > &buf, basic_string_view< Char > fmt, basic_format_args< FMT_BUFFER_CONTEXT(type_identity_t< Char >)> args, locale_ref loc={})
Definition: format.h:4056
FMT_BEGIN_DETAIL_NAMESPACE FMT_CONSTEXPR void ignore_unused(const T &...)
Definition: core.h:343
constexpr auto encode_types() -> unsigned long long
Definition: core.h:1723
constexpr FMT_INLINE auto is_constant_evaluated(bool default_value=false) noexcept -> bool
Definition: core.h:345
#define FMT_BUFFER_CONTEXT(Char)
Definition: core.h:1847
constexpr auto is_utf8() -> bool
Definition: core.h:415
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T > > > buffer_appender
Definition: core.h:1106
@ packed_arg_bits
Definition: core.h:1533
FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type, ErrorHandler &&eh={}) -> bool
Definition: core.h:2834
auto get_buffer(OutputIt out) -> iterator_buffer< OutputIt, T >
Definition: core.h:1110
constexpr auto count_statically_named_args() -> size_t
Definition: core.h:1214
#define FMT_ENABLE_IF(...)
Definition: core.h:335
FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string< T... > fmt, T &&... args) -> format_to_n_result< OutputIt >
\rst Formats args according to specifications in fmt, writes up to n characters of the result to the ...
Definition: core.h:3265
void void_t
Definition: core.h:1682
#define FMT_CONSTEXPR_CHAR_TRAITS
Definition: core.h:130
#define FMT_INLINE
Definition: core.h:199
auto get_iterator(Buffer &buf) -> decltype(buf.out())
Definition: core.h:1115
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition: core.h:407
auto convert_for_visit(T) -> monostate
Definition: core.h:402
FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char *begin, const Char *end, IDHandler &&handler) -> const Char *
Definition: core.h:2434
FMT_NORETURN FMT_API void throw_format_error(const char *message)
FMT_CONSTEXPR auto parse_nonnegative_int(const Char *&begin, const Char *end, int error_value) noexcept -> int
Definition: core.h:2336
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:536
#define FMT_NORETURN
Definition: core.h:163
#define FMT_MSC_WARNING(...)
Definition: core.h:57
typename type_identity< T >::type type_identity_t
Definition: core.h:309
FMT_INLINE auto format_to(OutputIt out, format_string< T... > fmt, T &&... args) -> OutputIt
\rst Formats args according to specifications in fmt, writes the result to the output iterator out an...
Definition: core.h:3233
@ max_packed_args
Definition: core.h:1535
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:300
#define FMT_CONSTEXPR20
Definition: core.h:114
auto get_container(std::back_insert_iterator< Container > it) -> Container &
Definition: core.h:829
sign::type sign_t
Definition: core.h:2081
typename std::remove_cv< remove_reference_t< T > >::type remove_cvref_t
Definition: core.h:307
auto runtime(string_view s) -> basic_runtime< char >
\rst Creates a runtime format string.
Definition: core.h:3187
constexpr int invalid_arg_index
Definition: core.h:2909
#define FMT_USE_DOUBLE
Definition: core.h:189
typename std::underlying_type< T >::type underlying_t
Definition: core.h:311
presentation_type
Definition: core.h:2110
#define FMT_END_NAMESPACE
Definition: core.h:217
FMT_BEGIN_DETAIL_NAMESPACE 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:812
constexpr bool is_arithmetic_type(type t)
Definition: core.h:626
#define FMT_MODULE_EXPORT_END
Definition: core.h:225
constexpr auto has_const_formatter() -> bool
Definition: core.h:823
FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs< Char > &specs, ErrorHandler &&eh={}) -> float_specs
Definition: core.h:2790
FMT_API auto vformat(string_view fmt, format_args args) -> std::string
Definition: format-inl.h:1466
auto find< false, char >(const char *first, const char *last, char value, const char *&out) -> bool
Definition: core.h:2326
FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view< Char > name) -> int
Definition: core.h:2925
FMT_CONSTEXPR auto parse_align(const Char *begin, const Char *end, Handler &&handler) -> const Char *
Definition: core.h:2360
constexpr auto digits10() noexcept -> int
Definition: format.h:1154
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1637
static const symbolic::SymbolExpr< internal::symbolic_last_tag > last
Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last...
Definition: IndexedViewHelper.h:38
typename units::detail::prefix< std::micro, U >::type micro
Represents the type of class U with the metric 'micro' prefix appended.
Definition: base.h:1481
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
Definition: IndexedViewHelper.h:81
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: core.h:2073
Definition: chrono.h:303
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:426
result
Definition: format.h:2556
constexpr auto format_as(Enum e) noexcept -> underlying_t< Enum >
Definition: format.h:3836
GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept
Definition: filesystem.hpp:5746
GHC_FS_API space_info space(const path &p, std::error_code &ec) noexcept
Definition: filesystem.hpp:4858
GHC_FS_API bool is_empty(const path &p, std::error_code &ec) noexcept
Definition: filesystem.hpp:4335
Definition: core.h:2078
Definition: StdDeque.h:50
static constexpr const unit_t< compound_unit< energy::joules, inverse< temperature::kelvin >, inverse< substance::moles > > > R(8.3144598)
Gas constant.
static constexpr const velocity::meters_per_second_t c(299792458.0)
Speed of light in vacuum.
b
Definition: data.h:44
FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t
Definition: core.h:1171
FMT_CONSTEXPR FMT_INLINE auto args() const -> const T *
Definition: core.h:1170
FMT_CONSTEXPR FMT_INLINE arg_data(const U &... init)
Definition: core.h:1169
Definition: core.h:1150
T args_[1+(NUM_ARGS !=0 ? NUM_ARGS :+1)]
Definition: core.h:1153
arg_data(const arg_data &other)=delete
auto args() const -> const T *
Definition: core.h:1159
auto named_args() -> named_arg_info< Char > *
Definition: core.h:1160
named_arg_info< Char > named_args_[NUM_NAMED_ARGS]
Definition: core.h:1154
arg_data(const U &... init)
Definition: core.h:1157
Definition: core.h:1487
Definition: core.h:1345
FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float
Definition: core.h:1392
FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double
Definition: core.h:1394
FMT_CONSTEXPR FMT_INLINE auto map(const T(&values)[N]) -> const T(&)[N]
Definition: core.h:1461
FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned
Definition: core.h:1357
typename Context::char_type char_type
Definition: core.h:1346
FMT_CONSTEXPR FMT_INLINE auto do_map(T &&val) -> T &
Definition: core.h:1497
auto map(...) -> unformattable
Definition: core.h:1524
FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(const T &val) -> decltype(std::declval< arg_mapper >().map(static_cast< underlying_t< T > >(val)))
Definition: core.h:1470
FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double
Definition: core.h:1393
FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type
Definition: core.h:1359
FMT_CONSTEXPR FMT_INLINE auto map(const char_type *val) -> const char_type *
Definition: core.h:1401
FMT_CONSTEXPR FMT_INLINE auto map(int128_opt val) -> int128_opt
Definition: core.h:1367
FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int
Definition: core.h:1356
FMT_CONSTEXPR FMT_INLINE auto map(const T &val) -> decltype(std::declval< arg_mapper >().map(format_as(T())))
Definition: core.h:1478
FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long
Definition: core.h:1362
FMT_CONSTEXPR FMT_INLINE auto map(char_type *val) -> const char_type *
Definition: core.h:1398
FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int
Definition: core.h:1348
FMT_CONSTEXPR auto map(const T &) -> unformattable_pointer
Definition: core.h:1455
FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void *
Definition: core.h:1441
FMT_CONSTEXPR FMT_INLINE auto map(T) -> unformattable_char
Definition: core.h:1388
FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool
Definition: core.h:1373
FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned
Definition: core.h:1353
FMT_CONSTEXPR FMT_INLINE auto map(uint128_opt val) -> uint128_opt
Definition: core.h:1370
FMT_CONSTEXPR FMT_INLINE auto map(const T &val) -> basic_string_view< char_type >
Definition: core.h:1407
FMT_CONSTEXPR FMT_INLINE auto map(void *val) -> const void *
Definition: core.h:1437
FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val) -> unsigned long long
Definition: core.h:1363
FMT_CONSTEXPR FMT_INLINE auto map(T &&val) -> decltype(this->do_map(std::forward< T >(val)))
Definition: core.h:1513
FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type
Definition: core.h:1358
FMT_CONSTEXPR FMT_INLINE auto map(T val) -> char_type
Definition: core.h:1377
FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int
Definition: core.h:1352
FMT_CONSTEXPR FMT_INLINE auto map(const T &) -> unformattable_char
Definition: core.h:1414
FMT_CONSTEXPR FMT_INLINE auto map(const void *val) -> const void *
Definition: core.h:1438
FMT_CONSTEXPR FMT_INLINE auto do_map(T &&) -> unformattable_const
Definition: core.h:1501
FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned
Definition: core.h:1349
FMT_CONSTEXPR FMT_INLINE auto map(const T &named_arg) -> decltype(std::declval< arg_mapper >().map(named_arg.value))
Definition: core.h:1519
Definition: core.h:2161
FMT_CONSTEXPR arg_ref(basic_string_view< Char > name)
Definition: core.h:2166
FMT_CONSTEXPR arg_ref()
Definition: core.h:2162
FMT_CONSTEXPR auto operator=(int idx) -> arg_ref &
Definition: core.h:2169
arg_id_kind kind
Definition: core.h:2175
FMT_CONSTEXPR arg_ref(int index)
Definition: core.h:2164
Definition: core.h:2194
Definition: core.h:2134
presentation_type type
Definition: core.h:2137
sign_t sign
Definition: core.h:2139
detail::fill_t< Char > fill
Definition: core.h:2142
align_t align
Definition: core.h:2138
bool alt
Definition: core.h:2140
int precision
Definition: core.h:2136
constexpr basic_format_specs()
Definition: core.h:2144
int width
Definition: core.h:2135
bool localized
Definition: core.h:2141
Definition: core.h:3137
basic_string_view< Char > str
Definition: core.h:3137
Definition: core.h:948
buffer_traits(size_t)
Definition: core.h:949
auto limit(size_t size) -> size_t
Definition: core.h:951
auto count() const -> size_t
Definition: core.h:950
decltype(to_string_view(std::declval< S >())) result
Definition: core.h:571
typename result::value_type type
Definition: core.h:572
Definition: core.h:569
Definition: core.h:529
Definition: core.h:320
Definition: core.h:319
Definition: core.h:1233
void(* format)(void *arg, parse_context &parse_ctx, Context &ctx)
Definition: core.h:1236
void * value
Definition: core.h:1235
typename Context::parse_context_type parse_context
Definition: core.h:1234
Definition: format.h:1544
Definition: core.h:314
Definition: core.h:313
Definition: core.h:2189
arg_ref< Char > precision_ref
Definition: core.h:2191
arg_ref< Char > width_ref
Definition: core.h:2190
Definition: core.h:632
FMT_NORETURN void on_error(const char *message)
Definition: core.h:637
constexpr error_handler()=default
constexpr error_handler(const error_handler &)=default
Definition: core.h:1123
fallback_formatter()=delete
Definition: core.h:2086
FMT_CONSTEXPR void operator=(basic_string_view< Char > s)
Definition: core.h:2093
FMT_CONSTEXPR auto operator[](size_t index) const -> const Char &
Definition: core.h:2104
constexpr auto size() const -> size_t
Definition: core.h:2100
constexpr auto data() const -> const Char *
Definition: core.h:2101
FMT_CONSTEXPR auto operator[](size_t index) -> Char &
Definition: core.h:2103
Definition: core.h:2779
float_format format
Definition: core.h:2781
int precision
Definition: core.h:2780
bool upper
Definition: core.h:2783
bool showpoint
Definition: core.h:2786
sign_t sign
Definition: core.h:2782
bool binary32
Definition: core.h:2785
bool locale
Definition: core.h:2784
Definition: core.h:3238
OutputIt out
Iterator past the end of the output range.
Definition: core.h:3240
size_t size
Total (not truncated) output size.
Definition: core.h:3242
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: core.h:3037
FMT_CONSTEXPR auto format(const T &val, FormatContext &ctx) const -> decltype(ctx.out())
Definition: core.h:791
formatter()=delete
Definition: core.h:1333
static auto check(U *) -> std::true_type
static auto check(...) -> std::false_type
Definition: core.h:1696
Specifies if T is a character type.
Definition: core.h:523
Definition: core.h:532
Definition: core.h:1702
Definition: core.h:803
Definition: core.h:1179
Definition: core.h:1686
Definition: core.h:1180
Definition: core.h:566
Definition: core.h:325
constexpr monostate()
Definition: core.h:326
Definition: core.h:1144
const Char * name
Definition: core.h:1145
int id
Definition: core.h:1146
Definition: core.h:1228
const named_arg_info< Char > * data
Definition: core.h:1229
size_t size
Definition: core.h:1230
Definition: core.h:1138
const T & value
Definition: core.h:1140
const Char * name
Definition: core.h:1139
named_arg(const Char *n, const T &v)
Definition: core.h:1141
Definition: core.h:382
Definition: core.h:1223
const Char * data
Definition: core.h:1224
size_t size
Definition: core.h:1225
remove_cvref_t< decltype(T::value)> type
Definition: core.h:2730
Definition: core.h:2726
T type
Definition: core.h:2727
Definition: core.h:600
Definition: core.h:308
T type
Definition: core.h:308
Definition: core.h:1219
Definition: core.h:1220
Definition: core.h:1221
Definition: core.h:1218
Definition: core.h:1136
Definition: core.h:2176
int index
Definition: core.h:2180
basic_string_view< Char > name
Definition: core.h:2181
FMT_CONSTEXPR value(basic_string_view< Char > n)
Definition: core.h:2178
FMT_CONSTEXPR value(int id=0)
Definition: core.h:2177
#define S(label, offset, message)
Definition: Errors.h:118