brintos

brintos / llvm-project-archived public Read only

0
0
Text · 22.4 KiB · eb27c70 Raw
576 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME11 12// This version runs the test when the platform has Unicode support.13// UNSUPPORTED: libcpp-has-no-unicode14 15// TODO FMT This test should not require std::to_chars(floating-point)16// XFAIL: availability-fp_to_chars-missing17 18// <format>19 20// This test the debug string type for the formatter specializations for char21// and string types. This tests Unicode strings.22 23#include <format>24 25#include <cassert>26#include <concepts>27#include <cstdint>28#include <iterator>29#include <list>30#include <vector>31 32#include "test_macros.h"33#include "make_string.h"34#include "test_format_string.h"35#include "assert_macros.h"36#include "concat_macros.h"37 38#ifndef TEST_HAS_NO_LOCALIZATION39#  include <iostream>40#endif41 42#define SV(S) MAKE_STRING_VIEW(CharT, S)43 44auto test_format = []<class CharT, class... Args>(45                       std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {46  {47    std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);48    TEST_REQUIRE(out == expected,49                 TEST_WRITE_CONCATENATED(50                     "\nFormat string   ", fmt.get(), "\nExpected output ", expected, "\nActual output   ", out, '\n'));51  }52#ifndef TEST_HAS_NO_LOCALIZATION53  {54    std::basic_string<CharT> out = std::format(std::locale(), fmt, std::forward<Args>(args)...);55    assert(out == expected);56  }57#endif // TEST_HAS_NO_LOCALIZATION58};59 60auto test_format_to =61    []<class CharT, class... Args>(62        std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {63      {64        std::basic_string<CharT> out(expected.size(), CharT(' '));65        auto it = std::format_to(out.begin(), fmt, std::forward<Args>(args)...);66        assert(it == out.end());67        assert(out == expected);68      }69#ifndef TEST_HAS_NO_LOCALIZATION70      {71        std::basic_string<CharT> out(expected.size(), CharT(' '));72        auto it = std::format_to(out.begin(), std::locale(), fmt, std::forward<Args>(args)...);73        assert(it == out.end());74        assert(out == expected);75      }76#endif // TEST_HAS_NO_LOCALIZATION77      {78        std::list<CharT> out;79        std::format_to(std::back_inserter(out), fmt, std::forward<Args>(args)...);80        assert(std::equal(out.begin(), out.end(), expected.begin(), expected.end()));81      }82      {83        std::vector<CharT> out;84        std::format_to(std::back_inserter(out), fmt, std::forward<Args>(args)...);85        assert(std::equal(out.begin(), out.end(), expected.begin(), expected.end()));86      }87      {88        assert(expected.size() < 4096 && "Update the size of the buffer.");89        CharT out[4096];90        CharT* it = std::format_to(out, fmt, std::forward<Args>(args)...);91        assert(std::distance(out, it) == int(expected.size()));92        // Convert to std::string since output contains '\0' for boolean tests.93        assert(std::basic_string<CharT>(out, it) == expected);94      }95    };96 97auto test_formatted_size =98    []<class CharT, class... Args>(99        std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {100      {101        std::size_t size = std::formatted_size(fmt, std::forward<Args>(args)...);102        assert(size == expected.size());103      }104#ifndef TEST_HAS_NO_LOCALIZATION105      {106        std::size_t size = std::formatted_size(std::locale(), fmt, std::forward<Args>(args)...);107        assert(size == expected.size());108      }109#endif // TEST_HAS_NO_LOCALIZATION110    };111 112auto test_format_to_n =113    []<class CharT, class... Args>(114        std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {115      {116        std::size_t n = expected.size();117        std::basic_string<CharT> out(n, CharT(' '));118        std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...);119        assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));120        assert(result.out == out.end());121        assert(out == expected);122      }123#ifndef TEST_HAS_NO_LOCALIZATION124      {125        std::size_t n = expected.size();126        std::basic_string<CharT> out(n, CharT(' '));127        std::format_to_n_result result =128            std::format_to_n(out.begin(), n, std::locale(), fmt, std::forward<Args>(args)...);129        assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));130        assert(result.out == out.end());131        assert(out == expected);132      }133#endif // TEST_HAS_NO_LOCALIZATION134      {135        std::ptrdiff_t n = 0;136        std::basic_string<CharT> out;137        std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...);138        assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));139        assert(result.out == out.end());140        assert(out.empty());141      }142      {143        std::ptrdiff_t n = expected.size() / 2;144        std::basic_string<CharT> out(n, CharT(' '));145        std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...);146        assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));147        assert(result.out == out.end());148        assert(out == expected.substr(0, n));149      }150    };151 152template <class CharT>153void test_char() {154  // *** P2286 examples ***155  test_format(SV("['\\'', '\"']"), SV("[{:?}, {:?}]"), CharT('\''), CharT('"'));156 157  // *** Special cases ***158  test_format(SV("'\\t'"), SV("{:?}"), CharT('\t'));159  test_format(SV("'\\n'"), SV("{:?}"), CharT('\n'));160  test_format(SV("'\\r'"), SV("{:?}"), CharT('\r'));161  test_format(SV("'\\\\'"), SV("{:?}"), CharT('\\'));162 163  test_format(SV("'\\\''"), SV("{:?}"), CharT('\''));164  test_format(SV("'\"'"), SV("{:?}"), CharT('"')); // only special for string165 166  test_format(SV("' '"), SV("{:?}"), CharT(' '));167 168  // *** Printable ***169  test_format(SV("'a'"), SV("{:?}"), CharT('a'));170  test_format(SV("'b'"), SV("{:?}"), CharT('b'));171  test_format(SV("'c'"), SV("{:?}"), CharT('c'));172 173  // *** Non-printable ***174 175  // Control176  test_format(SV("'\\u{0}'"), SV("{:?}"), CharT('\0'));177  test_format(SV("'\\u{1f}'"), SV("{:?}"), CharT('\x1f'));178 179  // Ill-formed180  if constexpr (sizeof(CharT) == 1)181    test_format(SV("'\\x{80}'"), SV("{:?}"), CharT('\x80'));182 183#ifndef TEST_HAS_NO_WIDE_CHARACTERS184  if constexpr (sizeof(CharT) > 1) {185    using V = std::basic_string_view<CharT>;186 187    // Unicode fitting in a 16-bit wchar_t188 189    // *** Non-printable ***190 191    // Space_Separator192    test_format(V{L"'\\u{a0}'"}, L"{:?}", L'\xa0');     // NO-BREAK SPACE193    test_format(V{L"'\\u{3000}'"}, L"{:?}", L'\x3000'); // IDEOGRAPHIC SPACE194 195    // Line_Separator196    test_format(V{L"'\\u{2028}'"}, L"{:?}", L'\x2028'); // LINE SEPARATOR197 198    // Paragraph_Separator199    test_format(V{L"'\\u{2029}'"}, L"{:?}", L'\x2029'); // PARAGRAPH SEPARATOR200 201    // Format202    test_format(V{L"'\\u{ad}'"}, L"{:?}", L'\xad');     // SOFT HYPHEN203    test_format(V{L"'\\u{600}'"}, L"{:?}", L'\x600');   // ARABIC NUMBER SIGN204    test_format(V{L"'\\u{feff}'"}, L"{:?}", L'\xfeff'); // ZERO WIDTH NO-BREAK SPACE205 206    // Incomplete surrogate pair in UTF-16207    test_format(V{L"'\\x{d800}'"}, L"{:?}", L'\xd800'); // <surrogate-D800>208    test_format(V{L"'\\x{dfff}'"}, L"{:?}", L'\xdfff'); // <surrogate-DFFF>209 210    // Private_Use211    test_format(V{L"'\\u{e000}'"}, L"{:?}", L'\xe000'); // <private-use-E000>212    test_format(V{L"'\\u{f8ff}'"}, L"{:?}", L'\xf8ff'); // <private-use-F8FF>213 214    // Unassigned215    test_format(V{L"'\\u{378}'"}, L"{:?}", L'\x378');   // <reserved-0378>216    test_format(V{L"'\\u{1774}'"}, L"{:?}", L'\x1774'); // <reserved-1774>217    test_format(V{L"'\\u{ffff}'"}, L"{:?}", L'\xffff'); // <noncharacter-FFFF>218 219    // Grapheme Extended220    test_format(V{L"'\\u{300}'"}, L"{:?}", L'\x300');   // COMBINING GRAVE ACCENT221    test_format(V{L"'\\u{fe20}'"}, L"{:?}", L'\xfe20'); // VARIATION SELECTOR-1222  }223#  ifndef TEST_SHORT_WCHAR224  if constexpr (sizeof(CharT) > 2) {225    static_assert(sizeof(CharT) == 4, "add support for unexpected size");226    // Unicode fitting in a 32-bit wchar_t227 228    constexpr wchar_t x       = 0x1ffff;229    constexpr std::uint32_t y = 0x1ffff;230    static_assert(x == y);231 232    using V = std::basic_string_view<CharT>;233 234    // *** Non-printable ***235    // Format236    test_format(V{L"'\\u{110bd}'"}, L"{:?}", L'\x110bd'); // KAITHI NUMBER SIGN237    test_format(V{L"'\\u{e007f}'"}, L"{:?}", L'\xe007f'); // CANCEL TAG238 239    // Private_Use240    test_format(V{L"'\\u{f0000}'"}, L"{:?}", L'\xf0000'); // <private-use-F0000>241    test_format(V{L"'\\u{ffffd}'"}, L"{:?}", L'\xffffd'); // <private-use-FFFFD>242 243    test_format(V{L"'\\u{100000}'"}, L"{:?}", L'\x100000'); // <private-use-100000>244    test_format(V{L"'\\u{10fffd}'"}, L"{:?}", L'\x10fffd'); // <private-use-10FFFD>245 246    // Unassigned247    test_format(V{L"'\\u{1000c}'"}, L"{:?}", L'\x1000c');   // <reserved-1000c>248    test_format(V{L"'\\u{fffff}'"}, L"{:?}", L'\xfffff');   // <noncharacter-FFFFF>249    test_format(V{L"'\\u{10fffe}'"}, L"{:?}", L'\x10fffe'); // <noncharacter-10FFFE>250 251    // Grapheme Extended252    test_format(V{L"'\\u{101fd}'"}, L"{:?}", L'\x101fd'); // COMBINING OLD PERMIC LETTER AN253    test_format(V{L"'\\u{e0100}'"}, L"{:?}", L'\xe0100'); // VARIATION SELECTOR-17254 255    // Ill-formed256    test_format(V{L"'\\x{110000}'"}, L"{:?}", L'\x110000');257    test_format(V{L"'\\x{ffffffff}'"}, L"{:?}", L'\xffffffff');258  }259#  endif // TEST_SHORT_WCHAR260#endif   // TEST_HAS_NO_WIDE_CHARACTERS261}262 263template <class CharT>264void test_string() {265  // *** P2286 examples ***266  test_format(SV("[h\tllo]"), SV("[{}]"), SV("h\tllo"));267  test_format(SV(R"(["h\tllo"])"), SV("[{:?}]"), SV("h\tllo"));268  test_format(SV(R"(["Спасибо, Виктор ♥!"])"), SV("[{:?}]"), SV("Спасибо, Виктор ♥!"));269 270  test_format(SV(R"(["\u{0} \n \t \u{2} \u{1b}"])"), SV("[{:?}]"), SV("\0 \n \t \x02 \x1b"));271 272  if constexpr (sizeof(CharT) == 1) {273    // Ill-formend UTF-8274    test_format(SV(R"(["\x{c3}"])"), SV("[{:?}]"), "\xc3");275    test_format(SV(R"(["\x{c3}("])"), SV("[{:?}]"), "\xc3\x28");276 277    /* U+0000..U+0007F 1 code unit range, encoded in 2 code units. */278    test_format(SV(R"(["\x{c0}\x{80}"])"), SV("[{:?}]"), "\xc0\x80"); // U+0000279    test_format(SV(R"(["\x{c1}\x{bf}"])"), SV("[{:?}]"), "\xc1\xbf"); // U+007F280    test_format(SV(R"(["\u{80}"])"), SV("[{:?}]"), "\xc2\x80");       // U+0080 first valid (General_Category=Control)281 282    /* U+0000..U+07FFF 1 and 2 code unit range, encoded in 3 code units. */283    test_format(SV(R"(["\x{e0}\x{80}\x{80}"])"), SV("[{:?}]"), "\xe0\x80\x80"); // U+0000284    test_format(SV(R"(["\x{e0}\x{81}\x{bf}"])"), SV("[{:?}]"), "\xe0\x81\xbf"); // U+007F285    test_format(SV(R"(["\x{e0}\x{82}\x{80}"])"), SV("[{:?}]"), "\xe0\x82\x80"); // U+0080286    test_format(SV(R"(["\x{e0}\x{9f}\x{bf}"])"), SV("[{:?}]"), "\xe0\x9f\xbf"); // U+07FF287    test_format(SV("[\"\u0800\"]"), SV("[{:?}]"), "\xe0\xa0\x80");              // U+0800 first valid288 289#if 0290	// This code point is in the Hangul Jamo Extended-B block and at the time of writing291	// it's unassigned. When it comes defined, this branch might become true.292    test_format(SV("[\"\ud7ff\"]"), SV("[{:?}]"), "\xed\x9f\xbf");              // U+D7FF last valid293#else294    /* U+D800..D+DFFFF surrogate range */295    test_format(SV(R"(["\u{d7ff}"])"), SV("[{:?}]"), "\xed\x9f\xbf"); // U+D7FF last valid296#endif297    test_format(SV(R"(["\x{ed}\x{a0}\x{80}"])"), SV("[{:?}]"), "\xed\xa0\x80"); // U+D800298    test_format(SV(R"(["\x{ed}\x{af}\x{bf}"])"), SV("[{:?}]"), "\xed\xaf\xbf"); // U+DBFF299    test_format(SV(R"(["\x{ed}\x{bf}\x{80}"])"), SV("[{:?}]"), "\xed\xbf\x80"); // U+DC00300    test_format(SV(R"(["\x{ed}\x{bf}\x{bf}"])"), SV("[{:?}]"), "\xed\xbf\xbf"); // U+DFFF301    test_format(SV(R"(["\u{e000}"])"), SV("[{:?}]"), "\xee\x80\x80");           // U+E000 first valid302                                                                                // (in the Private Use Area block)303 304    /* U+0000..U+FFFF 1, 2, and 3 code unit range */305    test_format(SV(R"(["\x{f0}\x{80}\x{80}\x{80}"])"), SV("[{:?}]"), "\xf0\x80\x80\x80"); // U+0000306    test_format(SV(R"(["\x{f0}\x{80}\x{81}\x{bf}"])"), SV("[{:?}]"), "\xf0\x80\x81\xbf"); // U+007F307    test_format(SV(R"(["\x{f0}\x{80}\x{82}\x{80}"])"), SV("[{:?}]"), "\xf0\x80\x82\x80"); // U+0080308    test_format(SV(R"(["\x{f0}\x{80}\x{9f}\x{bf}"])"), SV("[{:?}]"), "\xf0\x80\x9f\xbf"); // U+07FF309    test_format(SV(R"(["\x{f0}\x{80}\x{a0}\x{80}"])"), SV("[{:?}]"), "\xf0\x80\xa0\x80"); // U+0800310    test_format(SV(R"(["\x{f0}\x{8f}\x{bf}\x{bf}"])"), SV("[{:?}]"), "\xf0\x8f\xbf\xbf"); // U+FFFF311    test_format(SV("[\"\U00010000\"]"), SV("[{:?}]"), "\xf0\x90\x80\x80");                // U+10000 first valid312 313    /* U+10FFFF..U+1FFFFF invalid range */314    test_format(SV(R"(["\u{10ffff}"])"), SV("[{:?}]"), "\xf4\x8f\xbf\xbf"); // U+10FFFF last valid315                                                                            // (in Supplementary Private Use Area-B)316    test_format(SV(R"(["\x{f4}\x{90}\x{80}\x{80}"])"), SV("[{:?}]"), "\xf4\x90\x80\x80"); // U+110000317    test_format(SV(R"(["\x{f4}\x{bf}\x{bf}\x{bf}"])"), SV("[{:?}]"), "\xf4\xbf\xbf\xbf"); // U+11FFFF318  } else {319    // Valid UTF-16 and UTF-32320    test_format(SV("[\"\u00c3\"]"), SV("[{:?}]"), L"\xc3"); // LATIN CAPITAL LETTER A WITH TILDE321    test_format(SV("[\"\u00c3(\"]"), SV("[{:?}]"), L"\xc3\x28");322  }323 324  // LWG-3965325  test_format(SV(R"(["🤷🏻\u{200d}♂️"])"), SV("[{:?}]"), SV("🤷🏻‍♂️"));326 327  // *** Special cases ***328  test_format(SV(R"("\t\n\r\\'\" ")"), SV("{:?}"), SV("\t\n\r\\'\" "));329 330  // *** Printable ***331  test_format(SV(R"("abcdefg")"), SV("{:?}"), SV("abcdefg"));332 333  // *** Non-printable ***334 335  // Control336  test_format(SV(R"("\u{0}\u{1f}")"), SV("{:?}"), SV("\0\x1f"));337 338  // Ill-formed339  if constexpr (sizeof(CharT) == 1)340    test_format(SV(R"("\x{80}")"), SV("{:?}"), "\x80");341 342  // *** P2713R1 examples ***343  test_format(SV(R"(["\u{301}"])"), SV("[{:?}]"), SV("\u0301"));344  test_format(SV(R"(["\\\u{301}"])"), SV("[{:?}]"), SV("\\\u0301"));345  test_format(SV(R"(["ẹ́"])"), SV("[{:?}]"), SV("e\u0301\u0323"));346 347#ifndef TEST_HAS_NO_WIDE_CHARACTERS348  if constexpr (sizeof(CharT) > 1) {349    using V = std::basic_string_view<CharT>;350 351    // Unicode fitting in a 16-bit wchar_t352 353    // *** Non-printable ***354 355    // Space_Separator356    test_format(V{LR"("\u{a0}\u{3000}")"}, L"{:?}", L"\xa0\x3000");357 358    // Line_Separator359    test_format(V{LR"("\u{2028}")"}, L"{:?}", L"\x2028"); // LINE SEPARATOR360 361    // Paragraph_Separator362    test_format(V{LR"("\u{2029}")"}, L"{:?}", L"\x2029"); // PARAGRAPH SEPARATOR363 364    // Format365    test_format(V{LR"("\u{ad}\u{600}\u{feff}")"}, L"{:?}", L"\xad\x600\xfeff");366 367    // Incomplete surrogate pair in UTF-16368    test_format(V{LR"("\x{d800}")"}, L"{:?}", L"\xd800");369 370    // Private_Use371    test_format(V{LR"("\u{e000}\u{f8ff}")"}, L"{:?}", L"\xe000\xf8ff");372 373    // Unassigned374    test_format(V{LR"("\u{378}\u{1774}\u{ffff}")"}, L"{:?}", L"\x378\x1774\xffff");375 376    // Grapheme Extended377    test_format(V{LR"("\u{300}\u{fe20}")"}, L"{:?}", L"\x300\xfe20");378  }379#  ifndef TEST_SHORT_WCHAR380  if constexpr (sizeof(CharT) > 2) {381    static_assert(sizeof(CharT) == 4, "add support for unexpected size");382    // Unicode fitting in a 32-bit wchar_t383 384    constexpr wchar_t x       = 0x1ffff;385    constexpr std::uint32_t y = 0x1ffff;386    static_assert(x == y);387 388    using V = std::basic_string_view<CharT>;389 390    // *** Non-printable ***391    // Format392    test_format(V{LR"("\u{110bd}\u{e007f}")"}, L"{:?}", L"\x110bd\xe007f");393 394    // Private_Use395    test_format(V{LR"("\u{f0000}\u{ffffd}\u{100000}\u{10fffd}")"}, L"{:?}", L"\xf0000\xffffd\x100000\x10fffd");396 397    // Unassigned398    test_format(V{LR"("\u{1000c}\u{fffff}\u{10fffe}")"}, L"{:?}", L"\x1000c\xfffff\x10fffe");399 400    // Grapheme Extended401    test_format(V{LR"("\u{101fd}\u{e0100}")"}, L"{:?}", L"\x101fd\xe0100");402 403    // Ill-formed404    test_format(V{LR"("\x{110000}\x{ffffffff}")"}, L"{:?}", L"\x110000\xffffffff");405  }406#  endif // TEST_SHORT_WCHAR407#endif   // TEST_HAS_NO_WIDE_CHARACTERS408}409 410template <class CharT, class TestFunction>411void test_format_functions(TestFunction check) {412  // *** align-fill & width ***413  check(SV(R"(***"hellö")"), SV("{:*>10?}"), SV("hellö")); // ö is LATIN SMALL LETTER O WITH DIAERESIS414  check(SV(R"(*"hellö"**)"), SV("{:*^10?}"), SV("hellö"));415  check(SV(R"("hellö"***)"), SV("{:*<10?}"), SV("hellö"));416 417  check(SV(R"(***"hellö")"), SV("{:*>10?}"), SV("hello\u0308"));418  check(SV(R"(*"hellö"**)"), SV("{:*^10?}"), SV("hello\u0308"));419  check(SV(R"("hellö"***)"), SV("{:*<10?}"), SV("hello\u0308"));420 421  check(SV(R"(***"hello 🤷🏻\u{200d}♂️")"), SV("{:*>22?}"), SV("hello 🤷🏻‍♂️"));422  check(SV(R"(*"hello 🤷🏻\u{200d}♂️"**)"), SV("{:*^22?}"), SV("hello 🤷🏻‍♂️"));423  check(SV(R"("hello 🤷🏻\u{200d}♂️"***)"), SV("{:*<22?}"), SV("hello 🤷🏻‍♂️"));424 425  // *** width ***426  check(SV(R"("hellö"   )"), SV("{:10?}"), SV("hellö"));427  check(SV(R"("hellö"   )"), SV("{:10?}"), SV("hello\u0308"));428  check(SV(R"("hello 🤷🏻\u{200d}♂️"   )"), SV("{:22?}"), SV("hello 🤷🏻‍♂️"));429 430  // *** precision ***431  check(SV(R"("hell)"), SV("{:.5?}"), SV("hellö"));432  check(SV(R"("hellö)"), SV("{:.6?}"), SV("hellö"));433  check(SV(R"("hellö")"), SV("{:.7?}"), SV("hellö"));434 435  check(SV(R"("hello )"), SV("{:.7?}"), SV("hello 🤷🏻‍♂️"));436  check(SV(R"("hello )"), SV("{:.8?}"), SV("hello 🤷🏻‍♂️")); // shrug is two columns437  check(SV(R"("hello 🤷🏻)"), SV("{:.9?}"), SV("hello 🤷🏻‍♂️"));438  check(SV(R"("hello 🤷🏻\)"), SV("{:.10?}"), SV("hello 🤷🏻‍♂️"));439  check(SV(R"("hello 🤷🏻\u{200d})"), SV("{:.17?}"), SV("hello 🤷🏻‍♂️"));440  check(SV(R"("hello 🤷🏻\u{200d}♂️)"), SV("{:.18?}"), SV("hello 🤷🏻‍♂️"));441  check(SV(R"("hello 🤷🏻\u{200d}♂️")"), SV("{:.19?}"), SV("hello 🤷🏻‍♂️"));442 443  // *** width & precision ***444  check(SV(R"("hell#########################)"), SV("{:#<30.5?}"), SV("hellö"));445  check(SV(R"("hellö########################)"), SV("{:#<30.6?}"), SV("hellö"));446  check(SV(R"("hellö"#######################)"), SV("{:#<30.7?}"), SV("hellö"));447 448  check(SV(R"("hello #######################)"), SV("{:#<30.7?}"), SV("hello 🤷🏻‍♂️"));449  check(SV(R"("hello #######################)"), SV("{:#<30.8?}"), SV("hello 🤷🏻‍♂️"));450  check(SV(R"("hello 🤷🏻#####################)"), SV("{:#<30.9?}"), SV("hello 🤷🏻‍♂️"));451  check(SV(R"("hello 🤷🏻\####################)"), SV("{:#<30.10?}"), SV("hello 🤷🏻‍♂️"));452  check(SV(R"("hello 🤷🏻\u{200d}#############)"), SV("{:#<30.17?}"), SV("hello 🤷🏻‍♂️"));453  check(SV(R"("hello 🤷🏻\u{200d}♂️############)"), SV("{:#<30.18?}"), SV("hello 🤷🏻‍♂️"));454  check(SV(R"("hello 🤷🏻\u{200d}♂️"###########)"), SV("{:#<30.19?}"), SV("hello 🤷🏻‍♂️"));455}456 457template <class CharT>458void test() {459  test_char<CharT>();460  test_string<CharT>();461 462  test_format_functions<CharT>(test_format);463  test_format_functions<CharT>(test_format_to);464  test_format_functions<CharT>(test_formatted_size);465  test_format_functions<CharT>(test_format_to_n);466}467 468static void test_ill_formed_utf8() {469  using namespace std::literals;470 471  // Too few code units472  test_format(R"("\x{df}")"sv, "{:?}", "\xdf");473  test_format(R"("\x{ef}")"sv, "{:?}", "\xef");474  test_format(R"("\x{ef}\x{bf}")"sv, "{:?}", "\xef\xbf");475  test_format(R"("\x{f7}")"sv, "{:?}", "\xf7");476  test_format(R"("\x{f7}\x{bf}")"sv, "{:?}", "\xf7\xbf");477  test_format(R"("\x{f7}\x{bf}\x{bf}")"sv, "{:?}", "\xf7\xbf\xbf");478 479  // Invalid continuation byte480  test_format(R"("\x{df}a")"sv,481              "{:?}",482              "\xdf"483              "a");484  test_format(R"("\x{ef}a")"sv,485              "{:?}",486              "\xef"487              "a");488  test_format(R"("\x{ef}\x{bf}a")"sv,489              "{:?}",490              "\xef\xbf"491              "a");492  test_format(R"("\x{f7}a")"sv,493              "{:?}",494              "\xf7"495              "a");496  test_format(R"("\x{f7}\x{bf}a")"sv,497              "{:?}",498              "\xf7\xbf"499              "a");500  test_format(R"("\x{f7}\x{bf}\x{bf}a")"sv,501              "{:?}",502              "\xf7\xbf\xbf"503              "a");504 505  test_format(R"("a\x{f1}\x{80}\x{80}\x{e1}\x{80}\x{c2}b")"sv,506              "{:?}",507              "a"508              "\xf1\x80\x80\xe1\x80\xc2"509              "b");510 511  // Code unit out of range512  test_format(R"("\u{10ffff}")"sv, "{:?}", "\xf4\x8f\xbf\xbf");               // last valid code point513  test_format(R"("\x{f4}\x{90}\x{80}\x{80}")"sv, "{:?}", "\xf4\x90\x80\x80"); // first invalid code point514  test_format(R"("\x{f5}\x{b1}\x{b2}\x{b3}")"sv, "{:?}", "\xf5\xb1\xb2\xb3");515  test_format(R"("\x{f7}\x{bf}\x{bf}\x{bf}")"sv, "{:?}", "\xf7\xbf\xbf\xbf"); // largest encoded code point516}517 518#ifndef TEST_HAS_NO_WIDE_CHARACTERS519#  ifdef TEST_SHORT_WCHAR520static void test_ill_formed_utf16() {521  using namespace std::literals;522 523  // Too few code units524  test_format(LR"("\x{d800}")"sv, L"{:?}", L"\xd800");525  test_format(LR"("\x{dbff}")"sv, L"{:?}", L"\xdbff");526 527  // Start with low surrogate pair528  test_format(LR"("\x{dc00}a")"sv,529              L"{:?}",530              L"\xdc00"531              "a");532  test_format(LR"("\x{dfff}a")"sv,533              L"{:?}",534              L"\xdfff"535              "a");536 537  // Only high surrogate pair538  test_format(LR"("\x{d800}a")"sv,539              L"{:?}",540              L"\xd800"541              "a");542  test_format(LR"("\x{dbff}a")"sv,543              L"{:?}",544              L"\xdbff"545              "a");546}547#  else // TEST_SHORT_WCHAR548static void test_ill_formed_utf32() {549  using namespace std::literals;550 551  test_format(LR"("\u{10ffff}")"sv, L"{:?}", L"\x10ffff");     // last valid code point552  test_format(LR"("\x{110000}")"sv, L"{:?}", L"\x110000");     // first invalid code point553  test_format(LR"("\x{ffffffff}")"sv, L"{:?}", L"\xffffffff"); // largest encoded code point554}555 556#  endif // TEST_SHORT_WCHAR557#endif   // TEST_HAS_NO_WIDE_CHARACTERS558 559int main(int, char**) {560  test<char>();561#ifndef TEST_HAS_NO_WIDE_CHARACTERS562  test<wchar_t>();563#endif564 565  test_ill_formed_utf8();566#ifndef TEST_HAS_NO_WIDE_CHARACTERS567#  ifdef TEST_SHORT_WCHAR568  test_ill_formed_utf16();569#  else  // TEST_SHORT_WCHAR570  test_ill_formed_utf32();571#  endif // TEST_SHORT_WCHAR572#endif   // TEST_HAS_NO_WIDE_CHARACTERS573 574  return 0;575}576