1 // Formatting library for C++ - optional wchar_t and exotic character support
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
6 // For the license information refer to format.h.
18 using is_exotic_char
= bool_constant
<!std::is_same
<T
, char>::value
>;
21 FMT_MODULE_EXPORT_BEGIN
23 using wstring_view
= basic_string_view
<wchar_t>;
24 using wformat_parse_context
= basic_format_parse_context
<wchar_t>;
25 using wformat_context
= buffer_context
<wchar_t>;
26 using wformat_args
= basic_format_args
<wformat_context
>;
27 using wmemory_buffer
= basic_memory_buffer
<wchar_t>;
29 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
30 // Workaround broken conversion on older gcc.
31 template <typename
... Args
> using wformat_string
= wstring_view
;
32 inline auto runtime(wstring_view s
) -> wstring_view
{ return s
; }
34 template <typename
... Args
>
35 using wformat_string
= basic_format_string
<wchar_t, type_identity_t
<Args
>...>;
36 inline auto runtime(wstring_view s
) -> basic_runtime
<wchar_t> { return {{s
}}; }
39 template <> struct is_char
<wchar_t> : std::true_type
{};
40 template <> struct is_char
<detail::char8_type
> : std::true_type
{};
41 template <> struct is_char
<char16_t
> : std::true_type
{};
42 template <> struct is_char
<char32_t
> : std::true_type
{};
44 template <typename
... Args
>
45 constexpr format_arg_store
<wformat_context
, Args
...> make_wformat_args(
46 const Args
&... args
) {
50 inline namespace literals
{
51 #if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS
52 constexpr detail::udl_arg
<wchar_t> operator"" _a(const wchar_t* s
, size_t) {
56 } // namespace literals
58 template <typename It
, typename Sentinel
>
59 auto join(It begin
, Sentinel end
, wstring_view sep
)
60 -> join_view
<It
, Sentinel
, wchar_t> {
61 return {begin
, end
, sep
};
64 template <typename Range
>
65 auto join(Range
&& range
, wstring_view sep
)
66 -> join_view
<detail::iterator_t
<Range
>, detail::sentinel_t
<Range
>,
68 return join(std::begin(range
), std::end(range
), sep
);
72 auto join(std::initializer_list
<T
> list
, wstring_view sep
)
73 -> join_view
<const T
*, const T
*, wchar_t> {
74 return join(std::begin(list
), std::end(list
), sep
);
77 template <typename Char
, FMT_ENABLE_IF(!std::is_same
<Char
, char>::value
)>
78 auto vformat(basic_string_view
<Char
> format_str
,
79 basic_format_args
<buffer_context
<type_identity_t
<Char
>>> args
)
80 -> std::basic_string
<Char
> {
81 basic_memory_buffer
<Char
> buffer
;
82 detail::vformat_to(buffer
, format_str
, args
);
83 return to_string(buffer
);
86 template <typename
... T
>
87 auto format(wformat_string
<T
...> fmt
, T
&&... args
) -> std::wstring
{
88 return vformat(fmt::wstring_view(fmt
), fmt::make_wformat_args(args
...));
91 // Pass char_t as a default template parameter instead of using
92 // std::basic_string<char_t<S>> to reduce the symbol size.
93 template <typename S
, typename
... Args
, typename Char
= char_t
<S
>,
94 FMT_ENABLE_IF(!std::is_same
<Char
, char>::value
&&
95 !std::is_same
<Char
, wchar_t>::value
)>
96 auto format(const S
& format_str
, Args
&&... args
) -> std::basic_string
<Char
> {
97 return vformat(detail::to_string_view(format_str
),
98 fmt::make_format_args
<buffer_context
<Char
>>(args
...));
101 template <typename Locale
, typename S
, typename Char
= char_t
<S
>,
102 FMT_ENABLE_IF(detail::is_locale
<Locale
>::value
&&
103 detail::is_exotic_char
<Char
>::value
)>
105 const Locale
& loc
, const S
& format_str
,
106 basic_format_args
<buffer_context
<type_identity_t
<Char
>>> args
)
107 -> std::basic_string
<Char
> {
108 return detail::vformat(loc
, detail::to_string_view(format_str
), args
);
111 template <typename Locale
, typename S
, typename
... Args
,
112 typename Char
= char_t
<S
>,
113 FMT_ENABLE_IF(detail::is_locale
<Locale
>::value
&&
114 detail::is_exotic_char
<Char
>::value
)>
115 inline auto format(const Locale
& loc
, const S
& format_str
, Args
&&... args
)
116 -> std::basic_string
<Char
> {
117 return detail::vformat(loc
, detail::to_string_view(format_str
),
118 fmt::make_format_args
<buffer_context
<Char
>>(args
...));
121 template <typename OutputIt
, typename S
, typename Char
= char_t
<S
>,
122 FMT_ENABLE_IF(detail::is_output_iterator
<OutputIt
, Char
>::value
&&
123 detail::is_exotic_char
<Char
>::value
)>
124 auto vformat_to(OutputIt out
, const S
& format_str
,
125 basic_format_args
<buffer_context
<type_identity_t
<Char
>>> args
)
127 auto&& buf
= detail::get_buffer
<Char
>(out
);
128 detail::vformat_to(buf
, detail::to_string_view(format_str
), args
);
129 return detail::get_iterator(buf
);
132 template <typename OutputIt
, typename S
, typename
... Args
,
133 typename Char
= char_t
<S
>,
134 FMT_ENABLE_IF(detail::is_output_iterator
<OutputIt
, Char
>::value
&&
135 detail::is_exotic_char
<Char
>::value
)>
136 inline auto format_to(OutputIt out
, const S
& fmt
, Args
&&... args
) -> OutputIt
{
137 return vformat_to(out
, detail::to_string_view(fmt
),
138 fmt::make_format_args
<buffer_context
<Char
>>(args
...));
141 template <typename Locale
, typename S
, typename OutputIt
, typename
... Args
,
142 typename Char
= char_t
<S
>,
143 FMT_ENABLE_IF(detail::is_output_iterator
<OutputIt
, Char
>::value
&&
144 detail::is_locale
<Locale
>::value
&&
145 detail::is_exotic_char
<Char
>::value
)>
146 inline auto vformat_to(
147 OutputIt out
, const Locale
& loc
, const S
& format_str
,
148 basic_format_args
<buffer_context
<type_identity_t
<Char
>>> args
) -> OutputIt
{
149 auto&& buf
= detail::get_buffer
<Char
>(out
);
150 vformat_to(buf
, detail::to_string_view(format_str
), args
,
151 detail::locale_ref(loc
));
152 return detail::get_iterator(buf
);
156 typename OutputIt
, typename Locale
, typename S
, typename
... Args
,
157 typename Char
= char_t
<S
>,
158 bool enable
= detail::is_output_iterator
<OutputIt
, Char
>::value
&&
159 detail::is_locale
<Locale
>::value
&& detail::is_exotic_char
<Char
>::value
>
160 inline auto format_to(OutputIt out
, const Locale
& loc
, const S
& format_str
,
162 typename
std::enable_if
<enable
, OutputIt
>::type
{
163 return vformat_to(out
, loc
, to_string_view(format_str
),
164 fmt::make_format_args
<buffer_context
<Char
>>(args
...));
167 template <typename OutputIt
, typename Char
, typename
... Args
,
168 FMT_ENABLE_IF(detail::is_output_iterator
<OutputIt
, Char
>::value
&&
169 detail::is_exotic_char
<Char
>::value
)>
170 inline auto vformat_to_n(
171 OutputIt out
, size_t n
, basic_string_view
<Char
> format_str
,
172 basic_format_args
<buffer_context
<type_identity_t
<Char
>>> args
)
173 -> format_to_n_result
<OutputIt
> {
174 detail::iterator_buffer
<OutputIt
, Char
, detail::fixed_buffer_traits
> buf(out
,
176 detail::vformat_to(buf
, format_str
, args
);
177 return {buf
.out(), buf
.count()};
180 template <typename OutputIt
, typename S
, typename
... Args
,
181 typename Char
= char_t
<S
>,
182 FMT_ENABLE_IF(detail::is_output_iterator
<OutputIt
, Char
>::value
&&
183 detail::is_exotic_char
<Char
>::value
)>
184 inline auto format_to_n(OutputIt out
, size_t n
, const S
& fmt
,
185 const Args
&... args
) -> format_to_n_result
<OutputIt
> {
186 return vformat_to_n(out
, n
, detail::to_string_view(fmt
),
187 fmt::make_format_args
<buffer_context
<Char
>>(args
...));
190 template <typename S
, typename
... Args
, typename Char
= char_t
<S
>,
191 FMT_ENABLE_IF(detail::is_exotic_char
<Char
>::value
)>
192 inline auto formatted_size(const S
& fmt
, Args
&&... args
) -> size_t {
193 detail::counting_buffer
<Char
> buf
;
194 detail::vformat_to(buf
, detail::to_string_view(fmt
),
195 fmt::make_format_args
<buffer_context
<Char
>>(args
...));
199 inline void vprint(std::FILE* f
, wstring_view fmt
, wformat_args args
) {
200 wmemory_buffer buffer
;
201 detail::vformat_to(buffer
, fmt
, args
);
202 buffer
.push_back(L
'\0');
203 if (std::fputws(buffer
.data(), f
) == -1)
204 FMT_THROW(system_error(errno
, FMT_STRING("cannot write to file")));
207 inline void vprint(wstring_view fmt
, wformat_args args
) {
208 vprint(stdout
, fmt
, args
);
211 template <typename
... T
>
212 void print(std::FILE* f
, wformat_string
<T
...> fmt
, T
&&... args
) {
213 return vprint(f
, wstring_view(fmt
), fmt::make_wformat_args(args
...));
216 template <typename
... T
> void print(wformat_string
<T
...> fmt
, T
&&... args
) {
217 return vprint(wstring_view(fmt
), fmt::make_wformat_args(args
...));
221 Converts *value* to ``std::wstring`` using the default format for type *T*.
223 template <typename T
> inline auto to_wstring(const T
& value
) -> std::wstring
{
224 return format(FMT_STRING(L
"{}"), value
);
226 FMT_MODULE_EXPORT_END
229 #endif // FMT_XCHAR_H_