Warning, file /include/fmt/xchar.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef FMT_XCHAR_H_
0009 #define FMT_XCHAR_H_
0010
0011 #include "color.h"
0012 #include "format.h"
0013 #include "ostream.h"
0014 #include "ranges.h"
0015
0016 #ifndef FMT_MODULE
0017 # include <cwchar>
0018 # if FMT_USE_LOCALE
0019 # include <locale>
0020 # endif
0021 #endif
0022
0023 FMT_BEGIN_NAMESPACE
0024 namespace detail {
0025
0026 template <typename T>
0027 using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
0028
0029 template <typename S, typename = void> struct format_string_char {};
0030
0031 template <typename S>
0032 struct format_string_char<
0033 S, void_t<decltype(sizeof(detail::to_string_view(std::declval<S>())))>> {
0034 using type = char_t<S>;
0035 };
0036
0037 template <typename S>
0038 struct format_string_char<
0039 S, enable_if_t<std::is_base_of<detail::compile_string, S>::value>> {
0040 using type = typename S::char_type;
0041 };
0042
0043 template <typename S>
0044 using format_string_char_t = typename format_string_char<S>::type;
0045
0046 inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
0047 const format_specs& specs, locale_ref loc) -> bool {
0048 #if FMT_USE_LOCALE
0049 auto& numpunct =
0050 std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());
0051 auto separator = std::wstring();
0052 auto grouping = numpunct.grouping();
0053 if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());
0054 return value.visit(loc_writer<wchar_t>{out, specs, separator, grouping, {}});
0055 #endif
0056 return false;
0057 }
0058 }
0059
0060 FMT_BEGIN_EXPORT
0061
0062 using wstring_view = basic_string_view<wchar_t>;
0063 using wformat_parse_context = parse_context<wchar_t>;
0064 using wformat_context = buffered_context<wchar_t>;
0065 using wformat_args = basic_format_args<wformat_context>;
0066 using wmemory_buffer = basic_memory_buffer<wchar_t>;
0067
0068 template <typename Char, typename... T> struct basic_fstring {
0069 private:
0070 basic_string_view<Char> str_;
0071
0072 static constexpr int num_static_named_args =
0073 detail::count_static_named_args<T...>();
0074
0075 using checker = detail::format_string_checker<
0076 Char, static_cast<int>(sizeof...(T)), num_static_named_args,
0077 num_static_named_args != detail::count_named_args<T...>()>;
0078
0079 using arg_pack = detail::arg_pack<T...>;
0080
0081 public:
0082 using t = basic_fstring;
0083
0084 template <typename S,
0085 FMT_ENABLE_IF(
0086 std::is_convertible<const S&, basic_string_view<Char>>::value)>
0087 FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) {
0088 if (FMT_USE_CONSTEVAL)
0089 detail::parse_format_string<Char>(s, checker(s, arg_pack()));
0090 }
0091 template <typename S,
0092 FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&
0093 std::is_same<typename S::char_type, Char>::value)>
0094 FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) {
0095 FMT_CONSTEXPR auto sv = basic_string_view<Char>(S());
0096 FMT_CONSTEXPR int ignore =
0097 (parse_format_string(sv, checker(sv, arg_pack())), 0);
0098 detail::ignore_unused(ignore);
0099 }
0100 basic_fstring(runtime_format_string<Char> fmt) : str_(fmt.str) {}
0101
0102 operator basic_string_view<Char>() const { return str_; }
0103 auto get() const -> basic_string_view<Char> { return str_; }
0104 };
0105
0106 template <typename Char, typename... T>
0107 using basic_format_string = basic_fstring<Char, T...>;
0108
0109 template <typename... T>
0110 using wformat_string = typename basic_format_string<wchar_t, T...>::t;
0111 inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
0112 return {{s}};
0113 }
0114
0115 #ifdef __cpp_char8_t
0116 template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {};
0117 #endif
0118
0119 template <typename... T>
0120 constexpr auto make_wformat_args(T&... args)
0121 -> decltype(fmt::make_format_args<wformat_context>(args...)) {
0122 return fmt::make_format_args<wformat_context>(args...);
0123 }
0124
0125 #if !FMT_USE_NONTYPE_TEMPLATE_ARGS
0126 inline namespace literals {
0127 inline auto operator""_a(const wchar_t* s, size_t) -> detail::udl_arg<wchar_t> {
0128 return {s};
0129 }
0130 }
0131 #endif
0132
0133 template <typename It, typename Sentinel>
0134 auto join(It begin, Sentinel end, wstring_view sep)
0135 -> join_view<It, Sentinel, wchar_t> {
0136 return {begin, end, sep};
0137 }
0138
0139 template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
0140 auto join(Range&& range, wstring_view sep)
0141 -> join_view<decltype(std::begin(range)), decltype(std::end(range)),
0142 wchar_t> {
0143 return join(std::begin(range), std::end(range), sep);
0144 }
0145
0146 template <typename T>
0147 auto join(std::initializer_list<T> list, wstring_view sep)
0148 -> join_view<const T*, const T*, wchar_t> {
0149 return join(std::begin(list), std::end(list), sep);
0150 }
0151
0152 template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
0153 auto join(const Tuple& tuple, basic_string_view<wchar_t> sep)
0154 -> tuple_join_view<wchar_t, Tuple> {
0155 return {tuple, sep};
0156 }
0157
0158 template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
0159 auto vformat(basic_string_view<Char> fmt,
0160 typename detail::vformat_args<Char>::type args)
0161 -> std::basic_string<Char> {
0162 auto buf = basic_memory_buffer<Char>();
0163 detail::vformat_to(buf, fmt, args);
0164 return {buf.data(), buf.size()};
0165 }
0166
0167 template <typename... T>
0168 auto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {
0169 return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));
0170 }
0171
0172 template <typename OutputIt, typename... T>
0173 auto format_to(OutputIt out, wformat_string<T...> fmt, T&&... args)
0174 -> OutputIt {
0175 return vformat_to(out, fmt::wstring_view(fmt),
0176 fmt::make_wformat_args(args...));
0177 }
0178
0179
0180
0181 template <typename S, typename... T,
0182 typename Char = detail::format_string_char_t<S>,
0183 FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
0184 !std::is_same<Char, wchar_t>::value)>
0185 auto format(const S& fmt, T&&... args) -> std::basic_string<Char> {
0186 return vformat(detail::to_string_view(fmt),
0187 fmt::make_format_args<buffered_context<Char>>(args...));
0188 }
0189
0190 template <typename Locale, typename S,
0191 typename Char = detail::format_string_char_t<S>,
0192 FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
0193 detail::is_exotic_char<Char>::value)>
0194 inline auto vformat(const Locale& loc, const S& fmt,
0195 typename detail::vformat_args<Char>::type args)
0196 -> std::basic_string<Char> {
0197 auto buf = basic_memory_buffer<Char>();
0198 detail::vformat_to(buf, detail::to_string_view(fmt), args,
0199 detail::locale_ref(loc));
0200 return {buf.data(), buf.size()};
0201 }
0202
0203 template <typename Locale, typename S, typename... T,
0204 typename Char = detail::format_string_char_t<S>,
0205 FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
0206 detail::is_exotic_char<Char>::value)>
0207 inline auto format(const Locale& loc, const S& fmt, T&&... args)
0208 -> std::basic_string<Char> {
0209 return vformat(loc, detail::to_string_view(fmt),
0210 fmt::make_format_args<buffered_context<Char>>(args...));
0211 }
0212
0213 template <typename OutputIt, typename S,
0214 typename Char = detail::format_string_char_t<S>,
0215 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0216 detail::is_exotic_char<Char>::value)>
0217 auto vformat_to(OutputIt out, const S& fmt,
0218 typename detail::vformat_args<Char>::type args) -> OutputIt {
0219 auto&& buf = detail::get_buffer<Char>(out);
0220 detail::vformat_to(buf, detail::to_string_view(fmt), args);
0221 return detail::get_iterator(buf, out);
0222 }
0223
0224 template <typename OutputIt, typename S, typename... T,
0225 typename Char = detail::format_string_char_t<S>,
0226 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value &&
0227 !std::is_same<Char, char>::value &&
0228 !std::is_same<Char, wchar_t>::value)>
0229 inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
0230 return vformat_to(out, detail::to_string_view(fmt),
0231 fmt::make_format_args<buffered_context<Char>>(args...));
0232 }
0233
0234 template <typename Locale, typename S, typename OutputIt, typename... Args,
0235 typename Char = detail::format_string_char_t<S>,
0236 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0237 detail::is_locale<Locale>::value&&
0238 detail::is_exotic_char<Char>::value)>
0239 inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt,
0240 typename detail::vformat_args<Char>::type args)
0241 -> OutputIt {
0242 auto&& buf = detail::get_buffer<Char>(out);
0243 vformat_to(buf, detail::to_string_view(fmt), args, detail::locale_ref(loc));
0244 return detail::get_iterator(buf, out);
0245 }
0246
0247 template <typename Locale, typename OutputIt, typename S, typename... T,
0248 typename Char = detail::format_string_char_t<S>,
0249 bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
0250 detail::is_locale<Locale>::value &&
0251 detail::is_exotic_char<Char>::value>
0252 inline auto format_to(OutputIt out, const Locale& loc, const S& fmt,
0253 T&&... args) ->
0254 typename std::enable_if<enable, OutputIt>::type {
0255 return vformat_to(out, loc, detail::to_string_view(fmt),
0256 fmt::make_format_args<buffered_context<Char>>(args...));
0257 }
0258
0259 template <typename OutputIt, typename Char, typename... Args,
0260 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0261 detail::is_exotic_char<Char>::value)>
0262 inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view<Char> fmt,
0263 typename detail::vformat_args<Char>::type args)
0264 -> format_to_n_result<OutputIt> {
0265 using traits = detail::fixed_buffer_traits;
0266 auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
0267 detail::vformat_to(buf, fmt, args);
0268 return {buf.out(), buf.count()};
0269 }
0270
0271 template <typename OutputIt, typename S, typename... T,
0272 typename Char = detail::format_string_char_t<S>,
0273 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0274 detail::is_exotic_char<Char>::value)>
0275 inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
0276 -> format_to_n_result<OutputIt> {
0277 return vformat_to_n(out, n, fmt::basic_string_view<Char>(fmt),
0278 fmt::make_format_args<buffered_context<Char>>(args...));
0279 }
0280
0281 template <typename S, typename... T,
0282 typename Char = detail::format_string_char_t<S>,
0283 FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
0284 inline auto formatted_size(const S& fmt, T&&... args) -> size_t {
0285 auto buf = detail::counting_buffer<Char>();
0286 detail::vformat_to(buf, detail::to_string_view(fmt),
0287 fmt::make_format_args<buffered_context<Char>>(args...));
0288 return buf.count();
0289 }
0290
0291 inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
0292 auto buf = wmemory_buffer();
0293 detail::vformat_to(buf, fmt, args);
0294 buf.push_back(L'\0');
0295 if (std::fputws(buf.data(), f) == -1)
0296 FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
0297 }
0298
0299 inline void vprint(wstring_view fmt, wformat_args args) {
0300 vprint(stdout, fmt, args);
0301 }
0302
0303 template <typename... T>
0304 void print(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
0305 return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...));
0306 }
0307
0308 template <typename... T> void print(wformat_string<T...> fmt, T&&... args) {
0309 return vprint(wstring_view(fmt), fmt::make_wformat_args(args...));
0310 }
0311
0312 template <typename... T>
0313 void println(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
0314 return print(f, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
0315 }
0316
0317 template <typename... T> void println(wformat_string<T...> fmt, T&&... args) {
0318 return print(L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
0319 }
0320
0321 inline auto vformat(text_style ts, wstring_view fmt, wformat_args args)
0322 -> std::wstring {
0323 auto buf = wmemory_buffer();
0324 detail::vformat_to(buf, ts, fmt, args);
0325 return {buf.data(), buf.size()};
0326 }
0327
0328 template <typename... T>
0329 inline auto format(text_style ts, wformat_string<T...> fmt, T&&... args)
0330 -> std::wstring {
0331 return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));
0332 }
0333
0334 template <typename... T>
0335 FMT_DEPRECATED void print(std::FILE* f, text_style ts, wformat_string<T...> fmt,
0336 const T&... args) {
0337 vprint(f, ts, fmt, fmt::make_wformat_args(args...));
0338 }
0339
0340 template <typename... T>
0341 FMT_DEPRECATED void print(text_style ts, wformat_string<T...> fmt,
0342 const T&... args) {
0343 return print(stdout, ts, fmt, args...);
0344 }
0345
0346 inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) {
0347 auto buffer = basic_memory_buffer<wchar_t>();
0348 detail::vformat_to(buffer, fmt, args);
0349 detail::write_buffer(os, buffer);
0350 }
0351
0352 template <typename... T>
0353 void print(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
0354 vprint(os, fmt, fmt::make_format_args<buffered_context<wchar_t>>(args...));
0355 }
0356
0357 template <typename... T>
0358 void println(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
0359 print(os, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
0360 }
0361
0362
0363 template <typename T> inline auto to_wstring(const T& value) -> std::wstring {
0364 return format(FMT_STRING(L"{}"), value);
0365 }
0366 FMT_END_EXPORT
0367 FMT_END_NAMESPACE
0368
0369 #endif