xref: /llvm-project/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp (revision 5f5416e1c4b418d59f7f944060c8a39ced2189a0)
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 
24 struct NonAssignable {
25   NonAssignable& operator=(NonAssignable const&) = delete;
26   NonAssignable& operator=(NonAssignable&&) = delete;
27 };
28 struct CopyAssignable {
29   CopyAssignable& operator=(CopyAssignable const&) = default;
30   CopyAssignable& operator=(CopyAssignable &&) = delete;
31 };
32 static_assert(std::is_copy_assignable<CopyAssignable>::value, "");
33 struct MoveAssignable {
34   MoveAssignable& operator=(MoveAssignable const&) = delete;
35   MoveAssignable& operator=(MoveAssignable&&) = default;
36 };
37 struct NothrowCopyAssignable {
38   NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }
39 };
40 struct PotentiallyThrowingCopyAssignable {
41   PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }
42 };
43 
44 struct CopyAssignableInt {
45   CopyAssignableInt& operator=(int&) { return *this; }
46 };
47 
48 int main(int, char**)
49 {
50     {
51         typedef std::tuple<> T;
52         T t0;
53         T t;
54         t = t0;
55     }
56     {
57         typedef std::tuple<int> T;
58         T t0(2);
59         T t;
60         t = t0;
61         assert(std::get<0>(t) == 2);
62     }
63     {
64         typedef std::tuple<int, char> T;
65         T t0(2, 'a');
66         T t;
67         t = t0;
68         assert(std::get<0>(t) == 2);
69         assert(std::get<1>(t) == 'a');
70     }
71     {
72         typedef std::tuple<int, char, std::string> T;
73         const T t0(2, 'a', "some text");
74         T t;
75         t = t0;
76         assert(std::get<0>(t) == 2);
77         assert(std::get<1>(t) == 'a');
78         assert(std::get<2>(t) == "some text");
79     }
80     {
81         // test reference assignment.
82         using T = std::tuple<int&, int&&>;
83         int x = 42;
84         int y = 100;
85         int x2 = -1;
86         int y2 = 500;
87         T t(x, std::move(y));
88         T t2(x2, std::move(y2));
89         t = t2;
90         assert(std::get<0>(t) == x2);
91         assert(&std::get<0>(t) == &x);
92         assert(std::get<1>(t) == y2);
93         assert(&std::get<1>(t) == &y);
94     }
95     {
96         // test that the implicitly generated copy assignment operator
97         // is properly deleted
98         using T = std::tuple<std::unique_ptr<int>>;
99         static_assert(!std::is_copy_assignable<T>::value, "");
100     }
101     {
102       using T = std::tuple<int, NonAssignable>;
103       static_assert(!std::is_copy_assignable<T>::value, "");
104     }
105     {
106         using T = std::tuple<int, CopyAssignable>;
107         static_assert(std::is_copy_assignable<T>::value, "");
108     }
109     {
110         using T = std::tuple<int, MoveAssignable>;
111         static_assert(!std::is_copy_assignable<T>::value, "");
112     }
113     {
114         using T = std::tuple<int, int, int>;
115         using P = std::pair<int, int>;
116         static_assert(!std::is_assignable<T&, P>::value, "");
117     }
118     {
119         // test const requirement
120         using T = std::tuple<CopyAssignableInt, CopyAssignableInt>;
121         using P = std::pair<int, int>;
122         static_assert(!std::is_assignable<T&, P const>::value, "");
123     }
124     {
125         using T = std::tuple<int, MoveAssignable>;
126         using P = std::pair<int, MoveAssignable>;
127         static_assert(!std::is_assignable<T&, P&>::value, "");
128     }
129     {
130         using T = std::tuple<NothrowCopyAssignable, int>;
131         static_assert(std::is_nothrow_copy_assignable<T>::value, "");
132     }
133     {
134         using T = std::tuple<PotentiallyThrowingCopyAssignable, int>;
135         static_assert(!std::is_nothrow_copy_assignable<T>::value, "");
136     }
137 
138     return 0;
139 }
140