[PATCH] libstdc++: Expand compile-time ranges tests for vector and basic_string.
Patrick Palka
ppalka@redhat.com
Thu Jul 24 13:09:06 GMT 2025
On Wed, 23 Jul 2025, Tomasz Kamiński wrote:
> 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 from test_constexpr.
> * testsuite/23_containers/vector/modifiers/append_range.cc:
> Replace test_constexpr with calls to test_ranges/test_overlapping.
> * testsuite/util/testsuite_allocator.h (__gnu_tests::SimpleAllocator):
__gnu_test
LGTM
> Declared member functions as constexpr.
> ---
> Tested on x86_64 linux locally. basic_string view also tested with
> -D_GLIBCXX_USE_CXX11_ABI=0 and -D_GLIBCXX_DEBUG.
>
> .../basic_string/cons/from_range.cc | 31 ++++----
> .../modifiers/append/append_range.cc | 24 ++----
> .../modifiers/assign/assign_range.cc | 24 ++----
> .../modifiers/insert/insert_range.cc | 24 ++----
> .../modifiers/replace/replace_with_range.cc | 24 ++----
> .../vector/bool/cons/from_range.cc | 24 +++---
> .../bool/modifiers/assign/assign_range.cc | 20 ++---
> .../bool/modifiers/insert/append_range.cc | 13 ++--
> .../bool/modifiers/insert/insert_range.cc | 20 ++---
> .../23_containers/vector/cons/from_range.cc | 24 +++---
> .../vector/modifiers/append_range.cc | 76 ++++---------------
> .../vector/modifiers/assign/assign_range.cc | 20 ++---
> .../vector/modifiers/insert/insert_range.cc | 20 ++---
> .../testsuite/util/testsuite_allocator.h | 5 ++
> 14 files changed, 111 insertions(+), 238 deletions(-)
>
> 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 6331050309c..df9e4c35cf1 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range>(std::allocator<char>());
> - do_test<Range>(__gnu_test::uneq_allocator<char>(42));
> do_test<Range>(std::allocator<wchar_t>());
> - do_test<Range>(__gnu_test::uneq_allocator<wchar_t>(42));
> +
> + if not consteval {
> + do_test<Range>(__gnu_test::uneq_allocator<char>(42));
> + do_test<Range>(__gnu_test::uneq_allocator<wchar_t>(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<C, input_iterator_wrapper_rval>;
> @@ -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::string_view>(std::allocator<char>());
> -#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 6c0bc0cab18..984db3640f9 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<char>>();
> @@ -58,7 +58,7 @@ do_test_a()
> do_test<Range, __gnu_test::SimpleAllocator<wchar_t>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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<std::string_view, std::allocator<char>>();
> -#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 310c8bc0003..aa1b329a551 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<char>>();
> @@ -50,7 +50,7 @@ do_test_a()
> do_test<Range, __gnu_test::SimpleAllocator<wchar_t>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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<std::string_view, std::allocator<char>>();
> -#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 4fead3245d1..c026fd4b8d8 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<char>>();
> @@ -63,7 +63,7 @@ do_test_a()
> do_test<Range, __gnu_test::SimpleAllocator<wchar_t>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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<std::string_view, std::allocator<char>>();
> -#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 9acf11ab5bd..4c6bba5993e 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<char>>();
> @@ -63,7 +63,7 @@ do_test_a()
> do_test<Range, __gnu_test::SimpleAllocator<wchar_t>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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<std::string_view, std::allocator<char>>();
> -#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 339c06bd70e..516d888b977 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range>(std::allocator<bool>());
> - do_test<Range>(__gnu_test::uneq_allocator<bool>(42));
> + if not consteval {
> + do_test<Range>(__gnu_test::uneq_allocator<bool>(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<C, input_iterator_wrapper_rval>;
> @@ -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::span<bool>>(std::allocator<bool>());
> - 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 7e58700ff2b..ced7efebc7c 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<bool>>();
> do_test<Range, __gnu_test::SimpleAllocator<bool>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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::span<short>, std::allocator<bool>>();
> - 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 43a698f65c4..c2e218653a8 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<bool>>();
> do_test<Range, __gnu_test::SimpleAllocator<bool>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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::span<short>, std::allocator<bool>>();
> + test_ranges();
>
> // Some basic tests for overlapping ranges in constant expressions.
> using I = std::vector<bool>::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 5c65610667d..2ec91b07ce7 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<bool>>();
> do_test<Range, __gnu_test::SimpleAllocator<bool>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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::span<bool>, std::allocator<bool>>();
> - 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 3784b9cd66a..be3e6992890 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range>(std::allocator<int>());
> - do_test<Range>(__gnu_test::uneq_allocator<int>(42));
> + if not consteval {
> + do_test<Range>(__gnu_test::uneq_allocator<int>(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<C, input_iterator_wrapper_rval>;
> @@ -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::span<short>>(std::allocator<int>());
> - 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 be097e2b131..f5b21df9360 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<int>>();
> do_test<Range, __gnu_test::SimpleAllocator<int>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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::span<short>, std::allocator<int>>();
> -
> - // 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<InputRange> );
> - static_assert( ! std::ranges::forward_range<InputRange> );
> -
> - std::vector<int> 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<int>(vec)); // no capacity
> - vec.reserve(vec.size() + 2);
> - vec.append_range(std::span<int>(vec).subspan(1, 4)); // some capacity
> - vec.reserve(vec.size() + 6);
> - vec.append_range(std::span<int>(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 db3b06cfbc0..26d33bcf981 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<int>>();
> do_test<Range, __gnu_test::SimpleAllocator<int>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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::span<short>, std::allocator<int>>();
> - 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 59071435126..506bebbe519 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<typename Range>
> -void
> +constexpr void
> do_test_a()
> {
> do_test<Range, std::allocator<int>>();
> do_test<Range, __gnu_test::SimpleAllocator<int>>();
> }
>
> -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<C, input_iterator_wrapper_rval>;
> @@ -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::span<short>, std::allocator<int>>();
> - 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 e5ffad2ba58..ee9575266a0 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 <class T>
> + constexpr
> SimpleAllocator(const SimpleAllocator<T>&) { }
>
> + _GLIBCXX20_CONSTEXPR
> Tp *allocate(std::size_t n)
> { return std::allocator<Tp>().allocate(n); }
>
> + _GLIBCXX20_CONSTEXPR
> void deallocate(Tp *p, std::size_t n)
> { std::allocator<Tp>().deallocate(p, n); }
> };
>
> template <class T, class U>
> + constexpr
> bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&)
> { return true; }
> template <class T, class U>
> + constexpr
> bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&)
> { return false; }
>
> --
> 2.49.0
>
>
More information about the Libstdc++
mailing list