aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/std/text_encoding/members.cc
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();
}