WPILibC++ 2024.3.2
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 <atomic>
12#include <bitset>
13#include <cstdlib>
14#include <exception>
15#include <memory>
16#include <thread>
17#include <type_traits>
18#include <typeinfo>
19#include <utility>
20#include <vector>
21
22#include "format.h"
23#include "ostream.h"
24
25#if FMT_HAS_INCLUDE(<version>)
26# include <version>
27#endif
28// Checking FMT_CPLUSPLUS for warning suppression in MSVC.
29#if FMT_CPLUSPLUS >= 201703L
30# if FMT_HAS_INCLUDE(<filesystem>)
31# include <filesystem>
32# endif
33# if FMT_HAS_INCLUDE(<variant>)
34# include <variant>
35# endif
36# if FMT_HAS_INCLUDE(<optional>)
37# include <optional>
38# endif
39#endif
40
41// GCC 4 does not support FMT_HAS_INCLUDE.
42#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
43# include <cxxabi.h>
44// Android NDK with gabi++ library on some architectures does not implement
45// abi::__cxa_demangle().
46# ifndef __GABIXX_CXXABI_H__
47# define FMT_HAS_ABI_CXA_DEMANGLE
48# endif
49#endif
50
51// Check if typeid is available.
52#ifndef FMT_USE_TYPEID
53// __RTTI is for EDG compilers. In MSVC typeid is available without RTTI.
54# if defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || FMT_MSC_VERSION || \
55 defined(__INTEL_RTTI__) || defined(__RTTI)
56# define FMT_USE_TYPEID 1
57# else
58# define FMT_USE_TYPEID 0
59# endif
60#endif
61
62#ifdef __cpp_lib_filesystem
64
65namespace detail {
66
67template <typename Char> auto get_path_string(const std::filesystem::path& p) {
68 return p.string<Char>();
69}
70
71template <typename Char>
72void write_escaped_path(basic_memory_buffer<Char>& quoted,
73 const std::filesystem::path& p) {
74 write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
75}
76
77# ifdef _WIN32
78template <>
79inline auto get_path_string<char>(const std::filesystem::path& p) {
80 return to_utf8<wchar_t>(p.native(), to_utf8_error_policy::replace);
81}
82
83template <>
84inline void write_escaped_path<char>(memory_buffer& quoted,
85 const std::filesystem::path& p) {
87 write_escaped_string<wchar_t>(std::back_inserter(buf), p.native());
88 bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
89 FMT_ASSERT(valid, "invalid utf16");
90}
91# endif // _WIN32
92
93template <>
94inline void write_escaped_path<std::filesystem::path::value_type>(
96 const std::filesystem::path& p) {
97 write_escaped_string<std::filesystem::path::value_type>(
98 std::back_inserter(quoted), p.native());
99}
100
101} // namespace detail
102
104template <typename Char> struct formatter<std::filesystem::path, Char> {
105 private:
106 format_specs<Char> specs_;
107 detail::arg_ref<Char> width_ref_;
108 bool debug_ = false;
109
110 public:
111 FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
112
113 template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
114 auto it = ctx.begin(), end = ctx.end();
115 if (it == end) return it;
116
117 it = detail::parse_align(it, end, specs_);
118 if (it == end) return it;
119
120 it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
121 if (it != end && *it == '?') {
122 debug_ = true;
123 ++it;
124 }
125 return it;
126 }
127
128 template <typename FormatContext>
129 auto format(const std::filesystem::path& p, FormatContext& ctx) const {
130 auto specs = specs_;
131 detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
132 ctx);
133 if (!debug_) {
134 auto s = detail::get_path_string<Char>(p);
135 return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
136 }
137 auto quoted = basic_memory_buffer<Char>();
138 detail::write_escaped_path(quoted, p);
139 return detail::write(ctx.out(),
140 basic_string_view<Char>(quoted.data(), quoted.size()),
141 specs);
142 }
143};
145#endif
146
149template <typename Char>
150struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
152
153#ifdef __cpp_lib_optional
156template <typename T, typename Char>
157struct formatter<std::optional<T>, Char,
158 std::enable_if_t<is_formattable<T, Char>::value>> {
159 private:
160 formatter<T, Char> underlying_;
161 static constexpr basic_string_view<Char> optional =
162 detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',
163 '('>{};
164 static constexpr basic_string_view<Char> none =
166
167 template <class U>
168 FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, bool set)
169 -> decltype(u.set_debug_format(set)) {
170 u.set_debug_format(set);
171 }
172
173 template <class U>
174 FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}
175
176 public:
177 template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
178 maybe_set_debug_format(underlying_, true);
179 return underlying_.parse(ctx);
180 }
181
182 template <typename FormatContext>
183 auto format(std::optional<T> const& opt, FormatContext& ctx) const
184 -> decltype(ctx.out()) {
185 if (!opt) return detail::write<Char>(ctx.out(), none);
186
187 auto out = ctx.out();
188 out = detail::write<Char>(out, optional);
189 ctx.advance_to(out);
190 out = underlying_.format(*opt, ctx);
191 return detail::write(out, ')');
192 }
193};
195#endif // __cpp_lib_optional
196
197#ifdef __cpp_lib_variant
199namespace detail {
200
201template <typename T>
202using variant_index_sequence =
203 std::make_index_sequence<std::variant_size<T>::value>;
204
205template <typename> struct is_variant_like_ : std::false_type {};
206template <typename... Types>
207struct is_variant_like_<std::variant<Types...>> : std::true_type {};
208
209// formattable element check.
210template <typename T, typename C> class is_variant_formattable_ {
211 template <std::size_t... Is>
212 static std::conjunction<
214 check(std::index_sequence<Is...>);
215
216 public:
217 static constexpr const bool value =
218 decltype(check(variant_index_sequence<T>{}))::value;
219};
220
221template <typename Char, typename OutputIt, typename T>
222auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt {
223 if constexpr (is_string<T>::value)
224 return write_escaped_string<Char>(out, detail::to_string_view(v));
225 else if constexpr (std::is_same_v<T, Char>)
226 return write_escaped_char(out, v);
227 else
228 return write<Char>(out, v);
229}
230
231} // namespace detail
232
233template <typename T> struct is_variant_like {
234 static constexpr const bool value = detail::is_variant_like_<T>::value;
235};
236
237template <typename T, typename C> struct is_variant_formattable {
238 static constexpr const bool value =
239 detail::is_variant_formattable_<T, C>::value;
240};
241
243template <typename Char> struct formatter<std::monostate, Char> {
244 template <typename ParseContext>
245 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
246 return ctx.begin();
247 }
248
249 template <typename FormatContext>
250 auto format(const std::monostate&, FormatContext& ctx) const
251 -> decltype(ctx.out()) {
252 return detail::write<Char>(ctx.out(), "monostate");
253 }
254};
255
257template <typename Variant, typename Char>
258struct formatter<
259 Variant, Char,
260 std::enable_if_t<std::conjunction_v<
261 is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
262 template <typename ParseContext>
263 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
264 return ctx.begin();
265 }
266
267 template <typename FormatContext>
268 auto format(const Variant& value, FormatContext& ctx) const
269 -> decltype(ctx.out()) {
270 auto out = ctx.out();
271
272 out = detail::write<Char>(out, "variant(");
273 FMT_TRY {
274 std::visit(
275 [&](const auto& v) {
276 out = detail::write_variant_alternative<Char>(out, v);
277 },
278 value);
279 }
280 FMT_CATCH(const std::bad_variant_access&) {
281 detail::write<Char>(out, "valueless by exception");
282 }
283 *out++ = ')';
284 return out;
285 }
286};
288#endif // __cpp_lib_variant
289
292template <typename Char> struct formatter<std::error_code, Char> {
293 template <typename ParseContext>
294 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
295 return ctx.begin();
296 }
297
298 template <typename FormatContext>
299 FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
300 -> decltype(ctx.out()) {
301 auto out = ctx.out();
302 out = detail::write_bytes(out, ec.category().name(), format_specs<Char>());
303 out = detail::write<Char>(out, Char(':'));
304 out = detail::write<Char>(out, ec.value());
305 return out;
306 }
307};
308
310template <typename T, typename Char>
312 T, Char,
313 typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
314 private:
315 bool with_typename_ = false;
316
317 public:
319 -> decltype(ctx.begin()) {
320 auto it = ctx.begin();
321 auto end = ctx.end();
322 if (it == end || *it == '}') return it;
323 if (*it == 't') {
324 ++it;
325 with_typename_ = FMT_USE_TYPEID != 0;
326 }
327 return it;
328 }
329
330 template <typename OutputIt>
331 auto format(const std::exception& ex,
332 basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
334 auto out = ctx.out();
335 if (!with_typename_)
336 return detail::write_bytes(out, string_view(ex.what()), spec);
337
338#if FMT_USE_TYPEID
339 const std::type_info& ti = typeid(ex);
340# ifdef FMT_HAS_ABI_CXA_DEMANGLE
341 int status = 0;
342 std::size_t size = 0;
343 std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr(
344 abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
345
346 string_view demangled_name_view;
347 if (demangled_name_ptr) {
348 demangled_name_view = demangled_name_ptr.get();
349
350 // Normalization of stdlib inline namespace names.
351 // libc++ inline namespaces.
352 // std::__1::* -> std::*
353 // std::__1::__fs::* -> std::*
354 // libstdc++ inline namespaces.
355 // std::__cxx11::* -> std::*
356 // std::filesystem::__cxx11::* -> std::filesystem::*
357 if (demangled_name_view.starts_with("std::")) {
358 char* begin = demangled_name_ptr.get();
359 char* to = begin + 5; // std::
360 for (char *from = to, *end = begin + demangled_name_view.size();
361 from < end;) {
362 // This is safe, because demangled_name is NUL-terminated.
363 if (from[0] == '_' && from[1] == '_') {
364 char* next = from + 1;
365 while (next < end && *next != ':') next++;
366 if (next[0] == ':' && next[1] == ':') {
367 from = next + 2;
368 continue;
369 }
370 }
371 *to++ = *from++;
372 }
373 demangled_name_view = {begin, detail::to_unsigned(to - begin)};
374 }
375 } else {
376 demangled_name_view = string_view(ti.name());
377 }
378 out = detail::write_bytes(out, demangled_name_view, spec);
379# elif FMT_MSC_VERSION
380 string_view demangled_name_view(ti.name());
381 if (demangled_name_view.starts_with("class "))
382 demangled_name_view.remove_prefix(6);
383 else if (demangled_name_view.starts_with("struct "))
384 demangled_name_view.remove_prefix(7);
385 out = detail::write_bytes(out, demangled_name_view, spec);
386# else
387 out = detail::write_bytes(out, string_view(ti.name()), spec);
388# endif
389 *out++ = ':';
390 *out++ = ' ';
391 return detail::write_bytes(out, string_view(ex.what()), spec);
392#endif
393 }
394};
395
396namespace detail {
397
398template <typename T, typename Enable = void>
399struct has_flip : std::false_type {};
400
401template <typename T>
402struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
403 : std::true_type {};
404
405template <typename T> struct is_bit_reference_like {
406 static constexpr const bool value =
407 std::is_convertible<T, bool>::value &&
408 std::is_nothrow_assignable<T, bool>::value && has_flip<T>::value;
409};
410
411#ifdef _LIBCPP_VERSION
412
413// Workaround for libc++ incompatibility with C++ standard.
414// According to the Standard, `bitset::operator[] const` returns bool.
415template <typename C>
416struct is_bit_reference_like<std::__bit_const_reference<C>> {
417 static constexpr const bool value = true;
418};
419
420#endif
421
422} // namespace detail
423
424// We can't use std::vector<bool, Allocator>::reference and
425// std::bitset<N>::reference because the compiler can't deduce Allocator and N
426// in partial specialization.
428template <typename BitRef, typename Char>
429struct formatter<BitRef, Char,
430 enable_if_t<detail::is_bit_reference_like<BitRef>::value>>
431 : formatter<bool, Char> {
432 template <typename FormatContext>
433 FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const
434 -> decltype(ctx.out()) {
435 return formatter<bool, Char>::format(v, ctx);
436 }
437};
438
440template <typename T, typename Char>
441struct formatter<std::atomic<T>, Char,
442 enable_if_t<is_formattable<T, Char>::value>>
443 : formatter<T, Char> {
444 template <typename FormatContext>
445 auto format(const std::atomic<T>& v, FormatContext& ctx) const
446 -> decltype(ctx.out()) {
447 return formatter<T, Char>::format(v.load(), ctx);
448 }
449};
450
451#ifdef __cpp_lib_atomic_flag_test
453template <typename Char>
454struct formatter<std::atomic_flag, Char>
455 : formatter<bool, Char> {
456 template <typename FormatContext>
457 auto format(const std::atomic_flag& v, FormatContext& ctx) const
458 -> decltype(ctx.out()) {
459 return formatter<bool, Char>::format(v.test(), ctx);
460 }
461};
462#endif // __cpp_lib_atomic_flag_test
463
465#endif // FMT_STD_H_
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 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:151
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 exception
Definition: ThirdPartyNotices.txt:289
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:128
Definition: core.h:1706
\rst Parsing context consisting of a format string range being parsed and an argument counter for aut...
Definition: core.h:656
\rst A dynamically growing memory buffer for trivially copyable/constructible types with the first SI...
Definition: format.h:918
An implementation of std::basic_string_view for pre-C++17.
Definition: core.h:398
constexpr auto size() const noexcept -> size_t
Returns the string size.
Definition: core.h:443
FMT_CONSTEXPR void remove_prefix(size_t n) noexcept
Definition: core.h:452
FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(basic_string_view< Char > sv) const noexcept
Definition: core.h:457
FMT_CONSTEXPR auto data() noexcept -> T *
Returns a pointer to the buffer data (not null-terminated).
Definition: core.h:844
bool convert(basic_string_view< WChar > s, to_utf8_error_policy policy=to_utf8_error_policy::abort)
Definition: format.h:1447
Definition: core.h:1238
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:256
#define FMT_ASSERT(condition, message)
Definition: core.h:336
basic_string_view< char > string_view
Definition: core.h:501
#define FMT_CONSTEXPR
Definition: core.h:105
#define FMT_BEGIN_NAMESPACE
Definition: core.h:174
#define FMT_END_NAMESPACE
Definition: core.h:177
bool_constant<!std::is_base_of< detail::unformattable, decltype(detail::arg_mapper< buffer_context< Char > >() .map(std::declval< T & >()))>::value > is_formattable
Definition: core.h:1764
#define FMT_EXPORT
Definition: core.h:183
#define FMT_TRY
Definition: format.h:138
#define FMT_CATCH(x)
Definition: format.h:139
detail namespace with internal helper functions
Definition: xchar.h:20
void void_t
Definition: core.h:1510
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const format_specs< Char > &specs) -> OutputIt
Definition: format.h:1819
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:419
FMT_CONSTEXPR auto parse_dynamic_spec(const Char *begin, const Char *end, int &value, arg_ref< Char > &ref, basic_format_parse_context< Char > &ctx) -> const Char *
Definition: core.h:2237
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:517
@ value
the parser finished reading a JSON value
auto write_escaped_char(OutputIt out, Char v) -> OutputIt
Definition: format.h:1986
type
Definition: core.h:556
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition: core.h:374
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter &f, bool set) -> decltype(f.set_debug_format(set))
Definition: ranges.h:292
FMT_CONSTEXPR auto parse_align(const Char *begin, const Char *end, format_specs< Char > &specs) -> const Char *
Definition: format.h:2399
Definition: array.h:89
#define FMT_USE_TYPEID
Definition: std.h:58
Definition: ostream.h:107
Definition: core.h:2067
Definition: std.h:399
Definition: std.h:405
Definition: format.h:298
int width
Definition: core.h:2043
FMT_CONSTEXPR auto format(const BitRef &v, FormatContext &ctx) const -> decltype(ctx.out())
Definition: std.h:433
FMT_CONSTEXPR auto parse(basic_format_parse_context< Char > &ctx) -> decltype(ctx.begin())
Definition: std.h:318
auto format(const std::exception &ex, basic_format_context< OutputIt, Char > &ctx) const -> OutputIt
Definition: std.h:331
auto format(const std::atomic< T > &v, FormatContext &ctx) const -> decltype(ctx.out())
Definition: std.h:445
FMT_CONSTEXPR auto format(const std::error_code &ec, FormatContext &ctx) const -> decltype(ctx.out())
Definition: std.h:299
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition: std.h:294
Definition: core.h:1068
Definition: core.h:276
auto format(wformat_string< T... > fmt, T &&... args) -> std::wstring
Definition: xchar.h:108