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 the return type deduction.
17
18#include <experimental/tuple>
19#include <cassert>
20
21static int my_int = 42;
22
23template <int N> struct index_t {};
24
25void f(index_t<0>) {}
26
27int f(index_t<1>) { return 0; }
28
29int & f(index_t<2>) { return static_cast<int &>(my_int); }
30int const & f(index_t<3>) { return static_cast<int const &>(my_int); }
31int volatile & f(index_t<4>) { return static_cast<int volatile &>(my_int); }
32int const volatile & f(index_t<5>) { return static_cast<int const volatile &>(my_int); }
33
34int && f(index_t<6>) { return static_cast<int &&>(my_int); }
35int const && f(index_t<7>) { return static_cast<int const &&>(my_int); }
36int volatile && f(index_t<8>) { return static_cast<int volatile &&>(my_int); }
37int const volatile && f(index_t<9>) { return static_cast<int const volatile &&>(my_int); }
38
39int * f(index_t<10>) { return static_cast<int *>(&my_int); }
40int const * f(index_t<11>) { return static_cast<int const *>(&my_int); }
41int volatile * f(index_t<12>) { return static_cast<int volatile *>(&my_int); }
42int const volatile * f(index_t<13>) { return static_cast<int const volatile *>(&my_int); }
43
44
45template <int Func, class Expect>
46void test()
47{
48    using F = decltype(f(index_t<Func>{}));
49    static_assert(std::is_same<F, Expect>::value, "");
50}
51
52namespace ex = std::experimental;
53
54int main()
55{
56    test<0, void>();
57    test<1, int>();
58    test<2, int &>();
59    test<3, int const &>();
60    test<4, int volatile &>();
61    test<5, int const volatile &>();
62    test<6, int &&>();
63    test<7, int const &&>();
64    test<8, int volatile &&>();
65    test<9, int const volatile &&>();
66    test<10, int *>();
67    test<11, int const *>();
68    test<12, int volatile *>();
69    test<13, int const volatile *>();
70}
71