From: Tomasz KamiƄski Date: Wed, 23 Jul 2025 09:33:22 +0000 (+0200) Subject: libstdc++: Expand compile-time ranges tests for vector and basic_string. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be6a864b25206dd85827c2960f38f36f49b38f31;p=thirdparty%2Fgcc.git libstdc++: Expand compile-time ranges tests for vector and basic_string. This replaces most test_constexpr invocations with direct calls to test_ranges(), which is also used for runtime tests. SimpleAllocator was made constexpr to simplify this refactoring. Other test allocators, like uneq_allocator (used in from_range constructor tests), were not updated. libstdc++-v3/ChangeLog: * testsuite/21_strings/basic_string/cons/from_range.cc: Replace test_constexpr with test_ranges inside static_assert. * testsuite/21_strings/basic_string/modifiers/append/append_range.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/assign/assign_range.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/insert/insert_range.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/replace/replace_with_range.cc: Likewise. * testsuite/23_containers/vector/bool/cons/from_range.cc: Likewise. * testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc: Likewise. * testsuite/23_containers/vector/bool/modifiers/insert/insert_range.cc: Likewise. * testsuite/23_containers/vector/cons/from_range.cc: Likewise. * testsuite/23_containers/vector/modifiers/assign/assign_range.cc: Likewise. * testsuite/23_containers/vector/modifiers/insert/insert_range.cc: Likewise. * testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc: Run full test_ranges instead of span-only in test_constexpr. * testsuite/23_containers/vector/modifiers/append_range.cc: Replace test_constexpr with calls to test_ranges and test_overlapping. * testsuite/util/testsuite_allocator.h (__gnu_test::SimpleAllocator): Declared member functions as constexpr. --- diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/from_range.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/from_range.cc index 6331050309ce..df9e4c35cf11 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/cons/from_range.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/from_range.cc @@ -73,16 +73,19 @@ do_test(Alloc alloc) } template -void +constexpr void do_test_a() { do_test(std::allocator()); - do_test(__gnu_test::uneq_allocator(42)); do_test(std::allocator()); - do_test(__gnu_test::uneq_allocator(42)); + + if not consteval { + do_test(__gnu_test::uneq_allocator(42)); + do_test(__gnu_test::uneq_allocator(42)); + } } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -101,9 +104,9 @@ test_ranges() // Not lvalue-convertible to char struct C { - C(char v) : val(v) { } - operator char() && { return val; } - bool operator==(char b) const { return b == val; } + constexpr C(char v) : val(v) { } + constexpr operator char() && { return val; } + constexpr bool operator==(char b) const { return b == val; } char val; }; using rvalue_input_range = test_range; @@ -112,18 +115,10 @@ test_ranges() return true; } -constexpr bool -test_constexpr() -{ -#if _GLIBCXX_USE_CXX11_ABI - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test(std::allocator()); -#endif // _GLIBCXX_USE_CXX11_ABI - return true; -} - int main() { test_ranges(); - static_assert( test_constexpr() ); +#if _GLIBCXX_USE_CXX11_ABI + static_assert( test_ranges() ); +#endif // _GLIBCXX_USE_CXX11_ABI } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/append_range.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/append_range.cc index 6c0bc0cab185..984db3640f94 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/append_range.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/append_range.cc @@ -49,7 +49,7 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); @@ -58,7 +58,7 @@ do_test_a() do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -77,9 +77,9 @@ test_ranges() // Not lvalue-convertible to char struct C { - C(char v) : val(v) { } - operator char() && { return val; } - bool operator==(char b) const { return b == val; } + constexpr C(char v) : val(v) { } + constexpr operator char() && { return val; } + constexpr bool operator==(char b) const { return b == val; } char val; }; using rvalue_input_range = test_range; @@ -107,19 +107,11 @@ test_overlapping() VERIFY( c == "1234abcd1234" ); } -constexpr bool -test_constexpr() -{ -#if _GLIBCXX_USE_CXX11_ABI - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test>(); -#endif // _GLIBCXX_USE_CXX11_ABI - return true; -} - int main() { test_ranges(); test_overlapping(); - static_assert( test_constexpr() ); +#if _GLIBCXX_USE_CXX11_ABI + static_assert( test_ranges() ); +#endif // _GLIBCXX_USE_CXX11_ABI } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/assign_range.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/assign_range.cc index 310c8bc0003b..aa1b329a5511 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/assign_range.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/assign_range.cc @@ -41,7 +41,7 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); @@ -50,7 +50,7 @@ do_test_a() do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -69,9 +69,9 @@ test_ranges() // Not lvalue-convertible to char struct C { - C(char v) : val(v) { } - operator char() && { return val; } - bool operator==(char b) const { return b == val; } + constexpr C(char v) : val(v) { } + constexpr operator char() && { return val; } + constexpr bool operator==(char b) const { return b == val; } char val; }; using rvalue_input_range = test_range; @@ -98,19 +98,11 @@ test_overlapping() VERIFY( c == "1234" ); } -constexpr bool -test_constexpr() -{ -#if _GLIBCXX_USE_CXX11_ABI - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test>(); -#endif // _GLIBCXX_USE_CXX11_ABI - return true; -} - int main() { test_ranges(); test_overlapping(); - static_assert( test_constexpr() ); +#if _GLIBCXX_USE_CXX11_ABI + static_assert( test_ranges() ); +#endif // _GLIBCXX_USE_CXX11_ABI } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/insert_range.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/insert_range.cc index 4fead3245d1f..c026fd4b8d81 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/insert_range.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/insert_range.cc @@ -54,7 +54,7 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); @@ -63,7 +63,7 @@ do_test_a() do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -82,9 +82,9 @@ test_ranges() // Not lvalue-convertible to char struct C { - C(char v) : val(v) { } - operator char() && { return val; } - bool operator==(char b) const { return b == val; } + constexpr C(char v) : val(v) { } + constexpr operator char() && { return val; } + constexpr bool operator==(char b) const { return b == val; } char val; }; using rvalue_input_range = test_range; @@ -112,19 +112,11 @@ test_overlapping() VERIFY( c == "12123434abcd" ); } -constexpr bool -test_constexpr() -{ -#if _GLIBCXX_USE_CXX11_ABI - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test>(); -#endif // _GLIBCXX_USE_CXX11_ABI - return true; -} - int main() { test_ranges(); test_overlapping(); - static_assert( test_constexpr() ); +#if _GLIBCXX_USE_CXX11_ABI + static_assert( test_ranges() ); +#endif // _GLIBCXX_USE_CXX11_ABI } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/replace/replace_with_range.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/replace/replace_with_range.cc index 9acf11ab5bdf..4c6bba5993ef 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/replace/replace_with_range.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/replace/replace_with_range.cc @@ -54,7 +54,7 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); @@ -63,7 +63,7 @@ do_test_a() do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -82,9 +82,9 @@ test_ranges() // Not lvalue-convertible to char struct C { - C(char v) : val(v) { } - operator char() && { return val; } - bool operator==(char b) const { return b == val; } + constexpr C(char v) : val(v) { } + constexpr operator char() && { return val; } + constexpr bool operator==(char b) const { return b == val; } char val; }; using rvalue_input_range = test_range; @@ -115,19 +115,11 @@ test_overlapping() VERIFY( c == "12123434abcd" ); } -constexpr bool -test_constexpr() -{ -#if _GLIBCXX_USE_CXX11_ABI - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test>(); -#endif // _GLIBCXX_USE_CXX11_ABI - return true; -} - int main() { test_ranges(); test_overlapping(); - static_assert( test_constexpr() ); +#if _GLIBCXX_USE_CXX11_ABI + static_assert( test_ranges() ); +#endif // _GLIBCXX_USE_CXX11_ABI } diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc index 339c06bd70e9..516d888b977a 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc @@ -42,14 +42,16 @@ do_test(Alloc alloc) } template -void +constexpr void do_test_a() { do_test(std::allocator()); - do_test(__gnu_test::uneq_allocator(42)); + if not consteval { + do_test(__gnu_test::uneq_allocator(42)); + } } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -71,9 +73,9 @@ test_ranges() // Not lvalue-convertible to bool struct C { - C(bool v) : val(v) { } - operator bool() && { return val; } - bool operator==(bool b) const { return b == val; } + constexpr C(bool v) : val(v) { } + constexpr operator bool() && { return val; } + constexpr bool operator==(bool b) const { return b == val; } bool val; }; using rvalue_input_range = test_range; @@ -82,16 +84,8 @@ test_ranges() return true; } -constexpr bool -test_constexpr() -{ - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test>(std::allocator()); - return true; -} - int main() { test_ranges(); - static_assert( test_constexpr() ); + static_assert( test_ranges() ); } diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc index 7e58700ff2bb..ced7efebc7cb 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc @@ -59,14 +59,14 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -88,9 +88,9 @@ test_ranges() // Not lvalue-convertible to bool struct C { - C(bool v) : val(v) { } - operator bool() && { return val; } - bool operator==(bool b) const { return b == val; } + constexpr C(bool v) : val(v) { } + constexpr operator bool() && { return val; } + constexpr bool operator==(bool b) const { return b == val; } bool val; }; using rvalue_input_range = test_range; @@ -99,16 +99,8 @@ test_ranges() return true; } -constexpr bool -test_constexpr() -{ - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test, std::allocator>(); - return true; -} - int main() { test_ranges(); - static_assert( test_constexpr() ); + static_assert( test_ranges() ); } diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc index 43a698f65c41..c2e218653a82 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc @@ -38,14 +38,14 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -67,9 +67,9 @@ test_ranges() // Not lvalue-convertible to bool struct C { - C(bool v) : val(v) { } - operator bool() && { return val; } - bool operator==(bool b) const { return b == val; } + constexpr C(bool v) : val(v) { } + constexpr operator bool() && { return val; } + constexpr bool operator==(bool b) const { return b == val; } bool val; }; using rvalue_input_range = test_range; @@ -81,8 +81,7 @@ test_ranges() constexpr bool test_constexpr() { - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test, std::allocator>(); + test_ranges(); // Some basic tests for overlapping ranges in constant expressions. using I = std::vector::iterator; diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/insert_range.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/insert_range.cc index 5c65610667d5..2ec91b07ce78 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/insert_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/insert/insert_range.cc @@ -55,14 +55,14 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -84,9 +84,9 @@ test_ranges() // Not lvalue-convertible to bool struct C { - C(bool v) : val(v) { } - operator bool() && { return val; } - bool operator==(bool b) const { return b == val; } + constexpr C(bool v) : val(v) { } + constexpr operator bool() && { return val; } + constexpr bool operator==(bool b) const { return b == val; } bool val; }; using rvalue_input_range = test_range; @@ -95,16 +95,8 @@ test_ranges() return true; } -constexpr bool -test_constexpr() -{ - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test, std::allocator>(); - return true; -} - int main() { test_ranges(); - static_assert( test_constexpr() ); + static_assert( test_ranges() ); } diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc index 3784b9cd66ad..be3e69928903 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc @@ -58,14 +58,16 @@ do_test(Alloc alloc) } template -void +constexpr void do_test_a() { do_test(std::allocator()); - do_test(__gnu_test::uneq_allocator(42)); + if not consteval { + do_test(__gnu_test::uneq_allocator(42)); + } } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -87,9 +89,9 @@ test_ranges() // Not lvalue-convertible to int struct C { - C(int v) : val(v) { } - operator int() && { return val; } - bool operator==(int b) const { return b == val; } + constexpr C(int v) : val(v) { } + constexpr operator int() && { return val; } + constexpr bool operator==(int b) const { return b == val; } int val; }; using rvalue_input_range = test_range; @@ -98,14 +100,6 @@ test_ranges() return true; } -constexpr bool -test_constexpr() -{ - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test>(std::allocator()); - return true; -} - void test_pr120367() { @@ -130,6 +124,6 @@ test_pr120367() int main() { test_ranges(); - static_assert( test_constexpr() ); + static_assert( test_ranges() ); test_pr120367(); } diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc index be097e2b1310..f5b21df9360d 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc @@ -42,14 +42,14 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -71,9 +71,9 @@ test_ranges() // Not lvalue-convertible to int struct C { - C(int v) : val(v) { } - operator int() && { return val; } - bool operator==(int b) const { return b == val; } + constexpr C(int v) : val(v) { } + constexpr operator int() && { return val; } + constexpr bool operator==(int b) const { return b == val; } int val; }; using rvalue_input_range = test_range; @@ -82,7 +82,7 @@ test_ranges() return true; } -void +constexpr void test_overlapping() { using __gnu_test::test_input_range; @@ -199,64 +199,14 @@ test_overlapping() } } -constexpr bool -test_constexpr() +int main() { - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test, std::allocator>(); - - // Some basic tests for overlapping ranges in constant expressions. - struct InputRange - { - struct Sent { const void* end; }; - - struct Iter - { - using value_type = int; - using difference_type = int; - constexpr explicit Iter(int* p) : ptr(p) { } - constexpr Iter& operator++() { ++ptr; return *this; } - constexpr Iter operator++(int) { auto i = *this; ++ptr; return i; } - constexpr int operator*() const { return *ptr; } - constexpr bool operator==(const Iter&) const = default; - constexpr bool operator==(const Sent& s) const { return ptr == s.end; } - int* ptr; - }; - - Iter iter; - Sent sent; - - constexpr InputRange(int* f, int* l) : iter{f}, sent{l} { } - constexpr Iter begin() const { return iter; } - constexpr Sent end() const { return sent; } + auto test_all = [] { + test_ranges(); + test_overlapping(); + return true; }; - static_assert( std::ranges::input_range ); - static_assert( ! std::ranges::forward_range ); - - std::vector vec(5); - - // Test overlapping input ranges - vec.resize(vec.capacity()); - vec.append_range(InputRange(vec.data(), vec.data() + 3)); // no capacity - vec.reserve(vec.capacity() + 2); - vec.append_range(InputRange(vec.data(), vec.data() + 4)); // some capacity - vec.reserve(vec.capacity() + 6); - vec.append_range(InputRange(vec.data(), vec.data() + 5)); // enough capacity - - // Test overlapping forward ranges - vec.resize(vec.capacity()); - vec.append_range(std::span(vec)); // no capacity - vec.reserve(vec.size() + 2); - vec.append_range(std::span(vec).subspan(1, 4)); // some capacity - vec.reserve(vec.size() + 6); - vec.append_range(std::span(vec).subspan(1, 5)); // enough capacity - return true; -} - -int main() -{ - test_ranges(); - test_overlapping(); - static_assert( test_constexpr() ); + test_all(); + static_assert( test_all() ); } diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc index db3b06cfbc06..26d33bcf9811 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc @@ -63,14 +63,14 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -92,9 +92,9 @@ test_ranges() // Not lvalue-convertible to int struct C { - C(int v) : val(v) { } - operator int() && { return val; } - bool operator==(int b) const { return b == val; } + constexpr C(int v) : val(v) { } + constexpr operator int() && { return val; } + constexpr bool operator==(int b) const { return b == val; } int val; }; using rvalue_input_range = test_range; @@ -103,16 +103,8 @@ test_ranges() return true; } -constexpr bool -test_constexpr() -{ - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test, std::allocator>(); - return true; -} - int main() { test_ranges(); - static_assert( test_constexpr() ); + static_assert( test_ranges() ); } diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc index 590714351267..506bebbe519e 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc @@ -59,14 +59,14 @@ do_test() } template -void +constexpr void do_test_a() { do_test>(); do_test>(); } -bool +constexpr bool test_ranges() { using namespace __gnu_test; @@ -88,9 +88,9 @@ test_ranges() // Not lvalue-convertible to int struct C { - C(int v) : val(v) { } - operator int() && { return val; } - bool operator==(int b) const { return b == val; } + constexpr C(int v) : val(v) { } + constexpr operator int() && { return val; } + constexpr bool operator==(int b) const { return b == val; } int val; }; using rvalue_input_range = test_range; @@ -99,16 +99,8 @@ test_ranges() return true; } -constexpr bool -test_constexpr() -{ - // XXX: this doesn't test the non-forward_range code paths are constexpr. - do_test, std::allocator>(); - return true; -} - int main() { test_ranges(); - static_assert( test_constexpr() ); + static_assert( test_ranges() ); } diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h index e5ffad2ba587..ee9575266a00 100644 --- a/libstdc++-v3/testsuite/util/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h @@ -517,19 +517,24 @@ namespace __gnu_test constexpr SimpleAllocator() noexcept { } template + constexpr SimpleAllocator(const SimpleAllocator&) { } + _GLIBCXX20_CONSTEXPR Tp *allocate(std::size_t n) { return std::allocator().allocate(n); } + _GLIBCXX20_CONSTEXPR void deallocate(Tp *p, std::size_t n) { std::allocator().deallocate(p, n); } }; template + constexpr bool operator==(const SimpleAllocator&, const SimpleAllocator&) { return true; } template + constexpr bool operator!=(const SimpleAllocator&, const SimpleAllocator&) { return false; }