types.pass.cpp revision 1d4a1edbc7e4461b59239e1b8297e9dd395a6322
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// 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
23namespace 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}
428