1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <tuple> 11 12 // template <class... Types> class tuple; 13 14 // template <class... Types> 15 // class tuple_size<tuple<Types...>> 16 // : public integral_constant<size_t, sizeof...(Types)> { }; 17 18 // UNSUPPORTED: c++98, c++03, c++11, c++14 19 // UNSUPPORTED: libcpp-no-structured-bindings 20 21 #include <tuple> 22 #include <array> 23 #include <type_traits> 24 #include <cassert> 25 26 struct S { int x; }; 27 28 void test_decomp_user_type() { 29 { 30 S s{99}; 31 auto [m1] = s; 32 auto& [r1] = s; 33 assert(m1 == 99); 34 assert(&r1 == &s.x); 35 } 36 { 37 S const s{99}; 38 auto [m1] = s; 39 auto& [r1] = s; 40 assert(m1 == 99); 41 assert(&r1 == &s.x); 42 } 43 } 44 45 void test_decomp_tuple() { 46 typedef std::tuple<int> T; 47 { 48 T s{99}; 49 auto [m1] = s; 50 auto& [r1] = s; 51 assert(m1 == 99); 52 assert(&r1 == &std::get<0>(s)); 53 } 54 { 55 T const s{99}; 56 auto [m1] = s; 57 auto& [r1] = s; 58 assert(m1 == 99); 59 assert(&r1 == &std::get<0>(s)); 60 } 61 } 62 63 64 void test_decomp_pair() { 65 typedef std::pair<int, double> T; 66 { 67 T s{99, 42.5}; 68 auto [m1, m2] = s; 69 auto& [r1, r2] = s; 70 assert(m1 == 99); 71 assert(m2 == 42.5); 72 assert(&r1 == &std::get<0>(s)); 73 assert(&r2 == &std::get<1>(s)); 74 } 75 { 76 T const s{99, 42.5}; 77 auto [m1, m2] = s; 78 auto& [r1, r2] = s; 79 assert(m1 == 99); 80 assert(m2 == 42.5); 81 assert(&r1 == &std::get<0>(s)); 82 assert(&r2 == &std::get<1>(s)); 83 } 84 } 85 86 void test_decomp_array() { 87 typedef std::array<int, 3> T; 88 { 89 T s{{99, 42, -1}}; 90 auto [m1, m2, m3] = s; 91 auto& [r1, r2, r3] = s; 92 assert(m1 == 99); 93 assert(m2 == 42); 94 assert(m3 == -1); 95 assert(&r1 == &std::get<0>(s)); 96 assert(&r2 == &std::get<1>(s)); 97 assert(&r3 == &std::get<2>(s)); 98 } 99 { 100 T const s{{99, 42, -1}}; 101 auto [m1, m2, m3] = s; 102 auto& [r1, r2, r3] = s; 103 assert(m1 == 99); 104 assert(m2 == 42); 105 assert(m3 == -1); 106 assert(&r1 == &std::get<0>(s)); 107 assert(&r2 == &std::get<1>(s)); 108 assert(&r3 == &std::get<2>(s)); 109 } 110 } 111 112 struct Test { 113 int x; 114 }; 115 116 template <size_t N> 117 int get(Test const&) { static_assert(N == 0, ""); return -1; } 118 119 template <> 120 class std::tuple_element<0, Test> { 121 public: 122 typedef int type; 123 }; 124 125 void test_before_tuple_size_specialization() { 126 Test const t{99}; 127 auto& [p] = t; 128 assert(p == 99); 129 } 130 131 template <> 132 class std::tuple_size<Test> { 133 public: 134 static const size_t value = 1; 135 }; 136 137 void test_after_tuple_size_specialization() { 138 Test const t{99}; 139 auto& [p] = t; 140 assert(p == -1); 141 } 142 143 int main() { 144 test_decomp_user_type(); 145 test_decomp_tuple(); 146 test_decomp_pair(); 147 test_decomp_array(); 148 test_before_tuple_size_specialization(); 149 test_after_tuple_size_specialization(); 150 } 151