brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · 942714e Raw
130 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only %s2// RUN: %clang_cc1 -fsyntax-only -std=c++20 -DWITH_AUTO_FUNCTION_PARAMETER=1 %s3 4// When __array_rank is used with a template type parameter, this test5// ensures clang considers the final expression could be used with6// static_assert/constexpr.7//8// Although array_extent was handled well, we add it as a precaution.9 10template <typename T>11using remove_reference_t = __remove_reference_t(T);12 13template <typename T, int N>14constexpr int array_rank(T (&lhs)[N]) {15  return __array_rank(T[N]);16}17 18template <int I, typename T, int N>19 constexpr int array_extent(T (&lhs)[N]) {20  return __array_extent(T[N], I);21}22 23template <typename T>24struct Rank {25  using ArrayT = remove_reference_t<T>;26 27  template <int N>28  static constexpr int call(ArrayT (&lhs)[N]) {29    return __array_rank(ArrayT[N]);30  }31};32 33template <typename T>34struct Extent {35  using ArrayT = remove_reference_t<T>;36 37  template <int I, int N>38  static constexpr int call(ArrayT (&lhs)[N]) {39    return __array_extent(ArrayT[N], I);40  }41};42 43#ifdef WITH_AUTO_FUNCTION_PARAMETER44template <int N>45constexpr int array_rank_auto(auto (&lhs)[N]) {46  return __array_rank(remove_reference_t<decltype(lhs[0])>[N]);47}48 49template <int I, int N>50constexpr int array_extent_auto(auto (&lhs)[N]) {51  return __array_extent(remove_reference_t<decltype(lhs[0])>[N], I);52}53#endif54 55template <int N>56constexpr int array_rank_int(const int (&lhs)[N]) {57  return __array_rank(const int[N]);58}59 60template <int I, int N>61constexpr int array_extent_int(const int (&lhs)[N]) {62  return __array_extent(const int[N], I);63}64 65template <int M, int N>66constexpr int array_rank_int(const int (&lhs)[M][N]) {67  return __array_rank(const int[M][N]);68}69 70template <int I, int M, int N>71constexpr int array_extent_int(const int (&lhs)[M][N]) {72  return __array_extent(const int[M][N], I);73}74 75int main() {76  constexpr int vec[] = {0, 1, 2, 1};77  constexpr int mat[4][4] = {78    {1, 0, 0, 0},79    {0, 1, 0, 0},80    {0, 0, 1, 0},81    {0, 0, 0, 1}82  };83 84#define ATT_TESTS_WITH_ASSERT(ATT_ASSERT)	\85  { ATT_ASSERT(RANK(vec) == 1);	}		\86  { ATT_ASSERT(RANK(mat) == 2);	}		\87  { ATT_ASSERT(EXTENT(vec, 0) == 4); }		\88  { ATT_ASSERT(EXTENT(vec, 1) == 0); }		\89  { ATT_ASSERT(EXTENT(mat, 1) == 4); }90 91#define ATT_TESTS()				\92  ATT_TESTS_WITH_ASSERT( constexpr bool cst = )	\93  ATT_TESTS_WITH_ASSERT( (void) )		\94  ATT_TESTS_WITH_ASSERT( static_assert )95 96  {97#define RANK(lhs) array_rank(lhs)98#define EXTENT(lhs, i) array_extent<i>(lhs)99    ATT_TESTS();100#undef RANK101#undef EXTENT102  }103 104  {105#define RANK(lhs) Rank<decltype(lhs[0])>::call(lhs)106#define EXTENT(lhs, i) Extent<decltype(lhs[0])>::call<i>(lhs)107    ATT_TESTS();108#undef RANK109#undef EXTENT110  }111 112#ifdef WITH_AUTO_FUNCTION_PARAMETER113  {114#define RANK(lhs) array_rank_auto(lhs)115#define EXTENT(lhs, i) array_extent_auto<i>(lhs)116    ATT_TESTS();117#undef RANK118#undef EXTENT119  }120#endif121 122  {123#define RANK(lhs) array_rank_int(lhs)124#define EXTENT(lhs, i) array_extent_int<i>(lhs)125    ATT_TESTS();126#undef RANK127#undef EXTENT128  }129}130