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// Testing constexpr evaluation
17
18#include <experimental/tuple>
19#include <utility>
20#include <cassert>
21
22constexpr int f_int_0() { return 1; }
23constexpr int f_int_1(int x) { return  x; }
24constexpr int f_int_2(int x, int y) { return (x + y); }
25
26struct A_int_0
27{
28    constexpr A_int_0() {}
29    constexpr int operator()() const { return 1; }
30};
31
32struct A_int_1
33{
34    constexpr A_int_1() {}
35    constexpr int operator()(int x) const { return x; }
36};
37
38struct A_int_2
39{
40    constexpr A_int_2() {}
41    constexpr int operator()(int x, int y) const { return (x + y); }
42};
43
44namespace ex = std::experimental;
45
46template <class Tuple>
47void test_0()
48{
49    // function
50    {
51        constexpr Tuple t{};
52        static_assert(1 == ex::apply(f_int_0, t), "");
53    }
54    // function pointer
55    {
56        constexpr Tuple t{};
57        constexpr auto fp = &f_int_0;
58        static_assert(1 == ex::apply(fp, t), "");
59    }
60    // functor
61    {
62        constexpr Tuple t{};
63        constexpr A_int_0 a;
64        static_assert(1 == ex::apply(a, t), "");
65    }
66}
67
68template <class Tuple>
69void test_1()
70{
71    // function
72    {
73        constexpr Tuple t{1};
74        static_assert(1 == ex::apply(f_int_1, t), "");
75    }
76    // function pointer
77    {
78        constexpr Tuple t{2};
79        constexpr int (*fp)(int) = f_int_1;
80        static_assert(2 == ex::apply(fp, t), "");
81    }
82    // functor
83    {
84        constexpr Tuple t{3};
85        constexpr A_int_1 fn;
86        static_assert(3 == ex::apply(fn, t), "");
87    }
88}
89
90template <class Tuple>
91void test_2()
92{
93    // function
94    {
95        constexpr Tuple t{1, 2};
96        static_assert(3 == ex::apply(f_int_2, t), "");
97    }
98        // function pointer
99    {
100        constexpr Tuple t{2, 3};
101        constexpr auto fp = &f_int_2;
102        static_assert(5 == ex::apply(fp, t), "");
103    }
104    // functor
105    {
106        constexpr Tuple t{3, 4};
107        constexpr A_int_2 a;
108        static_assert(7 == ex::apply(a, t), "");
109    }
110}
111
112int main()
113{
114    test_0<std::tuple<>>();
115    test_1<std::tuple<int>>();
116    test_2<std::tuple<int, int>>();
117    test_2<std::pair<int, int>>();
118}
119