xref: /llvm-project/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp (revision 57b08b0944046a6a57ee9b7b479181f548a5b9b4)
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=(tuple<UTypes...>&& u);
15 
16 // UNSUPPORTED: c++98, c++03
17 
18 #include <tuple>
19 #include <string>
20 #include <memory>
21 #include <utility>
22 #include <cassert>
23 
24 struct B
25 {
26     int id_;
27 
28     explicit B(int i= 0) : id_(i) {}
29 
30     virtual ~B() {}
31 };
32 
33 struct D
34     : B
35 {
36     explicit D(int i) : B(i) {}
37 };
38 
39 struct E {
40   E() = default;
41   E& operator=(int) {
42       return *this;
43   }
44 };
45 
46 int main()
47 {
48     {
49         typedef std::tuple<long> T0;
50         typedef std::tuple<long long> T1;
51         T0 t0(2);
52         T1 t1;
53         t1 = std::move(t0);
54         assert(std::get<0>(t1) == 2);
55     }
56     {
57         typedef std::tuple<long, char> T0;
58         typedef std::tuple<long long, int> T1;
59         T0 t0(2, 'a');
60         T1 t1;
61         t1 = std::move(t0);
62         assert(std::get<0>(t1) == 2);
63         assert(std::get<1>(t1) == int('a'));
64     }
65     {
66         typedef std::tuple<long, char, D> T0;
67         typedef std::tuple<long long, int, B> T1;
68         T0 t0(2, 'a', D(3));
69         T1 t1;
70         t1 = std::move(t0);
71         assert(std::get<0>(t1) == 2);
72         assert(std::get<1>(t1) == int('a'));
73         assert(std::get<2>(t1).id_ == 3);
74     }
75     {
76         D d(3);
77         D d2(2);
78         typedef std::tuple<long, char, D&> T0;
79         typedef std::tuple<long long, int, B&> T1;
80         T0 t0(2, 'a', d2);
81         T1 t1(1, 'b', d);
82         t1 = std::move(t0);
83         assert(std::get<0>(t1) == 2);
84         assert(std::get<1>(t1) == int('a'));
85         assert(std::get<2>(t1).id_ == 2);
86     }
87     {
88         typedef std::tuple<long, char, std::unique_ptr<D>> T0;
89         typedef std::tuple<long long, int, std::unique_ptr<B>> T1;
90         T0 t0(2, 'a', std::unique_ptr<D>(new D(3)));
91         T1 t1;
92         t1 = std::move(t0);
93         assert(std::get<0>(t1) == 2);
94         assert(std::get<1>(t1) == int('a'));
95         assert(std::get<2>(t1)->id_ == 3);
96     }
97     {
98         // Test that tuple evaluates correctly applies an lvalue reference
99         // before evaluating is_assignable (ie 'is_assignable<int&, int&&>')
100         // instead of evaluating 'is_assignable<int&&, int&&>' which is false.
101         int x = 42;
102         int y = 43;
103         std::tuple<int&&, E> t(std::move(x), E{});
104         std::tuple<int&&, int> t2(std::move(y), 44);
105         t = std::move(t2);
106         assert(std::get<0>(t) == 43);
107         assert(&std::get<0>(t) == &x);
108     }
109 }
110