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// Stress testing large arities with tuple and array. 17 18#include <experimental/tuple> 19#include <array> 20#include <utility> 21#include <cassert> 22 23//////////////////////////////////////////////////////////////////////////////// 24template <class T, std::size_t Dummy = 0> 25struct always_imp 26{ 27 typedef T type; 28}; 29 30template <class T, std::size_t Dummy = 0> 31using always_t = typename always_imp<T, Dummy>::type; 32 33//////////////////////////////////////////////////////////////////////////////// 34template <class Tuple, class Idx> 35struct make_function; 36 37template <class Tp, std::size_t ...Idx> 38struct make_function<Tp, std::integer_sequence<std::size_t, Idx...>> 39{ 40 using type = bool (*)(always_t<Tp, Idx>...); 41}; 42 43template <class Tp, std::size_t Size> 44using make_function_t = typename make_function<Tp, std::make_index_sequence<Size>>::type; 45 46//////////////////////////////////////////////////////////////////////////////// 47template <class Tp, class Idx> 48struct make_tuple_imp; 49 50//////////////////////////////////////////////////////////////////////////////// 51template <class Tp, std::size_t ...Idx> 52struct make_tuple_imp<Tp, std::integer_sequence<std::size_t, Idx...>> 53{ 54 using type = std::tuple<always_t<Tp, Idx>...>; 55}; 56 57template <class Tp, std::size_t Size> 58using make_tuple_t = typename make_tuple_imp<Tp, std::make_index_sequence<Size>>::type; 59 60template <class ...Types> 61bool test_apply_fn(Types...) { return true; } 62 63namespace ex = std::experimental; 64 65template <std::size_t Size> 66void test_all() 67{ 68 69 using A = std::array<int, Size>; 70 using ConstA = std::array<int const, Size>; 71 72 using Tuple = make_tuple_t<int, Size>; 73 using CTuple = make_tuple_t<const int, Size>; 74 75 using ValFn = make_function_t<int, Size>; 76 ValFn val_fn = &test_apply_fn; 77 78 using RefFn = make_function_t<int &, Size>; 79 RefFn ref_fn = &test_apply_fn; 80 81 using CRefFn = make_function_t<int const &, Size>; 82 CRefFn cref_fn = &test_apply_fn; 83 84 using RRefFn = make_function_t<int &&, Size>; 85 RRefFn rref_fn = &test_apply_fn; 86 87 { 88 A a{}; 89 assert(ex::apply(val_fn, a)); 90 assert(ex::apply(ref_fn, a)); 91 assert(ex::apply(cref_fn, a)); 92 assert(ex::apply(rref_fn, std::move(a))); 93 } 94 { 95 ConstA a{}; 96 assert(ex::apply(val_fn, a)); 97 assert(ex::apply(cref_fn, a)); 98 } 99 { 100 Tuple a{}; 101 assert(ex::apply(val_fn, a)); 102 assert(ex::apply(ref_fn, a)); 103 assert(ex::apply(cref_fn, a)); 104 assert(ex::apply(rref_fn, std::move(a))); 105 } 106 { 107 CTuple a{}; 108 assert(ex::apply(val_fn, a)); 109 assert(ex::apply(cref_fn, a)); 110 } 111 112} 113 114 115template <std::size_t Size> 116void test_one() 117{ 118 using A = std::array<int, Size>; 119 using Tuple = make_tuple_t<int, Size>; 120 121 using ValFn = make_function_t<int, Size>; 122 ValFn val_fn = &test_apply_fn; 123 124 { 125 A a{}; 126 assert(ex::apply(val_fn, a)); 127 } 128 { 129 Tuple a{}; 130 assert(ex::apply(val_fn, a)); 131 } 132} 133 134int main() 135{ 136 // Instantiate with 1-5 arguments. 137 test_all<1>(); 138 test_all<2>(); 139 test_all<3>(); 140 test_all<4>(); 141 test_all<5>(); 142 143 // Stress test with 128. 144 test_one<128>(); 145 //test_one<256>(); 146} 147