apply_large_arity.pass.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // UNSUPPORTED: c++98, c++03, c++11, c++14
  9. // <tuple>
  10. // template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
  11. // Stress testing large arities with tuple and array.
  12. #include <tuple>
  13. #include <array>
  14. #include <utility>
  15. #include <cassert>
  16. ////////////////////////////////////////////////////////////////////////////////
  17. template <class T, std::size_t Dummy = 0>
  18. struct always_imp
  19. {
  20. typedef T type;
  21. };
  22. template <class T, std::size_t Dummy = 0>
  23. using always_t = typename always_imp<T, Dummy>::type;
  24. ////////////////////////////////////////////////////////////////////////////////
  25. template <class Tuple, class Idx>
  26. struct make_function;
  27. template <class Tp, std::size_t ...Idx>
  28. struct make_function<Tp, std::integer_sequence<std::size_t, Idx...>>
  29. {
  30. using type = bool (*)(always_t<Tp, Idx>...);
  31. };
  32. template <class Tp, std::size_t Size>
  33. using make_function_t = typename make_function<Tp, std::make_index_sequence<Size>>::type;
  34. ////////////////////////////////////////////////////////////////////////////////
  35. template <class Tp, class Idx>
  36. struct make_tuple_imp;
  37. ////////////////////////////////////////////////////////////////////////////////
  38. template <class Tp, std::size_t ...Idx>
  39. struct make_tuple_imp<Tp, std::integer_sequence<std::size_t, Idx...>>
  40. {
  41. using type = std::tuple<always_t<Tp, Idx>...>;
  42. };
  43. template <class Tp, std::size_t Size>
  44. using make_tuple_t = typename make_tuple_imp<Tp, std::make_index_sequence<Size>>::type;
  45. template <class ...Types>
  46. bool test_apply_fn(Types...) { return true; }
  47. template <std::size_t Size>
  48. void test_all()
  49. {
  50. using A = std::array<int, Size>;
  51. using ConstA = std::array<int const, Size>;
  52. using Tuple = make_tuple_t<int, Size>;
  53. using CTuple = make_tuple_t<const int, Size>;
  54. using ValFn = make_function_t<int, Size>;
  55. ValFn val_fn = &test_apply_fn;
  56. using RefFn = make_function_t<int &, Size>;
  57. RefFn ref_fn = &test_apply_fn;
  58. using CRefFn = make_function_t<int const &, Size>;
  59. CRefFn cref_fn = &test_apply_fn;
  60. using RRefFn = make_function_t<int &&, Size>;
  61. RRefFn rref_fn = &test_apply_fn;
  62. {
  63. A a{};
  64. assert(std::apply(val_fn, a));
  65. assert(std::apply(ref_fn, a));
  66. assert(std::apply(cref_fn, a));
  67. assert(std::apply(rref_fn, std::move(a)));
  68. }
  69. {
  70. ConstA a{};
  71. assert(std::apply(val_fn, a));
  72. assert(std::apply(cref_fn, a));
  73. }
  74. {
  75. Tuple a{};
  76. assert(std::apply(val_fn, a));
  77. assert(std::apply(ref_fn, a));
  78. assert(std::apply(cref_fn, a));
  79. assert(std::apply(rref_fn, std::move(a)));
  80. }
  81. {
  82. CTuple a{};
  83. assert(std::apply(val_fn, a));
  84. assert(std::apply(cref_fn, a));
  85. }
  86. }
  87. template <std::size_t Size>
  88. void test_one()
  89. {
  90. using A = std::array<int, Size>;
  91. using Tuple = make_tuple_t<int, Size>;
  92. using ValFn = make_function_t<int, Size>;
  93. ValFn val_fn = &test_apply_fn;
  94. {
  95. A a{};
  96. assert(std::apply(val_fn, a));
  97. }
  98. {
  99. Tuple a{};
  100. assert(std::apply(val_fn, a));
  101. }
  102. }
  103. int main(int, char**)
  104. {
  105. // Instantiate with 1-5 arguments.
  106. test_all<1>();
  107. test_all<2>();
  108. test_all<3>();
  109. test_all<4>();
  110. test_all<5>();
  111. // Stress test with 256
  112. test_one<256>();
  113. return 0;
  114. }