1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // <tuple>
11 
12 // template <class... Types> class tuple;
13 
14 // template <class... UTypes>
15 //   tuple& operator=(tuple<UTypes...>&& u);
16 
17 // UNSUPPORTED: c++98, c++03
18 
19 #include <tuple>
20 #include <string>
21 #include <memory>
22 #include <utility>
23 #include <cassert>
24 
25 struct B
26 {
27     int id_;
28 
BB29     explicit B(int i= 0) : id_(i) {}
30 
~BB31     virtual ~B() {}
32 };
33 
34 struct D
35     : B
36 {
DD37     explicit D(int i) : B(i) {}
38 };
39 
40 struct E {
41   E() = default;
operator =E42   E& operator=(int) {
43       return *this;
44   }
45 };
46 
main()47 int main()
48 {
49     {
50         typedef std::tuple<long> T0;
51         typedef std::tuple<long long> T1;
52         T0 t0(2);
53         T1 t1;
54         t1 = std::move(t0);
55         assert(std::get<0>(t1) == 2);
56     }
57     {
58         typedef std::tuple<long, char> T0;
59         typedef std::tuple<long long, int> T1;
60         T0 t0(2, 'a');
61         T1 t1;
62         t1 = std::move(t0);
63         assert(std::get<0>(t1) == 2);
64         assert(std::get<1>(t1) == int('a'));
65     }
66     {
67         typedef std::tuple<long, char, D> T0;
68         typedef std::tuple<long long, int, B> T1;
69         T0 t0(2, 'a', D(3));
70         T1 t1;
71         t1 = std::move(t0);
72         assert(std::get<0>(t1) == 2);
73         assert(std::get<1>(t1) == int('a'));
74         assert(std::get<2>(t1).id_ == 3);
75     }
76     {
77         D d(3);
78         D d2(2);
79         typedef std::tuple<long, char, D&> T0;
80         typedef std::tuple<long long, int, B&> T1;
81         T0 t0(2, 'a', d2);
82         T1 t1(1, 'b', d);
83         t1 = std::move(t0);
84         assert(std::get<0>(t1) == 2);
85         assert(std::get<1>(t1) == int('a'));
86         assert(std::get<2>(t1).id_ == 2);
87     }
88     {
89         typedef std::tuple<long, char, std::unique_ptr<D>> T0;
90         typedef std::tuple<long long, int, std::unique_ptr<B>> T1;
91         T0 t0(2, 'a', std::unique_ptr<D>(new D(3)));
92         T1 t1;
93         t1 = std::move(t0);
94         assert(std::get<0>(t1) == 2);
95         assert(std::get<1>(t1) == int('a'));
96         assert(std::get<2>(t1)->id_ == 3);
97     }
98     {
99         // Test that tuple evaluates correctly applies an lvalue reference
100         // before evaluating is_assignable (ie 'is_assignable<int&, int&&>')
101         // instead of evaluating 'is_assignable<int&&, int&&>' which is false.
102         int x = 42;
103         int y = 43;
104         std::tuple<int&&, E> t(std::move(x), E{});
105         std::tuple<int&&, int> t2(std::move(y), 44);
106         t = std::move(t2);
107         assert(std::get<0>(t) == 43);
108         assert(&std::get<0>(t) == &x);
109     }
110 }
111