mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
f4ab68469c
Tests which check for feature test macros should use the no_pch option, so that we're really testing for the definition being in the intended header, and not just testing that it's present in <bits/stdc++.h> (which includes all the standard headers and so defines all the macros). libstdc++-v3/ChangeLog: * testsuite/18_support/byte/requirements.cc: Disable PCH. * testsuite/18_support/destroying_delete.cc: Likewise. * testsuite/18_support/source_location/1.cc: Likewise. * testsuite/18_support/source_location/version.cc: Likewise. * testsuite/18_support/type_info/constexpr.cc: Likewise. * testsuite/18_support/uncaught_exceptions/uncaught_exceptions.cc: Likewise. * testsuite/19_diagnostics/stacktrace/output.cc: Likewise. * testsuite/19_diagnostics/stacktrace/synopsis.cc: Likewise. * testsuite/19_diagnostics/stacktrace/version.cc: Likewise. * testsuite/20_util/addressof/requirements/constexpr.cc: Likewise. * testsuite/20_util/allocator_traits/header-2.cc: Likewise. * testsuite/20_util/allocator_traits/header.cc: Likewise. * testsuite/20_util/as_const/1.cc: Likewise. Likewise. * testsuite/20_util/bitset/cons/constexpr_c++23.cc: Likewise. * testsuite/20_util/bitset/version.cc: Likewise. * testsuite/20_util/duration/arithmetic/constexpr_c++17.cc: Likewise. * testsuite/20_util/duration_cast/rounding.cc: Likewise. * testsuite/20_util/enable_shared_from_this/members/weak_from_this.cc: Likewise. * testsuite/20_util/exchange/constexpr.cc: Likewise. * testsuite/20_util/expected/synopsis.cc: Likewise. * testsuite/20_util/expected/version.cc: Likewise. * testsuite/20_util/function_objects/bind_front/1.cc: Likewise. * testsuite/20_util/function_objects/bind_front/2.cc: Likewise. * testsuite/20_util/function_objects/invoke/3.cc: Likewise. * testsuite/20_util/function_objects/invoke/4.cc: Likewise. * testsuite/20_util/function_objects/invoke/constexpr.cc: Likewise. * testsuite/20_util/function_objects/invoke/version.cc: Likewise. * testsuite/20_util/function_objects/searchers.cc: Likewise. * testsuite/20_util/integer_comparisons/1.cc: Likewise. * testsuite/20_util/integer_comparisons/2.cc: Likewise. * testsuite/20_util/is_bounded_array/value.cc: Likewise. * testsuite/20_util/is_layout_compatible/value.cc: Likewise. * testsuite/20_util/is_layout_compatible/version.cc: Likewise. * testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_nothrow_swappable/value.cc: Likewise. * testsuite/20_util/is_nothrow_swappable/value.h: Likewise. * testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc: Remove redundant checks already tested elsewhere. * testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_nothrow_swappable_with/value.cc: Disable PCH. * testsuite/20_util/is_pointer_interconvertible/value.cc: Likewise. * testsuite/20_util/is_pointer_interconvertible/version.cc: Likewise. * testsuite/20_util/is_scoped_enum/value.cc: Likewise. * testsuite/20_util/is_scoped_enum/version.cc: Likewise. * testsuite/20_util/is_swappable/requirements/explicit_instantiation.cc: Remove redundant checks already tested elsewhere. * testsuite/20_util/is_swappable/requirements/typedefs.cc: Remove redundant checks already tested elsewhere. * testsuite/20_util/is_swappable/value.cc: Disable PCH. * testsuite/20_util/is_swappable/value.h: Reorder headers. * testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc: Remove redundant checks already tested elsewhere. * testsuite/20_util/is_swappable_with/requirements/typedefs.cc: Remove redundant checks already tested elsewhere. * testsuite/20_util/is_swappable_with/value.cc: Disable PCH. * testsuite/20_util/is_unbounded_array/value.cc: Likewise. * testsuite/20_util/move_only_function/cons.cc: Likewise. * testsuite/20_util/move_only_function/version.cc: Likewise. * testsuite/20_util/optional/monadic/and_then.cc: Likewise. * testsuite/20_util/optional/requirements.cc: Likewise. * testsuite/20_util/optional/version.cc: Likewise. * testsuite/20_util/owner_less/void.cc: Likewise. * testsuite/20_util/reference_from_temporary/value.cc: Likewise. * testsuite/20_util/reference_from_temporary/version.cc: Likewise. * testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc: Likewise. * testsuite/20_util/shared_ptr/creation/array.cc: Likewise. * testsuite/20_util/shared_ptr/creation/overwrite.cc: Likewise. * testsuite/20_util/shared_ptr/creation/version.cc: Likewise. * testsuite/20_util/time_point_cast/rounding.cc: Likewise. * testsuite/20_util/to_chars/constexpr.cc: Likewise. * testsuite/20_util/to_chars/result.cc: Likewise. * testsuite/20_util/to_chars/version.cc: Likewise. * testsuite/20_util/to_underlying/1.cc: Likewise. * testsuite/20_util/to_underlying/version.cc: Likewise. * testsuite/20_util/tuple/apply/1.cc: Likewise. * testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc: Likewise. * testsuite/20_util/tuple/make_from_tuple/1.cc: Likewise. * testsuite/20_util/tuple/p2321r2.cc: Likewise. * testsuite/20_util/tuple/tuple_element_t.cc: Likewise. * testsuite/20_util/unique_ptr/cons/constexpr_c++20.cc: Likewise. * testsuite/20_util/unique_ptr/creation/for_overwrite.cc: Likewise. * testsuite/20_util/unreachable/1.cc: Likewise. * testsuite/20_util/unreachable/version.cc: Likewise. * testsuite/20_util/unwrap_reference/1.cc: Likewise. * testsuite/20_util/unwrap_reference/3.cc: Likewise. * testsuite/20_util/variant/constexpr.cc: Likewise. * testsuite/20_util/variant/version.cc: Likewise. * testsuite/20_util/variant/visit_inherited.cc: Likewise. * testsuite/20_util/void_t/1.cc: Likewise. * testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc: Likewise. * testsuite/21_strings/basic_string/cons/char/constexpr.cc: Likewise. * testsuite/21_strings/basic_string/cons/wchar_t/constexpr.cc: Likewise. * testsuite/21_strings/basic_string/erasure.cc: Likewise. * testsuite/21_strings/basic_string/numeric_conversions/char/to_string_float.cc: Likewise. * testsuite/21_strings/basic_string/numeric_conversions/version.cc: Likewise. * testsuite/21_strings/basic_string/version.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/contains/char.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/contains/char/2.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/copy/char/constexpr.cc: Likewise. * testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc: Likewise. * testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc: Likewise. * testsuite/21_strings/char_traits/requirements/version.cc: Likewise. * testsuite/23_containers/array/comparison_operators/constexpr.cc: Likewise. * testsuite/23_containers/array/creation/1.cc: Likewise. * testsuite/23_containers/array/creation/2.cc: Likewise. * testsuite/23_containers/array/element_access/constexpr_c++17.cc: Likewise. * testsuite/23_containers/array/requirements/constexpr_fill.cc: Likewise. * testsuite/23_containers/array/requirements/constexpr_iter.cc: Likewise. * testsuite/23_containers/deque/erasure.cc: Likewise. * testsuite/23_containers/forward_list/erasure.cc: Likewise. * testsuite/23_containers/list/erasure.cc: Likewise. * testsuite/23_containers/map/erasure.cc: Likewise. * testsuite/23_containers/queue/cons_from_iters.cc: Likewise. * testsuite/23_containers/set/erasure.cc: Likewise. * testsuite/23_containers/span/1.cc: Likewise. * testsuite/23_containers/span/2.cc: Likewise. * testsuite/23_containers/stack/cons_from_iters.cc: Likewise. * testsuite/23_containers/unordered_map/erasure.cc: Likewise. * testsuite/23_containers/unordered_map/operations/1.cc: Likewise. * testsuite/23_containers/unordered_set/erasure.cc: Likewise. * testsuite/23_containers/unordered_set/operations/1.cc: Likewise. * testsuite/23_containers/vector/cons/constexpr.cc: Likewise. * testsuite/23_containers/vector/erasure.cc: Likewise. * testsuite/23_containers/vector/requirements/version.cc: Likewise. * testsuite/24_iterators/insert_iterator/constexpr.cc: Likewise. * testsuite/25_algorithms/clamp/constexpr.cc: Likewise. * testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc: Remove redundant checks already tested elsewhere. * testsuite/25_algorithms/constexpr_macro.cc: Likewise. * testsuite/25_algorithms/cpp_lib_constexpr.cc: Likewise. * testsuite/25_algorithms/fold_left/1.cc: Likewise. * testsuite/25_algorithms/pstl/feature_test-2.cc: Likewise. * testsuite/25_algorithms/pstl/feature_test-3.cc: Likewise. * testsuite/25_algorithms/pstl/feature_test-4.cc: Likewise. * testsuite/25_algorithms/pstl/feature_test-5.cc: Likewise. * testsuite/25_algorithms/pstl/feature_test.cc: Likewise. * testsuite/26_numerics/bit/bit.byteswap/byteswap.cc: Likewise. * testsuite/26_numerics/bit/bit.byteswap/version.cc: Likewise. * testsuite/26_numerics/bit/bit.cast/bit_cast.cc: Likewise. * testsuite/26_numerics/bit/bit.cast/version.cc: Likewise. * testsuite/26_numerics/bit/header-2.cc: Likewise. * testsuite/26_numerics/bit/header.cc: Likewise. * testsuite/26_numerics/complex/1.cc: Likewise. * testsuite/26_numerics/complex/2.cc: Likewise. * testsuite/26_numerics/endian/2.cc: Likewise. * testsuite/26_numerics/endian/3.cc: Likewise. * testsuite/26_numerics/gcd/1.cc: Likewise. * testsuite/26_numerics/lcm/1.cc: Likewise. * testsuite/26_numerics/lerp/1.cc: Likewise. * testsuite/26_numerics/lerp/version.cc: Likewise. * testsuite/26_numerics/midpoint/integral.cc: Likewise. * testsuite/26_numerics/midpoint/version.cc: Likewise. * testsuite/26_numerics/numbers/1.cc: Likewise. * testsuite/26_numerics/numbers/2.cc: Likewise. * testsuite/27_io/basic_filebuf/native_handle/char/1.cc: Likewise. * testsuite/27_io/basic_filebuf/native_handle/version.cc: Likewise. * testsuite/27_io/basic_ofstream/open/char/noreplace.cc: Likewise. * testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc: Likewise. * testsuite/27_io/basic_syncbuf/1.cc: Likewise. * testsuite/27_io/basic_syncbuf/2.cc: Likewise. * testsuite/27_io/basic_syncstream/1.cc: Likewise. * testsuite/27_io/basic_syncstream/2.cc: Likewise. * testsuite/27_io/spanstream/1.cc: Likewise. * testsuite/27_io/spanstream/version.cc: Likewise. * testsuite/29_atomics/atomic/cons/value_init.cc: Likewise. * testsuite/29_atomics/atomic/lock_free_aliases.cc: Likewise. * testsuite/29_atomics/atomic/wait_notify/1.cc: Likewise. * testsuite/29_atomics/atomic/wait_notify/2.cc: Likewise. * testsuite/29_atomics/headers/stdatomic.h/c_compat.cc: Likewise. * testsuite/29_atomics/headers/stdatomic.h/version.cc: Likewise. * testsuite/30_threads/barrier/1.cc: Likewise. * testsuite/30_threads/barrier/2.cc: Likewise. * testsuite/30_threads/condition_variable_any/stop_token/1.cc: Likewise. * testsuite/30_threads/condition_variable_any/stop_token/2.cc: Likewise. * testsuite/30_threads/jthread/1.cc: Likewise. * testsuite/30_threads/jthread/version.cc: Likewise. * testsuite/30_threads/latch/1.cc: Likewise. * testsuite/30_threads/latch/2.cc: Likewise. * testsuite/30_threads/scoped_lock/requirements/typedefs.cc: Likewise. * testsuite/30_threads/semaphore/1.cc: Likewise. * testsuite/30_threads/semaphore/2.cc: Likewise. * testsuite/30_threads/stop_token/1.cc: Likewise. * testsuite/30_threads/stop_token/2.cc: Likewise. * testsuite/experimental/feat-char8_t.cc: Likewise. * testsuite/experimental/iterator/ostream_joiner.cc: Likewise. * testsuite/experimental/numeric/gcd.cc: Likewise. * testsuite/experimental/scopeguard/uniqueres.cc: Likewise. * testsuite/std/concepts/1.cc: Likewise. * testsuite/std/concepts/2.cc: Likewise. * testsuite/std/ranges/adaptors/as_const/1.cc: Likewise. * testsuite/std/ranges/adaptors/as_rvalue/1.cc: Likewise. * testsuite/std/ranges/adaptors/chunk/1.cc: Likewise. * testsuite/std/ranges/adaptors/chunk_by/1.cc: Likewise. * testsuite/std/ranges/adaptors/enumerate/1.cc: Likewise. * testsuite/std/ranges/adaptors/join_with/1.cc: Likewise. * testsuite/std/ranges/adaptors/slide/1.cc: Likewise. * testsuite/std/ranges/adaptors/stride/1.cc: Likewise. * testsuite/std/ranges/cartesian_product/1.cc: Likewise. * testsuite/std/ranges/headers/ranges/synopsis.cc: Likewise. * testsuite/std/ranges/repeat/1.cc: Likewise. * testsuite/std/ranges/version_c++23.cc: Likewise. * testsuite/std/ranges/zip/1.cc: Likewise. * testsuite/std/time/syn_c++20.cc: Likewise. * testsuite/experimental/feat-cxx14.cc: Likewise. Include <algorithm> and <iterator>. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust dg-error line numbers.
672 lines
16 KiB
C++
672 lines
16 KiB
C++
// Verify P2321R2 "zip" enhancements to std::tuple.
|
|
// { dg-do run { target c++23 } }
|
|
// FIXME [!HOSTED]: avoidable std::allocator usage
|
|
// { dg-require-effective-target hosted }
|
|
// { dg-add-options no_pch }
|
|
|
|
#include <tuple>
|
|
|
|
#if __cpp_lib_ranges_zip != 202110L
|
|
# error "Feature-test macro __cpp_lib_ranges_zip has wrong value in <tuple>"
|
|
#endif
|
|
|
|
#include <memory>
|
|
#include <testsuite_hooks.h>
|
|
|
|
using std::tuple;
|
|
using std::pair;
|
|
using std::allocator;
|
|
using std::allocator_arg_t;
|
|
using std::allocator_arg;
|
|
|
|
namespace alloc {
|
|
struct B01;
|
|
struct B02;
|
|
struct B03;
|
|
struct B04;
|
|
}
|
|
|
|
template<> struct std::uses_allocator<alloc::B01, allocator<int>> : std::true_type { };
|
|
template<> struct std::uses_allocator<alloc::B02, allocator<int>> : std::true_type { };
|
|
template<> struct std::uses_allocator<alloc::B03, allocator<int>> : std::true_type { };
|
|
template<> struct std::uses_allocator<alloc::B04, allocator<int>> : std::true_type { };
|
|
|
|
struct A { };
|
|
|
|
constexpr bool
|
|
test01()
|
|
{
|
|
struct B { bool v; constexpr B(A&) : v(true) { } };
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(false) tuple(tuple<UTypes...>&);
|
|
|
|
tuple<A> t1a;
|
|
tuple<B> t1b = t1a;
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0 = t2a0;
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1 = t2a1;
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0 = t3a0;
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1 = t3a1;
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2 = t3a2;
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(false) tuple(pair<UTypes...>&);
|
|
|
|
pair<A, int> p2a0;
|
|
tuple<B, int> p2b0 = p2a0;
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
pair<int, A> p2a1;
|
|
tuple<int, B> p2b1 = p2a1;
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
|
|
namespace alloc
|
|
{
|
|
struct B01
|
|
{
|
|
bool v;
|
|
B01(A&);
|
|
constexpr B01(allocator_arg_t, allocator<int>, A&) : v(true) { }
|
|
};
|
|
|
|
constexpr bool
|
|
test01()
|
|
{
|
|
using B = B01;
|
|
|
|
// template<class Alloc, class... UTypes>
|
|
// constexpr explicit(false)
|
|
// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&);
|
|
|
|
tuple<A> t1a;
|
|
tuple<B> t1b = {allocator_arg, allocator<int>{}, t1a};
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0 = {allocator_arg, allocator<int>{}, t2a0};
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1 = {allocator_arg, allocator<int>{}, t2a1};
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0 = {allocator_arg, allocator<int>{}, t3a0};
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1 = {allocator_arg, allocator<int>{}, t3a1};
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2 = {allocator_arg, allocator<int>{}, t3a2};
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class Alloc, class U1, class U2>
|
|
// constexpr explicit(false)
|
|
// tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&);
|
|
|
|
pair<A, int> p2a0;
|
|
tuple<B, int> p2b0 = {allocator_arg, allocator<int>{}, p2a0};
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
pair<int, A> p2a1;
|
|
tuple<int, B> p2b1 = {allocator_arg, allocator<int>{}, p2a1};
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
constexpr bool
|
|
test02()
|
|
{
|
|
struct B { bool v; explicit constexpr B(A&) : v(true) { } };
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(true) tuple(tuple<UTypes...>&);
|
|
|
|
static_assert(!std::is_convertible_v<tuple<A>&, tuple<B>>);
|
|
|
|
tuple<A> t1a;
|
|
tuple<B> t1b(t1a);
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
static_assert(!std::is_convertible_v<tuple<A, int>&, tuple<B, int>>);
|
|
static_assert(!std::is_convertible_v<tuple<int, A>&, tuple<int, B>>);
|
|
|
|
tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0(t2a0);
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1(t2a1);
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
static_assert(!std::is_convertible_v<tuple<A, int, int>&, tuple<B, int, int>>);
|
|
static_assert(!std::is_convertible_v<tuple<int, A, int>&, tuple<int, B, int>>);
|
|
static_assert(!std::is_convertible_v<tuple<int, int, A>&, tuple<int, int, B>>);
|
|
|
|
tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0(t3a0);
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1(t3a1);
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2(t3a2);
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(true) tuple(pair<UTypes...>&);
|
|
|
|
static_assert(!std::is_convertible_v<pair<A, int>&, tuple<B, int>>);
|
|
static_assert(!std::is_convertible_v<pair<int, A>&, tuple<int, B>>);
|
|
|
|
pair<A, int> p2a0;
|
|
tuple<B, int> p2b0(p2a0);
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
pair<int, A> p2a1;
|
|
tuple<int, B> p2b1(p2a1);
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
|
|
namespace alloc
|
|
{
|
|
struct B02
|
|
{
|
|
bool v;
|
|
explicit B02(A&);
|
|
explicit constexpr B02(allocator_arg_t, allocator<int>, A&) : v(true) { }
|
|
};
|
|
|
|
constexpr bool
|
|
test02()
|
|
{
|
|
using B = B02;
|
|
|
|
// template<class Alloc, class... UTypes>
|
|
// constexpr explicit(true)
|
|
// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&);
|
|
|
|
tuple<A> t1a;
|
|
tuple<B> t1b(allocator_arg, allocator<int>{}, t1a);
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0(allocator_arg, allocator<int>{}, t2a0);
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1(allocator_arg, allocator<int>{}, t2a1);
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0(allocator_arg, allocator<int>{}, t3a0);
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1(allocator_arg, allocator<int>{}, t3a1);
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2(allocator_arg, allocator<int>{}, t3a2);
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class Alloc, class U1, class U2>
|
|
// constexpr explicit(true)
|
|
// tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&);
|
|
|
|
pair<A, int> p2a0;
|
|
tuple<B, int> p2b0(allocator_arg, allocator<int>{}, p2a0);
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
pair<int, A> p2a1;
|
|
tuple<int, B> p2b1(allocator_arg, allocator<int>{}, p2a1);
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
} // namespace alloc
|
|
|
|
constexpr bool
|
|
test03()
|
|
{
|
|
struct B { bool v; constexpr B(const A&&) : v(true) { } };
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(false) tuple(const tuple<UTypes...>&&);
|
|
|
|
const tuple<A> t1a;
|
|
tuple<B> t1b = std::move(t1a);
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
const tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0 = std::move(t2a0);
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
const tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1 = std::move(t2a1);
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
const tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0 = std::move(t3a0);
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
const tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1 = std::move(t3a1);
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
const tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2 = std::move(t3a2);
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(false) tuple(const pair<UTypes...>&&);
|
|
|
|
const pair<A, int> p2a0;
|
|
tuple<B, int> p2b0 = std::move(p2a0);
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
const pair<int, A> p2a1;
|
|
tuple<int, B> p2b1 = std::move(p2a1);
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
|
|
namespace alloc
|
|
{
|
|
struct B03
|
|
{
|
|
bool v;
|
|
B03(const A&&);
|
|
constexpr B03(allocator_arg_t, allocator<int>, const A&&) : v(true) { }
|
|
};
|
|
|
|
constexpr bool
|
|
test03()
|
|
{
|
|
using B = B03;
|
|
|
|
// template<class Alloc, class... UTypes>
|
|
// constexpr explicit(false)
|
|
// tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&);
|
|
|
|
const tuple<A> t1a;
|
|
tuple<B> t1b = {allocator_arg, allocator<int>{}, std::move(t1a)};
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
const tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0 = {allocator_arg, allocator<int>{}, std::move(t2a0)};
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
const tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1 = {allocator_arg, allocator<int>{}, std::move(t2a1)};
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
const tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0 = {allocator_arg, allocator<int>{}, std::move(t3a0)};
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
const tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1 = {allocator_arg, allocator<int>{}, std::move(t3a1)};
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
const tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2 = {allocator_arg, allocator<int>{}, std::move(t3a2)};
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class Alloc, class U1, class U2>
|
|
// constexpr explicit(false)
|
|
// tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&);
|
|
|
|
const pair<A, int> p2a0;
|
|
tuple<B, int> p2b0 = {allocator_arg, allocator<int>{}, std::move(p2a0)};
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
const pair<int, A> p2a1;
|
|
tuple<int, B> p2b1 = {allocator_arg, allocator<int>{}, std::move(p2a1)};
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
constexpr bool
|
|
test04()
|
|
{
|
|
struct B { bool v; explicit constexpr B(const A&&) : v(true) { } };
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(true) tuple(const tuple<UTypes...>&&);
|
|
|
|
static_assert(!std::is_convertible_v<tuple<A>&, tuple<B>>);
|
|
|
|
const tuple<A> t1a;
|
|
tuple<B> t1b(std::move(t1a));
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
static_assert(!std::is_convertible_v<tuple<A, int>&, tuple<B, int>>);
|
|
static_assert(!std::is_convertible_v<tuple<int, A>&, tuple<int, B>>);
|
|
|
|
const tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0(std::move(t2a0));
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
const tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1(std::move(t2a1));
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
static_assert(!std::is_convertible_v<tuple<A, int, int>&, tuple<B, int, int>>);
|
|
static_assert(!std::is_convertible_v<tuple<int, A, int>&, tuple<int, B, int>>);
|
|
static_assert(!std::is_convertible_v<tuple<int, int, A>&, tuple<int, int, B>>);
|
|
|
|
const tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0(std::move(t3a0));
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
const tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1(std::move(t3a1));
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
const tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2(std::move(t3a2));
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class... UTypes>
|
|
// constexpr explicit(true) tuple(const pair<UTypes...>&&);
|
|
|
|
static_assert(!std::is_convertible_v<pair<A, int>&, tuple<B, int>>);
|
|
static_assert(!std::is_convertible_v<pair<int, A>&, tuple<int, B>>);
|
|
|
|
const pair<A, int> p2a0;
|
|
tuple<B, int> p2b0(std::move(p2a0));
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
const pair<int, A> p2a1;
|
|
tuple<int, B> p2b1(std::move(p2a1));
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
|
|
namespace alloc
|
|
{
|
|
struct B04
|
|
{
|
|
bool v;
|
|
explicit B04(const A&&);
|
|
explicit constexpr B04(allocator_arg_t, allocator<int>, const A&&) : v(true) { }
|
|
};
|
|
|
|
constexpr bool
|
|
test04()
|
|
{
|
|
using B = B04;
|
|
|
|
// template<class Alloc, class... UTypes>
|
|
// constexpr explicit(true)
|
|
// tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&);
|
|
|
|
const tuple<A> t1a;
|
|
tuple<B> t1b(allocator_arg, allocator<int>{}, std::move(t1a));
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
const tuple<A, int> t2a0;
|
|
tuple<B, int> t2b0(allocator_arg, allocator<int>{}, std::move(t2a0));
|
|
VERIFY( std::get<0>(t2b0).v );
|
|
|
|
const tuple<int, A> t2a1;
|
|
tuple<int, B> t2b1(allocator_arg, allocator<int>{}, std::move(t2a1));
|
|
VERIFY( std::get<1>(t2b1).v );
|
|
|
|
const tuple<A, int, int> t3a0;
|
|
tuple<B, int, int> t3b0(allocator_arg, allocator<int>{}, std::move(t3a0));
|
|
VERIFY( std::get<0>(t3b0).v );
|
|
|
|
const tuple<int, A, int> t3a1;
|
|
tuple<int, B, int> t3b1(allocator_arg, allocator<int>{}, std::move(t3a1));
|
|
VERIFY( std::get<1>(t3b1).v );
|
|
|
|
const tuple<int, int, A> t3a2;
|
|
tuple<int, int, B> t3b2(allocator_arg, allocator<int>{}, std::move(t3a2));
|
|
VERIFY( std::get<2>(t3b2).v );
|
|
|
|
// template<class Alloc, class U1, class U2>
|
|
// constexpr explicit(true)
|
|
// tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&);
|
|
|
|
tuple<B, int> p2b0(allocator_arg, allocator<int>{}, std::move(t2a0));
|
|
VERIFY( std::get<0>(p2b0).v );
|
|
|
|
tuple<int, B> p2b1(allocator_arg, allocator<int>{}, std::move(t2a1));
|
|
VERIFY( std::get<1>(p2b1).v );
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
constexpr bool
|
|
test05()
|
|
{
|
|
struct B
|
|
{
|
|
mutable bool v;
|
|
constexpr const B& operator=(const A&) const { v = true; return *this; }
|
|
};
|
|
|
|
// template<class... UTypes>
|
|
// constexpr const tuple& operator=(const tuple<UTypes...>&) const;
|
|
|
|
const tuple<A> t1a;
|
|
const tuple<B> t1b;
|
|
t1b = t1a;
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
const tuple<A, A> t2a;
|
|
const tuple<B, B> t2b;
|
|
t2b = t2a;
|
|
VERIFY( std::get<0>(t2b).v );
|
|
VERIFY( std::get<1>(t2b).v );
|
|
|
|
const tuple<A, A, A> t3a;
|
|
const tuple<B, B, B> t3b;
|
|
t3b = t3a;
|
|
VERIFY( std::get<0>(t3b).v );
|
|
VERIFY( std::get<1>(t3b).v );
|
|
VERIFY( std::get<2>(t3b).v );
|
|
|
|
// template<class U1, class U2>
|
|
// constexpr const tuple& operator=(const pair<U1, U2>&) const;
|
|
|
|
const pair<A, A> p2a;
|
|
const tuple<B, B> p2b;
|
|
p2b = p2a;
|
|
|
|
return true;
|
|
}
|
|
|
|
constexpr bool
|
|
test06()
|
|
{
|
|
struct B
|
|
{
|
|
mutable bool v;
|
|
constexpr const B& operator=(A&&) const { v = true; return *this; }
|
|
};
|
|
|
|
// template<class... UTypes>
|
|
// constexpr const tuple& operator=(tuple<UTypes...>&&) const;
|
|
|
|
tuple<A> t1a;
|
|
const tuple<B> t1b;
|
|
t1b = std::move(t1a);
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
tuple<A, A> t2a;
|
|
const tuple<B, B> t2b;
|
|
t2b = std::move(t2a);
|
|
VERIFY( std::get<0>(t2b).v );
|
|
VERIFY( std::get<1>(t2b).v );
|
|
|
|
tuple<A, A, A> t3a;
|
|
const tuple<B, B, B> t3b;
|
|
t3b = std::move(t3a);
|
|
VERIFY( std::get<0>(t3b).v );
|
|
VERIFY( std::get<1>(t3b).v );
|
|
VERIFY( std::get<2>(t3b).v );
|
|
|
|
// template<class U1, class U2>
|
|
// constexpr const tuple& operator=(pair<U1, U2>&&) const;
|
|
|
|
pair<A, A> p2a;
|
|
const tuple<B, B> p2b;
|
|
p2b = std::move(p2a);
|
|
|
|
return true;
|
|
}
|
|
|
|
constexpr bool
|
|
test07()
|
|
{
|
|
struct B
|
|
{
|
|
mutable bool v;
|
|
constexpr const B& operator=(const B&) const { v = true; return *this; }
|
|
};
|
|
|
|
// constexpr const tuple& operator=(const tuple&) const;
|
|
|
|
const tuple<B> t1a;
|
|
const tuple<B> t1b;
|
|
t1b = t1a;
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
const tuple<B, B> t2a;
|
|
const tuple<B, B> t2b;
|
|
t2b = t2a;
|
|
VERIFY( std::get<0>(t2b).v );
|
|
VERIFY( std::get<1>(t2b).v );
|
|
|
|
const tuple<B, B, B> t3a;
|
|
const tuple<B, B, B> t3b;
|
|
t3b = t3a;
|
|
VERIFY( std::get<0>(t3b).v );
|
|
VERIFY( std::get<1>(t3b).v );
|
|
VERIFY( std::get<2>(t3b).v );
|
|
|
|
return true;
|
|
}
|
|
|
|
constexpr bool
|
|
test08()
|
|
{
|
|
struct B
|
|
{
|
|
mutable bool v;
|
|
constexpr const B& operator=(B&&) const { v = true; return *this; }
|
|
};
|
|
|
|
// constexpr const tuple& operator=(tuple&&) const;
|
|
|
|
tuple<B> t1a;
|
|
const tuple<B> t1b;
|
|
t1b = std::move(t1a);
|
|
VERIFY( std::get<0>(t1b).v );
|
|
|
|
tuple<B, B> t2a;
|
|
const tuple<B, B> t2b;
|
|
t2b = std::move(t2a);
|
|
VERIFY( std::get<0>(t2b).v );
|
|
VERIFY( std::get<1>(t2b).v );
|
|
|
|
tuple<B, B, B> t3a;
|
|
const tuple<B, B, B> t3b;
|
|
t3b = std::move(t3a);
|
|
VERIFY( std::get<0>(t3b).v );
|
|
VERIFY( std::get<1>(t3b).v );
|
|
VERIFY( std::get<2>(t3b).v );
|
|
|
|
return true;
|
|
}
|
|
|
|
struct S
|
|
{
|
|
mutable int v = 0;
|
|
friend constexpr void swap(S&& x, S&& y) = delete;
|
|
friend constexpr void swap(const S& x, const S& y) { ++x.v; ++y.v; }
|
|
};
|
|
|
|
constexpr bool
|
|
test09()
|
|
{
|
|
const tuple<S> t1, u1;
|
|
std::swap(t1, u1);
|
|
VERIFY( std::get<0>(t1).v == 1 );
|
|
VERIFY( std::get<0>(u1).v == 1 );
|
|
|
|
const tuple<S, S> t2, u2;
|
|
std::swap(t2, u2);
|
|
VERIFY( std::get<0>(t2).v == 1 );
|
|
VERIFY( std::get<0>(u2).v == 1 );
|
|
VERIFY( std::get<1>(t2).v == 1 );
|
|
VERIFY( std::get<1>(u2).v == 1 );
|
|
|
|
const tuple<S, S, S> t3, u3;
|
|
std::swap(t3, u3);
|
|
VERIFY( std::get<0>(t3).v == 1 );
|
|
VERIFY( std::get<0>(u3).v == 1 );
|
|
VERIFY( std::get<1>(t3).v == 1 );
|
|
VERIFY( std::get<1>(u3).v == 1 );
|
|
VERIFY( std::get<2>(t3).v == 1 );
|
|
VERIFY( std::get<2>(u3).v == 1 );
|
|
|
|
static_assert(!std::is_swappable_v<const tuple<A>&>);
|
|
|
|
return true;
|
|
}
|
|
|
|
int
|
|
main()
|
|
{
|
|
static_assert(test01());
|
|
static_assert(alloc::test01());
|
|
static_assert(test02());
|
|
static_assert(alloc::test02());
|
|
static_assert(test03());
|
|
static_assert(alloc::test03());
|
|
static_assert(test04());
|
|
static_assert(alloc::test04());
|
|
// FIXME: G++ doesn't support reading mutable members during constexpr (PR c++/92505).
|
|
test05();
|
|
test06();
|
|
test07();
|
|
test08();
|
|
test09();
|
|
}
|