WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
std.h
Go to the documentation of this file.
1// Formatting library for C++ - formatters for standard library types
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_STD_H_
9#define FMT_STD_H_
10
11#include "format.h"
12#include "ostream.h"
13
14#ifndef FMT_MODULE
15# include <atomic>
16# include <bitset>
17# include <complex>
18# include <exception>
19# include <functional> // std::reference_wrapper
20# include <memory>
21# include <thread>
22# include <type_traits>
23# include <typeinfo> // std::type_info
24# include <utility> // std::make_index_sequence
25
26// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
27# if FMT_CPLUSPLUS >= 201703L
28# if FMT_HAS_INCLUDE(<filesystem>) && \
29 (!defined(FMT_CPP_LIB_FILESYSTEM) || FMT_CPP_LIB_FILESYSTEM != 0)
30# include <filesystem>
31# endif
32# if FMT_HAS_INCLUDE(<variant>)
33# include <variant>
34# endif
35# if FMT_HAS_INCLUDE(<optional>)
36# include <optional>
37# endif
38# endif
39// Use > instead of >= in the version check because <source_location> may be
40// available after C++17 but before C++20 is marked as implemented.
41# if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE(<source_location>)
42# include <source_location>
43# endif
44# if FMT_CPLUSPLUS > 202002L && FMT_HAS_INCLUDE(<expected>)
45# include <expected>
46# endif
47#endif // FMT_MODULE
48
49#if FMT_HAS_INCLUDE(<version>)
50# include <version>
51#endif
52
53// GCC 4 does not support FMT_HAS_INCLUDE.
54#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
55# include <cxxabi.h>
56// Android NDK with gabi++ library on some architectures does not implement
57// abi::__cxa_demangle().
58# ifndef __GABIXX_CXXABI_H__
59# define FMT_HAS_ABI_CXA_DEMANGLE
60# endif
61#endif
62
63#ifdef FMT_CPP_LIB_FILESYSTEM
64// Use the provided definition.
65#elif defined(__cpp_lib_filesystem)
66# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
67#else
68# define FMT_CPP_LIB_FILESYSTEM 0
69#endif
70
71#ifdef FMT_CPP_LIB_VARIANT
72// Use the provided definition.
73#elif defined(__cpp_lib_variant)
74# define FMT_CPP_LIB_VARIANT __cpp_lib_variant
75#else
76# define FMT_CPP_LIB_VARIANT 0
77#endif
78
80namespace detail {
81
82#if FMT_CPP_LIB_FILESYSTEM
83
84template <typename Char, typename PathChar>
85auto get_path_string(const std::filesystem::path& p,
86 const std::basic_string<PathChar>& native) {
87 if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>)
88 return to_utf8<wchar_t>(native, to_utf8_error_policy::replace);
89 else
90 return p.string<Char>();
91}
92
93template <typename Char, typename PathChar>
94void write_escaped_path(basic_memory_buffer<Char>& quoted,
95 const std::filesystem::path& p,
96 const std::basic_string<PathChar>& native) {
97 if constexpr (std::is_same_v<Char, char> &&
98 std::is_same_v<PathChar, wchar_t>) {
100 write_escaped_string<wchar_t>(std::back_inserter(buf), native);
101 bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
102 FMT_ASSERT(valid, "invalid utf16");
103 } else if constexpr (std::is_same_v<Char, PathChar>) {
105 std::back_inserter(quoted), native);
106 } else {
107 write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
108 }
109}
110
111#endif // FMT_CPP_LIB_FILESYSTEM
112
113#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
114
115template <typename Char, typename OutputIt, typename T, typename FormatContext>
116auto write_escaped_alternative(OutputIt out, const T& v, FormatContext& ctx)
117 -> OutputIt {
118 if constexpr (has_to_string_view<T>::value)
120 if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
121
124 return underlying.format(v, ctx);
125}
126#endif
127
128#if FMT_CPP_LIB_VARIANT
129
130template <typename> struct is_variant_like_ : std::false_type {};
131template <typename... Types>
132struct is_variant_like_<std::variant<Types...>> : std::true_type {};
133
134template <typename Variant, typename Char> class is_variant_formattable {
135 template <size_t... Is>
136 static auto check(std::index_sequence<Is...>) -> std::conjunction<
138
139 public:
140 static constexpr bool value = decltype(check(
141 std::make_index_sequence<std::variant_size<Variant>::value>()))::value;
142};
143
144#endif // FMT_CPP_LIB_VARIANT
145
146#if FMT_USE_RTTI
147inline auto normalize_libcxx_inline_namespaces(string_view demangled_name_view,
148 char* begin) -> string_view {
149 // Normalization of stdlib inline namespace names.
150 // libc++ inline namespaces.
151 // std::__1::* -> std::*
152 // std::__1::__fs::* -> std::*
153 // libstdc++ inline namespaces.
154 // std::__cxx11::* -> std::*
155 // std::filesystem::__cxx11::* -> std::filesystem::*
156 if (demangled_name_view.starts_with("std::")) {
157 char* to = begin + 5; // std::
158 for (const char *from = to, *end = begin + demangled_name_view.size();
159 from < end;) {
160 // This is safe, because demangled_name is NUL-terminated.
161 if (from[0] == '_' && from[1] == '_') {
162 const char* next = from + 1;
163 while (next < end && *next != ':') next++;
164 if (next[0] == ':' && next[1] == ':') {
165 from = next + 2;
166 continue;
167 }
168 }
169 *to++ = *from++;
170 }
171 demangled_name_view = {begin, detail::to_unsigned(to - begin)};
172 }
173 return demangled_name_view;
174}
175
176template <class OutputIt>
177auto normalize_msvc_abi_name(string_view abi_name_view, OutputIt out)
178 -> OutputIt {
179 const string_view demangled_name(abi_name_view);
180 for (size_t i = 0; i < demangled_name.size(); ++i) {
181 auto sub = demangled_name;
182 sub.remove_prefix(i);
183 if (sub.starts_with("enum ")) {
184 i += 4;
185 continue;
186 }
187 if (sub.starts_with("class ") || sub.starts_with("union ")) {
188 i += 5;
189 continue;
190 }
191 if (sub.starts_with("struct ")) {
192 i += 6;
193 continue;
194 }
195 if (*sub.begin() != ' ') *out++ = *sub.begin();
196 }
197 return out;
198}
199
200template <typename OutputIt>
201auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
202# ifdef FMT_HAS_ABI_CXA_DEMANGLE
203 int status = 0;
204 size_t size = 0;
205 std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
206 abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &free);
207
208 string_view demangled_name_view;
209 if (demangled_name_ptr) {
210 demangled_name_view = normalize_libcxx_inline_namespaces(
211 demangled_name_ptr.get(), demangled_name_ptr.get());
212 } else {
213 demangled_name_view = string_view(ti.name());
214 }
215 return detail::write_bytes<char>(out, demangled_name_view);
216# elif FMT_MSC_VERSION && defined(_MSVC_STL_UPDATE)
217 return normalize_msvc_abi_name(ti.name(), out);
218# elif FMT_MSC_VERSION && defined(_LIBCPP_VERSION)
219 const string_view demangled_name = ti.name();
220 std::string name_copy(demangled_name.size(), '\0');
221 // normalize_msvc_abi_name removes class, struct, union etc that MSVC has in
222 // front of types
223 name_copy.erase(normalize_msvc_abi_name(demangled_name, name_copy.begin()),
224 name_copy.end());
225 // normalize_libcxx_inline_namespaces removes the inline __1, __2, etc
226 // namespaces libc++ uses for ABI versioning On MSVC ABI + libc++
227 // environments, we need to eliminate both of them.
228 const string_view normalized_name =
229 normalize_libcxx_inline_namespaces(name_copy, name_copy.data());
230 return detail::write_bytes<char>(out, normalized_name);
231# else
232 return detail::write_bytes<char>(out, string_view(ti.name()));
233# endif
234}
235
236#endif // FMT_USE_RTTI
237
238template <typename T, typename Enable = void>
239struct has_flip : std::false_type {};
240
241template <typename T>
242struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
243 : std::true_type {};
244
245template <typename T> struct is_bit_reference_like {
246 static constexpr bool value = std::is_convertible<T, bool>::value &&
247 std::is_nothrow_assignable<T, bool>::value &&
249};
250
251// Workaround for libc++ incompatibility with C++ standard.
252// According to the Standard, `bitset::operator[] const` returns bool.
253#if defined(_LIBCPP_VERSION) && !defined(FMT_IMPORT_STD)
254template <typename C>
255struct is_bit_reference_like<std::__bit_const_reference<C>> {
256 static constexpr bool value = true;
257};
258#endif
259
260template <typename T, typename Enable = void>
261struct has_format_as : std::false_type {};
262template <typename T>
263struct has_format_as<T, void_t<decltype(format_as(std::declval<const T&>()))>>
264 : std::true_type {};
265
266template <typename T, typename Enable = void>
267struct has_format_as_member : std::false_type {};
268template <typename T>
270 T, void_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>>
271 : std::true_type {};
272
273} // namespace detail
274
275template <typename T, typename Deleter>
276auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
277 return p.get();
278}
279template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
280 return p.get();
281}
282
283#if FMT_CPP_LIB_FILESYSTEM
284
285template <typename Char> struct formatter<std::filesystem::path, Char> {
286 private:
287 format_specs specs_;
288 detail::arg_ref<Char> width_ref_;
289 bool debug_ = false;
290 char path_type_ = 0;
291
292 public:
293 FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
294
295 FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
296 auto it = ctx.begin(), end = ctx.end();
297 if (it == end) return it;
298
299 it = detail::parse_align(it, end, specs_);
300 if (it == end) return it;
301
302 Char c = *it;
303 if ((c >= '0' && c <= '9') || c == '{')
304 it = detail::parse_width(it, end, specs_, width_ref_, ctx);
305 if (it != end && *it == '?') {
306 debug_ = true;
307 ++it;
308 }
309 if (it != end && (*it == 'g')) path_type_ = detail::to_ascii(*it++);
310 return it;
311 }
312
313 template <typename FormatContext>
314 auto format(const std::filesystem::path& p, FormatContext& ctx) const {
315 auto specs = specs_;
316 auto path_string =
317 !path_type_ ? p.native()
318 : p.generic_string<std::filesystem::path::value_type>();
319
320 detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
321 ctx);
322 if (!debug_) {
323 auto s = detail::get_path_string<Char>(p, path_string);
324 return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
325 }
326 auto quoted = basic_memory_buffer<Char>();
327 detail::write_escaped_path(quoted, p, path_string);
328 return detail::write(ctx.out(),
329 basic_string_view<Char>(quoted.data(), quoted.size()),
330 specs);
331 }
332};
333
334class path : public std::filesystem::path {
335 public:
336 auto display_string() const -> std::string {
337 const std::filesystem::path& base = *this;
338 return fmt::format(FMT_STRING("{}"), base);
339 }
340 auto system_string() const -> std::string { return string(); }
341
342 auto generic_display_string() const -> std::string {
343 const std::filesystem::path& base = *this;
344 return fmt::format(FMT_STRING("{:g}"), base);
345 }
346 auto generic_system_string() const -> std::string { return generic_string(); }
347};
348
349#endif // FMT_CPP_LIB_FILESYSTEM
350
351template <size_t N, typename Char>
352struct formatter<std::bitset<N>, Char>
353 : nested_formatter<basic_string_view<Char>, Char> {
354 private:
355 // This is a functor because C++11 doesn't support generic lambdas.
356 struct writer {
357 const std::bitset<N>& bs;
358
359 template <typename OutputIt>
360 FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt {
361 for (auto pos = N; pos > 0; --pos)
362 out = detail::write<Char>(out, bs[pos - 1] ? Char('1') : Char('0'));
363 return out;
364 }
365 };
366
367 public:
368 template <typename FormatContext>
369 auto format(const std::bitset<N>& bs, FormatContext& ctx) const
370 -> decltype(ctx.out()) {
371 return this->write_padded(ctx, writer{bs});
372 }
373};
374
375template <typename Char>
376struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
377
378#ifdef __cpp_lib_optional
379template <typename T, typename Char>
380struct formatter<std::optional<T>, Char,
381 std::enable_if_t<is_formattable<T, Char>::value>> {
382 private:
383 formatter<std::remove_cv_t<T>, Char> underlying_;
384 static constexpr basic_string_view<Char> optional =
385 detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',
386 '('>{};
387 static constexpr basic_string_view<Char> none =
388 detail::string_literal<Char, 'n', 'o', 'n', 'e'>{};
389
390 public:
391 FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
392 detail::maybe_set_debug_format(underlying_, true);
393 return underlying_.parse(ctx);
394 }
395
396 template <typename FormatContext>
397 auto format(const std::optional<T>& opt, FormatContext& ctx) const
398 -> decltype(ctx.out()) {
399 if (!opt) return detail::write<Char>(ctx.out(), none);
400
401 auto out = ctx.out();
402 out = detail::write<Char>(out, optional);
403 ctx.advance_to(out);
404 out = underlying_.format(*opt, ctx);
405 return detail::write(out, ')');
406 }
407};
408#endif // __cpp_lib_optional
409
410#ifdef __cpp_lib_expected
411template <typename T, typename E, typename Char>
412struct formatter<std::expected<T, E>, Char,
413 std::enable_if_t<(std::is_void<T>::value ||
414 is_formattable<T, Char>::value) &&
415 is_formattable<E, Char>::value>> {
416 FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
417 return ctx.begin();
418 }
419
420 template <typename FormatContext>
421 auto format(const std::expected<T, E>& value, FormatContext& ctx) const
422 -> decltype(ctx.out()) {
423 auto out = ctx.out();
424
425 if (value.has_value()) {
426 out = detail::write<Char>(out, "expected(");
427 if constexpr (!std::is_void<T>::value)
428 out = detail::write_escaped_alternative<Char>(out, *value, ctx);
429 } else {
430 out = detail::write<Char>(out, "unexpected(");
431 out = detail::write_escaped_alternative<Char>(out, value.error(), ctx);
432 }
433 *out++ = ')';
434 return out;
435 }
436};
437#endif // __cpp_lib_expected
438
439#ifdef __cpp_lib_source_location
440template <> struct formatter<std::source_location> {
441 FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }
442
443 template <typename FormatContext>
444 auto format(const std::source_location& loc, FormatContext& ctx) const
445 -> decltype(ctx.out()) {
446 auto out = ctx.out();
447 out = detail::write(out, loc.file_name());
448 out = detail::write(out, ':');
449 out = detail::write<char>(out, loc.line());
450 out = detail::write(out, ':');
451 out = detail::write<char>(out, loc.column());
452 out = detail::write(out, ": ");
453 out = detail::write(out, loc.function_name());
454 return out;
455 }
456};
457#endif
458
459#if FMT_CPP_LIB_VARIANT
460
461template <typename T> struct is_variant_like {
462 static constexpr bool value = detail::is_variant_like_<T>::value;
463};
464
465template <typename Char> struct formatter<std::monostate, Char> {
466 FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
467 return ctx.begin();
468 }
469
470 template <typename FormatContext>
471 auto format(const std::monostate&, FormatContext& ctx) const
472 -> decltype(ctx.out()) {
473 return detail::write<Char>(ctx.out(), "monostate");
474 }
475};
476
477template <typename Variant, typename Char>
478struct formatter<Variant, Char,
479 std::enable_if_t<std::conjunction_v<
480 is_variant_like<Variant>,
481 detail::is_variant_formattable<Variant, Char>>>> {
482 FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
483 return ctx.begin();
484 }
485
486 template <typename FormatContext>
487 auto format(const Variant& value, FormatContext& ctx) const
488 -> decltype(ctx.out()) {
489 auto out = ctx.out();
490
491 out = detail::write<Char>(out, "variant(");
492 FMT_TRY {
493 std::visit(
494 [&](const auto& v) {
495 out = detail::write_escaped_alternative<Char>(out, v, ctx);
496 },
497 value);
498 }
499 FMT_CATCH(const std::bad_variant_access&) {
500 detail::write<Char>(out, "valueless by exception");
501 }
502 *out++ = ')';
503 return out;
504 }
505};
506
507#endif // FMT_CPP_LIB_VARIANT
508
509template <> struct formatter<std::error_code> {
510 private:
511 format_specs specs_;
512 detail::arg_ref<char> width_ref_;
513 bool debug_ = false;
514
515 public:
516 FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
517
518 FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
519 auto it = ctx.begin(), end = ctx.end();
520 if (it == end) return it;
521
522 it = detail::parse_align(it, end, specs_);
523
524 char c = *it;
525 if (it != end && ((c >= '0' && c <= '9') || c == '{'))
526 it = detail::parse_width(it, end, specs_, width_ref_, ctx);
527
528 if (it != end && *it == '?') {
529 debug_ = true;
530 ++it;
531 }
532 if (it != end && *it == 's') {
533 specs_.set_type(presentation_type::string);
534 ++it;
535 }
536 return it;
537 }
538
539 template <typename FormatContext>
540 FMT_CONSTEXPR20 auto format(const std::error_code& ec,
541 FormatContext& ctx) const -> decltype(ctx.out()) {
542 auto specs = specs_;
543 detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
544 ctx);
545 auto buf = memory_buffer();
546 if (specs_.type() == presentation_type::string) {
547 buf.append(ec.message());
548 } else {
549 buf.append(string_view(ec.category().name()));
550 buf.push_back(':');
551 detail::write<char>(appender(buf), ec.value());
552 }
553 auto quoted = memory_buffer();
554 auto str = string_view(buf.data(), buf.size());
555 if (debug_) {
556 detail::write_escaped_string<char>(std::back_inserter(quoted), str);
557 str = string_view(quoted.data(), quoted.size());
558 }
559 return detail::write<char>(ctx.out(), str, specs);
560 }
561};
562
563#if FMT_USE_RTTI
564template <> struct formatter<std::type_info> {
565 public:
566 FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
567 return ctx.begin();
568 }
569
570 template <typename Context>
571 auto format(const std::type_info& ti, Context& ctx) const
572 -> decltype(ctx.out()) {
573 return detail::write_demangled_name(ctx.out(), ti);
574 }
575};
576#endif // FMT_USE_RTTI
577
578template <typename T>
580 T, char,
581 typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
582 private:
583 bool with_typename_ = false;
584
585 public:
586 FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
587 auto it = ctx.begin();
588 auto end = ctx.end();
589 if (it == end || *it == '}') return it;
590 if (*it == 't') {
591 ++it;
592 with_typename_ = FMT_USE_RTTI != 0;
593 }
594 return it;
595 }
596
597 template <typename Context>
598 auto format(const std::exception& ex, Context& ctx) const
599 -> decltype(ctx.out()) {
600 auto out = ctx.out();
601#if FMT_USE_RTTI
602 if (with_typename_) {
603 out = detail::write_demangled_name(out, typeid(ex));
604 *out++ = ':';
605 *out++ = ' ';
606 }
607#endif
608 return detail::write_bytes<char>(out, string_view(ex.what()));
609 }
610};
611
612// We can't use std::vector<bool, Allocator>::reference and
613// std::bitset<N>::reference because the compiler can't deduce Allocator and N
614// in partial specialization.
615template <typename BitRef, typename Char>
616struct formatter<BitRef, Char,
617 enable_if_t<detail::is_bit_reference_like<BitRef>::value>>
618 : formatter<bool, Char> {
619 template <typename FormatContext>
620 FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const
621 -> decltype(ctx.out()) {
622 return formatter<bool, Char>::format(v, ctx);
623 }
624};
625
626template <typename T, typename Char>
627struct formatter<std::atomic<T>, Char,
628 enable_if_t<is_formattable<T, Char>::value>>
629 : formatter<T, Char> {
630 template <typename FormatContext>
631 auto format(const std::atomic<T>& v, FormatContext& ctx) const
632 -> decltype(ctx.out()) {
633 return formatter<T, Char>::format(v.load(), ctx);
634 }
635};
636
637#ifdef __cpp_lib_atomic_flag_test
638template <typename Char>
639struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
640 template <typename FormatContext>
641 auto format(const std::atomic_flag& v, FormatContext& ctx) const
642 -> decltype(ctx.out()) {
643 return formatter<bool, Char>::format(v.test(), ctx);
644 }
645};
646#endif // __cpp_lib_atomic_flag_test
647
648template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
649 private:
651
652 template <typename FormatContext, typename OutputIt>
653 FMT_CONSTEXPR auto do_format(const std::complex<T>& c,
655 FormatContext& ctx, OutputIt out) const
656 -> OutputIt {
657 if (c.real() != 0) {
658 *out++ = Char('(');
659 out = detail::write<Char>(out, c.real(), specs, ctx.locale());
660 specs.set_sign(sign::plus);
661 out = detail::write<Char>(out, c.imag(), specs, ctx.locale());
662 if (!detail::isfinite(c.imag())) *out++ = Char(' ');
663 *out++ = Char('i');
664 *out++ = Char(')');
665 return out;
666 }
667 out = detail::write<Char>(out, c.imag(), specs, ctx.locale());
668 if (!detail::isfinite(c.imag())) *out++ = Char(' ');
669 *out++ = Char('i');
670 return out;
671 }
672
673 public:
674 FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
675 if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
676 return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
678 }
679
680 template <typename FormatContext>
681 auto format(const std::complex<T>& c, FormatContext& ctx) const
682 -> decltype(ctx.out()) {
683 auto specs = specs_;
684 if (specs.dynamic()) {
686 specs.width_ref, ctx);
688 specs.precision_ref, ctx);
689 }
690
691 if (specs.width == 0) return do_format(c, specs, ctx, ctx.out());
692 auto buf = basic_memory_buffer<Char>();
693
694 auto outer_specs = format_specs();
695 outer_specs.width = specs.width;
696 outer_specs.copy_fill_from(specs);
697 outer_specs.set_align(specs.align());
698
699 specs.width = 0;
700 specs.set_fill({});
701 specs.set_align(align::none);
702
703 do_format(c, specs, ctx, basic_appender<Char>(buf));
704 return detail::write<Char>(ctx.out(),
705 basic_string_view<Char>(buf.data(), buf.size()),
706 outer_specs);
707 }
708};
709
710template <typename T, typename Char>
711struct formatter<std::reference_wrapper<T>, Char,
712 // Guard against format_as because reference_wrapper is
713 // implicitly convertible to T&.
714 enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value &&
715 !detail::has_format_as<T>::value &&
716 !detail::has_format_as_member<T>::value>>
717 : formatter<remove_cvref_t<T>, Char> {
718 template <typename FormatContext>
719 auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const
720 -> decltype(ctx.out()) {
721 return formatter<remove_cvref_t<T>, Char>::format(ref.get(), ctx);
722 }
723};
724
726
727#endif // FMT_STD_H_
constexpr auto format_as(HAL_AddressableLEDColorOrder order)
Definition AddressableLEDTypes.h:34
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 glfw and nanopb were modified for use in 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:140
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 glfw and nanopb were modified for use in 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 or merely the Work and Derivative Works thereof Contribution shall mean any work of including the original version of the Work and any modifications or additions to that Work or Derivative Works that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner For the purposes of this submitted means any form of or written communication sent to the Licensor or its including but not limited to communication on electronic mailing source code control and issue tracking systems that are managed or on behalf the Licensor for the purpose of discussing and improving the but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as Not a Contribution Contributor shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work Grant of Copyright License Subject to the terms and conditions of this each Contributor hereby grants to You a non no royalty free
Definition ThirdPartyNotices.txt:163
typename std::enable_if< B, T >::type enable_if_t
Definition base.h:307
#define FMT_ASSERT(condition, message)
Definition base.h:394
basic_string_view< char > string_view
Definition base.h:620
#define FMT_TRY
Definition base.h:162
basic_appender< char > appender
Definition base.h:623
#define FMT_CONSTEXPR
Definition base.h:113
@ none
Definition base.h:688
#define FMT_BEGIN_NAMESPACE
Definition base.h:256
@ plus
Definition base.h:689
void void_t
Definition base.h:331
#define FMT_CATCH(x)
Definition base.h:163
#define FMT_CONSTEXPR20
Definition base.h:143
@ none
Definition base.h:667
@ string
Definition base.h:669
#define FMT_END_NAMESPACE
Definition base.h:259
bool_constant<!std::is_same< detail::mapped_t< conditional_t< std::is_void< T >::value, int *, T >, Char >, void >::value > is_formattable
Definition base.h:2797
Definition base.h:2484
A dynamically growing memory buffer for trivially copyable/constructible types with the first SIZE el...
Definition format.h:797
FMT_CONSTEXPR void set_fill(char c)
Definition base.h:817
constexpr auto align() const -> align
Definition base.h:751
FMT_CONSTEXPR auto dynamic_precision() const -> arg_id_kind
Definition base.h:765
FMT_CONSTEXPR void set_sign(fmt::sign s)
Definition base.h:781
constexpr auto dynamic() const -> bool
Definition base.h:774
constexpr auto dynamic_width() const -> arg_id_kind
Definition base.h:758
FMT_CONSTEXPR void set_align(fmt::align a)
Definition base.h:754
An implementation of std::basic_string_view for pre-C++17.
Definition base.h:522
constexpr auto size() const noexcept -> size_t
Returns the string size.
Definition base.h:567
constexpr auto begin() const noexcept -> iterator
Definition base.h:569
FMT_CONSTEXPR void remove_prefix(size_t n) noexcept
Definition base.h:576
FMT_CONSTEXPR auto starts_with(basic_string_view< Char > sv) const noexcept -> bool
Definition base.h:581
auto convert(basic_string_view< WChar > s, to_utf8_error_policy policy=to_utf8_error_policy::abort) -> bool
Definition format.h:1340
Definition base.h:2178
Parsing context consisting of a format string range being parsed and an argument counter for automati...
Definition base.h:857
constexpr auto begin() const noexcept -> iterator
Returns an iterator to the beginning of the format string range being parsed.
Definition base.h:876
FMT_CONSTEXPR void advance_to(iterator it)
Advances the begin iterator to it.
Definition base.h:882
constexpr auto end() const noexcept -> iterator
Returns an iterator past the end of the format string range being parsed.
Definition base.h:879
#define FMT_STRING(s)
Constructs a legacy compile-time format string from a string literal s.
Definition format.h:4251
T * p
Definition format.h:758
FMT_INLINE auto format(locale_ref loc, format_string< T... > fmt, T &&... args) -> std::string
Definition format.h:4305
basic_memory_buffer< char > memory_buffer
Definition format.h:919
#define FMT_USE_RTTI
Definition format.h:109
constexpr auto underlying(Enum e) noexcept -> underlying_t< Enum >
Converts e to the underlying type.
Definition format.h:3989
Converts a string literal into a format string that will be parsed at compile time and converted into...
Definition printf.h:50
FMT_CONSTEXPR20 auto isfinite(T value) -> bool
Definition format.h:2629
constexpr auto to_ascii(Char c) -> char
Definition base.h:1307
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const format_specs &specs={}) -> OutputIt
Definition format.h:1714
FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t< Int >
Definition base.h:439
@ replace
Definition format.h:1314
auto write_escaped_char(OutputIt out, Char v) -> OutputIt
Definition format.h:1842
FMT_CONSTEXPR auto parse_width(const Char *begin, const Char *end, format_specs &specs, arg_ref< Char > &width_ref, parse_context< Char > &ctx) -> const Char *
Definition base.h:1443
FMT_CONSTEXPR auto parse_align(const Char *begin, const Char *end, format_specs &specs) -> const Char *
Definition format.h:2312
constexpr auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition base.h:958
FMT_CONSTEXPR void handle_dynamic_spec(arg_id_kind kind, int &value, const arg_ref< typename Context::char_type > &ref, Context &ctx)
Definition format.h:3712
FMT_CONSTEXPR FMT_INLINE auto write(basic_appender< Char > out, T value, const format_specs &specs, locale_ref loc) -> basic_appender< Char >
Definition format.h:2137
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter &f, bool set) -> decltype(f.set_debug_format(set))
Definition format.h:767
auto write_escaped_string(OutputIt out, basic_string_view< Char > str) -> OutputIt
Definition format.h:1826
Definition StringMap.hpp:773
@ string
Definition ranges.h:31
@ set
Definition ranges.h:31
auto ptr(const std::unique_ptr< T, Deleter > &p) -> const void *
Definition std.h:276
Definition ostream.h:75
Definition base.h:1300
arg_ref< Char > width_ref
Definition base.h:1301
arg_ref< Char > precision_ref
Definition base.h:1302
Definition std.h:239
Definition std.h:267
Definition std.h:261
Definition std.h:245
static constexpr bool value
Definition std.h:246
Definition format.h:267
Definition base.h:1010
Definition base.h:846
int width
Definition base.h:847
int precision
Definition base.h:848
FMT_CONSTEXPR auto format(const BitRef &v, FormatContext &ctx) const -> decltype(ctx.out())
Definition std.h:620
auto format(const std::exception &ex, Context &ctx) const -> decltype(ctx.out())
Definition std.h:598
FMT_CONSTEXPR auto parse(parse_context<> &ctx) -> const char *
Definition std.h:586
auto format(const std::atomic< T > &v, FormatContext &ctx) const -> decltype(ctx.out())
Definition std.h:631
auto format(const std::bitset< N > &bs, FormatContext &ctx) const -> decltype(ctx.out())
Definition std.h:369
auto format(const std::complex< T > &c, FormatContext &ctx) const -> decltype(ctx.out())
Definition std.h:681
FMT_CONSTEXPR auto parse(parse_context< Char > &ctx) -> const Char *
Definition std.h:674
FMT_CONSTEXPR20 auto format(const std::error_code &ec, FormatContext &ctx) const -> decltype(ctx.out())
Definition std.h:540
FMT_CONSTEXPR void set_debug_format(bool set=true)
Definition std.h:516
FMT_CONSTEXPR auto parse(parse_context<> &ctx) -> const char *
Definition std.h:518
Definition base.h:655
Definition base.h:334
constexpr nested_formatter()
Definition format.h:4107
auto write_padded(FormatContext &ctx, F write) const -> decltype(ctx.out())
Definition format.h:4126
Definition base.h:1289