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 5 // 6 //===----------------------------------------------------------------------===// 7 8 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 9 // UNSUPPORTED: libcpp-has-no-incomplete-format 10 11 // This version runs the test when the platform has Unicode support. 12 // UNSUPPORTED: libcpp-has-no-unicode 13 14 // TODO FMT Investigate Windows and AIX issues. 15 // UNSUPPORTED: msvc, target={{.+}}-windows-gnu 16 // UNSUPPORTED: LIBCXX-AIX-FIXME 17 18 // <format> 19 20 // This test the debug string type for the formatter specializations for char 21 // and string types. This tests Unicode strings. 22 23 #include <format> 24 25 #include <cassert> 26 #include <concepts> 27 #include <iterator> 28 #include <list> 29 #include <vector> 30 31 #include "test_macros.h" 32 #include "make_string.h" 33 #include "test_format_string.h" 34 #include "assert_macros.h" 35 #include "concat_macros.h" 36 37 #ifndef TEST_HAS_NO_LOCALIZATION 38 # include <iostream> 39 #endif 40 41 #define SV(S) MAKE_STRING_VIEW(CharT, S) 42 43 auto test_format = []<class CharT, class... Args>( 44 std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) { 45 { 46 std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...); 47 TEST_REQUIRE(out == expected, 48 TEST_WRITE_CONCATENATED( 49 "\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n')); 50 } 51 #ifndef TEST_HAS_NO_LOCALIZATION 52 { 53 std::basic_string<CharT> out = std::format(std::locale(), fmt, std::forward<Args>(args)...); 54 assert(out == expected); 55 } 56 #endif // TEST_HAS_NO_LOCALIZATION 57 }; 58 59 auto test_format_to = 60 []<class CharT, class... Args>( 61 std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) { 62 { 63 std::basic_string<CharT> out(expected.size(), CharT(' ')); 64 auto it = std::format_to(out.begin(), fmt, std::forward<Args>(args)...); 65 assert(it == out.end()); 66 assert(out == expected); 67 } 68 #ifndef TEST_HAS_NO_LOCALIZATION 69 { 70 std::basic_string<CharT> out(expected.size(), CharT(' ')); 71 auto it = std::format_to(out.begin(), std::locale(), fmt, std::forward<Args>(args)...); 72 assert(it == out.end()); 73 assert(out == expected); 74 } 75 #endif // TEST_HAS_NO_LOCALIZATION 76 { 77 std::list<CharT> out; 78 std::format_to(std::back_inserter(out), fmt, std::forward<Args>(args)...); 79 assert(std::equal(out.begin(), out.end(), expected.begin(), expected.end())); 80 } 81 { 82 std::vector<CharT> out; 83 std::format_to(std::back_inserter(out), fmt, std::forward<Args>(args)...); 84 assert(std::equal(out.begin(), out.end(), expected.begin(), expected.end())); 85 } 86 { 87 assert(expected.size() < 4096 && "Update the size of the buffer."); 88 CharT out[4096]; 89 CharT* it = std::format_to(out, fmt, std::forward<Args>(args)...); 90 assert(std::distance(out, it) == int(expected.size())); 91 // Convert to std::string since output contains '\0' for boolean tests. 92 assert(std::basic_string<CharT>(out, it) == expected); 93 } 94 }; 95 96 auto test_formatted_size = 97 []<class CharT, class... Args>( 98 std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) { 99 { 100 size_t size = std::formatted_size(fmt, std::forward<Args>(args)...); 101 assert(size == expected.size()); 102 } 103 #ifndef TEST_HAS_NO_LOCALIZATION 104 { 105 size_t size = std::formatted_size(std::locale(), fmt, std::forward<Args>(args)...); 106 assert(size == expected.size()); 107 } 108 #endif // TEST_HAS_NO_LOCALIZATION 109 }; 110 111 auto test_format_to_n = 112 []<class CharT, class... Args>( 113 std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) { 114 { 115 size_t n = expected.size(); 116 std::basic_string<CharT> out(n, CharT(' ')); 117 std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...); 118 assert(result.size == static_cast<ptrdiff_t>(expected.size())); 119 assert(result.out == out.end()); 120 assert(out == expected); 121 } 122 #ifndef TEST_HAS_NO_LOCALIZATION 123 { 124 size_t n = expected.size(); 125 std::basic_string<CharT> out(n, CharT(' ')); 126 std::format_to_n_result result = 127 std::format_to_n(out.begin(), n, std::locale(), fmt, std::forward<Args>(args)...); 128 assert(result.size == static_cast<ptrdiff_t>(expected.size())); 129 assert(result.out == out.end()); 130 assert(out == expected); 131 } 132 #endif // TEST_HAS_NO_LOCALIZATION 133 { 134 ptrdiff_t n = 0; 135 std::basic_string<CharT> out; 136 std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...); 137 assert(result.size == static_cast<ptrdiff_t>(expected.size())); 138 assert(result.out == out.end()); 139 assert(out.empty()); 140 } 141 { 142 ptrdiff_t n = expected.size() / 2; 143 std::basic_string<CharT> out(n, CharT(' ')); 144 std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...); 145 assert(result.size == static_cast<ptrdiff_t>(expected.size())); 146 assert(result.out == out.end()); 147 assert(out == expected.substr(0, n)); 148 } 149 }; 150 151 template <class CharT> 152 void test_char() { 153 // *** P2286 examples *** 154 test_format(SV("['\\'', '\"']"), SV("[{:?}, {:?}]"), CharT('\''), CharT('"')); 155 156 // *** Specical cases *** 157 test_format(SV("'\\t'"), SV("{:?}"), CharT('\t')); 158 test_format(SV("'\\n'"), SV("{:?}"), CharT('\n')); 159 test_format(SV("'\\r'"), SV("{:?}"), CharT('\r')); 160 test_format(SV("'\\\\'"), SV("{:?}"), CharT('\\')); 161 162 test_format(SV("'\\\''"), SV("{:?}"), CharT('\'')); 163 test_format(SV("'\"'"), SV("{:?}"), CharT('"')); // only special for string 164 165 test_format(SV("' '"), SV("{:?}"), CharT(' ')); 166 167 // *** Printable *** 168 test_format(SV("'a'"), SV("{:?}"), CharT('a')); 169 test_format(SV("'b'"), SV("{:?}"), CharT('b')); 170 test_format(SV("'c'"), SV("{:?}"), CharT('c')); 171 172 // *** Non-printable *** 173 174 // Control 175 test_format(SV("'\\u{0}'"), SV("{:?}"), CharT('\0')); 176 test_format(SV("'\\u{1f}'"), SV("{:?}"), CharT('\x1f')); 177 178 // Ill-formed 179 if constexpr (sizeof(CharT) == 1) 180 test_format(SV("'\\x{80}'"), SV("{:?}"), CharT('\x80')); 181 182 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 183 if constexpr (sizeof(CharT) > 1) { 184 using V = std::basic_string_view<CharT>; 185 186 // Unicode fitting in a 16-bit wchar_t 187 188 // *** Non-printable *** 189 190 // Space_Separator 191 test_format(V{L"'\\u{a0}'"}, L"{:?}", L'\xa0'); // NO-BREAK SPACE 192 test_format(V{L"'\\u{3000}'"}, L"{:?}", L'\x3000'); // IDEOGRAPHIC SPACE 193 194 // Line_Separator 195 test_format(V{L"'\\u{2028}'"}, L"{:?}", L'\x2028'); // LINE SEPARATOR 196 197 // Paragraph_Separator 198 test_format(V{L"'\\u{2029}'"}, L"{:?}", L'\x2029'); // PARAGRAPH SEPARATOR 199 200 // Format 201 test_format(V{L"'\\u{ad}'"}, L"{:?}", L'\xad'); // SOFT HYPHEN 202 test_format(V{L"'\\u{600}'"}, L"{:?}", L'\x600'); // ARABIC NUMBER SIGN 203 test_format(V{L"'\\u{feff}'"}, L"{:?}", L'\xfeff'); // ZERO WIDTH NO-BREAK SPACE 204 205 if constexpr (sizeof(CharT) == 2) { 206 // Incomplete surrogate pair in UTF-16 207 test_format(V{L"'\\x{d800}'"}, L"{:?}", L'\xd800'); // <surrogate-D800> 208 test_format(V{L"'\\x{dfff}'"}, L"{:?}", L'\xdfff'); // <surrogate-DFFF> 209 } else { 210 test_format(V{L"'\\u{d800}'"}, L"{:?}", L'\xd800'); // <surrogate-D800> 211 test_format(V{L"'\\u{dfff}'"}, L"{:?}", L'\xdfff'); // <surrogate-DFFF> 212 } 213 214 // Private_Use 215 test_format(V{L"'\\u{e000}'"}, L"{:?}", L'\xe000'); // <private-use-E000> 216 test_format(V{L"'\\u{f8ff}'"}, L"{:?}", L'\xf8ff'); // <private-use-F8FF> 217 218 // Unassigned 219 test_format(V{L"'\\u{378}'"}, L"{:?}", L'\x378'); // <reserved-0378> 220 test_format(V{L"'\\u{1774}'"}, L"{:?}", L'\x1774'); // <reserved-1774> 221 test_format(V{L"'\\u{ffff}'"}, L"{:?}", L'\xffff'); // <noncharacter-FFFF> 222 223 // Grapheme Extended 224 test_format(V{L"'\\u{300}'"}, L"{:?}", L'\x300'); // COMBINING GRAVE ACCENT 225 test_format(V{L"'\\u{fe20}'"}, L"{:?}", L'\xfe20'); // VARIATION SELECTOR-1 226 } 227 # ifndef TEST_SHORT_WCHAR 228 if constexpr (sizeof(CharT) > 2) { 229 static_assert(sizeof(CharT) == 4, "add support for unexpected size"); 230 // Unicode fitting in a 32-bit wchar_t 231 232 constexpr wchar_t x = 0x1ffff; 233 constexpr uint32_t y = 0x1ffff; 234 static_assert(x == y); 235 236 using V = std::basic_string_view<CharT>; 237 238 // *** Non-printable *** 239 // Format 240 test_format(V{L"'\\u{110bd}'"}, L"{:?}", L'\x110bd'); // KAITHI NUMBER SIGN 241 test_format(V{L"'\\u{e007f}'"}, L"{:?}", L'\xe007f'); // CANCEL TAG 242 243 // Private_Use 244 test_format(V{L"'\\u{f0000}'"}, L"{:?}", L'\xf0000'); // <private-use-F0000> 245 test_format(V{L"'\\u{ffffd}'"}, L"{:?}", L'\xffffd'); // <private-use-FFFFD> 246 247 test_format(V{L"'\\u{100000}'"}, L"{:?}", L'\x100000'); // <private-use-100000> 248 test_format(V{L"'\\u{10fffd}'"}, L"{:?}", L'\x10fffd'); // <private-use-10FFFD> 249 250 // Unassigned 251 test_format(V{L"'\\u{1000c}'"}, L"{:?}", L'\x1000c'); // <reserved-1000c> 252 test_format(V{L"'\\u{fffff}'"}, L"{:?}", L'\xfffff'); // <noncharacter-FFFFF> 253 test_format(V{L"'\\u{10fffe}'"}, L"{:?}", L'\x10fffe'); // <noncharacter-10FFFE> 254 255 // Grapheme Extended 256 test_format(V{L"'\\u{101fd}'"}, L"{:?}", L'\x101fd'); // COMBINING OLD PERMIC LETTER AN 257 test_format(V{L"'\\u{e0100}'"}, L"{:?}", L'\xe0100'); // VARIATION SELECTOR-17 258 259 // Ill-formed 260 test_format(V{L"'\\x{110000}'"}, L"{:?}", L'\x110000'); 261 test_format(V{L"'\\x{ffffffff}'"}, L"{:?}", L'\xffffffff'); 262 } 263 # endif // TEST_SHORT_WCHAR 264 #endif // TEST_HAS_NO_WIDE_CHARACTERS 265 } 266 267 template <class CharT> 268 void test_string() { 269 // *** P2286 examples *** 270 test_format(SV("[h\tllo]"), SV("[{}]"), SV("h\tllo")); 271 test_format(SV(R"(["h\tllo"])"), SV("[{:?}]"), SV("h\tllo")); 272 test_format(SV(R"(["Спасибо, Виктор ♥!"])"), SV("[{:?}]"), SV("Спасибо, Виктор ♥!")); 273 274 test_format(SV(R"(["\u{0} \n \t \u{2} \u{1b}"])"), SV("[{:?}]"), SV("\0 \n \t \x02 \x1b")); 275 276 if constexpr (sizeof(CharT) == 1) { 277 // Ill-formend UTF-8 278 test_format(SV(R"(["\x{c3}"])"), SV("[{:?}]"), "\xc3"); 279 test_format(SV(R"(["\x{c3}("])"), SV("[{:?}]"), "\xc3\x28"); 280 } else { 281 // Valid UTF-16 and UTF-32 282 test_format(SV("[\"\u00c3\"]"), SV("[{:?}]"), L"\xc3"); // LATIN CAPITAL LETTER A WITH TILDE 283 test_format(SV("[\"\u00c3(\"]"), SV("[{:?}]"), L"\xc3\x28"); 284 } 285 286 test_format(SV(R"(["\u{200d}♂\u{fe0f}"])"), SV("[{:?}]"), SV("♂️")); 287 288 // *** Specical cases *** 289 test_format(SV(R"("\t\n\r\\'\" ")"), SV("{:?}"), SV("\t\n\r\\'\" ")); 290 291 // *** Printable *** 292 test_format(SV(R"("abcdefg")"), SV("{:?}"), SV("abcdefg")); 293 294 // *** Non-printable *** 295 296 // Control 297 test_format(SV(R"("\u{0}\u{1f}")"), SV("{:?}"), SV("\0\x1f")); 298 299 // Ill-formed 300 if constexpr (sizeof(CharT) == 1) 301 test_format(SV(R"("\x{80}")"), SV("{:?}"), SV("\x80")); 302 303 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 304 if constexpr (sizeof(CharT) > 1) { 305 using V = std::basic_string_view<CharT>; 306 307 // Unicode fitting in a 16-bit wchar_t 308 309 // *** Non-printable *** 310 311 // Space_Separator 312 test_format(V{LR"("\u{a0}\u{3000}")"}, L"{:?}", L"\xa0\x3000"); 313 314 // Line_Separator 315 test_format(V{LR"("\u{2028}")"}, L"{:?}", L"\x2028"); // LINE SEPARATOR 316 317 // Paragraph_Separator 318 test_format(V{LR"("\u{2029}")"}, L"{:?}", L"\x2029"); // PARAGRAPH SEPARATOR 319 320 // Format 321 test_format(V{LR"("\u{ad}\u{600}\u{feff}")"}, L"{:?}", L"\xad\x600\xfeff"); 322 323 if constexpr (sizeof(CharT) == 2) 324 // Incomplete surrogate pair in UTF-16 325 test_format(V{LR"("\x{d800}")"}, L"{:?}", L"\xd800"); 326 else 327 test_format(V{LR"("\u{d800}")"}, L"{:?}", L"\xd800"); 328 329 // Private_Use 330 test_format(V{LR"("\u{e000}\u{f8ff}")"}, L"{:?}", L"\xe000\xf8ff"); 331 332 // Unassigned 333 test_format(V{LR"("\u{378}\u{1774}\u{ffff}")"}, L"{:?}", L"\x378\x1774\xffff"); 334 335 // Grapheme Extended 336 test_format(V{LR"("\u{300}\u{fe20}")"}, L"{:?}", L"\x300\xfe20"); 337 } 338 # ifndef TEST_SHORT_WCHAR 339 if constexpr (sizeof(CharT) > 2) { 340 static_assert(sizeof(CharT) == 4, "add support for unexpected size"); 341 // Unicode fitting in a 32-bit wchar_t 342 343 constexpr wchar_t x = 0x1ffff; 344 constexpr uint32_t y = 0x1ffff; 345 static_assert(x == y); 346 347 using V = std::basic_string_view<CharT>; 348 349 // *** Non-printable *** 350 // Format 351 test_format(V{LR"("\u{110bd}\u{e007f}")"}, L"{:?}", L"\x110bd\xe007f"); 352 353 // Private_Use 354 test_format(V{LR"("\u{f0000}\u{ffffd}\u{100000}\u{10fffd}")"}, L"{:?}", L"\xf0000\xffffd\x100000\x10fffd"); 355 356 // Unassigned 357 test_format(V{LR"("\u{1000c}\u{fffff}\u{10fffe}")"}, L"{:?}", L"\x1000c\xfffff\x10fffe"); 358 359 // Grapheme Extended 360 test_format(V{LR"("\u{101fd}\u{e0100}")"}, L"{:?}", L"\x101fd\xe0100"); 361 362 // Ill-formed 363 test_format(V{LR"("\x{110000}\x{ffffffff}")"}, L"{:?}", L"\x110000\xffffffff"); 364 } 365 # endif // TEST_SHORT_WCHAR 366 #endif // TEST_HAS_NO_WIDE_CHARACTERS 367 } 368 369 template <class CharT, class TestFunction> 370 void test_format_functions(TestFunction check) { 371 // *** align-fill & width *** 372 check(SV(R"(***"hellö")"), SV("{:*>10?}"), SV("hellö")); // ö is LATIN SMALL LETTER O WITH DIAERESIS 373 check(SV(R"(*"hellö"**)"), SV("{:*^10?}"), SV("hellö")); 374 check(SV(R"("hellö"***)"), SV("{:*<10?}"), SV("hellö")); 375 376 check(SV(R"("hello\u{308}")"), SV("{:*>10?}"), SV("hello\u0308")); 377 check(SV(R"(***"hello\u{308}")"), SV("{:*>17?}"), SV("hello\u0308")); 378 check(SV(R"(*"hello\u{308}"**)"), SV("{:*^17?}"), SV("hello\u0308")); 379 check(SV(R"("hello\u{308}"***)"), SV("{:*<17?}"), SV("hello\u0308")); 380 381 check(SV(R"("hello \u{200d}♂\u{fe0f}")"), SV("{:*>10?}"), SV("hello ♂️")); 382 check(SV(R"(***"hello \u{200d}♂\u{fe0f}")"), SV("{:*>30?}"), SV("hello ♂️")); 383 check(SV(R"(*"hello \u{200d}♂\u{fe0f}"**)"), SV("{:*^30?}"), SV("hello ♂️")); 384 check(SV(R"("hello \u{200d}♂\u{fe0f}"***)"), SV("{:*<30?}"), SV("hello ♂️")); 385 386 // *** width *** 387 check(SV(R"("hellö" )"), SV("{:10?}"), SV("hellö")); 388 check(SV(R"("hello\u{308}" )"), SV("{:17?}"), SV("hello\u0308")); 389 check(SV(R"("hello \u{200d}♂\u{fe0f}" )"), SV("{:30?}"), SV("hello ♂️")); 390 391 // *** precision *** 392 check(SV(R"("hell)"), SV("{:.5?}"), SV("hellö")); 393 check(SV(R"("hellö)"), SV("{:.6?}"), SV("hellö")); 394 check(SV(R"("hellö")"), SV("{:.7?}"), SV("hellö")); 395 396 check(SV(R"("hello )"), SV("{:.7?}"), SV("hello ♂️")); 397 check(SV(R"("hello )"), SV("{:.8?}"), SV("hello ♂️")); // shrug is two columns 398 check(SV(R"("hello )"), SV("{:.9?}"), SV("hello ♂️")); 399 check(SV(R"("hello \)"), SV("{:.10?}"), SV("hello ♂️")); 400 check(SV(R"("hello \u{200d})"), SV("{:.17?}"), SV("hello ♂️")); 401 check(SV(R"("hello \u{200d}♂)"), SV("{:.18?}"), SV("hello ♂️")); 402 check(SV(R"("hello \u{200d}♂\)"), SV("{:.19?}"), SV("hello ♂️")); 403 check(SV(R"("hello \u{200d}♂\u{fe0f}")"), SV("{:.28?}"), SV("hello ♂️")); 404 405 // *** width & precision *** 406 check(SV(R"("hell#########################)"), SV("{:#<30.5?}"), SV("hellö")); 407 check(SV(R"("hellö########################)"), SV("{:#<30.6?}"), SV("hellö")); 408 check(SV(R"("hellö"#######################)"), SV("{:#<30.7?}"), SV("hellö")); 409 410 check(SV(R"("hello #######################)"), SV("{:#<30.7?}"), SV("hello ♂️")); 411 check(SV(R"("hello #######################)"), SV("{:#<30.8?}"), SV("hello ♂️")); 412 check(SV(R"("hello #####################)"), SV("{:#<30.9?}"), SV("hello ♂️")); 413 check(SV(R"("hello \####################)"), SV("{:#<30.10?}"), SV("hello ♂️")); 414 check(SV(R"("hello \u{200d}#############)"), SV("{:#<30.17?}"), SV("hello ♂️")); 415 check(SV(R"("hello \u{200d}♂############)"), SV("{:#<30.18?}"), SV("hello ♂️")); 416 check(SV(R"("hello \u{200d}♂\###########)"), SV("{:#<30.19?}"), SV("hello ♂️")); 417 check(SV(R"("hello \u{200d}♂\u{fe0f}"###)"), SV("{:#<30.28?}"), SV("hello ♂️")); 418 } 419 420 template <class CharT> 421 void test() { 422 test_char<CharT>(); 423 test_string<CharT>(); 424 425 test_format_functions<CharT>(test_format); 426 test_format_functions<CharT>(test_format_to); 427 test_format_functions<CharT>(test_formatted_size); 428 test_format_functions<CharT>(test_format_to_n); 429 } 430 431 static void test_ill_formed_utf8() { 432 using namespace std::literals; 433 434 // Too few code units 435 test_format(R"("\x{df}")"sv, "{:?}", "\xdf"); 436 test_format(R"("\x{ef}")"sv, "{:?}", "\xef"); 437 test_format(R"("\x{ef}\x{bf}")"sv, "{:?}", "\xef\xbf"); 438 test_format(R"("\x{f7}")"sv, "{:?}", "\xf7"); 439 test_format(R"("\x{f7}\x{bf}")"sv, "{:?}", "\xf7\xbf"); 440 test_format(R"("\x{f7}\x{bf}\x{bf}")"sv, "{:?}", "\xf7\xbf\xbf"); 441 442 // Invalid continuation byte 443 test_format(R"("\x{df}a")"sv, 444 "{:?}", 445 "\xdf" 446 "a"); 447 test_format(R"("\x{ef}a")"sv, 448 "{:?}", 449 "\xef" 450 "a"); 451 test_format(R"("\x{ef}\x{bf}a")"sv, 452 "{:?}", 453 "\xef\xbf" 454 "a"); 455 test_format(R"("\x{f7}a")"sv, 456 "{:?}", 457 "\xf7" 458 "a"); 459 test_format(R"("\x{f7}\x{bf}a")"sv, 460 "{:?}", 461 "\xf7\xbf" 462 "a"); 463 test_format(R"("\x{f7}\x{bf}\x{bf}a")"sv, 464 "{:?}", 465 "\xf7\xbf\xbf" 466 "a"); 467 468 // Code unit out of range 469 test_format(R"("\u{10ffff}")"sv, "{:?}", "\xf4\x8f\xbf\xbf"); // last valid code point 470 test_format(R"("\x{f4}\x{90}\x{80}\x{80}")"sv, "{:?}", "\xf4\x90\x80\x80"); // first invalid code point 471 test_format(R"("\x{f5}\x{b1}\x{b2}\x{b3}")"sv, "{:?}", "\xf5\xb1\xb2\xb3"); 472 test_format(R"("\x{f7}\x{bf}\x{bf}\x{bf}")"sv, "{:?}", "\xf7\xbf\xbf\xbf"); // largest encoded code point 473 } 474 475 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 476 # ifdef _LIBCPP_SHORT_WCHAR 477 static void test_ill_formed_utf16() { 478 using namespace std::literals; 479 480 // Too few code units 481 test_format(LR"("\x{d800}")"sv, L"{:?}", L"\xd800"); 482 test_format(LR"("\x{dbff}")"sv, L"{:?}", L"\xdbff"); 483 484 // Start with low surrogate pair 485 test_format(LR"("\x{dc00}a")"sv, 486 L"{:?}", 487 L"\xdc00" 488 "a"); 489 test_format(LR"("\x{dfff}a")"sv, 490 L"{:?}", 491 L"\xdfff" 492 "a"); 493 494 // Only high surrogate pair 495 test_format(LR"("\x{d800}a")"sv, 496 L"{:?}", 497 L"\xd800" 498 "a"); 499 test_format(LR"("\x{dbff}a")"sv, 500 L"{:?}", 501 L"\xdbff" 502 "a"); 503 } 504 # else // _LIBCPP_SHORT_WCHAR 505 static void test_ill_formed_utf32() { 506 using namespace std::literals; 507 508 test_format(LR"("\u{10ffff}")"sv, L"{:?}", L"\x10ffff"); // last valid code point 509 test_format(LR"("\x{110000}")"sv, L"{:?}", L"\x110000"); // first invalid code point 510 test_format(LR"("\x{ffffffff}")"sv, L"{:?}", L"\xffffffff"); // largest encoded code point 511 } 512 513 # endif // _LIBCPP_SHORT_WCHAR 514 #endif // TEST_HAS_NO_WIDE_CHARACTERS 515 516 int main(int, char**) { 517 test<char>(); 518 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 519 test<wchar_t>(); 520 #endif 521 522 test_ill_formed_utf8(); 523 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 524 # ifdef _LIBCPP_SHORT_WCHAR 525 test_ill_formed_utf16(); 526 assert(false); 527 # else // _LIBCPP_SHORT_WCHAR 528 test_ill_formed_utf32(); 529 # endif // _LIBCPP_SHORT_WCHAR 530 #endif // TEST_HAS_NO_WIDE_CHARACTERS 531 532 return 0; 533 } 534