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