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