xref: /aosp_15_r20/external/fmtlib/include/fmt/xchar.h (revision 5c90c05cd622c0a81b57953a4d343e0e489f2e08)
1*5c90c05cSAndroid Build Coastguard Worker // Formatting library for C++ - optional wchar_t and exotic character support
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_XCHAR_H_
9*5c90c05cSAndroid Build Coastguard Worker #define FMT_XCHAR_H_
10*5c90c05cSAndroid Build Coastguard Worker 
11*5c90c05cSAndroid Build Coastguard Worker #include "color.h"
12*5c90c05cSAndroid Build Coastguard Worker #include "format.h"
13*5c90c05cSAndroid Build Coastguard Worker #include "ostream.h"
14*5c90c05cSAndroid Build Coastguard Worker #include "ranges.h"
15*5c90c05cSAndroid Build Coastguard Worker 
16*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_MODULE
17*5c90c05cSAndroid Build Coastguard Worker #  include <cwchar>
18*5c90c05cSAndroid Build Coastguard Worker #  if FMT_USE_LOCALE
19*5c90c05cSAndroid Build Coastguard Worker #    include <locale>
20*5c90c05cSAndroid Build Coastguard Worker #  endif
21*5c90c05cSAndroid Build Coastguard Worker #endif
22*5c90c05cSAndroid Build Coastguard Worker 
23*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
24*5c90c05cSAndroid Build Coastguard Worker namespace detail {
25*5c90c05cSAndroid Build Coastguard Worker 
26*5c90c05cSAndroid Build Coastguard Worker template <typename T>
27*5c90c05cSAndroid Build Coastguard Worker using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
28*5c90c05cSAndroid Build Coastguard Worker 
29*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename = void> struct format_string_char {};
30*5c90c05cSAndroid Build Coastguard Worker 
31*5c90c05cSAndroid Build Coastguard Worker template <typename S>
32*5c90c05cSAndroid Build Coastguard Worker struct format_string_char<
33*5c90c05cSAndroid Build Coastguard Worker     S, void_t<decltype(sizeof(detail::to_string_view(std::declval<S>())))>> {
34*5c90c05cSAndroid Build Coastguard Worker   using type = char_t<S>;
35*5c90c05cSAndroid Build Coastguard Worker };
36*5c90c05cSAndroid Build Coastguard Worker 
37*5c90c05cSAndroid Build Coastguard Worker template <typename S>
38*5c90c05cSAndroid Build Coastguard Worker struct format_string_char<
39*5c90c05cSAndroid Build Coastguard Worker     S, enable_if_t<std::is_base_of<detail::compile_string, S>::value>> {
40*5c90c05cSAndroid Build Coastguard Worker   using type = typename S::char_type;
41*5c90c05cSAndroid Build Coastguard Worker };
42*5c90c05cSAndroid Build Coastguard Worker 
43*5c90c05cSAndroid Build Coastguard Worker template <typename S>
44*5c90c05cSAndroid Build Coastguard Worker using format_string_char_t = typename format_string_char<S>::type;
45*5c90c05cSAndroid Build Coastguard Worker 
46*5c90c05cSAndroid Build Coastguard Worker inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
47*5c90c05cSAndroid Build Coastguard Worker                       const format_specs& specs, locale_ref loc) -> bool {
48*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_LOCALE
49*5c90c05cSAndroid Build Coastguard Worker   auto& numpunct =
50*5c90c05cSAndroid Build Coastguard Worker       std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());
51*5c90c05cSAndroid Build Coastguard Worker   auto separator = std::wstring();
52*5c90c05cSAndroid Build Coastguard Worker   auto grouping = numpunct.grouping();
53*5c90c05cSAndroid Build Coastguard Worker   if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());
54*5c90c05cSAndroid Build Coastguard Worker   return value.visit(loc_writer<wchar_t>{out, specs, separator, grouping, {}});
55*5c90c05cSAndroid Build Coastguard Worker #endif
56*5c90c05cSAndroid Build Coastguard Worker   return false;
57*5c90c05cSAndroid Build Coastguard Worker }
58*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
59*5c90c05cSAndroid Build Coastguard Worker 
60*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_EXPORT
61*5c90c05cSAndroid Build Coastguard Worker 
62*5c90c05cSAndroid Build Coastguard Worker using wstring_view = basic_string_view<wchar_t>;
63*5c90c05cSAndroid Build Coastguard Worker using wformat_parse_context = parse_context<wchar_t>;
64*5c90c05cSAndroid Build Coastguard Worker using wformat_context = buffered_context<wchar_t>;
65*5c90c05cSAndroid Build Coastguard Worker using wformat_args = basic_format_args<wformat_context>;
66*5c90c05cSAndroid Build Coastguard Worker using wmemory_buffer = basic_memory_buffer<wchar_t>;
67*5c90c05cSAndroid Build Coastguard Worker 
68*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename... T> struct basic_fstring {
69*5c90c05cSAndroid Build Coastguard Worker  private:
70*5c90c05cSAndroid Build Coastguard Worker   basic_string_view<Char> str_;
71*5c90c05cSAndroid Build Coastguard Worker 
72*5c90c05cSAndroid Build Coastguard Worker   static constexpr int num_static_named_args =
73*5c90c05cSAndroid Build Coastguard Worker       detail::count_static_named_args<T...>();
74*5c90c05cSAndroid Build Coastguard Worker 
75*5c90c05cSAndroid Build Coastguard Worker   using checker = detail::format_string_checker<
76*5c90c05cSAndroid Build Coastguard Worker       Char, static_cast<int>(sizeof...(T)), num_static_named_args,
77*5c90c05cSAndroid Build Coastguard Worker       num_static_named_args != detail::count_named_args<T...>()>;
78*5c90c05cSAndroid Build Coastguard Worker 
79*5c90c05cSAndroid Build Coastguard Worker   using arg_pack = detail::arg_pack<T...>;
80*5c90c05cSAndroid Build Coastguard Worker 
81*5c90c05cSAndroid Build Coastguard Worker  public:
82*5c90c05cSAndroid Build Coastguard Worker   using t = basic_fstring;
83*5c90c05cSAndroid Build Coastguard Worker 
84*5c90c05cSAndroid Build Coastguard Worker   template <typename S,
85*5c90c05cSAndroid Build Coastguard Worker             FMT_ENABLE_IF(
86*5c90c05cSAndroid Build Coastguard Worker                 std::is_convertible<const S&, basic_string_view<Char>>::value)>
87*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) {
88*5c90c05cSAndroid Build Coastguard Worker     if (FMT_USE_CONSTEVAL)
89*5c90c05cSAndroid Build Coastguard Worker       detail::parse_format_string<Char>(s, checker(s, arg_pack()));
90*5c90c05cSAndroid Build Coastguard Worker   }
91*5c90c05cSAndroid Build Coastguard Worker   template <typename S,
92*5c90c05cSAndroid Build Coastguard Worker             FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&
93*5c90c05cSAndroid Build Coastguard Worker                               std::is_same<typename S::char_type, Char>::value)>
94*5c90c05cSAndroid Build Coastguard Worker   FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) {
95*5c90c05cSAndroid Build Coastguard Worker     FMT_CONSTEXPR auto sv = basic_string_view<Char>(S());
96*5c90c05cSAndroid Build Coastguard Worker     FMT_CONSTEXPR int ignore =
97*5c90c05cSAndroid Build Coastguard Worker         (parse_format_string(sv, checker(sv, arg_pack())), 0);
98*5c90c05cSAndroid Build Coastguard Worker     detail::ignore_unused(ignore);
99*5c90c05cSAndroid Build Coastguard Worker   }
100*5c90c05cSAndroid Build Coastguard Worker   basic_fstring(runtime_format_string<Char> fmt) : str_(fmt.str) {}
101*5c90c05cSAndroid Build Coastguard Worker 
102*5c90c05cSAndroid Build Coastguard Worker   operator basic_string_view<Char>() const { return str_; }
103*5c90c05cSAndroid Build Coastguard Worker   auto get() const -> basic_string_view<Char> { return str_; }
104*5c90c05cSAndroid Build Coastguard Worker };
105*5c90c05cSAndroid Build Coastguard Worker 
106*5c90c05cSAndroid Build Coastguard Worker template <typename Char, typename... T>
107*5c90c05cSAndroid Build Coastguard Worker using basic_format_string = basic_fstring<Char, T...>;
108*5c90c05cSAndroid Build Coastguard Worker 
109*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
110*5c90c05cSAndroid Build Coastguard Worker using wformat_string = typename basic_format_string<wchar_t, T...>::t;
111*5c90c05cSAndroid Build Coastguard Worker inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
112*5c90c05cSAndroid Build Coastguard Worker   return {{s}};
113*5c90c05cSAndroid Build Coastguard Worker }
114*5c90c05cSAndroid Build Coastguard Worker 
115*5c90c05cSAndroid Build Coastguard Worker template <> struct is_char<wchar_t> : std::true_type {};
116*5c90c05cSAndroid Build Coastguard Worker template <> struct is_char<char16_t> : std::true_type {};
117*5c90c05cSAndroid Build Coastguard Worker template <> struct is_char<char32_t> : std::true_type {};
118*5c90c05cSAndroid Build Coastguard Worker 
119*5c90c05cSAndroid Build Coastguard Worker #ifdef __cpp_char8_t
120*5c90c05cSAndroid Build Coastguard Worker template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {};
121*5c90c05cSAndroid Build Coastguard Worker #endif
122*5c90c05cSAndroid Build Coastguard Worker 
123*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
124*5c90c05cSAndroid Build Coastguard Worker constexpr auto make_wformat_args(T&... args)
125*5c90c05cSAndroid Build Coastguard Worker     -> decltype(fmt::make_format_args<wformat_context>(args...)) {
126*5c90c05cSAndroid Build Coastguard Worker   return fmt::make_format_args<wformat_context>(args...);
127*5c90c05cSAndroid Build Coastguard Worker }
128*5c90c05cSAndroid Build Coastguard Worker 
129*5c90c05cSAndroid Build Coastguard Worker #if !FMT_USE_NONTYPE_TEMPLATE_ARGS
130*5c90c05cSAndroid Build Coastguard Worker inline namespace literals {
131*5c90c05cSAndroid Build Coastguard Worker inline auto operator""_a(const wchar_t* s, size_t) -> detail::udl_arg<wchar_t> {
132*5c90c05cSAndroid Build Coastguard Worker   return {s};
133*5c90c05cSAndroid Build Coastguard Worker }
134*5c90c05cSAndroid Build Coastguard Worker }  // namespace literals
135*5c90c05cSAndroid Build Coastguard Worker #endif
136*5c90c05cSAndroid Build Coastguard Worker 
137*5c90c05cSAndroid Build Coastguard Worker template <typename It, typename Sentinel>
138*5c90c05cSAndroid Build Coastguard Worker auto join(It begin, Sentinel end, wstring_view sep)
139*5c90c05cSAndroid Build Coastguard Worker     -> join_view<It, Sentinel, wchar_t> {
140*5c90c05cSAndroid Build Coastguard Worker   return {begin, end, sep};
141*5c90c05cSAndroid Build Coastguard Worker }
142*5c90c05cSAndroid Build Coastguard Worker 
143*5c90c05cSAndroid Build Coastguard Worker template <typename Range>
144*5c90c05cSAndroid Build Coastguard Worker auto join(Range&& range, wstring_view sep)
145*5c90c05cSAndroid Build Coastguard Worker     -> join_view<decltype(std::begin(range)), decltype(std::end(range)),
146*5c90c05cSAndroid Build Coastguard Worker                  wchar_t> {
147*5c90c05cSAndroid Build Coastguard Worker   return join(std::begin(range), std::end(range), sep);
148*5c90c05cSAndroid Build Coastguard Worker }
149*5c90c05cSAndroid Build Coastguard Worker 
150*5c90c05cSAndroid Build Coastguard Worker template <typename T>
151*5c90c05cSAndroid Build Coastguard Worker auto join(std::initializer_list<T> list, wstring_view sep)
152*5c90c05cSAndroid Build Coastguard Worker     -> join_view<const T*, const T*, wchar_t> {
153*5c90c05cSAndroid Build Coastguard Worker   return join(std::begin(list), std::end(list), sep);
154*5c90c05cSAndroid Build Coastguard Worker }
155*5c90c05cSAndroid Build Coastguard Worker 
156*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
157*5c90c05cSAndroid Build Coastguard Worker auto join(const std::tuple<T...>& tuple, basic_string_view<wchar_t> sep)
158*5c90c05cSAndroid Build Coastguard Worker     -> tuple_join_view<wchar_t, T...> {
159*5c90c05cSAndroid Build Coastguard Worker   return {tuple, sep};
160*5c90c05cSAndroid Build Coastguard Worker }
161*5c90c05cSAndroid Build Coastguard Worker 
162*5c90c05cSAndroid Build Coastguard Worker template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
163*5c90c05cSAndroid Build Coastguard Worker auto vformat(basic_string_view<Char> fmt,
164*5c90c05cSAndroid Build Coastguard Worker              typename detail::vformat_args<Char>::type args)
165*5c90c05cSAndroid Build Coastguard Worker     -> std::basic_string<Char> {
166*5c90c05cSAndroid Build Coastguard Worker   auto buf = basic_memory_buffer<Char>();
167*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, fmt, args);
168*5c90c05cSAndroid Build Coastguard Worker   return {buf.data(), buf.size()};
169*5c90c05cSAndroid Build Coastguard Worker }
170*5c90c05cSAndroid Build Coastguard Worker 
171*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
172*5c90c05cSAndroid Build Coastguard Worker auto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {
173*5c90c05cSAndroid Build Coastguard Worker   return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));
174*5c90c05cSAndroid Build Coastguard Worker }
175*5c90c05cSAndroid Build Coastguard Worker 
176*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename... T>
177*5c90c05cSAndroid Build Coastguard Worker auto format_to(OutputIt out, wformat_string<T...> fmt, T&&... args)
178*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
179*5c90c05cSAndroid Build Coastguard Worker   return vformat_to(out, fmt::wstring_view(fmt),
180*5c90c05cSAndroid Build Coastguard Worker                     fmt::make_wformat_args(args...));
181*5c90c05cSAndroid Build Coastguard Worker }
182*5c90c05cSAndroid Build Coastguard Worker 
183*5c90c05cSAndroid Build Coastguard Worker // Pass char_t as a default template parameter instead of using
184*5c90c05cSAndroid Build Coastguard Worker // std::basic_string<char_t<S>> to reduce the symbol size.
185*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename... T,
186*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
187*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
188*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<Char, wchar_t>::value)>
189*5c90c05cSAndroid Build Coastguard Worker auto format(const S& fmt, T&&... args) -> std::basic_string<Char> {
190*5c90c05cSAndroid Build Coastguard Worker   return vformat(detail::to_string_view(fmt),
191*5c90c05cSAndroid Build Coastguard Worker                  fmt::make_format_args<buffered_context<Char>>(args...));
192*5c90c05cSAndroid Build Coastguard Worker }
193*5c90c05cSAndroid Build Coastguard Worker 
194*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename Char = detail::format_string_char_t<S>,
195*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
196*5c90c05cSAndroid Build Coastguard Worker inline auto vformat(detail::locale_ref loc, const S& fmt,
197*5c90c05cSAndroid Build Coastguard Worker                     typename detail::vformat_args<Char>::type args)
198*5c90c05cSAndroid Build Coastguard Worker     -> std::basic_string<Char> {
199*5c90c05cSAndroid Build Coastguard Worker   auto buf = basic_memory_buffer<Char>();
200*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, detail::to_string_view(fmt), args,
201*5c90c05cSAndroid Build Coastguard Worker                      detail::locale_ref(loc));
202*5c90c05cSAndroid Build Coastguard Worker   return {buf.data(), buf.size()};
203*5c90c05cSAndroid Build Coastguard Worker }
204*5c90c05cSAndroid Build Coastguard Worker 
205*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename... T,
206*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
207*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
208*5c90c05cSAndroid Build Coastguard Worker inline auto format(detail::locale_ref loc, const S& fmt, T&&... args)
209*5c90c05cSAndroid Build Coastguard Worker     -> std::basic_string<Char> {
210*5c90c05cSAndroid Build Coastguard Worker   return vformat(loc, detail::to_string_view(fmt),
211*5c90c05cSAndroid Build Coastguard Worker                  fmt::make_format_args<buffered_context<Char>>(args...));
212*5c90c05cSAndroid Build Coastguard Worker }
213*5c90c05cSAndroid Build Coastguard Worker 
214*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename S,
215*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
216*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
217*5c90c05cSAndroid Build Coastguard Worker                             detail::is_exotic_char<Char>::value)>
218*5c90c05cSAndroid Build Coastguard Worker auto vformat_to(OutputIt out, const S& fmt,
219*5c90c05cSAndroid Build Coastguard Worker                 typename detail::vformat_args<Char>::type args) -> OutputIt {
220*5c90c05cSAndroid Build Coastguard Worker   auto&& buf = detail::get_buffer<Char>(out);
221*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, detail::to_string_view(fmt), args);
222*5c90c05cSAndroid Build Coastguard Worker   return detail::get_iterator(buf, out);
223*5c90c05cSAndroid Build Coastguard Worker }
224*5c90c05cSAndroid Build Coastguard Worker 
225*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename S, typename... T,
226*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
227*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value &&
228*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<Char, char>::value &&
229*5c90c05cSAndroid Build Coastguard Worker                         !std::is_same<Char, wchar_t>::value)>
230*5c90c05cSAndroid Build Coastguard Worker inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
231*5c90c05cSAndroid Build Coastguard Worker   return vformat_to(out, detail::to_string_view(fmt),
232*5c90c05cSAndroid Build Coastguard Worker                     fmt::make_format_args<buffered_context<Char>>(args...));
233*5c90c05cSAndroid Build Coastguard Worker }
234*5c90c05cSAndroid Build Coastguard Worker 
235*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename OutputIt, typename... Args,
236*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
237*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
238*5c90c05cSAndroid Build Coastguard Worker                             detail::is_exotic_char<Char>::value)>
239*5c90c05cSAndroid Build Coastguard Worker inline auto vformat_to(OutputIt out, detail::locale_ref loc, const S& fmt,
240*5c90c05cSAndroid Build Coastguard Worker                        typename detail::vformat_args<Char>::type args)
241*5c90c05cSAndroid Build Coastguard Worker     -> OutputIt {
242*5c90c05cSAndroid Build Coastguard Worker   auto&& buf = detail::get_buffer<Char>(out);
243*5c90c05cSAndroid Build Coastguard Worker   vformat_to(buf, detail::to_string_view(fmt), args, detail::locale_ref(loc));
244*5c90c05cSAndroid Build Coastguard Worker   return detail::get_iterator(buf, out);
245*5c90c05cSAndroid Build Coastguard Worker }
246*5c90c05cSAndroid Build Coastguard Worker 
247*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename S, typename... T,
248*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
249*5c90c05cSAndroid Build Coastguard Worker           bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
250*5c90c05cSAndroid Build Coastguard Worker                         detail::is_exotic_char<Char>::value>
251*5c90c05cSAndroid Build Coastguard Worker inline auto format_to(OutputIt out, detail::locale_ref loc, const S& fmt,
252*5c90c05cSAndroid Build Coastguard Worker                       T&&... args) ->
253*5c90c05cSAndroid Build Coastguard Worker     typename std::enable_if<enable, OutputIt>::type {
254*5c90c05cSAndroid Build Coastguard Worker   return vformat_to(out, loc, detail::to_string_view(fmt),
255*5c90c05cSAndroid Build Coastguard Worker                     fmt::make_format_args<buffered_context<Char>>(args...));
256*5c90c05cSAndroid Build Coastguard Worker }
257*5c90c05cSAndroid Build Coastguard Worker 
258*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename Char, typename... Args,
259*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
260*5c90c05cSAndroid Build Coastguard Worker                             detail::is_exotic_char<Char>::value)>
261*5c90c05cSAndroid Build Coastguard Worker inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view<Char> fmt,
262*5c90c05cSAndroid Build Coastguard Worker                          typename detail::vformat_args<Char>::type args)
263*5c90c05cSAndroid Build Coastguard Worker     -> format_to_n_result<OutputIt> {
264*5c90c05cSAndroid Build Coastguard Worker   using traits = detail::fixed_buffer_traits;
265*5c90c05cSAndroid Build Coastguard Worker   auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
266*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, fmt, args);
267*5c90c05cSAndroid Build Coastguard Worker   return {buf.out(), buf.count()};
268*5c90c05cSAndroid Build Coastguard Worker }
269*5c90c05cSAndroid Build Coastguard Worker 
270*5c90c05cSAndroid Build Coastguard Worker template <typename OutputIt, typename S, typename... T,
271*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
272*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
273*5c90c05cSAndroid Build Coastguard Worker                             detail::is_exotic_char<Char>::value)>
274*5c90c05cSAndroid Build Coastguard Worker inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
275*5c90c05cSAndroid Build Coastguard Worker     -> format_to_n_result<OutputIt> {
276*5c90c05cSAndroid Build Coastguard Worker   return vformat_to_n(out, n, fmt::basic_string_view<Char>(fmt),
277*5c90c05cSAndroid Build Coastguard Worker                       fmt::make_format_args<buffered_context<Char>>(args...));
278*5c90c05cSAndroid Build Coastguard Worker }
279*5c90c05cSAndroid Build Coastguard Worker 
280*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename... T,
281*5c90c05cSAndroid Build Coastguard Worker           typename Char = detail::format_string_char_t<S>,
282*5c90c05cSAndroid Build Coastguard Worker           FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
283*5c90c05cSAndroid Build Coastguard Worker inline auto formatted_size(const S& fmt, T&&... args) -> size_t {
284*5c90c05cSAndroid Build Coastguard Worker   auto buf = detail::counting_buffer<Char>();
285*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, detail::to_string_view(fmt),
286*5c90c05cSAndroid Build Coastguard Worker                      fmt::make_format_args<buffered_context<Char>>(args...));
287*5c90c05cSAndroid Build Coastguard Worker   return buf.count();
288*5c90c05cSAndroid Build Coastguard Worker }
289*5c90c05cSAndroid Build Coastguard Worker 
290*5c90c05cSAndroid Build Coastguard Worker inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
291*5c90c05cSAndroid Build Coastguard Worker   auto buf = wmemory_buffer();
292*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, fmt, args);
293*5c90c05cSAndroid Build Coastguard Worker   buf.push_back(L'\0');
294*5c90c05cSAndroid Build Coastguard Worker   if (std::fputws(buf.data(), f) == -1)
295*5c90c05cSAndroid Build Coastguard Worker     FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
296*5c90c05cSAndroid Build Coastguard Worker }
297*5c90c05cSAndroid Build Coastguard Worker 
298*5c90c05cSAndroid Build Coastguard Worker inline void vprint(wstring_view fmt, wformat_args args) {
299*5c90c05cSAndroid Build Coastguard Worker   vprint(stdout, fmt, args);
300*5c90c05cSAndroid Build Coastguard Worker }
301*5c90c05cSAndroid Build Coastguard Worker 
302*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
303*5c90c05cSAndroid Build Coastguard Worker void print(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
304*5c90c05cSAndroid Build Coastguard Worker   return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...));
305*5c90c05cSAndroid Build Coastguard Worker }
306*5c90c05cSAndroid Build Coastguard Worker 
307*5c90c05cSAndroid Build Coastguard Worker template <typename... T> void print(wformat_string<T...> fmt, T&&... args) {
308*5c90c05cSAndroid Build Coastguard Worker   return vprint(wstring_view(fmt), fmt::make_wformat_args(args...));
309*5c90c05cSAndroid Build Coastguard Worker }
310*5c90c05cSAndroid Build Coastguard Worker 
311*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
312*5c90c05cSAndroid Build Coastguard Worker void println(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
313*5c90c05cSAndroid Build Coastguard Worker   return print(f, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
314*5c90c05cSAndroid Build Coastguard Worker }
315*5c90c05cSAndroid Build Coastguard Worker 
316*5c90c05cSAndroid Build Coastguard Worker template <typename... T> void println(wformat_string<T...> fmt, T&&... args) {
317*5c90c05cSAndroid Build Coastguard Worker   return print(L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
318*5c90c05cSAndroid Build Coastguard Worker }
319*5c90c05cSAndroid Build Coastguard Worker 
320*5c90c05cSAndroid Build Coastguard Worker inline auto vformat(const text_style& ts, wstring_view fmt, wformat_args args)
321*5c90c05cSAndroid Build Coastguard Worker     -> std::wstring {
322*5c90c05cSAndroid Build Coastguard Worker   auto buf = wmemory_buffer();
323*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buf, ts, fmt, args);
324*5c90c05cSAndroid Build Coastguard Worker   return {buf.data(), buf.size()};
325*5c90c05cSAndroid Build Coastguard Worker }
326*5c90c05cSAndroid Build Coastguard Worker 
327*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
328*5c90c05cSAndroid Build Coastguard Worker inline auto format(const text_style& ts, wformat_string<T...> fmt, T&&... args)
329*5c90c05cSAndroid Build Coastguard Worker     -> std::wstring {
330*5c90c05cSAndroid Build Coastguard Worker   return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));
331*5c90c05cSAndroid Build Coastguard Worker }
332*5c90c05cSAndroid Build Coastguard Worker 
333*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
334*5c90c05cSAndroid Build Coastguard Worker FMT_DEPRECATED void print(std::FILE* f, const text_style& ts,
335*5c90c05cSAndroid Build Coastguard Worker                           wformat_string<T...> fmt, const T&... args) {
336*5c90c05cSAndroid Build Coastguard Worker   vprint(f, ts, fmt, fmt::make_wformat_args(args...));
337*5c90c05cSAndroid Build Coastguard Worker }
338*5c90c05cSAndroid Build Coastguard Worker 
339*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
340*5c90c05cSAndroid Build Coastguard Worker FMT_DEPRECATED void print(const text_style& ts, wformat_string<T...> fmt,
341*5c90c05cSAndroid Build Coastguard Worker                           const T&... args) {
342*5c90c05cSAndroid Build Coastguard Worker   return print(stdout, ts, fmt, args...);
343*5c90c05cSAndroid Build Coastguard Worker }
344*5c90c05cSAndroid Build Coastguard Worker 
345*5c90c05cSAndroid Build Coastguard Worker inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) {
346*5c90c05cSAndroid Build Coastguard Worker   auto buffer = basic_memory_buffer<wchar_t>();
347*5c90c05cSAndroid Build Coastguard Worker   detail::vformat_to(buffer, fmt, args);
348*5c90c05cSAndroid Build Coastguard Worker   detail::write_buffer(os, buffer);
349*5c90c05cSAndroid Build Coastguard Worker }
350*5c90c05cSAndroid Build Coastguard Worker 
351*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
352*5c90c05cSAndroid Build Coastguard Worker void print(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
353*5c90c05cSAndroid Build Coastguard Worker   vprint(os, fmt, fmt::make_format_args<buffered_context<wchar_t>>(args...));
354*5c90c05cSAndroid Build Coastguard Worker }
355*5c90c05cSAndroid Build Coastguard Worker 
356*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
357*5c90c05cSAndroid Build Coastguard Worker void println(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
358*5c90c05cSAndroid Build Coastguard Worker   print(os, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
359*5c90c05cSAndroid Build Coastguard Worker }
360*5c90c05cSAndroid Build Coastguard Worker 
361*5c90c05cSAndroid Build Coastguard Worker /// Converts `value` to `std::wstring` using the default format for type `T`.
362*5c90c05cSAndroid Build Coastguard Worker template <typename T> inline auto to_wstring(const T& value) -> std::wstring {
363*5c90c05cSAndroid Build Coastguard Worker   return format(FMT_STRING(L"{}"), value);
364*5c90c05cSAndroid Build Coastguard Worker }
365*5c90c05cSAndroid Build Coastguard Worker FMT_END_EXPORT
366*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
367*5c90c05cSAndroid Build Coastguard Worker 
368*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_XCHAR_H_
369