blob: 253653250c8aee437e106cddc674695d6144bb71 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
// { dg-options "-lstdc++exp" }
// { dg-do run { target c++26 } }
// { dg-require-namedlocale "en_US.ISO8859-1" }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
#include <text_encoding>
#include <string_view>
#include <locale.h>
#include <testsuite_hooks.h>
using namespace std::string_view_literals;
void
test_literal()
{
const std::text_encoding lit = std::text_encoding::literal();
VERIFY( lit.name() == std::string_view(__GNUC_EXECUTION_CHARSET_NAME) );
}
void
test_env()
{
const std::text_encoding env = std::text_encoding::environment();
if (env.mib() == std::text_encoding::UTF8)
VERIFY( std::text_encoding::environment_is<std::text_encoding::UTF8>() );
::setlocale(LC_ALL, ISO_8859(1, en_US));
const std::text_encoding env1 = std::text_encoding::environment();
VERIFY( env1 == env );
::setlocale(LC_ALL, ISO_8859(15, fr_FR));
const std::text_encoding env2 = std::text_encoding::environment();
VERIFY( env2 == env );
}
void
test_every_id()
{
for (int i = 0; i <= 2260; ++i)
{
std::text_encoding::id mib{i};
switch (i)
{
case 0:
case 33 ... 34:
case 107 ... 108:
case 120 ... 999:
case 1022 ... 1999:
case 2110 ... 2249:
// These do not correspond to an enumerator of std::text_encoding::id
// so are not valid arguments to the constructor. Without assertions
// enabled, we map bad IDs to id::unknown as a libstdc++ extension.
#ifndef _GLIBCXX_ASSERTIONS
{
std::text_encoding bad{mib};
VERIFY( bad.mib() == std::text_encoding::unknown );
VERIFY( bad.name() == ""sv );
}
#endif
continue;
}
std::text_encoding enc{mib};
auto aliases = enc.aliases();
if (i == 1 || i == 2)
VERIFY( enc.name() == ""sv );
else
VERIFY( enc.name() == std::string_view(aliases.front()) );
auto begin = aliases.begin();
auto end = aliases.end();
VERIFY( (begin + std::ranges::distance(aliases)) == end );
#ifndef _GLIBCXX_ASSERTIONS
// These ops violate preconditions, but as libstdc++ extensions they are
// guaranteed to either assert or have well-defined behaviour.
// This erroneously returns ""sv:
VERIFY( begin[std::ranges::distance(aliases)] == ""sv );
// Likewise:
VERIFY( begin[999999] == ""sv );
auto iter = begin;
std::ranges::advance(iter, end);
// Erroneously sets iter to a value-initialized state.
++iter;
VERIFY( iter == decltype(iter){} );
VERIFY( *iter == ""sv );
iter = begin;
// Erroneously sets iter to a value-initialized state.
--iter;
VERIFY( iter == decltype(iter){} );
#endif
}
}
int main()
{
test_literal();
test_env();
test_every_id();
}
|