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
24int 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