xref: /llvm-project/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp (revision 82c4701d4e7e6c3bb879a5e98d660a126025b87a)
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 
24 struct B
25 {
26     int id_;
27 
28     explicit B(int i = 0) : id_(i) {}
29 };
30 
31 struct D
32     : B
33 {
34     explicit D(int i = 0) : B(i) {}
35 };
36 
37 struct NonAssignable {
38   NonAssignable& operator=(NonAssignable const&) = delete;
39   NonAssignable& operator=(NonAssignable&&) = delete;
40 };
41 
42 int main(int, char**)
43 {
44     {
45         typedef std::tuple<long> T0;
46         typedef std::tuple<long long> T1;
47         T0 t0(2);
48         T1 t1;
49         t1 = t0;
50         assert(std::get<0>(t1) == 2);
51     }
52     {
53         typedef std::tuple<long, char> T0;
54         typedef std::tuple<long long, int> T1;
55         T0 t0(2, 'a');
56         T1 t1;
57         t1 = t0;
58         assert(std::get<0>(t1) == 2);
59         assert(std::get<1>(t1) == int('a'));
60     }
61     {
62         typedef std::tuple<long, char, D> T0;
63         typedef std::tuple<long long, int, B> T1;
64         T0 t0(2, 'a', D(3));
65         T1 t1;
66         t1 = t0;
67         assert(std::get<0>(t1) == 2);
68         assert(std::get<1>(t1) == int('a'));
69         assert(std::get<2>(t1).id_ == 3);
70     }
71     {
72         D d(3);
73         D d2(2);
74         typedef std::tuple<long, char, D&> T0;
75         typedef std::tuple<long long, int, B&> T1;
76         T0 t0(2, 'a', d2);
77         T1 t1(1, 'b', d);
78         t1 = t0;
79         assert(std::get<0>(t1) == 2);
80         assert(std::get<1>(t1) == int('a'));
81         assert(std::get<2>(t1).id_ == 2);
82     }
83     {
84         // Test that tuple evaluates correctly applies an lvalue reference
85         // before evaluating is_assignable (i.e. 'is_assignable<int&, int&>')
86         // instead of evaluating 'is_assignable<int&&, int&>' which is false.
87         int x = 42;
88         int y = 43;
89         std::tuple<int&&> t(std::move(x));
90         std::tuple<int&> t2(y);
91         t = t2;
92         assert(std::get<0>(t) == 43);
93         assert(&std::get<0>(t) == &x);
94     }
95     {
96       using T = std::tuple<int, NonAssignable>;
97       using U = std::tuple<NonAssignable, int>;
98       static_assert(!std::is_assignable<T, U const&>::value, "");
99       static_assert(!std::is_assignable<U, T const&>::value, "");
100     }
101 
102   return 0;
103 }
104