brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 0b0eb88 Raw
262 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++26 %s -verify2// RUN: %clang_cc1 -fsyntax-only -std=c++26 %s -verify -fexperimental-new-constant-interpreter3 4template <typename T>5struct type_ { };6 7template <typename ...T>8constexpr auto sum(T... t) { return (t + ...); }9 10struct my_struct {11  int a;12  int b;13  int c;14  int d;15};16 17struct fake_tuple {18  int arr[4] = {1, 2, 3, 6};19 20  template <unsigned i>21  constexpr int& get() {22    return arr[i];23  }24};25 26namespace std {27  template <typename T>28  struct tuple_size;29  template <unsigned i, typename T>30  struct tuple_element;31 32  template <>33  struct tuple_size<fake_tuple> {34    static constexpr unsigned value = 4;35  };36 37  template <unsigned i>38  struct tuple_element<i, fake_tuple> {39    using type = int;40  };41}42 43 44template <typename T>45void decompose_tuple() {46  auto tup = T{{1, 2, 3, 6}};47  auto&& [x, ...rest, y] = tup;48 49  ((void)type_<int>(type_<decltype(rest)>{}), ...);50 51  T arrtup[2] = {T{{1, 2, 3, 6}},52                 T{{7, 9, 10, 11}}};53  int sum = 0;54  for (auto [...xs] : arrtup) {55    sum += (xs + ...);56  }57}58 59template <typename T>60void decompose_struct() {61  T obj{1, 2, 3, 6};62  auto [x, ...rest, y] = obj;63  static_assert(sizeof...(rest) == 2);64 65  auto [...empty] = type_<int>{};66  static_assert(sizeof...(empty) == 0);67}68 69template <typename T>70void decompose_array() {71  int arr[4] = {1, 2, 3, 6};72  auto [x, ...rest, y] = arr;73 74  static_assert(sizeof...(rest) == 2);75  int size = sizeof...(rest);76  T arr2[sizeof...(rest)] = {rest...};77  auto [...pack] = arr2;78 79  // Array of size 1.80  int arr1[1] = {1};81  auto [a, ...b] = arr1;82  static_assert(sizeof...(b) == 0);83  auto [...c] = arr1;84  static_assert(sizeof...(c) == 1);85  auto [a1, ...b1, c1] = arr1; // expected-error{{binds to 1 element, but 3 names were provided}}86}87 88// Test case by Younan Zhang.89template <unsigned... P>90struct S {91  template <unsigned... Q>92  struct N {93    void foo() {94      int arr[] = {P..., Q...};95      auto [x, y, ...rest] = arr;96      [&]() {97        static_assert(sizeof...(rest) + 2 == sizeof...(P) + sizeof...(Q));98      }();99    }100  };101};102 103struct bit_fields {104  int a : 4 {1};105  int b : 4 {2};106  int c : 4 {3};107  int d : 4 {4};108};109 110template <typename T>111void decompose_bit_field() {112  auto [...x] = T{};113  static_assert(sizeof...(x) == 4);114  int a = x...[0];115  int b = x...[1];116  int c = x...[2];117  int d = x...[3];118}119 120template <typename T>121void lambda_capture() {122  auto [...x] = T{};123  [=] { (void)sum(x...); }();124  [&] { (void)sum(x...); }();125  [x...] { (void)sum(x...); }();126  [&x...] { (void)sum(x...); }();127}128 129struct S2 {130    int a, b, c;131};132 133auto X = [] <typename = void> () {134    auto [...pack] = S2{};135};136 137int main() {138  decompose_array<int>();139  decompose_tuple<fake_tuple>();140  decompose_struct<my_struct>();141  S<1, 2, 3, 4>::N<5, 6>().foo();142  decompose_bit_field<bit_fields>();143  lambda_capture<int[5]>();144  lambda_capture<fake_tuple>();145  lambda_capture<my_struct>();146  X();147 148}149 150// P1061R10 Stuff151namespace {152struct C { int x, y, z; };153 154template <class T>155void now_i_know_my() {156  auto [a, b, c] = C(); // OK, SB0 is a, SB1 is b, and SB2 is c157  auto [d, ...e] = C(); // OK, SB0 is d, the pack e (v1) contains two structured bindings: SB1 and SB2158  static_assert(sizeof...(e) == 2);159  auto [...f, g] = C(); // OK, the pack f (v0) contains two structured bindings: SB0 and SB1, and SB2 is g160  static_assert(sizeof...(e) == 2);161  auto [h, i, j, ...k] = C(); // OK, the pack k is empty162  static_assert(sizeof...(e) == 0);163  auto [l, m, n, o, ...p] = C(); // expected-error{{{binds to 3 elements, but 5 names were provided}}}164}165}  // namespace166 167namespace {168auto g() -> int(&)[4];169 170template <unsigned long N>171void h(int (&arr)[N]) {172  auto [a, ...b, c] = arr;  // a names the first element of the array,173                            // b is a pack referring to the second and174                            // third elements, and c names the fourth element175  static_assert(sizeof...(b) == 2);176  auto& [...e] = arr;        // e is a pack referring to the four elements of the array177  static_assert(sizeof...(e) == 4);178}179 180void call_h() {181 h(g());182}183}  // namespace184 185namespace {186struct D { };187 188int g(...) { return 1; }189 190template <typename T>191constexpr int f() {192  D arr[1];193  auto [...e] = arr;194  return g(e...);195}196 197constexpr int g(D) { return 2; }198 199void other_main() {200  static_assert(f<int>() == 2);201}202}  // namespace203 204namespace {205struct S {206  int a,b,c;207};208 209clsss S2 { // expected-error{{{unknown type name 'clsss'}}}210public:211  int a,b,c;212};213 214// Should not crash.215auto X = [] <typename = void> () {216    auto [...pack,a,b,c] = S{};217    auto [x,y,z,...pack2] = S{};218    auto [...pack3] = S2{};219    static_assert(sizeof...(pack3) == 5);220};221}  // namespace222 223namespace GH125165 {224 225template <typename = void>226auto f(auto t) {227    const auto& [...pack] = t;228    // expected-error@-1 {{cannot bind non-class, non-array type 'char const'}}229    (pack, ...);230};231 232void g() {233    f('x'); // expected-note {{in instantiation}}234}235 236}237 238namespace constant_interpreter {239using Arr = int[2];240struct Triple { int x, y, z = 3; };241 242constexpr int ref_to_same_obj(auto&& arg) {243  auto& [...xs] = arg;244  auto& [...ys] = arg;245  (..., (xs += 2));246  return sum(ys...);247}248static_assert(ref_to_same_obj(Arr{}) == 4);249static_assert(ref_to_same_obj(fake_tuple{}) == 20);250static_assert(ref_to_same_obj(Triple{}) == 9);251 252constexpr int copy_obj(auto&& arg) {253  auto& [...xs] = arg;254  auto [...ys] = arg;255  (..., (xs += 2));256  return sum(ys...);257}258static_assert(copy_obj(Arr{}) == 0);259static_assert(copy_obj(fake_tuple{}) == 12);260static_assert(copy_obj(Triple{}) == 3);261}262