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
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 // XFAIL: availability-fp_to_chars-missing
19 // P2572R1 std::format fill character allowances
20 // adds support for Unicode Scalar Values as fill character.
24 #include "assert_macros.h"
25 #include "concat_macros.h"
26 #include "format.functions.common.h"
27 #include "make_string.h"
28 #include "string_literal.h"
29 #include "test_format_string.h"
30 #include "test_macros.h"
32 #define SV(S) MAKE_STRING_VIEW(CharT, S)
34 auto check
= []<class CharT
, class... Args
>(
35 std::basic_string_view
<CharT
> expected
, test_format_string
<CharT
, Args
...> fmt
, Args
&&... args
) {
36 std::basic_string
<CharT
> out
= std::format(fmt
, std::forward
<Args
>(args
)...);
37 TEST_REQUIRE(out
== expected
,
38 TEST_WRITE_CONCATENATED(
39 "\nFormat string ", fmt
.get(), "\nExpected output ", expected
, "\nActual output ", out
, '\n'));
42 auto check_exception
=
43 []<class CharT
, class... Args
>(
44 [[maybe_unused
]] std::string_view what
,
45 [[maybe_unused
]] std::basic_string_view
<CharT
> fmt
,
46 [[maybe_unused
]] Args
&&... args
) {
47 TEST_VALIDATE_EXCEPTION(
49 [&]([[maybe_unused
]] const std::format_error
& e
) {
52 TEST_WRITE_CONCATENATED(
53 "\nFormat string ", fmt
, "\nExpected exception ", what
, "\nActual exception ", e
.what(), '\n'));
55 TEST_IGNORE_NODISCARD
std::vformat(fmt
, std::make_format_args
<context_t
<CharT
>>(args
...)));
58 template <class CharT
>
60 // 1, 2, 3, 4 code unit UTF-8 transitions
61 check(SV("\u000042\u0000"), SV("{:\u0000^4}"), 42);
62 check(SV("\u007f42\u007f"), SV("{:\u007f^4}"), 42);
63 check(SV("\u008042\u0080"), SV("{:\u0080^4}"), 42);
64 check(SV("\u07ff42\u07ff"), SV("{:\u07ff^4}"), 42);
65 check(SV("\u080042\u0800"), SV("{:\u0800^4}"), 42);
66 check(SV("\uffff42\uffff"), SV("{:\uffff^4}"), 42);
67 check(SV("\U0010000042\U00100000"), SV("{:\U00100000^4}"), 42);
68 check(SV("\U0010ffff42\U0010ffff"), SV("{:\U0010ffff^4}"), 42);
70 // Examples of P2572R1
71 check(SV("🤡🤡x🤡🤡🤡"), SV("{:🤡^6}"), SV("x"));
72 check(SV("🤡🤡🤡"), SV("{:*^6}"), SV("🤡🤡🤡"));
73 check(SV("12345678"), SV("{:*>6}"), SV("12345678"));
75 // Invalid Unicode Scalar Values
76 if constexpr (std::same_as
<CharT
, char>) {
77 check_exception("The format specifier contains malformed Unicode characters", SV("{:\xed\xa0\x80^}"), 42); // U+D800
78 check_exception("The format specifier contains malformed Unicode characters", SV("{:\xed\xa0\xbf^}"), 42); // U+DBFF
79 check_exception("The format specifier contains malformed Unicode characters", SV("{:\xed\xbf\x80^}"), 42); // U+DC00
80 check_exception("The format specifier contains malformed Unicode characters", SV("{:\xed\xbf\xbf^}"), 42); // U+DFFF
83 "The format specifier contains malformed Unicode characters", SV("{:\xf4\x90\x80\x80^}"), 42); // U+110000
85 "The format specifier contains malformed Unicode characters", SV("{:\xf4\x90\xbf\xbf^}"), 42); // U+11FFFF
87 check_exception("The format specifier contains malformed Unicode characters",
89 42); // Trailing code unit with no leading one.
90 check_exception("The format specifier contains malformed Unicode characters",
92 42); // Missing trailing code unit.
93 check_exception("The format specifier contains malformed Unicode characters",
95 42); // Missing trailing code unit.
96 check_exception("The format specifier contains malformed Unicode characters",
98 42); // Missing two trailing code units.
99 check_exception("The format specifier contains malformed Unicode characters",
100 SV("{:\xf0\x80\x80^}"),
101 42); // Missing trailing code unit.
103 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
105 # ifdef TEST_SHORT_WCHAR
106 check_exception("The format specifier contains malformed Unicode characters", std::wstring_view
{L
"{:\xd800^}"}, 42);
107 check_exception("The format specifier contains malformed Unicode characters", std::wstring_view
{L
"{:\xdbff^}"}, 42);
108 check_exception("The format specifier contains malformed Unicode characters", std::wstring_view
{L
"{:\xdc00^}"}, 42);
109 check_exception("The format specifier contains malformed Unicode characters", std::wstring_view
{L
"{:\xddff^}"}, 42);
111 check_exception("The format specifier contains malformed Unicode characters",
112 std::wstring_view
{L
"{:\xdc00\xd800^}"},
113 42); // Reverted surrogates.
115 # else // TEST_SHORT_WCHAR
116 check_exception("The fill option contains an invalid value", std::wstring_view
{L
"{:\xd800^}"}, 42);
117 check_exception("The fill option contains an invalid value", std::wstring_view
{L
"{:\xdbff^}"}, 42);
118 check_exception("The fill option contains an invalid value", std::wstring_view
{L
"{:\xdc00^}"}, 42);
119 check_exception("The fill option contains an invalid value", std::wstring_view
{L
"{:\xddff^}"}, 42);
122 "The format specifier should consume the input or end with a '}'", std::wstring_view
{L
"{:\xdc00\xd800^}"}, 42);
124 check_exception("The fill option contains an invalid value", std::wstring_view
{L
"{:\x00110000^}"}, 42);
125 check_exception("The fill option contains an invalid value", std::wstring_view
{L
"{:\x0011ffff^}"}, 42);
126 # endif // TEST_SHORT_WCHAR
127 #endif // TEST_HAS_NO_WIDE_CHARACTERS
131 int main(int, char**) {
134 #ifndef TEST_HAS_NO_WIDE_CHARACTERS