15839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier//===----------------------------------------------------------------------===//
25839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier//
35839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier//                     The LLVM Compiler Infrastructure
45839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier//
55839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
65839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier// Source Licenses. See LICENSE.TXT for details.
75839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier//
85839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier//===----------------------------------------------------------------------===//
95839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
105839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier// UNSUPPORTED: c++98, c++03, c++11, c++14
115839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
125839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier// <tuple>
135839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
145839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
155839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
165839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier// Stress testing large arities with tuple and array.
175839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
185839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier#include <tuple>
195839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier#include <array>
205839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier#include <utility>
215839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier#include <cassert>
225839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
235839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier////////////////////////////////////////////////////////////////////////////////
245839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class T, std::size_t Dummy = 0>
255839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierstruct always_imp
265839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier{
275839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    typedef T type;
285839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier};
295839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
305839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class T, std::size_t Dummy = 0>
315839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierusing always_t = typename always_imp<T, Dummy>::type;
325839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
335839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier////////////////////////////////////////////////////////////////////////////////
345839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class Tuple, class Idx>
355839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierstruct make_function;
365839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
375839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class Tp, std::size_t ...Idx>
385839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierstruct make_function<Tp, std::integer_sequence<std::size_t, Idx...>>
395839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier{
405839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using type = bool (*)(always_t<Tp, Idx>...);
415839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier};
425839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
435839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class Tp, std::size_t Size>
445839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierusing make_function_t = typename make_function<Tp, std::make_index_sequence<Size>>::type;
455839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
465839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier////////////////////////////////////////////////////////////////////////////////
475839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class Tp, class Idx>
485839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierstruct make_tuple_imp;
495839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
505839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier////////////////////////////////////////////////////////////////////////////////
515839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class Tp, std::size_t ...Idx>
525839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierstruct make_tuple_imp<Tp, std::integer_sequence<std::size_t, Idx...>>
535839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier{
545839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using type = std::tuple<always_t<Tp, Idx>...>;
555839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier};
565839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
575839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class Tp, std::size_t Size>
585839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierusing make_tuple_t = typename make_tuple_imp<Tp, std::make_index_sequence<Size>>::type;
595839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
605839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <class ...Types>
615839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierbool test_apply_fn(Types...) { return true; }
625839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
635839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
645839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <std::size_t Size>
655839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliervoid test_all()
665839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier{
675839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
685839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using A = std::array<int, Size>;
695839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using ConstA = std::array<int const, Size>;
705839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
715839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using Tuple = make_tuple_t<int, Size>;
725839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using CTuple = make_tuple_t<const int, Size>;
735839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
745839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using ValFn  = make_function_t<int, Size>;
755839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    ValFn val_fn = &test_apply_fn;
765839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
775839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using RefFn  = make_function_t<int &, Size>;
785839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    RefFn ref_fn = &test_apply_fn;
795839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
805839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using CRefFn = make_function_t<int const &, Size>;
815839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    CRefFn cref_fn = &test_apply_fn;
825839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
835839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using RRefFn = make_function_t<int &&, Size>;
845839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    RRefFn rref_fn = &test_apply_fn;
855839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
865839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    {
875839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        A a{};
885839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(val_fn, a));
895839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(ref_fn, a));
905839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(cref_fn, a));
915839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(rref_fn, std::move(a)));
925839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    }
935839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    {
945839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        ConstA a{};
955839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(val_fn, a));
965839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(cref_fn, a));
975839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    }
985839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    {
995839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        Tuple a{};
1005839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(val_fn, a));
1015839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(ref_fn, a));
1025839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(cref_fn, a));
1035839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(rref_fn, std::move(a)));
1045839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    }
1055839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    {
1065839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        CTuple a{};
1075839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(val_fn, a));
1085839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(cref_fn, a));
1095839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    }
1105839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
1115839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier}
1125839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
1135839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
1145839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliertemplate <std::size_t Size>
1155839fedf289f656cc6819a775a0328b643dc7c6bEric Fiseliervoid test_one()
1165839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier{
1175839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using A = std::array<int, Size>;
1185839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using Tuple = make_tuple_t<int, Size>;
1195839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
1205839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    using ValFn  = make_function_t<int, Size>;
1215839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    ValFn val_fn = &test_apply_fn;
1225839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
1235839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    {
1245839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        A a{};
1255839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(val_fn, a));
1265839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    }
1275839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    {
1285839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        Tuple a{};
1295839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier        assert(std::apply(val_fn, a));
1305839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    }
1315839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier}
1325839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
1335839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselierint main()
1345839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier{
1355839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    // Instantiate with 1-5 arguments.
1365839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    test_all<1>();
1375839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    test_all<2>();
1385839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    test_all<3>();
1395839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    test_all<4>();
1405839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    test_all<5>();
1415839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier
1425839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    // Stress test with 256
1435839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier    test_one<256>();
1445839fedf289f656cc6819a775a0328b643dc7c6bEric Fiselier}
145