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 
BB28     explicit B(int i = 0) : id_(i) {}
29 };
30 
31 struct D
32     : B
33 {
DD34     explicit D(int i = 0) : B(i) {}
35 };
36 
main(int,char **)37 int main(int, char**)
38 {
39     {
40         typedef std::tuple<long> T0;
41         typedef std::tuple<long long> T1;
42         T0 t0(2);
43         T1 t1;
44         t1 = t0;
45         assert(std::get<0>(t1) == 2);
46     }
47     {
48         typedef std::tuple<long, char> T0;
49         typedef std::tuple<long long, int> T1;
50         T0 t0(2, 'a');
51         T1 t1;
52         t1 = t0;
53         assert(std::get<0>(t1) == 2);
54         assert(std::get<1>(t1) == int('a'));
55     }
56     {
57         typedef std::tuple<long, char, D> T0;
58         typedef std::tuple<long long, int, B> T1;
59         T0 t0(2, 'a', D(3));
60         T1 t1;
61         t1 = t0;
62         assert(std::get<0>(t1) == 2);
63         assert(std::get<1>(t1) == int('a'));
64         assert(std::get<2>(t1).id_ == 3);
65     }
66     {
67         D d(3);
68         D d2(2);
69         typedef std::tuple<long, char, D&> T0;
70         typedef std::tuple<long long, int, B&> T1;
71         T0 t0(2, 'a', d2);
72         T1 t1(1, 'b', d);
73         t1 = t0;
74         assert(std::get<0>(t1) == 2);
75         assert(std::get<1>(t1) == int('a'));
76         assert(std::get<2>(t1).id_ == 2);
77     }
78     {
79         // Test that tuple evaluates correctly applies an lvalue reference
80         // before evaluating is_assignable (i.e. 'is_assignable<int&, int&>')
81         // instead of evaluating 'is_assignable<int&&, int&>' which is false.
82         int x = 42;
83         int y = 43;
84         std::tuple<int&&> t(std::move(x));
85         std::tuple<int&> t2(y);
86         t = t2;
87         assert(std::get<0>(t) == 43);
88         assert(&std::get<0>(t) == &x);
89     }
90 
91   return 0;
92 }
93