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