Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:31:56

0001 // Formatting library for C++ - optional wchar_t and exotic character support
0002 //
0003 // Copyright (c) 2012 - present, Victor Zverovich
0004 // All rights reserved.
0005 //
0006 // For the license information refer to format.h.
0007 
0008 #ifndef FMT_XCHAR_H_
0009 #define FMT_XCHAR_H_
0010 
0011 #include <cwchar>
0012 
0013 #include "format.h"
0014 
0015 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
0016 #  include <locale>
0017 #endif
0018 
0019 FMT_BEGIN_NAMESPACE
0020 namespace detail {
0021 
0022 template <typename T>
0023 using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
0024 
0025 inline auto write_loc(std::back_insert_iterator<detail::buffer<wchar_t>> out,
0026                       loc_value value, const format_specs<wchar_t>& specs,
0027                       locale_ref loc) -> bool {
0028 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
0029   auto& numpunct =
0030       std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());
0031   auto separator = std::wstring();
0032   auto grouping = numpunct.grouping();
0033   if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());
0034   return value.visit(loc_writer<wchar_t>{out, specs, separator, grouping, {}});
0035 #endif
0036   return false;
0037 }
0038 }  // namespace detail
0039 
0040 FMT_BEGIN_EXPORT
0041 
0042 using wstring_view = basic_string_view<wchar_t>;
0043 using wformat_parse_context = basic_format_parse_context<wchar_t>;
0044 using wformat_context = buffer_context<wchar_t>;
0045 using wformat_args = basic_format_args<wformat_context>;
0046 using wmemory_buffer = basic_memory_buffer<wchar_t>;
0047 
0048 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
0049 // Workaround broken conversion on older gcc.
0050 template <typename... Args> using wformat_string = wstring_view;
0051 inline auto runtime(wstring_view s) -> wstring_view { return s; }
0052 #else
0053 template <typename... Args>
0054 using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
0055 inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
0056   return {{s}};
0057 }
0058 #endif
0059 
0060 template <> struct is_char<wchar_t> : std::true_type {};
0061 template <> struct is_char<detail::char8_type> : std::true_type {};
0062 template <> struct is_char<char16_t> : std::true_type {};
0063 template <> struct is_char<char32_t> : std::true_type {};
0064 
0065 template <typename... T>
0066 constexpr auto make_wformat_args(const T&... args)
0067     -> format_arg_store<wformat_context, T...> {
0068   return {args...};
0069 }
0070 
0071 inline namespace literals {
0072 #if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS
0073 constexpr auto operator""_a(const wchar_t* s, size_t)
0074     -> detail::udl_arg<wchar_t> {
0075   return {s};
0076 }
0077 #endif
0078 }  // namespace literals
0079 
0080 template <typename It, typename Sentinel>
0081 auto join(It begin, Sentinel end, wstring_view sep)
0082     -> join_view<It, Sentinel, wchar_t> {
0083   return {begin, end, sep};
0084 }
0085 
0086 template <typename Range>
0087 auto join(Range&& range, wstring_view sep)
0088     -> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>,
0089                  wchar_t> {
0090   return join(std::begin(range), std::end(range), sep);
0091 }
0092 
0093 template <typename T>
0094 auto join(std::initializer_list<T> list, wstring_view sep)
0095     -> join_view<const T*, const T*, wchar_t> {
0096   return join(std::begin(list), std::end(list), sep);
0097 }
0098 
0099 template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
0100 auto vformat(basic_string_view<Char> format_str,
0101              basic_format_args<buffer_context<type_identity_t<Char>>> args)
0102     -> std::basic_string<Char> {
0103   auto buf = basic_memory_buffer<Char>();
0104   detail::vformat_to(buf, format_str, args);
0105   return to_string(buf);
0106 }
0107 
0108 template <typename... T>
0109 auto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {
0110   return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));
0111 }
0112 
0113 // Pass char_t as a default template parameter instead of using
0114 // std::basic_string<char_t<S>> to reduce the symbol size.
0115 template <typename S, typename... T, typename Char = char_t<S>,
0116           FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
0117                         !std::is_same<Char, wchar_t>::value)>
0118 auto format(const S& format_str, T&&... args) -> std::basic_string<Char> {
0119   return vformat(detail::to_string_view(format_str),
0120                  fmt::make_format_args<buffer_context<Char>>(args...));
0121 }
0122 
0123 template <typename Locale, typename S, typename Char = char_t<S>,
0124           FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
0125                             detail::is_exotic_char<Char>::value)>
0126 inline auto vformat(
0127     const Locale& loc, const S& format_str,
0128     basic_format_args<buffer_context<type_identity_t<Char>>> args)
0129     -> std::basic_string<Char> {
0130   return detail::vformat(loc, detail::to_string_view(format_str), args);
0131 }
0132 
0133 template <typename Locale, typename S, typename... T, typename Char = char_t<S>,
0134           FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
0135                             detail::is_exotic_char<Char>::value)>
0136 inline auto format(const Locale& loc, const S& format_str, T&&... args)
0137     -> std::basic_string<Char> {
0138   return detail::vformat(loc, detail::to_string_view(format_str),
0139                          fmt::make_format_args<buffer_context<Char>>(args...));
0140 }
0141 
0142 template <typename OutputIt, typename S, typename Char = char_t<S>,
0143           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0144                             detail::is_exotic_char<Char>::value)>
0145 auto vformat_to(OutputIt out, const S& format_str,
0146                 basic_format_args<buffer_context<type_identity_t<Char>>> args)
0147     -> OutputIt {
0148   auto&& buf = detail::get_buffer<Char>(out);
0149   detail::vformat_to(buf, detail::to_string_view(format_str), args);
0150   return detail::get_iterator(buf, out);
0151 }
0152 
0153 template <typename OutputIt, typename S, typename... T,
0154           typename Char = char_t<S>,
0155           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0156                             detail::is_exotic_char<Char>::value)>
0157 inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
0158   return vformat_to(out, detail::to_string_view(fmt),
0159                     fmt::make_format_args<buffer_context<Char>>(args...));
0160 }
0161 
0162 template <typename Locale, typename S, typename OutputIt, typename... Args,
0163           typename Char = char_t<S>,
0164           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0165                             detail::is_locale<Locale>::value&&
0166                                 detail::is_exotic_char<Char>::value)>
0167 inline auto vformat_to(
0168     OutputIt out, const Locale& loc, const S& format_str,
0169     basic_format_args<buffer_context<type_identity_t<Char>>> args) -> OutputIt {
0170   auto&& buf = detail::get_buffer<Char>(out);
0171   vformat_to(buf, detail::to_string_view(format_str), args,
0172              detail::locale_ref(loc));
0173   return detail::get_iterator(buf, out);
0174 }
0175 
0176 template <typename OutputIt, typename Locale, typename S, typename... T,
0177           typename Char = char_t<S>,
0178           bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
0179                         detail::is_locale<Locale>::value &&
0180                         detail::is_exotic_char<Char>::value>
0181 inline auto format_to(OutputIt out, const Locale& loc, const S& format_str,
0182                       T&&... args) ->
0183     typename std::enable_if<enable, OutputIt>::type {
0184   return vformat_to(out, loc, detail::to_string_view(format_str),
0185                     fmt::make_format_args<buffer_context<Char>>(args...));
0186 }
0187 
0188 template <typename OutputIt, typename Char, typename... Args,
0189           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0190                             detail::is_exotic_char<Char>::value)>
0191 inline auto vformat_to_n(
0192     OutputIt out, size_t n, basic_string_view<Char> format_str,
0193     basic_format_args<buffer_context<type_identity_t<Char>>> args)
0194     -> format_to_n_result<OutputIt> {
0195   using traits = detail::fixed_buffer_traits;
0196   auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
0197   detail::vformat_to(buf, format_str, args);
0198   return {buf.out(), buf.count()};
0199 }
0200 
0201 template <typename OutputIt, typename S, typename... T,
0202           typename Char = char_t<S>,
0203           FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
0204                             detail::is_exotic_char<Char>::value)>
0205 inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
0206     -> format_to_n_result<OutputIt> {
0207   return vformat_to_n(out, n, detail::to_string_view(fmt),
0208                       fmt::make_format_args<buffer_context<Char>>(args...));
0209 }
0210 
0211 template <typename S, typename... T, typename Char = char_t<S>,
0212           FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
0213 inline auto formatted_size(const S& fmt, T&&... args) -> size_t {
0214   auto buf = detail::counting_buffer<Char>();
0215   detail::vformat_to(buf, detail::to_string_view(fmt),
0216                      fmt::make_format_args<buffer_context<Char>>(args...));
0217   return buf.count();
0218 }
0219 
0220 inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
0221   auto buf = wmemory_buffer();
0222   detail::vformat_to(buf, fmt, args);
0223   buf.push_back(L'\0');
0224   if (std::fputws(buf.data(), f) == -1)
0225     FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
0226 }
0227 
0228 inline void vprint(wstring_view fmt, wformat_args args) {
0229   vprint(stdout, fmt, args);
0230 }
0231 
0232 template <typename... T>
0233 void print(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
0234   return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...));
0235 }
0236 
0237 template <typename... T> void print(wformat_string<T...> fmt, T&&... args) {
0238   return vprint(wstring_view(fmt), fmt::make_wformat_args(args...));
0239 }
0240 
0241 template <typename... T>
0242 void println(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
0243   return print(f, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
0244 }
0245 
0246 template <typename... T> void println(wformat_string<T...> fmt, T&&... args) {
0247   return print(L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
0248 }
0249 
0250 /**
0251   Converts *value* to ``std::wstring`` using the default format for type *T*.
0252  */
0253 template <typename T> inline auto to_wstring(const T& value) -> std::wstring {
0254   return format(FMT_STRING(L"{}"), value);
0255 }
0256 FMT_END_EXPORT
0257 FMT_END_NAMESPACE
0258 
0259 #endif  // FMT_XCHAR_H_