blob: 5d3d564c26fbbab0bbe2852f195c0e72f059029d [file] [log] [blame]
Eric Fiselier13858ee2015-03-17 18:28:14 +00001//===----------------------------------------------------------------------===//
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// UNSUPPORTED: c++98, c++03, c++11
11
12// <experimental/tuple>
13
14// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
15
16// Test function types.
17
18#include <experimental/tuple>
19#include <array>
20#include <utility>
21#include <cassert>
22
Eric Fiselier13858ee2015-03-17 18:28:14 +000023namespace ex = std::experimental;
24
25int count = 0;
26
27void f_void_0() { ++count; }
28void f_void_1(int i) { count += i; }
29void f_void_2(int x, int y) { count += (x + y); }
30void f_void_3(int x, int y, int z) { count += (x + y + z); }
31
32int f_int_0() { return ++count; }
33int f_int_1(int x) { return count += x; }
34int f_int_2(int x, int y) { return count += (x + y); }
35int f_int_3(int x, int y, int z) { return count += (x + y + z); }
36
37struct A_void_0
38{
39 A_void_0() {}
40 void operator()() { ++count; }
41 void operator()() const { ++count; ++count; }
42};
43
44struct A_void_1
45{
46 A_void_1() {}
47 void operator()(int x) { count += x; }
48 void operator()(int x) const { count += x + 1; }
49};
50
51struct A_void_2
52{
53 A_void_2() {}
54 void operator()(int x, int y) { count += (x + y); }
55 void operator()(int x, int y) const { count += (x + y) + 1; }
56};
57
58struct A_void_3
59{
60 A_void_3() {}
61 void operator()(int x, int y, int z) { count += (x + y + z); }
62 void operator()(int x, int y, int z) const { count += (x + y + z) + 1; }
63};
64
65
66struct A_int_0
67{
68 A_int_0() {}
69 int operator()() { return ++count; }
70 int operator()() const { ++count; return ++count; }
71};
72
73struct A_int_1
74{
75 A_int_1() {}
76 int operator()(int x) { return count += x; }
77 int operator()(int x) const { return count += (x + 1); }
78
79};
80
81struct A_int_2
82{
83 A_int_2() {}
84 int operator()(int x, int y) { return count += (x + y); }
85 int operator()(int x, int y) const { return count += (x + y + 1); }
86};
87
88struct A_int_3
89{
90 A_int_3() {}
91 int operator()(int x, int y, int z) { return count += (x + y + z); }
92 int operator()(int x, int y, int z) const { return count += (x + y + z + 1); }
93};
94
95
96template <class Tuple>
97void test_void_0()
98{
99 count = 0;
100 // function
101 {
102 Tuple t{};
103 ex::apply(f_void_0, t);
104 assert(count == 1);
105 }
106 count = 0;
107 // function pointer
108 {
109 Tuple t{};
110 auto fp = &f_void_0;
111 ex::apply(fp, t);
112 assert(count == 1);
113 }
114 count = 0;
115 // functor
116 {
117 Tuple t{};
118 A_void_0 a;
119 ex::apply(a, t);
120 assert(count == 1);
121 }
122 count = 0;
123 // const functor
124 {
125 Tuple t{};
126 A_void_0 const a;
127 ex::apply(a, t);
128 assert(count == 2);
129 }
130}
131
132template <class Tuple>
133void test_void_1()
134{
135 count = 0;
136 // function
137 {
138 Tuple t{1};
139 ex::apply(f_void_1, t);
140 assert(count == 1);
141 }
142 count = 0;
143 // function pointer
144 {
145 Tuple t{2};
146 void (*fp)(int) = f_void_1;
147 ex::apply(fp, t);
148 assert(count == 2);
149 }
150 count = 0;
151 // functor
152 {
153 Tuple t{3};
154 A_void_1 fn;
155 ex::apply(fn, t);
156 assert(count == 3);
157 }
158 count = 0;
159 // const functor
160 {
161 Tuple t{4};
162 A_void_1 const a;
163 ex::apply(a, t);
164 assert(count == 5);
165 }
166}
167
168template <class Tuple>
169void test_void_2()
170{
171 count = 0;
172 // function
173 {
174 Tuple t{1, 2};
175 ex::apply(f_void_2, t);
176 assert(count == 3);
177 }
178 count = 0;
179 // function pointer
180 {
181 Tuple t{2, 3};
182 auto fp = &f_void_2;
183 ex::apply(fp, t);
184 assert(count == 5);
185 }
186 count = 0;
187 // functor
188 {
189 Tuple t{3, 4};
190 A_void_2 a;
191 ex::apply(a, t);
192 assert(count == 7);
193 }
194 count = 0;
195 // const functor
196 {
197 Tuple t{4, 5};
198 A_void_2 const a;
199 ex::apply(a, t);
200 assert(count == 10);
201 }
202}
203
204template <class Tuple>
205void test_void_3()
206{
207 count = 0;
208 // function
209 {
210 Tuple t{1, 2, 3};
211 ex::apply(f_void_3, t);
212 assert(count == 6);
213 }
214 count = 0;
215 // function pointer
216 {
217 Tuple t{2, 3, 4};
218 auto fp = &f_void_3;
219 ex::apply(fp, t);
220 assert(count == 9);
221 }
222 count = 0;
223 // functor
224 {
225 Tuple t{3, 4, 5};
226 A_void_3 a;
227 ex::apply(a, t);
228 assert(count == 12);
229 }
230 count = 0;
231 // const functor
232 {
233 Tuple t{4, 5, 6};
234 A_void_3 const a;
235 ex::apply(a, t);
236 assert(count == 16);
237 }
238}
239
240
241
242template <class Tuple>
243void test_int_0()
244{
245 count = 0;
246 // function
247 {
248 Tuple t{};
249 assert(1 == ex::apply(f_int_0, t));
250 assert(count == 1);
251 }
252 count = 0;
253 // function pointer
254 {
255 Tuple t{};
256 auto fp = &f_int_0;
257 assert(1 == ex::apply(fp, t));
258 assert(count == 1);
259 }
260 count = 0;
261 // functor
262 {
263 Tuple t{};
264 A_int_0 a;
265 assert(1 == ex::apply(a, t));
266 assert(count == 1);
267 }
268 count = 0;
269 // const functor
270 {
271 Tuple t{};
272 A_int_0 const a;
273 assert(2 == ex::apply(a, t));
274 assert(count == 2);
275 }
276}
277
278template <class Tuple>
279void test_int_1()
280{
281 count = 0;
282 // function
283 {
284 Tuple t{1};
285 assert(1 == ex::apply(f_int_1, t));
286 assert(count == 1);
287 }
288 count = 0;
289 // function pointer
290 {
291 Tuple t{2};
292 int (*fp)(int) = f_int_1;
293 assert(2 == ex::apply(fp, t));
294 assert(count == 2);
295 }
296 count = 0;
297 // functor
298 {
299 Tuple t{3};
300 A_int_1 fn;
301 assert(3 == ex::apply(fn, t));
302 assert(count == 3);
303 }
304 count = 0;
305 // const functor
306 {
307 Tuple t{4};
308 A_int_1 const a;
309 assert(5 == ex::apply(a, t));
310 assert(count == 5);
311 }
312}
313
314template <class Tuple>
315void test_int_2()
316{
317 count = 0;
318 // function
319 {
320 Tuple t{1, 2};
321 assert(3 == ex::apply(f_int_2, t));
322 assert(count == 3);
323 }
324 count = 0;
325 // function pointer
326 {
327 Tuple t{2, 3};
328 auto fp = &f_int_2;
329 assert(5 == ex::apply(fp, t));
330 assert(count == 5);
331 }
332 count = 0;
333 // functor
334 {
335 Tuple t{3, 4};
336 A_int_2 a;
337 assert(7 == ex::apply(a, t));
338 assert(count == 7);
339 }
340 count = 0;
341 // const functor
342 {
343 Tuple t{4, 5};
344 A_int_2 const a;
345 assert(10 == ex::apply(a, t));
346 assert(count == 10);
347 }
348}
349
350template <class Tuple>
351void test_int_3()
352{
353 count = 0;
354 // function
355 {
356 Tuple t{1, 2, 3};
357 assert(6 == ex::apply(f_int_3, t));
358 assert(count == 6);
359 }
360 count = 0;
361 // function pointer
362 {
363 Tuple t{2, 3, 4};
364 auto fp = &f_int_3;
365 assert(9 == ex::apply(fp, t));
366 assert(count == 9);
367 }
368 count = 0;
369 // functor
370 {
371 Tuple t{3, 4, 5};
372 A_int_3 a;
373 assert(12 == ex::apply(a, t));
374 assert(count == 12);
375 }
376 count = 0;
377 // const functor
378 {
379 Tuple t{4, 5, 6};
380 A_int_3 const a;
381 assert(16 == ex::apply(a, t));
382 assert(count == 16);
383 }
384}
385
386template <class Tuple>
387void test_0()
388{
389 test_void_0<Tuple>();
390 test_int_0<Tuple>();
391}
392
393template <class Tuple>
394void test_1()
395{
396 test_void_1<Tuple>();
397 test_int_1<Tuple>();
398}
399
400template <class Tuple>
401void test_2()
402{
403 test_void_2<Tuple>();
404 test_int_2<Tuple>();
405}
406
407template <class Tuple>
408void test_3()
409{
410 test_void_3<Tuple>();
411 test_int_3<Tuple>();
412}
413
414int main()
415{
416 test_0<std::tuple<>>();
417
418 test_1<std::tuple<int>>();
419 test_1<std::array<int, 1>>();
420
421 test_2<std::tuple<int, int>>();
422 test_2<std::pair<int, int>>();
423 test_2<std::array<int, 2>>();
424
425 test_3<std::tuple<int, int, int>>();
426 test_3<std::array<int, 3>>();
427}