148 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// <tuple>12 13// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)14 15// Stress testing large arities with tuple and array.16 17#include <tuple>18#include <array>19#include <utility>20#include <cassert>21 22#include "test_macros.h"23 24////////////////////////////////////////////////////////////////////////////////25template <class T, std::size_t Dummy = 0>26struct always_imp27{28 typedef T type;29};30 31template <class T, std::size_t Dummy = 0>32using always_t = typename always_imp<T, Dummy>::type;33 34////////////////////////////////////////////////////////////////////////////////35template <class Tuple, class Idx>36struct make_function;37 38template <class Tp, std::size_t ...Idx>39struct make_function<Tp, std::integer_sequence<std::size_t, Idx...>>40{41 using type = bool (*)(always_t<Tp, Idx>...);42};43 44template <class Tp, std::size_t Size>45using make_function_t = typename make_function<Tp, std::make_index_sequence<Size>>::type;46 47////////////////////////////////////////////////////////////////////////////////48template <class Tp, class Idx>49struct make_tuple_imp;50 51////////////////////////////////////////////////////////////////////////////////52template <class Tp, std::size_t ...Idx>53struct make_tuple_imp<Tp, std::integer_sequence<std::size_t, Idx...>>54{55 using type = std::tuple<always_t<Tp, Idx>...>;56};57 58template <class Tp, std::size_t Size>59using make_tuple_t = typename make_tuple_imp<Tp, std::make_index_sequence<Size>>::type;60 61template <class ...Types>62bool test_apply_fn(Types...) { return true; }63 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(std::apply(val_fn, a));90 assert(std::apply(ref_fn, a));91 assert(std::apply(cref_fn, a));92 assert(std::apply(rref_fn, std::move(a)));93 }94 {95 ConstA a{};96 assert(std::apply(val_fn, a));97 assert(std::apply(cref_fn, a));98 }99 {100 Tuple a{};101 assert(std::apply(val_fn, a));102 assert(std::apply(ref_fn, a));103 assert(std::apply(cref_fn, a));104 assert(std::apply(rref_fn, std::move(a)));105 }106 {107 CTuple a{};108 assert(std::apply(val_fn, a));109 assert(std::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(std::apply(val_fn, a));127 }128 {129 Tuple a{};130 assert(std::apply(val_fn, a));131 }132}133 134int main(int, char**)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 256144 test_one<256>();145 146 return 0;147}148