27 using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
29 template <
typename S,
typename =
void>
struct format_string_char {};
32 struct format_string_char<
33 S, void_t<decltype(sizeof(
detail::to_string_view(std::declval<S>())))>> {
34 using type = char_t<S>;
38 struct format_string_char<
39 S, enable_if_t<
std::is_base_of<detail::compile_string, S>::value>> {
40 using type =
typename S::char_type;
44 using format_string_char_t =
typename format_string_char<S>::type;
46 inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
47 const format_specs& specs, locale_ref loc) ->
bool {
50 std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());
51 auto separator = std::wstring();
52 auto grouping = numpunct.grouping();
53 if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());
54 return value.visit(loc_writer<wchar_t>{out, specs, separator, grouping, {}});
59 template <
typename Char>
62 locale_ref loc = {}) {
63 static_assert(!std::is_same<Char, char>::value,
"");
64 auto out = basic_appender<Char>(buf);
74 using wformat_context = buffered_context<wchar_t>;
78 template <
typename Char,
typename... T>
struct basic_fstring {
82 static constexpr
int num_static_named_args =
83 detail::count_static_named_args<T...>();
85 using checker = detail::format_string_checker<
86 Char,
static_cast<int>(
sizeof...(T)), num_static_named_args,
87 num_static_named_args != detail::count_named_args<T...>()>;
89 using arg_pack = detail::arg_pack<T...>;
92 using t = basic_fstring;
97 FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(
const S& s) : str_(s) {
98 if (FMT_USE_CONSTEVAL)
99 detail::parse_format_string<Char>(s, checker(s, arg_pack()));
101 template <
typename S,
102 FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&
103 std::is_same<typename S::char_type, Char>::value)>
104 FMT_ALWAYS_INLINE basic_fstring(
const S&) : str_(S()) {
106 FMT_CONSTEXPR
int ignore =
107 (parse_format_string(sv, checker(sv, arg_pack())), 0);
108 detail::ignore_unused(ignore);
110 basic_fstring(runtime_format_string<Char> fmt) : str_(fmt.str) {}
116 template <
typename Char,
typename... T>
117 using basic_format_string = basic_fstring<Char, T...>;
119 template <
typename... T>
120 using wformat_string =
typename basic_format_string<wchar_t, T...>::t;
121 inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
125 template <
typename... T>
126 constexpr
auto make_wformat_args(T&... args)
127 -> decltype(fmt::make_format_args<wformat_context>(args...)) {
128 return fmt::make_format_args<wformat_context>(args...);
131 #if !FMT_USE_NONTYPE_TEMPLATE_ARGS 133 inline auto operator""_a(
const wchar_t* s,
size_t) -> detail::udl_arg<wchar_t> {
139 template <
typename It,
typename Sentinel>
140 auto join(It begin, Sentinel end, wstring_view sep)
141 -> join_view<It, Sentinel, wchar_t> {
142 return {begin, end, sep};
145 template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
146 auto join(Range&& range, wstring_view sep)
147 -> join_view<decltype(std::begin(range)), decltype(std::end(range)),
149 return join(std::begin(range), std::end(range), sep);
152 template <
typename T>
153 auto join(std::initializer_list<T> list, wstring_view sep)
154 -> join_view<const T*, const T*, wchar_t> {
155 return join(std::begin(list), std::end(list), sep);
158 template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
160 -> tuple_join_view<Tuple, wchar_t> {
164 template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
167 -> std::basic_string<Char> {
169 detail::vformat_to(buf, fmt, args);
170 return {buf.data(), buf.size()};
173 template <
typename... T>
174 auto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {
175 return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));
178 template <
typename OutputIt,
typename... T>
179 auto format_to(OutputIt out, wformat_string<T...> fmt, T&&... args)
181 return vformat_to(out, fmt::wstring_view(fmt),
182 fmt::make_wformat_args(args...));
187 template <
typename S,
typename... T,
188 typename Char = detail::format_string_char_t<S>,
189 FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
190 !std::is_same<Char, wchar_t>::value)>
191 auto format(
const S& fmt, T&&... args) -> std::basic_string<Char> {
192 return vformat(detail::to_string_view(fmt),
193 fmt::make_format_args<buffered_context<Char>>(args...));
196 template <
typename S,
typename Char = detail::format_
string_
char_t<S>,
197 FMT_ENABLE_IF(detail::is_exotic_
char<Char>::value)>
198 inline auto vformat(locale_ref loc,
const S& fmt,
200 -> std::basic_string<Char> {
202 detail::vformat_to(buf, detail::to_string_view(fmt), args, loc);
203 return {buf.data(), buf.size()};
206 template <
typename S,
typename... T,
207 typename Char = detail::format_string_char_t<S>,
208 FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
209 inline auto format(locale_ref loc,
const S& fmt, T&&... args)
210 -> std::basic_string<Char> {
211 return vformat(loc, detail::to_string_view(fmt),
212 fmt::make_format_args<buffered_context<Char>>(args...));
215 template <
typename OutputIt,
typename S,
216 typename Char = detail::format_string_char_t<S>,
217 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
218 detail::is_exotic_char<Char>::value)>
219 auto vformat_to(OutputIt out,
const S& fmt,
221 auto&& buf = detail::get_buffer<Char>(out);
222 detail::vformat_to(buf, detail::to_string_view(fmt), args);
223 return detail::get_iterator(buf, out);
226 template <
typename OutputIt,
typename S,
typename... T,
227 typename Char = detail::format_string_char_t<S>,
228 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value &&
229 !std::is_same<Char, char>::value &&
230 !std::is_same<Char, wchar_t>::value)>
231 inline auto format_to(OutputIt out,
const S& fmt, T&&... args) -> OutputIt {
232 return vformat_to(out, detail::to_string_view(fmt),
233 fmt::make_format_args<buffered_context<Char>>(args...));
236 template <
typename S,
typename OutputIt,
typename... Args,
237 typename Char = detail::format_string_char_t<S>,
238 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
239 detail::is_exotic_char<Char>::value)>
240 inline auto vformat_to(OutputIt out, locale_ref loc,
const S& fmt,
243 auto&& buf = detail::get_buffer<Char>(out);
244 vformat_to(buf, detail::to_string_view(fmt), args, loc);
245 return detail::get_iterator(buf, out);
248 template <
typename OutputIt,
typename S,
typename... T,
249 typename Char = detail::format_string_char_t<S>,
250 bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
251 detail::is_exotic_char<Char>::value>
252 inline auto format_to(OutputIt out, locale_ref loc,
const S& fmt, T&&... args)
253 ->
typename std::enable_if<enable, OutputIt>::type {
254 return vformat_to(out, loc, detail::to_string_view(fmt),
255 fmt::make_format_args<buffered_context<Char>>(args...));
258 template <
typename OutputIt,
typename Char,
typename... Args,
259 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
260 detail::is_exotic_char<Char>::value)>
263 -> format_to_n_result<OutputIt> {
264 using traits = detail::fixed_buffer_traits;
265 auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
266 detail::vformat_to(buf, fmt, args);
267 return {buf.out(), buf.count()};
270 template <
typename OutputIt,
typename S,
typename... T,
271 typename Char = detail::format_string_char_t<S>,
272 FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
273 detail::is_exotic_char<Char>::value)>
274 inline auto format_to_n(OutputIt out,
size_t n,
const S& fmt, T&&... args)
275 -> format_to_n_result<OutputIt> {
276 return vformat_to_n(out, n, fmt::basic_string_view<Char>(fmt),
277 fmt::make_format_args<buffered_context<Char>>(args...));
280 template <
typename S,
typename... T,
281 typename Char = detail::format_string_char_t<S>,
282 FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
283 inline auto formatted_size(
const S& fmt, T&&... args) ->
size_t {
284 auto buf = detail::counting_buffer<Char>();
285 detail::vformat_to(buf, detail::to_string_view(fmt),
286 fmt::make_format_args<buffered_context<Char>>(args...));
290 inline void vprint(std::FILE* f, wstring_view fmt,
wformat_args args) {
292 detail::vformat_to(buf, fmt, args);
293 buf.push_back(L
'\0');
294 if (std::fputws(buf.data(), f) == -1)
295 FMT_THROW(system_error(errno, FMT_STRING(
"cannot write to file")));
298 inline void vprint(wstring_view fmt,
wformat_args args) {
299 vprint(stdout, fmt, args);
302 template <
typename... T>
303 void print(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
304 return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...));
307 template <
typename... T>
void print(wformat_string<T...> fmt, T&&... args) {
308 return vprint(wstring_view(fmt), fmt::make_wformat_args(args...));
311 template <
typename... T>
312 void println(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
313 return print(f, L
"{}\n", fmt::format(fmt, std::forward<T>(args)...));
316 template <
typename... T>
void println(wformat_string<T...> fmt, T&&... args) {
317 return print(L
"{}\n", fmt::format(fmt, std::forward<T>(args)...));
323 detail::vformat_to(buf, ts, fmt, args);
324 return {buf.data(), buf.size()};
327 template <
typename... T>
328 inline auto format(
text_style ts, wformat_string<T...> fmt, T&&... args)
330 return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));
333 inline void vprint(std::wostream& os, wstring_view fmt,
wformat_args args) {
335 detail::vformat_to(buffer, fmt, args);
336 detail::write_buffer(os, buffer);
339 template <
typename... T>
340 void print(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
341 vprint(os, fmt, fmt::make_format_args<buffered_context<wchar_t>>(args...));
344 template <
typename... T>
345 void println(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
346 print(os, L
"{}\n", fmt::format(fmt, std::forward<T>(args)...));
350 template <
typename T>
inline auto to_wstring(
const T& value) -> std::wstring {
351 return format(FMT_STRING(L
"{}"), value);
356 #endif // FMT_XCHAR_H_
BasicCoordinate< num_dimensions+1, coordT > join(const coordT &a, const BasicCoordinate< num_dimensions, coordT > &c)
make a longer BasicCoordinate, by prepending c with the single coordT
Definition: BasicCoordinate.inl:447
Parsing context consisting of a format string range being parsed and an argument counter for automati...
Definition: base.h:623
Converts a string literal into a format string that will be parsed at compile time and converted into...
Definition: args.h:20
An implementation of std::basic_string_view for pre-C++17.
Definition: base.h:515
A text style consisting of foreground and background colors and emphasis.
Definition: color.h:236
Definition: format.h:4131