1*5c90c05cSAndroid Build Coastguard Worker // Formatting library for C++ - formatters for standard library types
2*5c90c05cSAndroid Build Coastguard Worker //
3*5c90c05cSAndroid Build Coastguard Worker // Copyright (c) 2012 - present, Victor Zverovich
4*5c90c05cSAndroid Build Coastguard Worker // All rights reserved.
5*5c90c05cSAndroid Build Coastguard Worker //
6*5c90c05cSAndroid Build Coastguard Worker // For the license information refer to format.h.
7*5c90c05cSAndroid Build Coastguard Worker
8*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_STD_H_
9*5c90c05cSAndroid Build Coastguard Worker #define FMT_STD_H_
10*5c90c05cSAndroid Build Coastguard Worker
11*5c90c05cSAndroid Build Coastguard Worker #include "format.h"
12*5c90c05cSAndroid Build Coastguard Worker #include "ostream.h"
13*5c90c05cSAndroid Build Coastguard Worker
14*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_MODULE
15*5c90c05cSAndroid Build Coastguard Worker # include <atomic>
16*5c90c05cSAndroid Build Coastguard Worker # include <bitset>
17*5c90c05cSAndroid Build Coastguard Worker # include <complex>
18*5c90c05cSAndroid Build Coastguard Worker # include <cstdlib>
19*5c90c05cSAndroid Build Coastguard Worker # include <exception>
20*5c90c05cSAndroid Build Coastguard Worker # include <functional>
21*5c90c05cSAndroid Build Coastguard Worker # include <memory>
22*5c90c05cSAndroid Build Coastguard Worker # include <thread>
23*5c90c05cSAndroid Build Coastguard Worker # include <type_traits>
24*5c90c05cSAndroid Build Coastguard Worker # include <typeinfo>
25*5c90c05cSAndroid Build Coastguard Worker # include <utility>
26*5c90c05cSAndroid Build Coastguard Worker # include <vector>
27*5c90c05cSAndroid Build Coastguard Worker
28*5c90c05cSAndroid Build Coastguard Worker // Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
29*5c90c05cSAndroid Build Coastguard Worker # if FMT_CPLUSPLUS >= 201703L
30*5c90c05cSAndroid Build Coastguard Worker # if FMT_HAS_INCLUDE(<filesystem>)
31*5c90c05cSAndroid Build Coastguard Worker # include <filesystem>
32*5c90c05cSAndroid Build Coastguard Worker # endif
33*5c90c05cSAndroid Build Coastguard Worker # if FMT_HAS_INCLUDE(<variant>)
34*5c90c05cSAndroid Build Coastguard Worker # include <variant>
35*5c90c05cSAndroid Build Coastguard Worker # endif
36*5c90c05cSAndroid Build Coastguard Worker # if FMT_HAS_INCLUDE(<optional>)
37*5c90c05cSAndroid Build Coastguard Worker # include <optional>
38*5c90c05cSAndroid Build Coastguard Worker # endif
39*5c90c05cSAndroid Build Coastguard Worker # endif
40*5c90c05cSAndroid Build Coastguard Worker // Use > instead of >= in the version check because <source_location> may be
41*5c90c05cSAndroid Build Coastguard Worker // available after C++17 but before C++20 is marked as implemented.
42*5c90c05cSAndroid Build Coastguard Worker # if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE(<source_location>)
43*5c90c05cSAndroid Build Coastguard Worker # include <source_location>
44*5c90c05cSAndroid Build Coastguard Worker # endif
45*5c90c05cSAndroid Build Coastguard Worker # if FMT_CPLUSPLUS > 202002L && FMT_HAS_INCLUDE(<expected>)
46*5c90c05cSAndroid Build Coastguard Worker # include <expected>
47*5c90c05cSAndroid Build Coastguard Worker # endif
48*5c90c05cSAndroid Build Coastguard Worker #endif // FMT_MODULE
49*5c90c05cSAndroid Build Coastguard Worker
50*5c90c05cSAndroid Build Coastguard Worker #if FMT_HAS_INCLUDE(<version>)
51*5c90c05cSAndroid Build Coastguard Worker # include <version>
52*5c90c05cSAndroid Build Coastguard Worker #endif
53*5c90c05cSAndroid Build Coastguard Worker
54*5c90c05cSAndroid Build Coastguard Worker // GCC 4 does not support FMT_HAS_INCLUDE.
55*5c90c05cSAndroid Build Coastguard Worker #if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
56*5c90c05cSAndroid Build Coastguard Worker # include <cxxabi.h>
57*5c90c05cSAndroid Build Coastguard Worker // Android NDK with gabi++ library on some architectures does not implement
58*5c90c05cSAndroid Build Coastguard Worker // abi::__cxa_demangle().
59*5c90c05cSAndroid Build Coastguard Worker # ifndef __GABIXX_CXXABI_H__
60*5c90c05cSAndroid Build Coastguard Worker # define FMT_HAS_ABI_CXA_DEMANGLE
61*5c90c05cSAndroid Build Coastguard Worker # endif
62*5c90c05cSAndroid Build Coastguard Worker #endif
63*5c90c05cSAndroid Build Coastguard Worker
64*5c90c05cSAndroid Build Coastguard Worker // For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined.
65*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_CPP_LIB_FILESYSTEM
66*5c90c05cSAndroid Build Coastguard Worker # ifdef __cpp_lib_filesystem
67*5c90c05cSAndroid Build Coastguard Worker # define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
68*5c90c05cSAndroid Build Coastguard Worker # else
69*5c90c05cSAndroid Build Coastguard Worker # define FMT_CPP_LIB_FILESYSTEM 0
70*5c90c05cSAndroid Build Coastguard Worker # endif
71*5c90c05cSAndroid Build Coastguard Worker #endif
72*5c90c05cSAndroid Build Coastguard Worker
73*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_CPP_LIB_VARIANT
74*5c90c05cSAndroid Build Coastguard Worker # ifdef __cpp_lib_variant
75*5c90c05cSAndroid Build Coastguard Worker # define FMT_CPP_LIB_VARIANT __cpp_lib_variant
76*5c90c05cSAndroid Build Coastguard Worker # else
77*5c90c05cSAndroid Build Coastguard Worker # define FMT_CPP_LIB_VARIANT 0
78*5c90c05cSAndroid Build Coastguard Worker # endif
79*5c90c05cSAndroid Build Coastguard Worker #endif
80*5c90c05cSAndroid Build Coastguard Worker
81*5c90c05cSAndroid Build Coastguard Worker #if FMT_CPP_LIB_FILESYSTEM
82*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
83*5c90c05cSAndroid Build Coastguard Worker
84*5c90c05cSAndroid Build Coastguard Worker namespace detail {
85*5c90c05cSAndroid Build Coastguard Worker
86*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename PathChar>
get_path_string(const std::filesystem::path & p,const std::basic_string<PathChar> & native)87*5c90c05cSAndroid Build Coastguard Worker auto get_path_string(const std::filesystem::path& p,
88*5c90c05cSAndroid Build Coastguard Worker const std::basic_string<PathChar>& native) {
89*5c90c05cSAndroid Build Coastguard Worker if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>)
90*5c90c05cSAndroid Build Coastguard Worker return to_utf8<wchar_t>(native, to_utf8_error_policy::replace);
91*5c90c05cSAndroid Build Coastguard Worker else
92*5c90c05cSAndroid Build Coastguard Worker return p.string<Char>();
93*5c90c05cSAndroid Build Coastguard Worker }
94*5c90c05cSAndroid Build Coastguard Worker
95*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename PathChar>
write_escaped_path(basic_memory_buffer<Char> & quoted,const std::filesystem::path & p,const std::basic_string<PathChar> & native)96*5c90c05cSAndroid Build Coastguard Worker void write_escaped_path(basic_memory_buffer<Char>& quoted,
97*5c90c05cSAndroid Build Coastguard Worker const std::filesystem::path& p,
98*5c90c05cSAndroid Build Coastguard Worker const std::basic_string<PathChar>& native) {
99*5c90c05cSAndroid Build Coastguard Worker if constexpr (std::is_same_v<Char, char> &&
100*5c90c05cSAndroid Build Coastguard Worker std::is_same_v<PathChar, wchar_t>) {
101*5c90c05cSAndroid Build Coastguard Worker auto buf = basic_memory_buffer<wchar_t>();
102*5c90c05cSAndroid Build Coastguard Worker write_escaped_string<wchar_t>(std::back_inserter(buf), native);
103*5c90c05cSAndroid Build Coastguard Worker bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
104*5c90c05cSAndroid Build Coastguard Worker FMT_ASSERT(valid, "invalid utf16");
105*5c90c05cSAndroid Build Coastguard Worker } else if constexpr (std::is_same_v<Char, PathChar>) {
106*5c90c05cSAndroid Build Coastguard Worker write_escaped_string<std::filesystem::path::value_type>(
107*5c90c05cSAndroid Build Coastguard Worker std::back_inserter(quoted), native);
108*5c90c05cSAndroid Build Coastguard Worker } else {
109*5c90c05cSAndroid Build Coastguard Worker write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
110*5c90c05cSAndroid Build Coastguard Worker }
111*5c90c05cSAndroid Build Coastguard Worker }
112*5c90c05cSAndroid Build Coastguard Worker
113*5c90c05cSAndroid Build Coastguard Worker } // namespace detail
114*5c90c05cSAndroid Build Coastguard Worker
115*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
116*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct formatter<std::filesystem::path, Char> {
117*5c90c05cSAndroid Build Coastguard Worker private:
118*5c90c05cSAndroid Build Coastguard Worker format_specs specs_;
119*5c90c05cSAndroid Build Coastguard Worker detail::arg_ref<Char> width_ref_;
120*5c90c05cSAndroid Build Coastguard Worker bool debug_ = false;
121*5c90c05cSAndroid Build Coastguard Worker char path_type_ = 0;
122*5c90c05cSAndroid Build Coastguard Worker
123*5c90c05cSAndroid Build Coastguard Worker public:
124*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
125*5c90c05cSAndroid Build Coastguard Worker
126*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
127*5c90c05cSAndroid Build Coastguard Worker auto it = ctx.begin(), end = ctx.end();
128*5c90c05cSAndroid Build Coastguard Worker if (it == end) return it;
129*5c90c05cSAndroid Build Coastguard Worker
130*5c90c05cSAndroid Build Coastguard Worker it = detail::parse_align(it, end, specs_);
131*5c90c05cSAndroid Build Coastguard Worker if (it == end) return it;
132*5c90c05cSAndroid Build Coastguard Worker
133*5c90c05cSAndroid Build Coastguard Worker Char c = *it;
134*5c90c05cSAndroid Build Coastguard Worker if ((c >= '0' && c <= '9') || c == '{')
135*5c90c05cSAndroid Build Coastguard Worker it = detail::parse_width(it, end, specs_, width_ref_, ctx);
136*5c90c05cSAndroid Build Coastguard Worker if (it != end && *it == '?') {
137*5c90c05cSAndroid Build Coastguard Worker debug_ = true;
138*5c90c05cSAndroid Build Coastguard Worker ++it;
139*5c90c05cSAndroid Build Coastguard Worker }
140*5c90c05cSAndroid Build Coastguard Worker if (it != end && (*it == 'g')) path_type_ = detail::to_ascii(*it++);
141*5c90c05cSAndroid Build Coastguard Worker return it;
142*5c90c05cSAndroid Build Coastguard Worker }
143*5c90c05cSAndroid Build Coastguard Worker
144*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
145*5c90c05cSAndroid Build Coastguard Worker auto format(const std::filesystem::path& p, FormatContext& ctx) const {
146*5c90c05cSAndroid Build Coastguard Worker auto specs = specs_;
147*5c90c05cSAndroid Build Coastguard Worker auto path_string =
148*5c90c05cSAndroid Build Coastguard Worker !path_type_ ? p.native()
149*5c90c05cSAndroid Build Coastguard Worker : p.generic_string<std::filesystem::path::value_type>();
150*5c90c05cSAndroid Build Coastguard Worker
151*5c90c05cSAndroid Build Coastguard Worker detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
152*5c90c05cSAndroid Build Coastguard Worker ctx);
153*5c90c05cSAndroid Build Coastguard Worker if (!debug_) {
154*5c90c05cSAndroid Build Coastguard Worker auto s = detail::get_path_string<Char>(p, path_string);
155*5c90c05cSAndroid Build Coastguard Worker return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
156*5c90c05cSAndroid Build Coastguard Worker }
157*5c90c05cSAndroid Build Coastguard Worker auto quoted = basic_memory_buffer<Char>();
158*5c90c05cSAndroid Build Coastguard Worker detail::write_escaped_path(quoted, p, path_string);
159*5c90c05cSAndroid Build Coastguard Worker return detail::write(ctx.out(),
160*5c90c05cSAndroid Build Coastguard Worker basic_string_view<Char>(quoted.data(), quoted.size()),
161*5c90c05cSAndroid Build Coastguard Worker specs);
162*5c90c05cSAndroid Build Coastguard Worker }
163*5c90c05cSAndroid Build Coastguard Worker };
164*5c90c05cSAndroid Build Coastguard Worker
165*5c90c05cSAndroid Build Coastguard Worker class path : public std::filesystem::path {
166*5c90c05cSAndroid Build Coastguard Worker public:
167*5c90c05cSAndroid Build Coastguard Worker auto display_string() const -> std::string {
168*5c90c05cSAndroid Build Coastguard Worker const std::filesystem::path& base = *this;
169*5c90c05cSAndroid Build Coastguard Worker return fmt::format(FMT_STRING("{}"), base);
170*5c90c05cSAndroid Build Coastguard Worker }
171*5c90c05cSAndroid Build Coastguard Worker auto system_string() const -> std::string { return string(); }
172*5c90c05cSAndroid Build Coastguard Worker
173*5c90c05cSAndroid Build Coastguard Worker auto generic_display_string() const -> std::string {
174*5c90c05cSAndroid Build Coastguard Worker const std::filesystem::path& base = *this;
175*5c90c05cSAndroid Build Coastguard Worker return fmt::format(FMT_STRING("{:g}"), base);
176*5c90c05cSAndroid Build Coastguard Worker }
177*5c90c05cSAndroid Build Coastguard Worker auto generic_system_string() const -> std::string { return generic_string(); }
178*5c90c05cSAndroid Build Coastguard Worker };
179*5c90c05cSAndroid Build Coastguard Worker
180*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
181*5c90c05cSAndroid Build Coastguard Worker #endif // FMT_CPP_LIB_FILESYSTEM
182*5c90c05cSAndroid Build Coastguard Worker
183*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
184*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
185*5c90c05cSAndroid Build Coastguard Worker template <std::size_t N, typename Char>
186*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
187*5c90c05cSAndroid Build Coastguard Worker private:
188*5c90c05cSAndroid Build Coastguard Worker // Functor because C++11 doesn't support generic lambdas.
189*5c90c05cSAndroid Build Coastguard Worker struct writer {
190*5c90c05cSAndroid Build Coastguard Worker const std::bitset<N>& bs;
191*5c90c05cSAndroid Build Coastguard Worker
192*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt>
193*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt {
194*5c90c05cSAndroid Build Coastguard Worker for (auto pos = N; pos > 0; --pos) {
195*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, bs[pos - 1] ? Char('1') : Char('0'));
196*5c90c05cSAndroid Build Coastguard Worker }
197*5c90c05cSAndroid Build Coastguard Worker
198*5c90c05cSAndroid Build Coastguard Worker return out;
199*5c90c05cSAndroid Build Coastguard Worker }
200*5c90c05cSAndroid Build Coastguard Worker };
201*5c90c05cSAndroid Build Coastguard Worker
202*5c90c05cSAndroid Build Coastguard Worker public:
203*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
204*5c90c05cSAndroid Build Coastguard Worker auto format(const std::bitset<N>& bs, FormatContext& ctx) const
205*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
206*5c90c05cSAndroid Build Coastguard Worker return write_padded(ctx, writer{bs});
207*5c90c05cSAndroid Build Coastguard Worker }
208*5c90c05cSAndroid Build Coastguard Worker };
209*5c90c05cSAndroid Build Coastguard Worker
210*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
211*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
212*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
213*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
214*5c90c05cSAndroid Build Coastguard Worker
215*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_lib_optional
216*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
217*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
218*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char>
219*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::optional<T>, Char,
220*5c90c05cSAndroid Build Coastguard Worker std::enable_if_t<is_formattable<T, Char>::value>> {
221*5c90c05cSAndroid Build Coastguard Worker private:
222*5c90c05cSAndroid Build Coastguard Worker formatter<T, Char> underlying_;
223*5c90c05cSAndroid Build Coastguard Worker static constexpr basic_string_view<Char> optional =
224*5c90c05cSAndroid Build Coastguard Worker detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',
225*5c90c05cSAndroid Build Coastguard Worker '('>{};
226*5c90c05cSAndroid Build Coastguard Worker static constexpr basic_string_view<Char> none =
227*5c90c05cSAndroid Build Coastguard Worker detail::string_literal<Char, 'n', 'o', 'n', 'e'>{};
228*5c90c05cSAndroid Build Coastguard Worker
229*5c90c05cSAndroid Build Coastguard Worker template <class U>
230*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, bool set)
231*5c90c05cSAndroid Build Coastguard Worker -> decltype(u.set_debug_format(set)) {
232*5c90c05cSAndroid Build Coastguard Worker u.set_debug_format(set);
233*5c90c05cSAndroid Build Coastguard Worker }
234*5c90c05cSAndroid Build Coastguard Worker
235*5c90c05cSAndroid Build Coastguard Worker template <class U>
236*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}
237*5c90c05cSAndroid Build Coastguard Worker
238*5c90c05cSAndroid Build Coastguard Worker public:
239*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
240*5c90c05cSAndroid Build Coastguard Worker maybe_set_debug_format(underlying_, true);
241*5c90c05cSAndroid Build Coastguard Worker return underlying_.parse(ctx);
242*5c90c05cSAndroid Build Coastguard Worker }
243*5c90c05cSAndroid Build Coastguard Worker
244*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
245*5c90c05cSAndroid Build Coastguard Worker auto format(const std::optional<T>& opt, FormatContext& ctx) const
246*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
247*5c90c05cSAndroid Build Coastguard Worker if (!opt) return detail::write<Char>(ctx.out(), none);
248*5c90c05cSAndroid Build Coastguard Worker
249*5c90c05cSAndroid Build Coastguard Worker auto out = ctx.out();
250*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, optional);
251*5c90c05cSAndroid Build Coastguard Worker ctx.advance_to(out);
252*5c90c05cSAndroid Build Coastguard Worker out = underlying_.format(*opt, ctx);
253*5c90c05cSAndroid Build Coastguard Worker return detail::write(out, ')');
254*5c90c05cSAndroid Build Coastguard Worker }
255*5c90c05cSAndroid Build Coastguard Worker };
256*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
257*5c90c05cSAndroid Build Coastguard Worker #endif // __cpp_lib_optional
258*5c90c05cSAndroid Build Coastguard Worker
259*5c90c05cSAndroid Build Coastguard Worker #if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
260*5c90c05cSAndroid Build Coastguard Worker
261*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
262*5c90c05cSAndroid Build Coastguard Worker namespace detail {
263*5c90c05cSAndroid Build Coastguard Worker
264*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt, typename T>
265*5c90c05cSAndroid Build Coastguard Worker auto write_escaped_alternative(OutputIt out, const T& v) -> OutputIt {
266*5c90c05cSAndroid Build Coastguard Worker if constexpr (has_to_string_view<T>::value)
267*5c90c05cSAndroid Build Coastguard Worker return write_escaped_string<Char>(out, detail::to_string_view(v));
268*5c90c05cSAndroid Build Coastguard Worker if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
269*5c90c05cSAndroid Build Coastguard Worker return write<Char>(out, v);
270*5c90c05cSAndroid Build Coastguard Worker }
271*5c90c05cSAndroid Build Coastguard Worker
272*5c90c05cSAndroid Build Coastguard Worker } // namespace detail
273*5c90c05cSAndroid Build Coastguard Worker
274*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
275*5c90c05cSAndroid Build Coastguard Worker #endif
276*5c90c05cSAndroid Build Coastguard Worker
277*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_lib_expected
278*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
279*5c90c05cSAndroid Build Coastguard Worker
280*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
281*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename E, typename Char>
282*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::expected<T, E>, Char,
283*5c90c05cSAndroid Build Coastguard Worker std::enable_if_t<(std::is_void<T>::value ||
284*5c90c05cSAndroid Build Coastguard Worker is_formattable<T, Char>::value) &&
285*5c90c05cSAndroid Build Coastguard Worker is_formattable<E, Char>::value>> {
286*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
287*5c90c05cSAndroid Build Coastguard Worker return ctx.begin();
288*5c90c05cSAndroid Build Coastguard Worker }
289*5c90c05cSAndroid Build Coastguard Worker
290*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
291*5c90c05cSAndroid Build Coastguard Worker auto format(const std::expected<T, E>& value, FormatContext& ctx) const
292*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
293*5c90c05cSAndroid Build Coastguard Worker auto out = ctx.out();
294*5c90c05cSAndroid Build Coastguard Worker
295*5c90c05cSAndroid Build Coastguard Worker if (value.has_value()) {
296*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, "expected(");
297*5c90c05cSAndroid Build Coastguard Worker if constexpr (!std::is_void<T>::value)
298*5c90c05cSAndroid Build Coastguard Worker out = detail::write_escaped_alternative<Char>(out, *value);
299*5c90c05cSAndroid Build Coastguard Worker } else {
300*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, "unexpected(");
301*5c90c05cSAndroid Build Coastguard Worker out = detail::write_escaped_alternative<Char>(out, value.error());
302*5c90c05cSAndroid Build Coastguard Worker }
303*5c90c05cSAndroid Build Coastguard Worker *out++ = ')';
304*5c90c05cSAndroid Build Coastguard Worker return out;
305*5c90c05cSAndroid Build Coastguard Worker }
306*5c90c05cSAndroid Build Coastguard Worker };
307*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
308*5c90c05cSAndroid Build Coastguard Worker #endif // __cpp_lib_expected
309*5c90c05cSAndroid Build Coastguard Worker
310*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_lib_source_location
311*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
312*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
313*5c90c05cSAndroid Build Coastguard Worker template <> struct formatter<std::source_location> {
314*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }
315*5c90c05cSAndroid Build Coastguard Worker
316*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
317*5c90c05cSAndroid Build Coastguard Worker auto format(const std::source_location& loc, FormatContext& ctx) const
318*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
319*5c90c05cSAndroid Build Coastguard Worker auto out = ctx.out();
320*5c90c05cSAndroid Build Coastguard Worker out = detail::write(out, loc.file_name());
321*5c90c05cSAndroid Build Coastguard Worker out = detail::write(out, ':');
322*5c90c05cSAndroid Build Coastguard Worker out = detail::write<char>(out, loc.line());
323*5c90c05cSAndroid Build Coastguard Worker out = detail::write(out, ':');
324*5c90c05cSAndroid Build Coastguard Worker out = detail::write<char>(out, loc.column());
325*5c90c05cSAndroid Build Coastguard Worker out = detail::write(out, ": ");
326*5c90c05cSAndroid Build Coastguard Worker out = detail::write(out, loc.function_name());
327*5c90c05cSAndroid Build Coastguard Worker return out;
328*5c90c05cSAndroid Build Coastguard Worker }
329*5c90c05cSAndroid Build Coastguard Worker };
330*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
331*5c90c05cSAndroid Build Coastguard Worker #endif
332*5c90c05cSAndroid Build Coastguard Worker
333*5c90c05cSAndroid Build Coastguard Worker #if FMT_CPP_LIB_VARIANT
334*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
335*5c90c05cSAndroid Build Coastguard Worker namespace detail {
336*5c90c05cSAndroid Build Coastguard Worker
337*5c90c05cSAndroid Build Coastguard Worker template <typename T>
338*5c90c05cSAndroid Build Coastguard Worker using variant_index_sequence =
339*5c90c05cSAndroid Build Coastguard Worker std::make_index_sequence<std::variant_size<T>::value>;
340*5c90c05cSAndroid Build Coastguard Worker
341*5c90c05cSAndroid Build Coastguard Worker template <typename> struct is_variant_like_ : std::false_type {};
342*5c90c05cSAndroid Build Coastguard Worker template <typename... Types>
343*5c90c05cSAndroid Build Coastguard Worker struct is_variant_like_<std::variant<Types...>> : std::true_type {};
344*5c90c05cSAndroid Build Coastguard Worker
345*5c90c05cSAndroid Build Coastguard Worker // formattable element check.
346*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename C> class is_variant_formattable_ {
347*5c90c05cSAndroid Build Coastguard Worker template <std::size_t... Is>
348*5c90c05cSAndroid Build Coastguard Worker static std::conjunction<
349*5c90c05cSAndroid Build Coastguard Worker is_formattable<std::variant_alternative_t<Is, T>, C>...>
350*5c90c05cSAndroid Build Coastguard Worker check(std::index_sequence<Is...>);
351*5c90c05cSAndroid Build Coastguard Worker
352*5c90c05cSAndroid Build Coastguard Worker public:
353*5c90c05cSAndroid Build Coastguard Worker static constexpr const bool value =
354*5c90c05cSAndroid Build Coastguard Worker decltype(check(variant_index_sequence<T>{}))::value;
355*5c90c05cSAndroid Build Coastguard Worker };
356*5c90c05cSAndroid Build Coastguard Worker
357*5c90c05cSAndroid Build Coastguard Worker } // namespace detail
358*5c90c05cSAndroid Build Coastguard Worker
359*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct is_variant_like {
360*5c90c05cSAndroid Build Coastguard Worker static constexpr const bool value = detail::is_variant_like_<T>::value;
361*5c90c05cSAndroid Build Coastguard Worker };
362*5c90c05cSAndroid Build Coastguard Worker
363*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename C> struct is_variant_formattable {
364*5c90c05cSAndroid Build Coastguard Worker static constexpr const bool value =
365*5c90c05cSAndroid Build Coastguard Worker detail::is_variant_formattable_<T, C>::value;
366*5c90c05cSAndroid Build Coastguard Worker };
367*5c90c05cSAndroid Build Coastguard Worker
368*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
369*5c90c05cSAndroid Build Coastguard Worker template <typename Char> struct formatter<std::monostate, Char> {
370*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
371*5c90c05cSAndroid Build Coastguard Worker return ctx.begin();
372*5c90c05cSAndroid Build Coastguard Worker }
373*5c90c05cSAndroid Build Coastguard Worker
374*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
375*5c90c05cSAndroid Build Coastguard Worker auto format(const std::monostate&, FormatContext& ctx) const
376*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
377*5c90c05cSAndroid Build Coastguard Worker return detail::write<Char>(ctx.out(), "monostate");
378*5c90c05cSAndroid Build Coastguard Worker }
379*5c90c05cSAndroid Build Coastguard Worker };
380*5c90c05cSAndroid Build Coastguard Worker
381*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
382*5c90c05cSAndroid Build Coastguard Worker template <typename Variant, typename Char>
383*5c90c05cSAndroid Build Coastguard Worker struct formatter<
384*5c90c05cSAndroid Build Coastguard Worker Variant, Char,
385*5c90c05cSAndroid Build Coastguard Worker std::enable_if_t<std::conjunction_v<
386*5c90c05cSAndroid Build Coastguard Worker is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
387*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
388*5c90c05cSAndroid Build Coastguard Worker return ctx.begin();
389*5c90c05cSAndroid Build Coastguard Worker }
390*5c90c05cSAndroid Build Coastguard Worker
391*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
392*5c90c05cSAndroid Build Coastguard Worker auto format(const Variant& value, FormatContext& ctx) const
393*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
394*5c90c05cSAndroid Build Coastguard Worker auto out = ctx.out();
395*5c90c05cSAndroid Build Coastguard Worker
396*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, "variant(");
397*5c90c05cSAndroid Build Coastguard Worker FMT_TRY {
398*5c90c05cSAndroid Build Coastguard Worker std::visit(
399*5c90c05cSAndroid Build Coastguard Worker [&](const auto& v) {
400*5c90c05cSAndroid Build Coastguard Worker out = detail::write_escaped_alternative<Char>(out, v);
401*5c90c05cSAndroid Build Coastguard Worker },
402*5c90c05cSAndroid Build Coastguard Worker value);
403*5c90c05cSAndroid Build Coastguard Worker }
404*5c90c05cSAndroid Build Coastguard Worker FMT_CATCH(const std::bad_variant_access&) {
405*5c90c05cSAndroid Build Coastguard Worker detail::write<Char>(out, "valueless by exception");
406*5c90c05cSAndroid Build Coastguard Worker }
407*5c90c05cSAndroid Build Coastguard Worker *out++ = ')';
408*5c90c05cSAndroid Build Coastguard Worker return out;
409*5c90c05cSAndroid Build Coastguard Worker }
410*5c90c05cSAndroid Build Coastguard Worker };
411*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
412*5c90c05cSAndroid Build Coastguard Worker #endif // FMT_CPP_LIB_VARIANT
413*5c90c05cSAndroid Build Coastguard Worker
414*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
415*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
416*5c90c05cSAndroid Build Coastguard Worker template <> struct formatter<std::error_code> {
417*5c90c05cSAndroid Build Coastguard Worker private:
418*5c90c05cSAndroid Build Coastguard Worker format_specs specs_;
419*5c90c05cSAndroid Build Coastguard Worker detail::arg_ref<char> width_ref_;
420*5c90c05cSAndroid Build Coastguard Worker
421*5c90c05cSAndroid Build Coastguard Worker public:
422*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
423*5c90c05cSAndroid Build Coastguard Worker auto it = ctx.begin(), end = ctx.end();
424*5c90c05cSAndroid Build Coastguard Worker if (it == end) return it;
425*5c90c05cSAndroid Build Coastguard Worker
426*5c90c05cSAndroid Build Coastguard Worker it = detail::parse_align(it, end, specs_);
427*5c90c05cSAndroid Build Coastguard Worker if (it == end) return it;
428*5c90c05cSAndroid Build Coastguard Worker
429*5c90c05cSAndroid Build Coastguard Worker char c = *it;
430*5c90c05cSAndroid Build Coastguard Worker if ((c >= '0' && c <= '9') || c == '{')
431*5c90c05cSAndroid Build Coastguard Worker it = detail::parse_width(it, end, specs_, width_ref_, ctx);
432*5c90c05cSAndroid Build Coastguard Worker return it;
433*5c90c05cSAndroid Build Coastguard Worker }
434*5c90c05cSAndroid Build Coastguard Worker
435*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
436*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR20 auto format(const std::error_code& ec,
437*5c90c05cSAndroid Build Coastguard Worker FormatContext& ctx) const -> decltype(ctx.out()) {
438*5c90c05cSAndroid Build Coastguard Worker auto specs = specs_;
439*5c90c05cSAndroid Build Coastguard Worker detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
440*5c90c05cSAndroid Build Coastguard Worker ctx);
441*5c90c05cSAndroid Build Coastguard Worker memory_buffer buf;
442*5c90c05cSAndroid Build Coastguard Worker buf.append(string_view(ec.category().name()));
443*5c90c05cSAndroid Build Coastguard Worker buf.push_back(':');
444*5c90c05cSAndroid Build Coastguard Worker detail::write<char>(appender(buf), ec.value());
445*5c90c05cSAndroid Build Coastguard Worker return detail::write<char>(ctx.out(), string_view(buf.data(), buf.size()),
446*5c90c05cSAndroid Build Coastguard Worker specs);
447*5c90c05cSAndroid Build Coastguard Worker }
448*5c90c05cSAndroid Build Coastguard Worker };
449*5c90c05cSAndroid Build Coastguard Worker
450*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_RTTI
451*5c90c05cSAndroid Build Coastguard Worker namespace detail {
452*5c90c05cSAndroid Build Coastguard Worker
453*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename OutputIt>
454*5c90c05cSAndroid Build Coastguard Worker auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
455*5c90c05cSAndroid Build Coastguard Worker # ifdef FMT_HAS_ABI_CXA_DEMANGLE
456*5c90c05cSAndroid Build Coastguard Worker int status = 0;
457*5c90c05cSAndroid Build Coastguard Worker std::size_t size = 0;
458*5c90c05cSAndroid Build Coastguard Worker std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
459*5c90c05cSAndroid Build Coastguard Worker abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
460*5c90c05cSAndroid Build Coastguard Worker
461*5c90c05cSAndroid Build Coastguard Worker string_view demangled_name_view;
462*5c90c05cSAndroid Build Coastguard Worker if (demangled_name_ptr) {
463*5c90c05cSAndroid Build Coastguard Worker demangled_name_view = demangled_name_ptr.get();
464*5c90c05cSAndroid Build Coastguard Worker
465*5c90c05cSAndroid Build Coastguard Worker // Normalization of stdlib inline namespace names.
466*5c90c05cSAndroid Build Coastguard Worker // libc++ inline namespaces.
467*5c90c05cSAndroid Build Coastguard Worker // std::__1::* -> std::*
468*5c90c05cSAndroid Build Coastguard Worker // std::__1::__fs::* -> std::*
469*5c90c05cSAndroid Build Coastguard Worker // libstdc++ inline namespaces.
470*5c90c05cSAndroid Build Coastguard Worker // std::__cxx11::* -> std::*
471*5c90c05cSAndroid Build Coastguard Worker // std::filesystem::__cxx11::* -> std::filesystem::*
472*5c90c05cSAndroid Build Coastguard Worker if (demangled_name_view.starts_with("std::")) {
473*5c90c05cSAndroid Build Coastguard Worker char* begin = demangled_name_ptr.get();
474*5c90c05cSAndroid Build Coastguard Worker char* to = begin + 5; // std::
475*5c90c05cSAndroid Build Coastguard Worker for (char *from = to, *end = begin + demangled_name_view.size();
476*5c90c05cSAndroid Build Coastguard Worker from < end;) {
477*5c90c05cSAndroid Build Coastguard Worker // This is safe, because demangled_name is NUL-terminated.
478*5c90c05cSAndroid Build Coastguard Worker if (from[0] == '_' && from[1] == '_') {
479*5c90c05cSAndroid Build Coastguard Worker char* next = from + 1;
480*5c90c05cSAndroid Build Coastguard Worker while (next < end && *next != ':') next++;
481*5c90c05cSAndroid Build Coastguard Worker if (next[0] == ':' && next[1] == ':') {
482*5c90c05cSAndroid Build Coastguard Worker from = next + 2;
483*5c90c05cSAndroid Build Coastguard Worker continue;
484*5c90c05cSAndroid Build Coastguard Worker }
485*5c90c05cSAndroid Build Coastguard Worker }
486*5c90c05cSAndroid Build Coastguard Worker *to++ = *from++;
487*5c90c05cSAndroid Build Coastguard Worker }
488*5c90c05cSAndroid Build Coastguard Worker demangled_name_view = {begin, detail::to_unsigned(to - begin)};
489*5c90c05cSAndroid Build Coastguard Worker }
490*5c90c05cSAndroid Build Coastguard Worker } else {
491*5c90c05cSAndroid Build Coastguard Worker demangled_name_view = string_view(ti.name());
492*5c90c05cSAndroid Build Coastguard Worker }
493*5c90c05cSAndroid Build Coastguard Worker return detail::write_bytes<Char>(out, demangled_name_view);
494*5c90c05cSAndroid Build Coastguard Worker # elif FMT_MSC_VERSION
495*5c90c05cSAndroid Build Coastguard Worker const string_view demangled_name(ti.name());
496*5c90c05cSAndroid Build Coastguard Worker for (std::size_t i = 0; i < demangled_name.size(); ++i) {
497*5c90c05cSAndroid Build Coastguard Worker auto sub = demangled_name;
498*5c90c05cSAndroid Build Coastguard Worker sub.remove_prefix(i);
499*5c90c05cSAndroid Build Coastguard Worker if (sub.starts_with("enum ")) {
500*5c90c05cSAndroid Build Coastguard Worker i += 4;
501*5c90c05cSAndroid Build Coastguard Worker continue;
502*5c90c05cSAndroid Build Coastguard Worker }
503*5c90c05cSAndroid Build Coastguard Worker if (sub.starts_with("class ") || sub.starts_with("union ")) {
504*5c90c05cSAndroid Build Coastguard Worker i += 5;
505*5c90c05cSAndroid Build Coastguard Worker continue;
506*5c90c05cSAndroid Build Coastguard Worker }
507*5c90c05cSAndroid Build Coastguard Worker if (sub.starts_with("struct ")) {
508*5c90c05cSAndroid Build Coastguard Worker i += 6;
509*5c90c05cSAndroid Build Coastguard Worker continue;
510*5c90c05cSAndroid Build Coastguard Worker }
511*5c90c05cSAndroid Build Coastguard Worker if (*sub.begin() != ' ') *out++ = *sub.begin();
512*5c90c05cSAndroid Build Coastguard Worker }
513*5c90c05cSAndroid Build Coastguard Worker return out;
514*5c90c05cSAndroid Build Coastguard Worker # else
515*5c90c05cSAndroid Build Coastguard Worker return detail::write_bytes<Char>(out, string_view(ti.name()));
516*5c90c05cSAndroid Build Coastguard Worker # endif
517*5c90c05cSAndroid Build Coastguard Worker }
518*5c90c05cSAndroid Build Coastguard Worker
519*5c90c05cSAndroid Build Coastguard Worker } // namespace detail
520*5c90c05cSAndroid Build Coastguard Worker
521*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
522*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
523*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
524*5c90c05cSAndroid Build Coastguard Worker > {
525*5c90c05cSAndroid Build Coastguard Worker public:
526*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
527*5c90c05cSAndroid Build Coastguard Worker return ctx.begin();
528*5c90c05cSAndroid Build Coastguard Worker }
529*5c90c05cSAndroid Build Coastguard Worker
530*5c90c05cSAndroid Build Coastguard Worker template <typename Context>
531*5c90c05cSAndroid Build Coastguard Worker auto format(const std::type_info& ti, Context& ctx) const
532*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
533*5c90c05cSAndroid Build Coastguard Worker return detail::write_demangled_name<Char>(ctx.out(), ti);
534*5c90c05cSAndroid Build Coastguard Worker }
535*5c90c05cSAndroid Build Coastguard Worker };
536*5c90c05cSAndroid Build Coastguard Worker #endif
537*5c90c05cSAndroid Build Coastguard Worker
538*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
539*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char>
540*5c90c05cSAndroid Build Coastguard Worker struct formatter<
541*5c90c05cSAndroid Build Coastguard Worker T, Char, // DEPRECATED! Mixing code unit types.
542*5c90c05cSAndroid Build Coastguard Worker typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
543*5c90c05cSAndroid Build Coastguard Worker private:
544*5c90c05cSAndroid Build Coastguard Worker bool with_typename_ = false;
545*5c90c05cSAndroid Build Coastguard Worker
546*5c90c05cSAndroid Build Coastguard Worker public:
547*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
548*5c90c05cSAndroid Build Coastguard Worker auto it = ctx.begin();
549*5c90c05cSAndroid Build Coastguard Worker auto end = ctx.end();
550*5c90c05cSAndroid Build Coastguard Worker if (it == end || *it == '}') return it;
551*5c90c05cSAndroid Build Coastguard Worker if (*it == 't') {
552*5c90c05cSAndroid Build Coastguard Worker ++it;
553*5c90c05cSAndroid Build Coastguard Worker with_typename_ = FMT_USE_RTTI != 0;
554*5c90c05cSAndroid Build Coastguard Worker }
555*5c90c05cSAndroid Build Coastguard Worker return it;
556*5c90c05cSAndroid Build Coastguard Worker }
557*5c90c05cSAndroid Build Coastguard Worker
558*5c90c05cSAndroid Build Coastguard Worker template <typename Context>
559*5c90c05cSAndroid Build Coastguard Worker auto format(const std::exception& ex, Context& ctx) const
560*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
561*5c90c05cSAndroid Build Coastguard Worker auto out = ctx.out();
562*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_RTTI
563*5c90c05cSAndroid Build Coastguard Worker if (with_typename_) {
564*5c90c05cSAndroid Build Coastguard Worker out = detail::write_demangled_name<Char>(out, typeid(ex));
565*5c90c05cSAndroid Build Coastguard Worker *out++ = ':';
566*5c90c05cSAndroid Build Coastguard Worker *out++ = ' ';
567*5c90c05cSAndroid Build Coastguard Worker }
568*5c90c05cSAndroid Build Coastguard Worker #endif
569*5c90c05cSAndroid Build Coastguard Worker return detail::write_bytes<Char>(out, string_view(ex.what()));
570*5c90c05cSAndroid Build Coastguard Worker }
571*5c90c05cSAndroid Build Coastguard Worker };
572*5c90c05cSAndroid Build Coastguard Worker
573*5c90c05cSAndroid Build Coastguard Worker namespace detail {
574*5c90c05cSAndroid Build Coastguard Worker
575*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Enable = void>
576*5c90c05cSAndroid Build Coastguard Worker struct has_flip : std::false_type {};
577*5c90c05cSAndroid Build Coastguard Worker
578*5c90c05cSAndroid Build Coastguard Worker template <typename T>
579*5c90c05cSAndroid Build Coastguard Worker struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
580*5c90c05cSAndroid Build Coastguard Worker : std::true_type {};
581*5c90c05cSAndroid Build Coastguard Worker
582*5c90c05cSAndroid Build Coastguard Worker template <typename T> struct is_bit_reference_like {
583*5c90c05cSAndroid Build Coastguard Worker static constexpr const bool value =
584*5c90c05cSAndroid Build Coastguard Worker std::is_convertible<T, bool>::value &&
585*5c90c05cSAndroid Build Coastguard Worker std::is_nothrow_assignable<T, bool>::value && has_flip<T>::value;
586*5c90c05cSAndroid Build Coastguard Worker };
587*5c90c05cSAndroid Build Coastguard Worker
588*5c90c05cSAndroid Build Coastguard Worker #ifdef _LIBCPP_VERSION
589*5c90c05cSAndroid Build Coastguard Worker
590*5c90c05cSAndroid Build Coastguard Worker // Workaround for libc++ incompatibility with C++ standard.
591*5c90c05cSAndroid Build Coastguard Worker // According to the Standard, `bitset::operator[] const` returns bool.
592*5c90c05cSAndroid Build Coastguard Worker template <typename C>
593*5c90c05cSAndroid Build Coastguard Worker struct is_bit_reference_like<std::__bit_const_reference<C>> {
594*5c90c05cSAndroid Build Coastguard Worker static constexpr const bool value = true;
595*5c90c05cSAndroid Build Coastguard Worker };
596*5c90c05cSAndroid Build Coastguard Worker
597*5c90c05cSAndroid Build Coastguard Worker #endif
598*5c90c05cSAndroid Build Coastguard Worker
599*5c90c05cSAndroid Build Coastguard Worker } // namespace detail
600*5c90c05cSAndroid Build Coastguard Worker
601*5c90c05cSAndroid Build Coastguard Worker // We can't use std::vector<bool, Allocator>::reference and
602*5c90c05cSAndroid Build Coastguard Worker // std::bitset<N>::reference because the compiler can't deduce Allocator and N
603*5c90c05cSAndroid Build Coastguard Worker // in partial specialization.
604*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
605*5c90c05cSAndroid Build Coastguard Worker template <typename BitRef, typename Char>
606*5c90c05cSAndroid Build Coastguard Worker struct formatter<BitRef, Char,
607*5c90c05cSAndroid Build Coastguard Worker enable_if_t<detail::is_bit_reference_like<BitRef>::value>>
608*5c90c05cSAndroid Build Coastguard Worker : formatter<bool, Char> {
609*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
610*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const
611*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
612*5c90c05cSAndroid Build Coastguard Worker return formatter<bool, Char>::format(v, ctx);
613*5c90c05cSAndroid Build Coastguard Worker }
614*5c90c05cSAndroid Build Coastguard Worker };
615*5c90c05cSAndroid Build Coastguard Worker
616*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Deleter>
617*5c90c05cSAndroid Build Coastguard Worker auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
618*5c90c05cSAndroid Build Coastguard Worker return p.get();
619*5c90c05cSAndroid Build Coastguard Worker }
620*5c90c05cSAndroid Build Coastguard Worker template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
621*5c90c05cSAndroid Build Coastguard Worker return p.get();
622*5c90c05cSAndroid Build Coastguard Worker }
623*5c90c05cSAndroid Build Coastguard Worker
624*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
625*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char>
626*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::atomic<T>, Char,
627*5c90c05cSAndroid Build Coastguard Worker enable_if_t<is_formattable<T, Char>::value>>
628*5c90c05cSAndroid Build Coastguard Worker : formatter<T, Char> {
629*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
630*5c90c05cSAndroid Build Coastguard Worker auto format(const std::atomic<T>& v, FormatContext& ctx) const
631*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
632*5c90c05cSAndroid Build Coastguard Worker return formatter<T, Char>::format(v.load(), ctx);
633*5c90c05cSAndroid Build Coastguard Worker }
634*5c90c05cSAndroid Build Coastguard Worker };
635*5c90c05cSAndroid Build Coastguard Worker
636*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_lib_atomic_flag_test
637*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
638*5c90c05cSAndroid Build Coastguard Worker template <typename Char>
639*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
640*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
641*5c90c05cSAndroid Build Coastguard Worker auto format(const std::atomic_flag& v, FormatContext& ctx) const
642*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
643*5c90c05cSAndroid Build Coastguard Worker return formatter<bool, Char>::format(v.test(), ctx);
644*5c90c05cSAndroid Build Coastguard Worker }
645*5c90c05cSAndroid Build Coastguard Worker };
646*5c90c05cSAndroid Build Coastguard Worker #endif // __cpp_lib_atomic_flag_test
647*5c90c05cSAndroid Build Coastguard Worker
648*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
649*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
650*5c90c05cSAndroid Build Coastguard Worker private:
651*5c90c05cSAndroid Build Coastguard Worker detail::dynamic_format_specs<Char> specs_;
652*5c90c05cSAndroid Build Coastguard Worker
653*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext, typename OutputIt>
654*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto do_format(const std::complex<T>& c,
655*5c90c05cSAndroid Build Coastguard Worker detail::dynamic_format_specs<Char>& specs,
656*5c90c05cSAndroid Build Coastguard Worker FormatContext& ctx, OutputIt out) const
657*5c90c05cSAndroid Build Coastguard Worker -> OutputIt {
658*5c90c05cSAndroid Build Coastguard Worker if (c.real() != 0) {
659*5c90c05cSAndroid Build Coastguard Worker *out++ = Char('(');
660*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, c.real(), specs, ctx.locale());
661*5c90c05cSAndroid Build Coastguard Worker specs.set_sign(sign::plus);
662*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, c.imag(), specs, ctx.locale());
663*5c90c05cSAndroid Build Coastguard Worker if (!detail::isfinite(c.imag())) *out++ = Char(' ');
664*5c90c05cSAndroid Build Coastguard Worker *out++ = Char('i');
665*5c90c05cSAndroid Build Coastguard Worker *out++ = Char(')');
666*5c90c05cSAndroid Build Coastguard Worker return out;
667*5c90c05cSAndroid Build Coastguard Worker }
668*5c90c05cSAndroid Build Coastguard Worker out = detail::write<Char>(out, c.imag(), specs, ctx.locale());
669*5c90c05cSAndroid Build Coastguard Worker if (!detail::isfinite(c.imag())) *out++ = Char(' ');
670*5c90c05cSAndroid Build Coastguard Worker *out++ = Char('i');
671*5c90c05cSAndroid Build Coastguard Worker return out;
672*5c90c05cSAndroid Build Coastguard Worker }
673*5c90c05cSAndroid Build Coastguard Worker
674*5c90c05cSAndroid Build Coastguard Worker public:
675*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
676*5c90c05cSAndroid Build Coastguard Worker if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
677*5c90c05cSAndroid Build Coastguard Worker return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
678*5c90c05cSAndroid Build Coastguard Worker detail::type_constant<T, Char>::value);
679*5c90c05cSAndroid Build Coastguard Worker }
680*5c90c05cSAndroid Build Coastguard Worker
681*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
682*5c90c05cSAndroid Build Coastguard Worker auto format(const std::complex<T>& c, FormatContext& ctx) const
683*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
684*5c90c05cSAndroid Build Coastguard Worker auto specs = specs_;
685*5c90c05cSAndroid Build Coastguard Worker if (specs.dynamic()) {
686*5c90c05cSAndroid Build Coastguard Worker detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
687*5c90c05cSAndroid Build Coastguard Worker specs.width_ref, ctx);
688*5c90c05cSAndroid Build Coastguard Worker detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
689*5c90c05cSAndroid Build Coastguard Worker specs.precision_ref, ctx);
690*5c90c05cSAndroid Build Coastguard Worker }
691*5c90c05cSAndroid Build Coastguard Worker
692*5c90c05cSAndroid Build Coastguard Worker if (specs.width == 0) return do_format(c, specs, ctx, ctx.out());
693*5c90c05cSAndroid Build Coastguard Worker auto buf = basic_memory_buffer<Char>();
694*5c90c05cSAndroid Build Coastguard Worker
695*5c90c05cSAndroid Build Coastguard Worker auto outer_specs = format_specs();
696*5c90c05cSAndroid Build Coastguard Worker outer_specs.width = specs.width;
697*5c90c05cSAndroid Build Coastguard Worker auto fill = specs.template fill<Char>();
698*5c90c05cSAndroid Build Coastguard Worker if (fill)
699*5c90c05cSAndroid Build Coastguard Worker outer_specs.set_fill(basic_string_view<Char>(fill, specs.fill_size()));
700*5c90c05cSAndroid Build Coastguard Worker outer_specs.set_align(specs.align());
701*5c90c05cSAndroid Build Coastguard Worker
702*5c90c05cSAndroid Build Coastguard Worker specs.width = 0;
703*5c90c05cSAndroid Build Coastguard Worker specs.set_fill({});
704*5c90c05cSAndroid Build Coastguard Worker specs.set_align(align::none);
705*5c90c05cSAndroid Build Coastguard Worker
706*5c90c05cSAndroid Build Coastguard Worker do_format(c, specs, ctx, basic_appender<Char>(buf));
707*5c90c05cSAndroid Build Coastguard Worker return detail::write<Char>(ctx.out(),
708*5c90c05cSAndroid Build Coastguard Worker basic_string_view<Char>(buf.data(), buf.size()),
709*5c90c05cSAndroid Build Coastguard Worker outer_specs);
710*5c90c05cSAndroid Build Coastguard Worker }
711*5c90c05cSAndroid Build Coastguard Worker };
712*5c90c05cSAndroid Build Coastguard Worker
713*5c90c05cSAndroid Build Coastguard Worker FMT_EXPORT
714*5c90c05cSAndroid Build Coastguard Worker template <typename T, typename Char>
715*5c90c05cSAndroid Build Coastguard Worker struct formatter<std::reference_wrapper<T>, Char,
716*5c90c05cSAndroid Build Coastguard Worker enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>
717*5c90c05cSAndroid Build Coastguard Worker : formatter<remove_cvref_t<T>, Char> {
718*5c90c05cSAndroid Build Coastguard Worker template <typename FormatContext>
719*5c90c05cSAndroid Build Coastguard Worker auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const
720*5c90c05cSAndroid Build Coastguard Worker -> decltype(ctx.out()) {
721*5c90c05cSAndroid Build Coastguard Worker return formatter<remove_cvref_t<T>, Char>::format(ref.get(), ctx);
722*5c90c05cSAndroid Build Coastguard Worker }
723*5c90c05cSAndroid Build Coastguard Worker };
724*5c90c05cSAndroid Build Coastguard Worker
725*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
726*5c90c05cSAndroid Build Coastguard Worker #endif // FMT_STD_H_
727