1 //===----------------------------------------------------------------------===//
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //===----------------------------------------------------------------------===//
8 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
11 // This version runs the test when the platform has Unicode support.
12 // UNSUPPORTED: libcpp-has-no-unicode
14 // TODO FMT Investigate Windows issues.
15 // UNSUPPORTED: msvc, target={{.+}}-windows-gnu
17 // TODO FMT This test should not require std::to_chars(floating-point)
18 // XFAIL: availability-fp_to_chars-missing
22 // This test the debug string type for the formatter specializations for char
23 // and string types. This tests Unicode strings.
33 #include "test_macros.h"
34 #include "make_string.h"
35 #include "test_format_string.h"
36 #include "assert_macros.h"
37 #include "concat_macros.h"
39 #ifndef TEST_HAS_NO_LOCALIZATION
43 #define SV(S) MAKE_STRING_VIEW(CharT, S)
45 auto test_format
= []<class CharT
, class... Args
>(
46 std::basic_string_view
<CharT
> expected
, test_format_string
<CharT
, Args
...> fmt
, Args
&&... args
) {
48 std::basic_string
<CharT
> out
= std::format(fmt
, std::forward
<Args
>(args
)...);
49 TEST_REQUIRE(out
== expected
,
50 TEST_WRITE_CONCATENATED(
51 "\nFormat string ", fmt
.get(), "\nExpected output ", expected
, "\nActual output ", out
, '\n'));
53 #ifndef TEST_HAS_NO_LOCALIZATION
55 std::basic_string
<CharT
> out
= std::format(std::locale(), fmt
, std::forward
<Args
>(args
)...);
56 assert(out
== expected
);
58 #endif // TEST_HAS_NO_LOCALIZATION
62 []<class CharT
, class... Args
>(
63 std::basic_string_view
<CharT
> expected
, test_format_string
<CharT
, Args
...> fmt
, Args
&&... args
) {
65 std::basic_string
<CharT
> out(expected
.size(), CharT(' '));
66 auto it
= std::format_to(out
.begin(), fmt
, std::forward
<Args
>(args
)...);
67 assert(it
== out
.end());
68 assert(out
== expected
);
70 #ifndef TEST_HAS_NO_LOCALIZATION
72 std::basic_string
<CharT
> out(expected
.size(), CharT(' '));
73 auto it
= std::format_to(out
.begin(), std::locale(), fmt
, std::forward
<Args
>(args
)...);
74 assert(it
== out
.end());
75 assert(out
== expected
);
77 #endif // TEST_HAS_NO_LOCALIZATION
80 std::format_to(std::back_inserter(out
), fmt
, std::forward
<Args
>(args
)...);
81 assert(std::equal(out
.begin(), out
.end(), expected
.begin(), expected
.end()));
84 std::vector
<CharT
> out
;
85 std::format_to(std::back_inserter(out
), fmt
, std::forward
<Args
>(args
)...);
86 assert(std::equal(out
.begin(), out
.end(), expected
.begin(), expected
.end()));
89 assert(expected
.size() < 4096 && "Update the size of the buffer.");
91 CharT
* it
= std::format_to(out
, fmt
, std::forward
<Args
>(args
)...);
92 assert(std::distance(out
, it
) == int(expected
.size()));
93 // Convert to std::string since output contains '\0' for boolean tests.
94 assert(std::basic_string
<CharT
>(out
, it
) == expected
);
98 auto test_formatted_size
=
99 []<class CharT
, class... Args
>(
100 std::basic_string_view
<CharT
> expected
, test_format_string
<CharT
, Args
...> fmt
, Args
&&... args
) {
102 std::size_t size
= std::formatted_size(fmt
, std::forward
<Args
>(args
)...);
103 assert(size
== expected
.size());
105 #ifndef TEST_HAS_NO_LOCALIZATION
107 std::size_t size
= std::formatted_size(std::locale(), fmt
, std::forward
<Args
>(args
)...);
108 assert(size
== expected
.size());
110 #endif // TEST_HAS_NO_LOCALIZATION
113 auto test_format_to_n
=
114 []<class CharT
, class... Args
>(
115 std::basic_string_view
<CharT
> expected
, test_format_string
<CharT
, Args
...> fmt
, Args
&&... args
) {
117 std::size_t n
= expected
.size();
118 std::basic_string
<CharT
> out(n
, CharT(' '));
119 std::format_to_n_result result
= std::format_to_n(out
.begin(), n
, fmt
, std::forward
<Args
>(args
)...);
120 assert(result
.size
== static_cast<std::ptrdiff_t>(expected
.size()));
121 assert(result
.out
== out
.end());
122 assert(out
== expected
);
124 #ifndef TEST_HAS_NO_LOCALIZATION
126 std::size_t n
= expected
.size();
127 std::basic_string
<CharT
> out(n
, CharT(' '));
128 std::format_to_n_result result
=
129 std::format_to_n(out
.begin(), n
, std::locale(), fmt
, std::forward
<Args
>(args
)...);
130 assert(result
.size
== static_cast<std::ptrdiff_t>(expected
.size()));
131 assert(result
.out
== out
.end());
132 assert(out
== expected
);
134 #endif // TEST_HAS_NO_LOCALIZATION
136 std::ptrdiff_t n
= 0;
137 std::basic_string
<CharT
> out
;
138 std::format_to_n_result result
= std::format_to_n(out
.begin(), n
, fmt
, std::forward
<Args
>(args
)...);
139 assert(result
.size
== static_cast<std::ptrdiff_t>(expected
.size()));
140 assert(result
.out
== out
.end());
144 std::ptrdiff_t n
= expected
.size() / 2;
145 std::basic_string
<CharT
> out(n
, CharT(' '));
146 std::format_to_n_result result
= std::format_to_n(out
.begin(), n
, fmt
, std::forward
<Args
>(args
)...);
147 assert(result
.size
== static_cast<std::ptrdiff_t>(expected
.size()));
148 assert(result
.out
== out
.end());
149 assert(out
== expected
.substr(0, n
));
153 template <class CharT
>
155 // *** P2286 examples ***
156 test_format(SV("['\\'', '\"']"), SV("[{:?}, {:?}]"), CharT('\''), CharT('"'));
158 // *** Specical cases ***
159 test_format(SV("'\\t'"), SV("{:?}"), CharT('\t'));
160 test_format(SV("'\\n'"), SV("{:?}"), CharT('\n'));
161 test_format(SV("'\\r'"), SV("{:?}"), CharT('\r'));
162 test_format(SV("'\\\\'"), SV("{:?}"), CharT('\\'));
164 test_format(SV("'\\\''"), SV("{:?}"), CharT('\''));
165 test_format(SV("'\"'"), SV("{:?}"), CharT('"')); // only special for string
167 test_format(SV("' '"), SV("{:?}"), CharT(' '));
170 test_format(SV("'a'"), SV("{:?}"), CharT('a'));
171 test_format(SV("'b'"), SV("{:?}"), CharT('b'));
172 test_format(SV("'c'"), SV("{:?}"), CharT('c'));
174 // *** Non-printable ***
177 test_format(SV("'\\u{0}'"), SV("{:?}"), CharT('\0'));
178 test_format(SV("'\\u{1f}'"), SV("{:?}"), CharT('\x1f'));
181 if constexpr (sizeof(CharT
) == 1)
182 test_format(SV("'\\x{80}'"), SV("{:?}"), CharT('\x80'));
184 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
185 if constexpr (sizeof(CharT
) > 1) {
186 using V
= std::basic_string_view
<CharT
>;
188 // Unicode fitting in a 16-bit wchar_t
190 // *** Non-printable ***
193 test_format(V
{L
"'\\u{a0}'"}, L
"{:?}", L
'\xa0'); // NO-BREAK SPACE
194 test_format(V
{L
"'\\u{3000}'"}, L
"{:?}", L
'\x3000'); // IDEOGRAPHIC SPACE
197 test_format(V
{L
"'\\u{2028}'"}, L
"{:?}", L
'\x2028'); // LINE SEPARATOR
199 // Paragraph_Separator
200 test_format(V
{L
"'\\u{2029}'"}, L
"{:?}", L
'\x2029'); // PARAGRAPH SEPARATOR
203 test_format(V
{L
"'\\u{ad}'"}, L
"{:?}", L
'\xad'); // SOFT HYPHEN
204 test_format(V
{L
"'\\u{600}'"}, L
"{:?}", L
'\x600'); // ARABIC NUMBER SIGN
205 test_format(V
{L
"'\\u{feff}'"}, L
"{:?}", L
'\xfeff'); // ZERO WIDTH NO-BREAK SPACE
207 // Incomplete surrogate pair in UTF-16
208 test_format(V
{L
"'\\x{d800}'"}, L
"{:?}", L
'\xd800'); // <surrogate-D800>
209 test_format(V
{L
"'\\x{dfff}'"}, L
"{:?}", L
'\xdfff'); // <surrogate-DFFF>
212 test_format(V
{L
"'\\u{e000}'"}, L
"{:?}", L
'\xe000'); // <private-use-E000>
213 test_format(V
{L
"'\\u{f8ff}'"}, L
"{:?}", L
'\xf8ff'); // <private-use-F8FF>
216 test_format(V
{L
"'\\u{378}'"}, L
"{:?}", L
'\x378'); // <reserved-0378>
217 test_format(V
{L
"'\\u{1774}'"}, L
"{:?}", L
'\x1774'); // <reserved-1774>
218 test_format(V
{L
"'\\u{ffff}'"}, L
"{:?}", L
'\xffff'); // <noncharacter-FFFF>
221 test_format(V
{L
"'\\u{300}'"}, L
"{:?}", L
'\x300'); // COMBINING GRAVE ACCENT
222 test_format(V
{L
"'\\u{fe20}'"}, L
"{:?}", L
'\xfe20'); // VARIATION SELECTOR-1
224 # ifndef TEST_SHORT_WCHAR
225 if constexpr (sizeof(CharT
) > 2) {
226 static_assert(sizeof(CharT
) == 4, "add support for unexpected size");
227 // Unicode fitting in a 32-bit wchar_t
229 constexpr wchar_t x
= 0x1ffff;
230 constexpr std::uint32_t y
= 0x1ffff;
231 static_assert(x
== y
);
233 using V
= std::basic_string_view
<CharT
>;
235 // *** Non-printable ***
237 test_format(V
{L
"'\\u{110bd}'"}, L
"{:?}", L
'\x110bd'); // KAITHI NUMBER SIGN
238 test_format(V
{L
"'\\u{e007f}'"}, L
"{:?}", L
'\xe007f'); // CANCEL TAG
241 test_format(V
{L
"'\\u{f0000}'"}, L
"{:?}", L
'\xf0000'); // <private-use-F0000>
242 test_format(V
{L
"'\\u{ffffd}'"}, L
"{:?}", L
'\xffffd'); // <private-use-FFFFD>
244 test_format(V
{L
"'\\u{100000}'"}, L
"{:?}", L
'\x100000'); // <private-use-100000>
245 test_format(V
{L
"'\\u{10fffd}'"}, L
"{:?}", L
'\x10fffd'); // <private-use-10FFFD>
248 test_format(V
{L
"'\\u{1000c}'"}, L
"{:?}", L
'\x1000c'); // <reserved-1000c>
249 test_format(V
{L
"'\\u{fffff}'"}, L
"{:?}", L
'\xfffff'); // <noncharacter-FFFFF>
250 test_format(V
{L
"'\\u{10fffe}'"}, L
"{:?}", L
'\x10fffe'); // <noncharacter-10FFFE>
253 test_format(V
{L
"'\\u{101fd}'"}, L
"{:?}", L
'\x101fd'); // COMBINING OLD PERMIC LETTER AN
254 test_format(V
{L
"'\\u{e0100}'"}, L
"{:?}", L
'\xe0100'); // VARIATION SELECTOR-17
257 test_format(V
{L
"'\\x{110000}'"}, L
"{:?}", L
'\x110000');
258 test_format(V
{L
"'\\x{ffffffff}'"}, L
"{:?}", L
'\xffffffff');
260 # endif // TEST_SHORT_WCHAR
261 #endif // TEST_HAS_NO_WIDE_CHARACTERS
264 template <class CharT
>
266 // *** P2286 examples ***
267 test_format(SV("[h\tllo]"), SV("[{}]"), SV("h\tllo"));
268 test_format(SV(R
"(["h
\tllo
"])"), SV("[{:?}]"), SV("h\tllo"));
269 test_format(SV(R
"(["Спасибо
, Виктор ♥
!"])"), SV("[{:?}]"), SV("Спасибо, Виктор ♥!"));
271 test_format(SV(R
"(["\u
{0} \n \t \u
{2} \u
{1b
}"])"), SV("[{:?}]"), SV("\0 \n \t \x02 \x1b"));
273 if constexpr (sizeof(CharT
) == 1) {
275 test_format(SV(R
"(["\x
{c3
}"])"), SV("[{:?}]"), "\xc3");
276 test_format(SV(R
"(["\x
{c3
}("])"), SV("[{:?}]"), "\xc3\x28");
278 /* U+0000..U+0007F 1 code unit range, encoded in 2 code units. */
279 test_format(SV(R
"(["\x
{c0
}\x
{80}"])"), SV("[{:?}]"), "\xc0\x80"); // U+0000
280 test_format(SV(R
"(["\x
{c1
}\x
{bf
}"])"), SV("[{:?}]"), "\xc1\xbf"); // U+007F
281 test_format(SV(R
"(["\u
{80}"])"), SV("[{:?}]"), "\xc2\x80"); // U+0080 first valid (General_Category=Control)
283 /* U+0000..U+07FFF 1 and 2 code unit range, encoded in 3 code units. */
284 test_format(SV(R
"(["\x
{e0
}\x
{80}\x
{80}"])"), SV("[{:?}]"), "\xe0\x80\x80"); // U+0000
285 test_format(SV(R
"(["\x
{e0
}\x
{81}\x
{bf
}"])"), SV("[{:?}]"), "\xe0\x81\xbf"); // U+007F
286 test_format(SV(R
"(["\x
{e0
}\x
{82}\x
{80}"])"), SV("[{:?}]"), "\xe0\x82\x80"); // U+0080
287 test_format(SV(R
"(["\x
{e0
}\x
{9f
}\x
{bf
}"])"), SV("[{:?}]"), "\xe0\x9f\xbf"); // U+07FF
288 test_format(SV("[\"\u0800\"]"), SV("[{:?}]"), "\xe0\xa0\x80"); // U+0800 first valid
291 // This code point is in the Hangul Jamo Extended-B block and at the time of writing
292 // it's unassigned. When it comes defined, this branch might become true.
293 test_format(SV("[\"\ud7ff\"]"), SV("[{:?}]"), "\xed\x9f\xbf"); // U+D7FF last valid
295 /* U+D800..D+DFFFF surrogate range */
296 test_format(SV(R
"(["\u
{d7ff
}"])"), SV("[{:?}]"), "\xed\x9f\xbf"); // U+D7FF last valid
298 test_format(SV(R
"(["\x
{ed
}\x
{a0
}\x
{80}"])"), SV("[{:?}]"), "\xed\xa0\x80"); // U+D800
299 test_format(SV(R
"(["\x
{ed
}\x
{af
}\x
{bf
}"])"), SV("[{:?}]"), "\xed\xaf\xbf"); // U+DBFF
300 test_format(SV(R
"(["\x
{ed
}\x
{bf
}\x
{80}"])"), SV("[{:?}]"), "\xed\xbf\x80"); // U+DC00
301 test_format(SV(R
"(["\x
{ed
}\x
{bf
}\x
{bf
}"])"), SV("[{:?}]"), "\xed\xbf\xbf"); // U+DFFF
302 test_format(SV(R
"(["\u
{e000
}"])"), SV("[{:?}]"), "\xee\x80\x80"); // U+E000 first valid
303 // (in the Private Use Area block)
305 /* U+0000..U+FFFF 1, 2, and 3 code unit range */
306 test_format(SV(R
"(["\x
{f0
}\x
{80}\x
{80}\x
{80}"])"), SV("[{:?}]"), "\xf0\x80\x80\x80"); // U+0000
307 test_format(SV(R
"(["\x
{f0
}\x
{80}\x
{81}\x
{bf
}"])"), SV("[{:?}]"), "\xf0\x80\x81\xbf"); // U+007F
308 test_format(SV(R
"(["\x
{f0
}\x
{80}\x
{82}\x
{80}"])"), SV("[{:?}]"), "\xf0\x80\x82\x80"); // U+0080
309 test_format(SV(R
"(["\x
{f0
}\x
{80}\x
{9f
}\x
{bf
}"])"), SV("[{:?}]"), "\xf0\x80\x9f\xbf"); // U+07FF
310 test_format(SV(R
"(["\x
{f0
}\x
{80}\x
{a0
}\x
{80}"])"), SV("[{:?}]"), "\xf0\x80\xa0\x80"); // U+0800
311 test_format(SV(R
"(["\x
{f0
}\x
{8f
}\x
{bf
}\x
{bf
}"])"), SV("[{:?}]"), "\xf0\x8f\xbf\xbf"); // U+FFFF
312 test_format(SV("[\"\U00010000\"]"), SV("[{:?}]"), "\xf0\x90\x80\x80"); // U+10000 first valid
314 /* U+10FFFF..U+1FFFFF invalid range */
315 test_format(SV(R
"(["\u
{10ffff
}"])"), SV("[{:?}]"), "\xf4\x8f\xbf\xbf"); // U+10FFFF last valid
316 // (in Supplementary Private Use Area-B)
317 test_format(SV(R
"(["\x
{f4
}\x
{90}\x
{80}\x
{80}"])"), SV("[{:?}]"), "\xf4\x90\x80\x80"); // U+110000
318 test_format(SV(R
"(["\x
{f4
}\x
{bf
}\x
{bf
}\x
{bf
}"])"), SV("[{:?}]"), "\xf4\xbf\xbf\xbf"); // U+11FFFF
320 // Valid UTF-16 and UTF-32
321 test_format(SV("[\"\u00c3\"]"), SV("[{:?}]"), L
"\xc3"); // LATIN CAPITAL LETTER A WITH TILDE
322 test_format(SV("[\"\u00c3(\"]"), SV("[{:?}]"), L
"\xc3\x28");
325 test_format(SV(R
"(["🤷🏻\u
{200d
}♂\u
{fe0f
}"])"), SV("[{:?}]"), SV("🤷🏻♂️"));
327 // *** Specical cases ***
328 test_format(SV(R
"("\t\n\r\\'\" ")"), SV("{:?}"), SV("\t\n\r\\'\" "));
331 test_format(SV(R"("abcdefg")"), SV("{:?}"), SV("abcdefg
"));
333 // *** Non-printable ***
336 test_format(SV(R"("\u{0}\u{1f}")"), SV("{:?}"), SV("\
0\x1f"));
339 if constexpr (sizeof(CharT) == 1)
340 test_format(SV(R"("\x{80}")"), SV("{:?}"), SV("\x80"));
342 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
343 if constexpr (sizeof(CharT) > 1) {
344 using V = std::basic_string_view<CharT>;
346 // Unicode fitting in a 16-bit wchar_t
348 // *** Non-printable ***
351 test_format(V{LR"("\u{a0}\u{3000}")"}, L"{:?}", L"\xa0\x3000
");
354 test_format(V{LR"("\u{2028}")"}, L"{:?}", L"\x2028
"); // LINE SEPARATOR
356 // Paragraph_Separator
357 test_format(V{LR"("\u{2029}")"}, L"{:?}", L"\x2029
"); // PARAGRAPH SEPARATOR
360 test_format(V{LR"("\u{ad}\u{600}\u{feff}")"}, L"{:?}", L"\xad\x600
\xfeff
");
362 // Incomplete surrogate pair in UTF-16
363 test_format(V{LR"("\x{d800}")"}, L"{:?}", L"\xd800
");
366 test_format(V{LR"("\u{e000}\u{f8ff}")"}, L"{:?}", L"\xe000
\xf8ff
");
369 test_format(V{LR"("\u{378}\u{1774}\u{ffff}")"}, L"{:?}", L"\x378
\x1774
\xffff
");
372 test_format(V{LR"("\u{300}\u{fe20}")"}, L"{:?}", L"\x300
\xfe20");
374 # ifndef TEST_SHORT_WCHAR
375 if constexpr (sizeof(CharT) > 2) {
376 static_assert(sizeof(CharT) == 4, "add support
for unexpected size
");
377 // Unicode fitting in a 32-bit wchar_t
379 constexpr wchar_t x = 0x1ffff;
380 constexpr std::uint32_t y = 0x1ffff;
381 static_assert(x == y);
383 using V = std::basic_string_view<CharT>;
385 // *** Non-printable ***
387 test_format(V{LR"("\u{110bd}\u{e007f}")"}, L"{:?}", L"\x110bd
\xe007f
");
390 test_format(V{LR"("\u{f0000}\u{ffffd}\u{100000}\u{10fffd}")"}, L"{:?}", L"\xf0000
\xffffd
\x100000
\x10fffd
");
393 test_format(V{LR"("\u{1000c}\u{fffff}\u{10fffe}")"}, L"{:?}", L"\x1000c
\xfffff
\x10fffe
");
396 test_format(V{LR"("\u{101fd}\u{e0100}")"}, L"{:?}", L"\x101fd
\xe0100
");
399 test_format(V{LR"("\x{110000}\x{ffffffff}")"}, L"{:?}", L"\x110000
\xffffffff
");
401 # endif // TEST_SHORT_WCHAR
402 #endif // TEST_HAS_NO_WIDE_CHARACTERS
405 template <class CharT, class TestFunction>
406 void test_format_functions(TestFunction check) {
407 // *** align-fill & width ***
408 check(SV(R"(***"hellö")"), SV("{:*>10?}"), SV("hellö
")); // ö is LATIN SMALL LETTER O WITH DIAERESIS
409 check(SV(R"(*"hellö"**)"), SV("{:*^10?}"), SV("hellö
"));
410 check(SV(R"("hellö"***)"), SV("{:*<10?}"), SV("hellö
"));
412 check(SV(R"("hello\u{308}")"), SV("{:*>10?}"), SV("hello
\u0308"));
413 check(SV(R"(***"hello\u{308}")"), SV("{:*>17?}"), SV("hello
\u0308"));
414 check(SV(R"(*"hello\u{308}"**)"), SV("{:*^17?}"), SV("hello
\u0308"));
415 check(SV(R"("hello\u{308}"***)"), SV("{:*<17?}"), SV("hello
\u0308"));
417 check(SV(R"("hello 🤷🏻\u{200d}♂\u{fe0f}")"), SV("{:*>10?}"), SV("hello 🤷🏻♂️
"));
418 check(SV(R"(***"hello 🤷🏻\u{200d}♂\u{fe0f}")"), SV("{:*>30?}"), SV("hello 🤷🏻♂️
"));
419 check(SV(R"(*"hello 🤷🏻\u{200d}♂\u{fe0f}"**)"), SV("{:*^30?}"), SV("hello 🤷🏻♂️
"));
420 check(SV(R"("hello 🤷🏻\u{200d}♂\u{fe0f}"***)"), SV("{:*<30?}"), SV("hello 🤷🏻♂️
"));
423 check(SV(R"("hellö" )"), SV("{:10?}"), SV("hellö
"));
424 check(SV(R"("hello\u{308}" )"), SV("{:17?}"), SV("hello
\u0308"));
425 check(SV(R"("hello 🤷🏻\u{200d}♂\u{fe0f}" )"), SV("{:30?}"), SV("hello 🤷🏻♂️
"));
428 check(SV(R"("hell)"), SV("{:.5?}"), SV("hellö"));
429 check(SV(R
"("hellö
)"), SV("{:.6?}"), SV("hellö
"));
430 check(SV(R"("hellö")"), SV("{:.7?}"), SV("hellö
"));
432 check(SV(R"("hello )"), SV("{:.7?}"), SV("hello 🤷🏻♂️"));
433 check(SV(R
"("hello
)"), SV("{:.8?}"), SV("hello 🤷🏻♂️
")); // shrug is two columns
434 check(SV(R"("hello 🤷🏻)"), SV("{:.9?}"), SV("hello 🤷🏻♂️"));
435 check(SV(R
"("hello 🤷🏻\
)"), SV("{:.10?}"), SV("hello 🤷🏻♂️
"));
436 check(SV(R"("hello 🤷🏻\u{200d})"), SV("{:.17?}"), SV("hello 🤷🏻♂️"));
437 check(SV(R
"("hello 🤷🏻\u
{200d
}♂
)"), SV("{:.18?}"), SV("hello 🤷🏻♂️
"));
438 check(SV(R"("hello 🤷🏻\u{200d}♂\)"), SV("{:.19?}"), SV("hello 🤷🏻♂️"));
439 check(SV(R
"("hello 🤷🏻\u
{200d
}♂\u
{fe0f
}")"), SV("{:.28?}"), SV("hello 🤷🏻♂️"));
441 // *** width & precision ***
442 check(SV(R
"("hell
#########################)"), SV("{:#<30.5?}"), SV("hellö"));
443 check(SV(R"("hellö########################)"), SV("{:#<30.6?}"), SV("hellö"));
444 check(SV(R
"("hellö
"#######################)"), SV("{:#<30.7?}"), SV("hellö"));
446 check(SV(R
"("hello
#######################)"), SV("{:#<30.7?}"), SV("hello 🤷🏻♂️"));
447 check(SV(R"("hello #######################)"), SV("{:#<30.8?}"), SV("hello 🤷🏻♂️"));
448 check(SV(R
"("hello 🤷🏻
#####################)"), SV("{:#<30.9?}"), SV("hello 🤷🏻♂️"));
449 check(SV(R"("hello 🤷🏻\####################)"), SV("{:#<30.10?}"), SV("hello 🤷🏻♂️"));
450 check(SV(R
"("hello 🤷🏻\u
{200d
}#############)"), SV("{:#<30.17?}"), SV("hello 🤷🏻♂️"));
451 check(SV(R"("hello 🤷🏻\u{200d}♂############)"), SV("{:#<30.18?}"), SV("hello 🤷🏻♂️"));
452 check(SV(R
"("hello 🤷🏻\u
{200d
}♂\
###########)"), SV("{:#<30.19?}"), SV("hello 🤷🏻♂️"));
453 check(SV(R"("hello 🤷🏻\u{200d}♂\u{fe0f}"###)"), SV("{:#<30.28?}"), SV("hello 🤷🏻♂️"));
456 template <class CharT>
459 test_string<CharT>();
461 test_format_functions<CharT>(test_format);
462 test_format_functions<CharT>(test_format_to);
463 test_format_functions<CharT>(test_formatted_size);
464 test_format_functions<CharT>(test_format_to_n);
467 static void test_ill_formed_utf8() {
468 using namespace std::literals;
470 // Too few code units
471 test_format(R"("\x{df}")"sv, "{:?}", "\xdf");
472 test_format(R"("\x{ef}")"sv, "{:?}", "\xef");
473 test_format(R"("\x{ef}\x{bf}")"sv, "{:?}", "\xef\xbf");
474 test_format(R"("\x{f7}")"sv, "{:?}", "\xf7");
475 test_format(R"("\x{f7}\x{bf}")"sv, "{:?}", "\xf7\xbf");
476 test_format(R"("\x{f7}\x{bf}\x{bf}")"sv, "{:?}", "\xf7\xbf\xbf");
478 // Invalid continuation byte
479 test_format(R"("\x{df}a")"sv,
483 test_format(R"("\x{ef}a")"sv,
487 test_format(R"("\x{ef}\x{bf}a")"sv,
491 test_format(R"("\x{f7}a")"sv,
495 test_format(R"("\x{f7}\x{bf}a")"sv,
499 test_format(R"("\x{f7}\x{bf}\x{bf}a")"sv,
504 test_format(R"("a\x{f1}\x{80}\x{80}\x{e1}\x{80}\x{c2}b")"sv,
507 "\xf1\x80\x80\xe1\x80\xc2"
510 // Code unit out of range
511 test_format(R"("\u{10ffff}")"sv, "{:?}", "\xf4\x8f\xbf\xbf"); // last valid code point
512 test_format(R"("\x{f4}\x{90}\x{80}\x{80}")"sv, "{:?}", "\xf4\x90\x80\x80"); // first invalid code point
513 test_format(R"("\x{f5}\x{b1}\x{b2}\x{b3}")"sv, "{:?}", "\xf5\xb1\xb2\xb3");
514 test_format(R"("\x{f7}\x{bf}\x{bf}\x{bf}")"sv, "{:?}", "\xf7\xbf\xbf\xbf"); // largest encoded code point
517 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
518 # ifdef _LIBCPP_SHORT_WCHAR
519 static void test_ill_formed_utf16() {
520 using namespace std::literals;
522 // Too few code units
523 test_format(LR"("\x{d800}")"sv, L"{:?}", L"\xd800");
524 test_format(LR"("\x{dbff}")"sv, L"{:?}", L"\xdbff");
526 // Start with low surrogate pair
527 test_format(LR"("\x{dc00}a")"sv,
531 test_format(LR"("\x{dfff}a")"sv,
536 // Only high surrogate pair
537 test_format(LR"("\x{d800}a")"sv,
541 test_format(LR"("\x{dbff}a")"sv,
546 # else // _LIBCPP_SHORT_WCHAR
547 static void test_ill_formed_utf32() {
548 using namespace std::literals;
550 test_format(LR"("\u{10ffff}")"sv, L"{:?}", L"\x10ffff"); // last valid code point
551 test_format(LR"("\x{110000}")"sv, L"{:?}", L"\x110000"); // first invalid code point
552 test_format(LR"("\x{ffffffff}")"sv, L"{:?}", L"\xffffffff"); // largest encoded code point
555 # endif // _LIBCPP_SHORT_WCHAR
556 #endif // TEST_HAS_NO_WIDE_CHARACTERS
558 int main(int, char**) {
560 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
564 test_ill_formed_utf8();
565 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
566 # ifdef _LIBCPP_SHORT_WCHAR
567 test_ill_formed_utf16();
568 # else // _LIBCPP_SHORT_WCHAR
569 test_ill_formed_utf32();
570 # endif // _LIBCPP_SHORT_WCHAR
571 #endif // TEST_HAS_NO_WIDE_CHARACTERS