Back to home page

EIC code displayed by LXR

 
 

    


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 // 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 "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 }  // namespace detail
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 }  // namespace literals
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 // Pass char_t as a default template parameter instead of using
0180 // std::basic_string<char_t<S>> to reduce the symbol size.
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 /// Converts `value` to `std::wstring` using the default format for type `T`.
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  // FMT_XCHAR_H_