aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/testsuite')
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc4
-rw-r--r--libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc129
-rw-r--r--libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc27
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/atomic/pr118757.cc1
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc17
-rw-r--r--libstdc++-v3/testsuite/20_util/weak_ptr/pr118757.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc121
-rw-r--r--libstdc++-v3/testsuite/26_numerics/valarray/108951.cc22
-rw-r--r--libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc3
-rw-r--r--libstdc++-v3/testsuite/30_threads/future/members/116586.cc3
-rw-r--r--libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/116586.cc3
-rw-r--r--libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc29
-rw-r--r--libstdc++-v3/testsuite/30_threads/thread/swap/1.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/116586.cc3
-rw-r--r--libstdc++-v3/testsuite/ext/iotaarray.cc20
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_iterators.h3
16 files changed, 372 insertions, 16 deletions
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc
index cd576ca..350a548 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-std=gnu++11" }
+// { dg-add-options no_pch }
// Copyright (C) 2009-2025 Free Software Foundation, Inc.
//
@@ -19,4 +19,4 @@
// <http://www.gnu.org/licenses/>.
// libstdc++/42319
-#include <bits/char_traits.h>
+#include <ios>
diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc
new file mode 100644
index 0000000..d8cb181
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc
@@ -0,0 +1,129 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <type_traits>
+
+#ifndef __cpp_lib_is_implicit_lifetime
+# error "Feature test macro for is_implicit_lifetime is missing in <type_traits>"
+#elif __cpp_lib_is_implicit_lifetime < 202302L
+# error "Feature test macro for is_implicit_lifetime has wrong value in <type_traits>"
+#endif
+
+#include <testsuite_tr1.h>
+
+template<typename T>
+ concept Is_implicit_lifetime
+ = __gnu_test::test_category<std::is_implicit_lifetime, T>(true);
+
+static_assert( ! Is_implicit_lifetime<void> );
+static_assert( ! Is_implicit_lifetime<const void> );
+static_assert( ! Is_implicit_lifetime<volatile void> );
+static_assert( Is_implicit_lifetime<char> );
+static_assert( Is_implicit_lifetime<signed char> );
+static_assert( Is_implicit_lifetime<const unsigned char> );
+static_assert( Is_implicit_lifetime<short> );
+static_assert( Is_implicit_lifetime<volatile unsigned short> );
+static_assert( Is_implicit_lifetime<int> );
+static_assert( Is_implicit_lifetime<unsigned int> );
+static_assert( Is_implicit_lifetime<const volatile long> );
+static_assert( Is_implicit_lifetime<unsigned long> );
+static_assert( Is_implicit_lifetime<long long> );
+static_assert( Is_implicit_lifetime<unsigned long long> );
+static_assert( Is_implicit_lifetime<float> );
+static_assert( Is_implicit_lifetime<double> );
+static_assert( Is_implicit_lifetime<long double volatile> );
+enum W { W1 };
+static_assert( Is_implicit_lifetime<W> );
+enum class X : int { X1 };
+static_assert( Is_implicit_lifetime<const volatile X> );
+static_assert( Is_implicit_lifetime<int *> );
+static_assert( Is_implicit_lifetime<int (*) (int)> );
+struct Y { int g; int foo (int); };
+static_assert( Is_implicit_lifetime<int (Y::*)> );
+static_assert( Is_implicit_lifetime<int (Y::*) (int)> );
+static_assert( ! Is_implicit_lifetime<int &> );
+static_assert( ! Is_implicit_lifetime<char &&> );
+static_assert( Is_implicit_lifetime<int []> );
+static_assert( Is_implicit_lifetime<int [1]> );
+static_assert( Is_implicit_lifetime<const Y [42]> );
+static_assert( ! Is_implicit_lifetime<int ()> );
+static_assert( ! Is_implicit_lifetime<int () &> );
+static_assert( ! Is_implicit_lifetime<int () const> );
+static_assert( ! Is_implicit_lifetime<int (&) ()> );
+struct Z;
+static_assert( Is_implicit_lifetime<Z []> );
+static_assert( Is_implicit_lifetime<Z [5]> );
+struct A { int a, b, c; };
+static_assert( Is_implicit_lifetime<A> );
+class B { static int a; private: static int b; public: int c; };
+static_assert( Is_implicit_lifetime<B> );
+struct C { C () {} int a, b, c; };
+static_assert( Is_implicit_lifetime<C> );
+struct D { explicit D (int) {} int a, b, c; };
+static_assert( Is_implicit_lifetime<D> );
+struct E : public A { int d, e, f; };
+static_assert( Is_implicit_lifetime<E> );
+struct F : public C { using C::C; int d, e, f; };
+static_assert( Is_implicit_lifetime<F> );
+class G { int a, b; };
+static_assert( Is_implicit_lifetime<G> );
+struct H { private: int a, b; };
+static_assert( Is_implicit_lifetime<H> );
+struct I { protected: int a, b; };
+static_assert( Is_implicit_lifetime<I> );
+struct J { int a, b; void foo (); };
+static_assert( Is_implicit_lifetime<J> );
+struct K { int a, b; virtual void foo (); };
+static_assert( ! Is_implicit_lifetime<K> );
+struct L : virtual public A { int d, e; };
+static_assert( ! Is_implicit_lifetime<L> );
+struct M : protected A { int d, e; };
+static_assert( Is_implicit_lifetime<M> );
+struct N : private A { int d, e; };
+static_assert( Is_implicit_lifetime<N> );
+struct O { O () = delete; int a, b, c; };
+static_assert( Is_implicit_lifetime<O> );
+struct P { P () = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<P> );
+struct Q { Q (); Q (const Q &); int a, b, c; };
+static_assert( ! Is_implicit_lifetime<Q> );
+struct R { R (); R (const R &); R (R &&) = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<R> );
+struct S { S (); ~S (); int a, b, c; };
+static_assert( ! Is_implicit_lifetime<S> );
+static_assert( Is_implicit_lifetime<S [3]> );
+struct T { T (); ~T () = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<T> );
+struct U { U (); U (const U &) = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<U> );
+struct V { V () = default; V (const V &); int a, b, c; };
+static_assert( Is_implicit_lifetime<V> );
+struct AA { Q a; Q b; };
+static_assert( Is_implicit_lifetime<AA> );
+struct AB { Q a; Q b; ~AB () = default; };
+static_assert( Is_implicit_lifetime<AB> );
+struct AC { Q a; Q b; ~AC () {} };
+static_assert( ! Is_implicit_lifetime<AC> );
+struct AD : public Q {};
+static_assert( Is_implicit_lifetime<AD> );
+struct AE : public Q { ~AE () = default; };
+static_assert( Is_implicit_lifetime<AE> );
+struct AF : public Q { ~AF () {} };
+static_assert( ! Is_implicit_lifetime<AF> );
diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc
new file mode 100644
index 0000000..ed90b47
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <version>
+
+#ifndef __cpp_lib_is_implicit_lifetime
+# error "Feature test macro for is_implicit_lifetime is missing in <version>"
+#elif __cpp_lib_is_implicit_lifetime < 202302L
+# error "Feature test macro for is_implicit_lifetime has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/pr118757.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/pr118757.cc
index d54abd8..f49ae38 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/pr118757.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/pr118757.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++20 } }
+// { dg-additional-options "-pthread" { target pthread } }
// { dg-require-gthreads "" }
// { dg-require-effective-target hosted }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc b/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc
new file mode 100644
index 0000000..ee18bb3
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++11 } }
+
+#include <tuple>
+#include <type_traits>
+
+// Check that tuple<> has the expected trivial properties
+static_assert(std::is_trivially_copyable<std::tuple<>>::value,
+ "tuple<> should be trivially copyable");
+static_assert(std::is_trivially_copy_constructible<std::tuple<>>::value,
+ "tuple<> should be trivially copy constructible");
+static_assert(std::is_trivially_move_constructible<std::tuple<>>::value,
+ "tuple<> should be trivially move constructible");
+static_assert(std::is_trivially_copy_assignable<std::tuple<>>::value,
+ "tuple<> should be trivially copy assignable");
+static_assert(std::is_trivially_move_assignable<std::tuple<>>::value,
+ "tuple<> should be trivially move assignable");
+
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/pr118757.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/pr118757.cc
index f048f13..77757f3 100644
--- a/libstdc++-v3/testsuite/20_util/weak_ptr/pr118757.cc
+++ b/libstdc++-v3/testsuite/20_util/weak_ptr/pr118757.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++20 } }
+// { dg-additional-options "-pthread" { target pthread } }
// { dg-require-gthreads "" }
// { dg-require-effective-target hosted }
diff --git a/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc
new file mode 100644
index 0000000..1d15238
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc
@@ -0,0 +1,121 @@
+// { dg-do run { target c++23 } }
+
+// Test for PR libstdc++/119721: tuple<> construction/assignment with array<T, 0>
+
+#include <tuple>
+#include <array>
+#include <memory>
+#include <testsuite_hooks.h>
+
+constexpr void
+test01()
+{
+ std::array<int, 0> a{};
+
+ // Constructor from array<int, 0>
+ std::tuple<> t1(a);
+ std::tuple<> t2(std::move(a));
+
+ // Assignment from array<int, 0>
+ std::tuple<> t3;
+ t3 = a;
+ t3 = std::move(a);
+
+ VERIFY( t1 == a );
+ VERIFY( t2 == a );
+ VERIFY( t3 == a );
+}
+
+constexpr void
+test02()
+{
+ // Test with non-comparable element type
+ struct NonComparable
+ {
+ void operator==(const NonComparable&) const = delete;
+ void operator<=>(const NonComparable&) const = delete;
+ };
+
+ std::array<NonComparable, 0> a{};
+
+ std::tuple<> t1(a);
+ std::tuple<> t2(std::move(a));
+
+ std::tuple<> t3;
+ t3 = a;
+ t3 = std::move(a);
+
+ VERIFY( t1 == a );
+}
+
+constexpr void
+test03()
+{
+ // Test assignment return type (non-const assignment)
+ std::tuple<> t, u;
+ std::tuple<>& r1 = (t = u);
+ VERIFY( &r1 == &t );
+
+ std::tuple<>& r2 = (t = {});
+ VERIFY( &r2 == &t );
+
+ std::array<int, 0> a{};
+ std::tuple<>& r3 = (t = a);
+ VERIFY( &r3 == &t );
+}
+
+constexpr void
+test04()
+{
+ std::array<int, 0> a{};
+ const std::tuple<> t1;
+
+ // Const assignment from array
+ std::tuple<> t2;
+ const std::tuple<>& r1 = (t1 = t2);
+ VERIFY( &r1 == &t1 );
+ const std::tuple<>& r2 = (t1 = std::move(t2));
+ VERIFY( &r2 == &t1 );
+
+ const std::tuple<>& r3 = (t1 = {});
+ VERIFY( &r3 == &t1 );
+
+ // Const assignment from array
+ const std::tuple<>& r4 = (t1 = a);
+ VERIFY( &r4 == &t1 );
+ const std::tuple<>& r5 = (t1 = std::move(a));
+ VERIFY( &r5 == &t1 );
+}
+
+void
+test05()
+{
+ std::array<int, 0> a{};
+ std::allocator<int> alloc;
+
+ // Allocator constructor from array
+ std::tuple<> t1(std::allocator_arg, alloc, a);
+ std::tuple<> t2(std::allocator_arg, alloc, std::move(a));
+
+ VERIFY( t1 == a );
+ VERIFY( t2 == a );
+}
+
+int main()
+{
+ auto test_all = [] {
+ test01();
+ test02();
+ test03();
+ test04();
+ return true;
+ };
+
+ test_all();
+ static_assert( test_all() );
+
+ // allocator test is not constexpr
+ test05();
+ return 0;
+}
+
diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/108951.cc b/libstdc++-v3/testsuite/26_numerics/valarray/108951.cc
new file mode 100644
index 0000000..929a1d4
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/valarray/108951.cc
@@ -0,0 +1,22 @@
+// { dg-do run { target c++11 } }
+// { dg-additional-options "-faligned-new" { target c++14_down } }
+
+#include <valarray>
+#include <cstdint>
+#include <testsuite_hooks.h>
+
+struct alignas(64) Num
+{
+ Num()
+ {
+ VERIFY(reinterpret_cast<std::uintptr_t>(this) % alignof(*this) == 0);
+ }
+
+ double val{};
+};
+
+int main()
+{
+ std::valarray<Num> v(2);
+ v.resize(4, {});
+}
diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
index 7114007..e8c3e16 100644
--- a/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
@@ -1,4 +1,7 @@
// { dg-do run { target c++11 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+// { dg-require-effective-target hosted }
#include <condition_variable>
#include <chrono>
diff --git a/libstdc++-v3/testsuite/30_threads/future/members/116586.cc b/libstdc++-v3/testsuite/30_threads/future/members/116586.cc
index b7cd12c..82f1e5c 100644
--- a/libstdc++-v3/testsuite/30_threads/future/members/116586.cc
+++ b/libstdc++-v3/testsuite/30_threads/future/members/116586.cc
@@ -1,4 +1,7 @@
// { dg-do run { target c++11 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+// { dg-require-effective-target hosted }
#include <future>
#include <chrono>
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/116586.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/116586.cc
index 941f3af..25a78e7 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/116586.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/116586.cc
@@ -1,4 +1,7 @@
// { dg-do run { target c++11 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+// { dg-require-effective-target hosted }
#include <mutex>
#include <chrono>
diff --git a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc
index cebbb3a..5736b7d 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc
@@ -1,4 +1,7 @@
// { dg-do run { target c++14 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+// { dg-require-effective-target hosted }
#include <shared_mutex>
#include <chrono>
@@ -8,10 +11,18 @@
namespace chrono = std::chrono;
-// thread.timedmutex.requirements.general:
+// [thread.timedmutex.requirements.general]:
// If abs_time has already passed, the function attempts to obtain
// ownership without blocking (as if by calling try_lock()).
+// C++14 [thread.sharedtimedmutex.class] 3.2 says it's undefined for a thread
+// to attempt to recursively gain any ownership of a shared_timed_mutex.
+// This isn't just theoretical, as Glibc's pthread_rwlock_timedrdlock will
+// return EDEADLK if called on the same thread that already holds the
+// exclusive (write) lock.
+#define VERIFY_IN_NEW_THREAD(X) \
+ (void) std::async(std::launch::async, [&] { VERIFY(X); })
+
template <typename Clock>
void
test_exclusive_absolute(chrono::nanoseconds offset)
@@ -19,7 +30,7 @@ test_exclusive_absolute(chrono::nanoseconds offset)
std::shared_timed_mutex stm;
chrono::time_point<Clock> tp(offset);
VERIFY(stm.try_lock_until(tp));
- VERIFY(!stm.try_lock_until(tp));
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_until(tp));
}
template <typename Clock>
@@ -32,15 +43,7 @@ test_shared_absolute(chrono::nanoseconds offset)
stm.unlock_shared();
VERIFY(stm.try_lock_for(chrono::seconds{10}));
-
- {
- // NPTL will give us EDEADLK if pthread_rwlock_timedrdlock() is called on
- // the same thread that already holds the exclusive (write) lock, so let's
- // arrange for a different thread to try to acquire the shared lock.
- auto t = std::async(std::launch::async, [&stm, tp]() {
- VERIFY(!stm.try_lock_shared_until(tp));
- });
- }
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_shared_until(tp));
}
// The type of clock used for the actual wait depends on whether
@@ -53,7 +56,7 @@ test_exclusive_relative(chrono::nanoseconds offset)
std::shared_timed_mutex stm;
const auto d = -Clock::now().time_since_epoch() + offset;
VERIFY(stm.try_lock_for(d));
- VERIFY(!stm.try_lock_for(d));
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_for(d));
}
template <typename Clock>
@@ -66,7 +69,7 @@ test_shared_relative(chrono::nanoseconds offset)
stm.unlock_shared();
// Should complete immediately
VERIFY(stm.try_lock_for(chrono::seconds{10}));
- VERIFY(!stm.try_lock_shared_for(d));
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_shared_for(d));
}
int main()
diff --git a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
index 9616b15..b1fde09 100644
--- a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
@@ -23,7 +23,7 @@
#include <thread>
#include <system_error>
-#include <bits/move.h> // std::move
+#include <utility> // std::move
#include <testsuite_hooks.h>
void f() { }
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/116586.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/116586.cc
index dcba7aa..1566228 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/116586.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/116586.cc
@@ -1,4 +1,7 @@
// { dg-do run { target c++11 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+// { dg-require-effective-target hosted }
#include <chrono>
#include <mutex>
diff --git a/libstdc++-v3/testsuite/ext/iotaarray.cc b/libstdc++-v3/testsuite/ext/iotaarray.cc
new file mode 100644
index 0000000..b259602
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/iotaarray.cc
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++26 } }
+
+#include <utility>
+#include <type_traits>
+
+template<auto N>
+void test()
+{
+ constexpr auto [id0, ...ids] = std::_IotaArray<N>;
+ static_assert( std::is_same_v<decltype(id0), const decltype(N)> );
+ static_assert( sizeof...(ids) == N - 1 );
+ static_assert( (id0 + ... + ids) == N*(N-1)/2 );
+}
+
+int main()
+{
+ test<1>();
+ test<4u>();
+ test<8ull>();
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h
index 5bf2e70..41fbcaa 100644
--- a/libstdc++-v3/testsuite/util/testsuite_iterators.h
+++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h
@@ -674,6 +674,9 @@ namespace __gnu_test
template <class T, template<class TT> class ItType>
struct test_container
{
+ typedef ItType<T> iterator;
+ typedef typename iterator::value_type value_type;
+
typename ItType<T>::ContainerType bounds;
_GLIBCXX_CONSTEXPR