1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// <tuple>
10
11// template <class... Types> class tuple;
12
13// template <class... UTypes>
14// tuple& operator=(const tuple<UTypes...>& u);
15
16// UNSUPPORTED: c++03
17
18#include <tuple>
19#include <string>
20#include <cassert>
21
22#include "test_macros.h"
23
24struct B {
25 int id_;
26
27 constexpr explicit B(int i = 0) : id_(i) {}
28};
29
30struct D : B {
31 constexpr explicit D(int i = 0) : B(i) {}
32};
33
34struct NonAssignable {
35 NonAssignable& operator=(NonAssignable const&) = delete;
36 NonAssignable& operator=(NonAssignable&&) = delete;
37};
38
39struct NothrowCopyAssignable {
40 NothrowCopyAssignable(NothrowCopyAssignable const&) = delete;
41 NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }
42};
43
44struct PotentiallyThrowingCopyAssignable {
45 PotentiallyThrowingCopyAssignable(PotentiallyThrowingCopyAssignable const&) = delete;
46 PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }
47};
48
49TEST_CONSTEXPR_CXX20
50bool test()
51{
52 {
53 typedef std::tuple<long> T0;
54 typedef std::tuple<long long> T1;
55 T0 t0(2);
56 T1 t1;
57 t1 = t0;
58 assert(std::get<0>(t1) == 2);
59 }
60 {
61 typedef std::tuple<long, char> T0;
62 typedef std::tuple<long long, int> T1;
63 T0 t0(2, 'a');
64 T1 t1;
65 t1 = t0;
66 assert(std::get<0>(t1) == 2);
67 assert(std::get<1>(t1) == int('a'));
68 }
69 {
70 typedef std::tuple<long, char, D> T0;
71 typedef std::tuple<long long, int, B> T1;
72 T0 t0(2, 'a', D(3));
73 T1 t1;
74 t1 = t0;
75 assert(std::get<0>(t1) == 2);
76 assert(std::get<1>(t1) == int('a'));
77 assert(std::get<2>(t1).id_ == 3);
78 }
79 {
80 D d(3);
81 D d2(2);
82 typedef std::tuple<long, char, D&> T0;
83 typedef std::tuple<long long, int, B&> T1;
84 T0 t0(2, 'a', d2);
85 T1 t1(1, 'b', d);
86 t1 = t0;
87 assert(std::get<0>(t1) == 2);
88 assert(std::get<1>(t1) == int('a'));
89 assert(std::get<2>(t1).id_ == 2);
90 }
91 {
92 // Test that tuple evaluates correctly applies an lvalue reference
93 // before evaluating is_assignable (i.e. 'is_assignable<int&, int&>')
94 // instead of evaluating 'is_assignable<int&&, int&>' which is false.
95 int x = 42;
96 int y = 43;
97 std::tuple<int&&> t(std::move(x));
98 std::tuple<int&> t2(y);
99 t = t2;
100 assert(std::get<0>(t) == 43);
101 assert(&std::get<0>(t) == &x);
102 }
103 return true;
104}
105
106int main(int, char**)
107{
108 test();
109#if TEST_STD_VER >= 20
110 static_assert(test());
111#endif
112
113 {
114 using T = std::tuple<int, NonAssignable>;
115 using U = std::tuple<NonAssignable, int>;
116 static_assert(!std::is_assignable<T&, U const&>::value, "");
117 static_assert(!std::is_assignable<U&, T const&>::value, "");
118 }
119 {
120 typedef std::tuple<NothrowCopyAssignable, long> T0;
121 typedef std::tuple<NothrowCopyAssignable, int> T1;
122 static_assert(std::is_nothrow_assignable<T0&, T1 const&>::value, "");
123 }
124 {
125 typedef std::tuple<PotentiallyThrowingCopyAssignable, long> T0;
126 typedef std::tuple<PotentiallyThrowingCopyAssignable, int> T1;
127 static_assert(std::is_assignable<T0&, T1 const&>::value, "");
128 static_assert(!std::is_nothrow_assignable<T0&, T1 const&>::value, "");
129 }
130
131 return 0;
132}
133

source code of libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp