brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · b649358 Raw
139 lines · cpp
1// Structured binding in C++ can bind identifiers to subobjects of an object.2//3// There are four cases we need to test:4// 1) arrays5// 2) tuple-like objects with `get` member functions6// 3) tuple-like objects with `get` free functions7// 4) non-static data members8//9// They can also bind by copy, reference or rvalue reference.10 11struct MyPair {12  int m1;13  int m2;14 15  // Helpers to enable tuple-like decomposition.16  template <unsigned> int get();17  template <> int get<0>() { return m1; }18  template <> int get<1>() { return m2; }19};20 21namespace std {22template <typename T1, typename T2, typename T3> struct mock_tuple {23  T1 m1;24  T2 m2;25  T3 m3;26};27 28template <typename T> struct tuple_size;29 30template <unsigned, typename T> struct tuple_element;31 32// Helpers to enable tuple-like decomposition for MyPair33template <unsigned I> struct tuple_element<I, MyPair> {34  using type = int;35};36 37template <> struct tuple_size<MyPair> {38  static constexpr unsigned value = 2;39};40 41// Helpers to enable tuple-like decomposition for mock_tuple42template <typename T1, typename T2, typename T3>43struct tuple_element<0, mock_tuple<T1, T2, T3>> {44  using type = T1;45};46 47template <typename T1, typename T2, typename T3>48struct tuple_element<1, mock_tuple<T1, T2, T3>> {49  using type = T2;50};51 52template <typename T1, typename T2, typename T3>53struct tuple_element<2, mock_tuple<T1, T2, T3>> {54  using type = T3;55};56 57template <typename T1, typename T2, typename T3>58struct tuple_size<mock_tuple<T1, T2, T3>> {59  static constexpr unsigned value = 3;60};61 62template <unsigned I, typename T1, typename T2, typename T3>63typename tuple_element<I, mock_tuple<T1, T2, T3>>::type64get(mock_tuple<T1, T2, T3> p) {65  switch (I) {66  case 0:67    return p.m1;68  case 1:69    return p.m2;70  case 2:71    return p.m3;72  default:73    __builtin_trap();74  }75}76 77} // namespace std78 79struct A {80  int x;81  int y;82};83 84// We want to cover a mix of types and also different sizes to make sure we85// hande the offsets correctly.86struct MixedTypesAndSizesStruct {87  A a;88  char b1;89  char b2;90  short b3;91  int b4;92  char b5;93};94 95int main() {96  MixedTypesAndSizesStruct b{{20, 30}, 'a', 'b', 50, 60, 'c'};97 98  auto [a1, b1, c1, d1, e1, f1] = b;99  auto &[a2, b2, c2, d2, e2, f2] = b;100  auto &&[a3, b3, c3, d3, e3, f3] =101      MixedTypesAndSizesStruct{{20, 30}, 'a', 'b', 50, 60, 'c'};102 103  // Array with different sized types104  char carr[]{'a', 'b', 'c'};105  short sarr[]{11, 12, 13};106  int iarr[]{22, 33, 44};107 108  auto [carr_copy1, carr_copy2, carr_copy3] = carr;109  auto [sarr_copy1, sarr_copy2, sarr_copy3] = sarr;110  auto [iarr_copy1, iarr_copy2, iarr_copy3] = iarr;111 112  auto &[carr_ref1, carr_ref2, carr_ref3] = carr;113  auto &[sarr_ref1, sarr_ref2, sarr_ref3] = sarr;114  auto &[iarr_ref1, iarr_ref2, iarr_ref3] = iarr;115 116  auto &&[carr_rref1, carr_rref2, carr_rref3] = carr;117  auto &&[sarr_rref1, sarr_rref2, sarr_rref3] = sarr;118  auto &&[iarr_rref1, iarr_rref2, iarr_rref3] = iarr;119 120  float x{4.0};121  char y{'z'};122  int z{10};123 124  std::mock_tuple<float, char, int> tpl{.m1 = x, .m2 = y, .m3 = z};125  auto [tx1, ty1, tz1] = tpl;126  auto &[tx2, ty2, tz2] = tpl;127 128  auto [mp1, mp2] = MyPair{.m1 = 1, .m2 = 2};129 130  return a1.x + b1 + c1 + d1 + e1 + f1 + a2.y + b2 + c2 + d2 + e2 + f2 + a3.x +131         b3 + c3 + d3 + e3 + f3 + carr_copy1 + carr_copy2 + carr_copy3 +132         sarr_copy1 + sarr_copy2 + sarr_copy3 + iarr_copy1 + iarr_copy2 +133         iarr_copy3 + carr_ref1 + carr_ref2 + carr_ref3 + sarr_ref1 +134         sarr_ref2 + sarr_ref3 + iarr_ref1 + iarr_ref2 + iarr_ref3 +135         carr_rref1 + carr_rref2 + carr_rref3 + sarr_rref1 + sarr_rref2 +136         sarr_rref3 + iarr_rref1 + iarr_rref2 + iarr_rref3 + tx1 + ty1 + tz1 +137         tx2 + ty2 + tz2 + mp1 + mp2; // break here138}139