brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 7d9f586 Raw
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