xref: /aosp_15_r20/external/fmtlib/include/fmt/std.h (revision 5c90c05cd622c0a81b57953a4d343e0e489f2e08)
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