libstdc++: Fix Unicode property detection functions
[official-gcc.git] / libstdc++-v3 / testsuite / ext / unicode / view.cc
blob79ea2bbc6b7e935ff731f0a2286a9b8d0342b207
1 // { dg-do run { target c++20 } }
2 #include <format>
3 #include <string_view>
4 #include <ranges>
5 #include <testsuite_hooks.h>
7 namespace uc = std::__unicode;
8 using namespace std::string_view_literals;
10 constexpr void
11 test_utf8_to_utf8()
13 const std::u8string_view s8 = u8"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡";
14 uc::_Utf8_view v(s8);
15 VERIFY( std::ranges::distance(v) == s8.size() );
16 VERIFY( std::ranges::equal(v, s8) );
19 constexpr void
20 test_utf8_to_utf16()
22 const std::u8string_view s8 = u8"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡";
23 const std::u16string_view s16 = u"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡";
24 uc::_Utf16_view v(s8);
25 VERIFY( std::ranges::distance(v) == s16.size() );
26 VERIFY( std::ranges::equal(v, s16) );
29 constexpr void
30 test_utf8_to_utf32()
32 const auto s8 = u8"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡"sv;
33 const auto s32 = U"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡"sv;
34 uc::_Utf32_view v(s8);
35 VERIFY( std::ranges::distance(v) == s32.size() );
36 VERIFY( std::ranges::equal(v, s32) );
39 constexpr void
40 test_illformed_utf8()
42 uc::_Utf32_view v("\xa3 10.99 \xee \xdd"sv);
43 VERIFY( std::ranges::equal(v, U"\uFFFD 10.99 \uFFFD \uFFFD"sv) );
45 uc::_Utf16_view v2(" \xf8\x80\x80\x80 "sv);
46 VERIFY( std::ranges::distance(v2) == 6 );
47 VERIFY( std::ranges::equal(v2, U" \uFFFD\uFFFD\uFFFD\uFFFD "sv) );
49 // Examples of U+FFFD substitution from Unicode standard.
50 uc::_Utf8_view v3("\xc0\xaf\xe0\x80\xbf\xf0\x81\x82\x41"sv); // Table 3-8
51 VERIFY( std::ranges::equal(v3, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv) );
52 uc::_Utf8_view v4("\xed\xa0\x80\xed\xbf\xbf\xed\xaf\x41"sv); // Table 3-9
53 VERIFY( std::ranges::equal(v4, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv) );
54 uc::_Utf8_view v5("\xf4\x91\x92\x93\xff\x41\x80\xbf\x42"sv); // Table 3-10
55 VERIFY( std::ranges::equal(v5, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41\uFFFD\uFFFD\x42"sv) );
56 uc::_Utf8_view v6("\xe1\x80\xe2\xf0\x91\x92\xf1\xbf\x41"sv); // Table 3-11
57 VERIFY( std::ranges::equal(v6, u8"\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv) );
60 constexpr void
61 test_illformed_utf16()
63 std::u16string_view s = u"\N{CLOWN FACE}";
64 std::u16string_view r = u"\uFFFD";
65 VERIFY( std::ranges::equal(uc::_Utf16_view(s.substr(0, 1)), r) );
66 VERIFY( std::ranges::equal(uc::_Utf16_view(s.substr(1, 1)), r) );
67 std::array s2{ s[0], s[0] };
68 VERIFY( std::ranges::equal(uc::_Utf16_view(s2), u"\uFFFD\uFFFD"sv) );
69 std::array s3{ s[0], s[0], s[1] };
70 VERIFY( std::ranges::equal(uc::_Utf16_view(s3), u"\uFFFD\N{CLOWN FACE}"sv) );
71 std::array s4{ s[1], s[0] };
72 VERIFY( std::ranges::equal(uc::_Utf16_view(s4), u"\uFFFD\uFFFD"sv) );
73 std::array s5{ s[1], s[0], s[1] };
74 VERIFY( std::ranges::equal(uc::_Utf16_view(s5), u"\uFFFD\N{CLOWN FACE}"sv) );
77 constexpr void
78 test_illformed_utf32()
80 std::u32string_view s = U"\x110000";
81 VERIFY( std::ranges::equal(uc::_Utf32_view(s), U"\uFFFD"sv) );
82 s = U"\xFFFFFF";
83 VERIFY( std::ranges::equal(uc::_Utf32_view(s), U"\uFFFD"sv) );
84 s = U"\xFFFFFFF0";
85 VERIFY( std::ranges::equal(uc::_Utf32_view(s), U"\uFFFD"sv) );
88 constexpr void
89 test_past_the_end()
91 const auto s8 = u8"1234"sv;
92 uc::_Utf32_view v(s8);
93 auto iter = v.begin();
94 std::advance(iter, 4);
95 VERIFY( iter == v.end() );
96 // Incrementing past the end has well-defined behaviour.
97 ++iter;
98 VERIFY( iter == v.end() );
99 VERIFY( *iter == U'4' ); // Still dereferenceable.
100 ++iter;
101 VERIFY( iter == v.end() );
102 VERIFY( *iter == U'4' );
103 iter++;
104 VERIFY( iter == v.end() );
105 VERIFY( *iter == U'4' );
107 std::string_view empty;
108 uc::_Utf32_view v2(empty);
109 auto iter2 = v2.begin();
110 VERIFY( iter2 == v2.end() );
111 VERIFY( *iter2 == U'\0' );
112 iter++;
113 VERIFY( iter2 == v2.end() );
114 VERIFY( *iter2 == U'\0' );
117 int main()
119 auto run_tests = []{
120 test_utf8_to_utf8();
121 test_utf8_to_utf16();
122 test_utf8_to_utf32();
123 test_illformed_utf8();
124 test_illformed_utf16();
125 test_illformed_utf32();
126 test_past_the_end();
127 return true;
130 VERIFY( run_tests() );
131 static_assert( run_tests() );