113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier//===----------------------------------------------------------------------===//
213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier//
313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier//                     The LLVM Compiler Infrastructure
413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier//
513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier// Source Licenses. See LICENSE.TXT for details.
713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier//
813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier//===----------------------------------------------------------------------===//
913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
1013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier// UNSUPPORTED: c++98, c++03, c++11
1113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
1213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier// <experimental/tuple>
1313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
1413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
1513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
1613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier// Testing constexpr evaluation
1713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
1813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier#include <experimental/tuple>
1913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier#include <utility>
2013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier#include <cassert>
2113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
2213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselierconstexpr int f_int_0() { return 1; }
2313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselierconstexpr int f_int_1(int x) { return  x; }
2413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselierconstexpr int f_int_2(int x, int y) { return (x + y); }
2513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
2613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselierstruct A_int_0
2713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier{
2813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    constexpr A_int_0() {}
2913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    constexpr int operator()() const { return 1; }
3013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier};
3113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
3213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselierstruct A_int_1
3313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier{
3413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    constexpr A_int_1() {}
3513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    constexpr int operator()(int x) const { return x; }
3613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier};
3713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
3813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselierstruct A_int_2
3913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier{
4013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    constexpr A_int_2() {}
4113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    constexpr int operator()(int x, int y) const { return (x + y); }
4213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier};
4313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
4413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiseliernamespace ex = std::experimental;
4513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
4613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiseliertemplate <class Tuple>
4713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiseliervoid test_0()
4813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier{
4913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // function
5013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
5113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{};
5213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(1 == ex::apply(f_int_0, t), "");
5313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
5413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // function pointer
5513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
5613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{};
5713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr auto fp = &f_int_0;
5813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(1 == ex::apply(fp, t), "");
5913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
6013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // functor
6113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
6213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{};
6313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr A_int_0 a;
6413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(1 == ex::apply(a, t), "");
6513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
6613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier}
6713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
6813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiseliertemplate <class Tuple>
6913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiseliervoid test_1()
7013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier{
7113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // function
7213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
7313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{1};
7413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(1 == ex::apply(f_int_1, t), "");
7513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
7613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // function pointer
7713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
7813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{2};
7913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr int (*fp)(int) = f_int_1;
8013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(2 == ex::apply(fp, t), "");
8113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
8213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // functor
8313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
8413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{3};
8513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr A_int_1 fn;
8613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(3 == ex::apply(fn, t), "");
8713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
8813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier}
8913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
9013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiseliertemplate <class Tuple>
9113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiseliervoid test_2()
9213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier{
9313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // function
9413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
9513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{1, 2};
9613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(3 == ex::apply(f_int_2, t), "");
9713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
9813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        // function pointer
9913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
10013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{2, 3};
10113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr auto fp = &f_int_2;
10213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(5 == ex::apply(fp, t), "");
10313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
10413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    // functor
10513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    {
10613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr Tuple t{3, 4};
10713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        constexpr A_int_2 a;
10813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier        static_assert(7 == ex::apply(a, t), "");
10913858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    }
11013858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier}
11113858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier
11213858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselierint main()
11313858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier{
11413858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    test_0<std::tuple<>>();
11513858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    test_1<std::tuple<int>>();
11613858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    test_2<std::tuple<int, int>>();
11713858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier    test_2<std::pair<int, int>>();
11813858ee05627bba4d0e7609ff84ad71d8d7e3ca0Eric Fiselier}
119