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... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
15 
16 #include <tuple>
17 #include <utility>
18 #include <array>
19 #include <string>
20 #include <cassert>
21 
22 #include "../MoveOnly.h"
23 
24 int main()
25 {
26     {
27         std::tuple<> t = std::tuple_cat();
28     }
29     {
30         std::tuple<> t1;
31         std::tuple<> t2 = std::tuple_cat(t1);
32     }
33     {
34         std::tuple<> t = std::tuple_cat(std::tuple<>());
35     }
36     {
37         std::tuple<> t = std::tuple_cat(std::array<int, 0>());
38     }
39     {
40         std::tuple<int> t1(1);
41         std::tuple<int> t = std::tuple_cat(t1);
42         assert(std::get<0>(t) == 1);
43     }
44 
45 #if _LIBCPP_STD_VER > 11
46     {
47         constexpr std::tuple<> t = std::tuple_cat();
48     }
49     {
50         constexpr std::tuple<> t1;
51         constexpr std::tuple<> t2 = std::tuple_cat(t1);
52     }
53     {
54         constexpr std::tuple<> t = std::tuple_cat(std::tuple<>());
55     }
56     {
57         constexpr std::tuple<> t = std::tuple_cat(std::array<int, 0>());
58     }
59     {
60         constexpr std::tuple<int> t1(1);
61         constexpr std::tuple<int> t = std::tuple_cat(t1);
62         static_assert(std::get<0>(t) == 1, "");
63     }
64     {
65         constexpr std::tuple<int> t1(1);
66         constexpr std::tuple<int, int> t = std::tuple_cat(t1, t1);
67         static_assert(std::get<0>(t) == 1, "");
68         static_assert(std::get<1>(t) == 1, "");
69     }
70 #endif
71     {
72         std::tuple<int, MoveOnly> t =
73                                 std::tuple_cat(std::tuple<int, MoveOnly>(1, 2));
74         assert(std::get<0>(t) == 1);
75         assert(std::get<1>(t) == 2);
76     }
77     {
78         std::tuple<int, int, int> t = std::tuple_cat(std::array<int, 3>());
79         assert(std::get<0>(t) == 0);
80         assert(std::get<1>(t) == 0);
81         assert(std::get<2>(t) == 0);
82     }
83     {
84         std::tuple<int, MoveOnly> t = std::tuple_cat(std::pair<int, MoveOnly>(2, 1));
85         assert(std::get<0>(t) == 2);
86         assert(std::get<1>(t) == 1);
87     }
88 
89     {
90         std::tuple<> t1;
91         std::tuple<> t2;
92         std::tuple<> t3 = std::tuple_cat(t1, t2);
93     }
94     {
95         std::tuple<> t1;
96         std::tuple<int> t2(2);
97         std::tuple<int> t3 = std::tuple_cat(t1, t2);
98         assert(std::get<0>(t3) == 2);
99     }
100     {
101         std::tuple<> t1;
102         std::tuple<int> t2(2);
103         std::tuple<int> t3 = std::tuple_cat(t2, t1);
104         assert(std::get<0>(t3) == 2);
105     }
106     {
107         std::tuple<int*> t1;
108         std::tuple<int> t2(2);
109         std::tuple<int*, int> t3 = std::tuple_cat(t1, t2);
110         assert(std::get<0>(t3) == nullptr);
111         assert(std::get<1>(t3) == 2);
112     }
113     {
114         std::tuple<int*> t1;
115         std::tuple<int> t2(2);
116         std::tuple<int, int*> t3 = std::tuple_cat(t2, t1);
117         assert(std::get<0>(t3) == 2);
118         assert(std::get<1>(t3) == nullptr);
119     }
120     {
121         std::tuple<int*> t1;
122         std::tuple<int, double> t2(2, 3.5);
123         std::tuple<int*, int, double> t3 = std::tuple_cat(t1, t2);
124         assert(std::get<0>(t3) == nullptr);
125         assert(std::get<1>(t3) == 2);
126         assert(std::get<2>(t3) == 3.5);
127     }
128     {
129         std::tuple<int*> t1;
130         std::tuple<int, double> t2(2, 3.5);
131         std::tuple<int, double, int*> t3 = std::tuple_cat(t2, t1);
132         assert(std::get<0>(t3) == 2);
133         assert(std::get<1>(t3) == 3.5);
134         assert(std::get<2>(t3) == nullptr);
135     }
136     {
137         std::tuple<int*, MoveOnly> t1(nullptr, 1);
138         std::tuple<int, double> t2(2, 3.5);
139         std::tuple<int*, MoveOnly, int, double> t3 =
140                                               std::tuple_cat(std::move(t1), t2);
141         assert(std::get<0>(t3) == nullptr);
142         assert(std::get<1>(t3) == 1);
143         assert(std::get<2>(t3) == 2);
144         assert(std::get<3>(t3) == 3.5);
145     }
146     {
147         std::tuple<int*, MoveOnly> t1(nullptr, 1);
148         std::tuple<int, double> t2(2, 3.5);
149         std::tuple<int, double, int*, MoveOnly> t3 =
150                                               std::tuple_cat(t2, std::move(t1));
151         assert(std::get<0>(t3) == 2);
152         assert(std::get<1>(t3) == 3.5);
153         assert(std::get<2>(t3) == nullptr);
154         assert(std::get<3>(t3) == 1);
155     }
156     {
157         std::tuple<MoveOnly, MoveOnly> t1(1, 2);
158         std::tuple<int*, MoveOnly> t2(nullptr, 4);
159         std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =
160                                    std::tuple_cat(std::move(t1), std::move(t2));
161         assert(std::get<0>(t3) == 1);
162         assert(std::get<1>(t3) == 2);
163         assert(std::get<2>(t3) == nullptr);
164         assert(std::get<3>(t3) == 4);
165     }
166 
167     {
168         std::tuple<MoveOnly, MoveOnly> t1(1, 2);
169         std::tuple<int*, MoveOnly> t2(nullptr, 4);
170         std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =
171                                    std::tuple_cat(std::tuple<>(),
172                                                   std::move(t1),
173                                                   std::move(t2));
174         assert(std::get<0>(t3) == 1);
175         assert(std::get<1>(t3) == 2);
176         assert(std::get<2>(t3) == nullptr);
177         assert(std::get<3>(t3) == 4);
178     }
179     {
180         std::tuple<MoveOnly, MoveOnly> t1(1, 2);
181         std::tuple<int*, MoveOnly> t2(nullptr, 4);
182         std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =
183                                    std::tuple_cat(std::move(t1),
184                                                   std::tuple<>(),
185                                                   std::move(t2));
186         assert(std::get<0>(t3) == 1);
187         assert(std::get<1>(t3) == 2);
188         assert(std::get<2>(t3) == nullptr);
189         assert(std::get<3>(t3) == 4);
190     }
191     {
192         std::tuple<MoveOnly, MoveOnly> t1(1, 2);
193         std::tuple<int*, MoveOnly> t2(nullptr, 4);
194         std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =
195                                    std::tuple_cat(std::move(t1),
196                                                   std::move(t2),
197                                                   std::tuple<>());
198         assert(std::get<0>(t3) == 1);
199         assert(std::get<1>(t3) == 2);
200         assert(std::get<2>(t3) == nullptr);
201         assert(std::get<3>(t3) == 4);
202     }
203     {
204         std::tuple<MoveOnly, MoveOnly> t1(1, 2);
205         std::tuple<int*, MoveOnly> t2(nullptr, 4);
206         std::tuple<MoveOnly, MoveOnly, int*, MoveOnly, int> t3 =
207                                    std::tuple_cat(std::move(t1),
208                                                   std::move(t2),
209                                                   std::tuple<int>(5));
210         assert(std::get<0>(t3) == 1);
211         assert(std::get<1>(t3) == 2);
212         assert(std::get<2>(t3) == nullptr);
213         assert(std::get<3>(t3) == 4);
214         assert(std::get<4>(t3) == 5);
215     }
216 }
217