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// tuple& operator=(const tuple& u);
14
15// UNSUPPORTED: c++03
16
17#include <tuple>
18#include <memory>
19#include <string>
20#include <cassert>
21
22#include "test_macros.h"
23
24struct NonAssignable {
25 NonAssignable& operator=(NonAssignable const&) = delete;
26 NonAssignable& operator=(NonAssignable&&) = delete;
27};
28struct CopyAssignable {
29 CopyAssignable& operator=(CopyAssignable const&) = default;
30 CopyAssignable& operator=(CopyAssignable &&) = delete;
31};
32static_assert(std::is_copy_assignable<CopyAssignable>::value, "");
33struct MoveAssignable {
34 MoveAssignable& operator=(MoveAssignable const&) = delete;
35 MoveAssignable& operator=(MoveAssignable&&) = default;
36};
37struct NothrowCopyAssignable {
38 NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }
39};
40struct PotentiallyThrowingCopyAssignable {
41 PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }
42};
43
44struct CopyAssignableInt {
45 CopyAssignableInt& operator=(int&) { return *this; }
46};
47
48TEST_CONSTEXPR_CXX20
49bool test()
50{
51 {
52 typedef std::tuple<> T;
53 T t0;
54 T t;
55 t = t0;
56 }
57 {
58 typedef std::tuple<int> T;
59 T t0(2);
60 T t;
61 t = t0;
62 assert(std::get<0>(t) == 2);
63 }
64 {
65 typedef std::tuple<int, char> T;
66 T t0(2, 'a');
67 T t;
68 t = t0;
69 assert(std::get<0>(t) == 2);
70 assert(std::get<1>(t) == 'a');
71 }
72 {
73 // test reference assignment.
74 using T = std::tuple<int&, int&&>;
75 int x = 42;
76 int y = 100;
77 int x2 = -1;
78 int y2 = 500;
79 T t(x, std::move(y));
80 T t2(x2, std::move(y2));
81 t = t2;
82 assert(std::get<0>(t) == x2);
83 assert(&std::get<0>(t) == &x);
84 assert(std::get<1>(t) == y2);
85 assert(&std::get<1>(t) == &y);
86 }
87
88 return true;
89}
90
91int main(int, char**)
92{
93 test();
94#if TEST_STD_VER >= 20
95 static_assert(test());
96#endif
97
98 {
99 // cannot be constexpr because of std::string
100 typedef std::tuple<int, char, std::string> T;
101 const T t0(2, 'a', "some text");
102 T t;
103 t = t0;
104 assert(std::get<0>(t) == 2);
105 assert(std::get<1>(t) == 'a');
106 assert(std::get<2>(t) == "some text");
107 }
108 {
109 // test that the implicitly generated copy assignment operator
110 // is properly deleted
111 using T = std::tuple<std::unique_ptr<int>>;
112 static_assert(!std::is_copy_assignable<T>::value, "");
113 }
114 {
115 using T = std::tuple<int, NonAssignable>;
116 static_assert(!std::is_copy_assignable<T>::value, "");
117 }
118 {
119 using T = std::tuple<int, CopyAssignable>;
120 static_assert(std::is_copy_assignable<T>::value, "");
121 }
122 {
123 using T = std::tuple<int, MoveAssignable>;
124 static_assert(!std::is_copy_assignable<T>::value, "");
125 }
126 {
127 using T = std::tuple<int, int, int>;
128 using P = std::pair<int, int>;
129 static_assert(!std::is_assignable<T&, P>::value, "");
130 }
131 {
132 // test const requirement
133 using T = std::tuple<CopyAssignableInt, CopyAssignableInt>;
134 using P = std::pair<int, int>;
135 static_assert(!std::is_assignable<T&, P const>::value, "");
136 }
137 {
138 using T = std::tuple<int, MoveAssignable>;
139 using P = std::pair<int, MoveAssignable>;
140 static_assert(!std::is_assignable<T&, P&>::value, "");
141 }
142 {
143 using T = std::tuple<NothrowCopyAssignable, int>;
144 static_assert(std::is_nothrow_copy_assignable<T>::value, "");
145 }
146 {
147 using T = std::tuple<PotentiallyThrowingCopyAssignable, int>;
148 static_assert(std::is_copy_assignable<T>::value, "");
149 static_assert(!std::is_nothrow_copy_assignable<T>::value, "");
150 }
151
152 return 0;
153}
154

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