| // { 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(); |
| } |