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... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); 15 16 // UNSUPPORTED: c++98, c++03 17 18 #include <tuple> 19 #include <utility> 20 #include <array> 21 #include <string> 22 #include <cassert> 23 24 #include "MoveOnly.h" 25 26 int main() 27 { 28 { 29 std::tuple<> t = std::tuple_cat(); 30 ((void)t); // Prevent unused warning 31 } 32 { 33 std::tuple<> t1; 34 std::tuple<> t2 = std::tuple_cat(t1); 35 ((void)t2); // Prevent unused warning 36 } 37 { 38 std::tuple<> t = std::tuple_cat(std::tuple<>()); 39 ((void)t); // Prevent unused warning 40 } 41 { 42 std::tuple<> t = std::tuple_cat(std::array<int, 0>()); 43 ((void)t); // Prevent unused warning 44 } 45 { 46 std::tuple<int> t1(1); 47 std::tuple<int> t = std::tuple_cat(t1); 48 assert(std::get<0>(t) == 1); 49 } 50 51 #if _LIBCPP_STD_VER > 11 52 { 53 constexpr std::tuple<> t = std::tuple_cat(); 54 ((void)t); // Prevent unused warning 55 } 56 { 57 constexpr std::tuple<> t1; 58 constexpr std::tuple<> t2 = std::tuple_cat(t1); 59 ((void)t2); // Prevent unused warning 60 } 61 { 62 constexpr std::tuple<> t = std::tuple_cat(std::tuple<>()); 63 ((void)t); // Prevent unused warning 64 } 65 { 66 constexpr std::tuple<> t = std::tuple_cat(std::array<int, 0>()); 67 ((void)t); // Prevent unused warning 68 } 69 { 70 constexpr std::tuple<int> t1(1); 71 constexpr std::tuple<int> t = std::tuple_cat(t1); 72 static_assert(std::get<0>(t) == 1, ""); 73 } 74 { 75 constexpr std::tuple<int> t1(1); 76 constexpr std::tuple<int, int> t = std::tuple_cat(t1, t1); 77 static_assert(std::get<0>(t) == 1, ""); 78 static_assert(std::get<1>(t) == 1, ""); 79 } 80 #endif 81 { 82 std::tuple<int, MoveOnly> t = 83 std::tuple_cat(std::tuple<int, MoveOnly>(1, 2)); 84 assert(std::get<0>(t) == 1); 85 assert(std::get<1>(t) == 2); 86 } 87 { 88 std::tuple<int, int, int> t = std::tuple_cat(std::array<int, 3>()); 89 assert(std::get<0>(t) == 0); 90 assert(std::get<1>(t) == 0); 91 assert(std::get<2>(t) == 0); 92 } 93 { 94 std::tuple<int, MoveOnly> t = std::tuple_cat(std::pair<int, MoveOnly>(2, 1)); 95 assert(std::get<0>(t) == 2); 96 assert(std::get<1>(t) == 1); 97 } 98 99 { 100 std::tuple<> t1; 101 std::tuple<> t2; 102 std::tuple<> t3 = std::tuple_cat(t1, t2); 103 ((void)t3); // Prevent unused warning 104 } 105 { 106 std::tuple<> t1; 107 std::tuple<int> t2(2); 108 std::tuple<int> t3 = std::tuple_cat(t1, t2); 109 assert(std::get<0>(t3) == 2); 110 } 111 { 112 std::tuple<> t1; 113 std::tuple<int> t2(2); 114 std::tuple<int> t3 = std::tuple_cat(t2, t1); 115 assert(std::get<0>(t3) == 2); 116 } 117 { 118 std::tuple<int*> t1; 119 std::tuple<int> t2(2); 120 std::tuple<int*, int> t3 = std::tuple_cat(t1, t2); 121 assert(std::get<0>(t3) == nullptr); 122 assert(std::get<1>(t3) == 2); 123 } 124 { 125 std::tuple<int*> t1; 126 std::tuple<int> t2(2); 127 std::tuple<int, int*> t3 = std::tuple_cat(t2, t1); 128 assert(std::get<0>(t3) == 2); 129 assert(std::get<1>(t3) == nullptr); 130 } 131 { 132 std::tuple<int*> t1; 133 std::tuple<int, double> t2(2, 3.5); 134 std::tuple<int*, int, double> t3 = std::tuple_cat(t1, t2); 135 assert(std::get<0>(t3) == nullptr); 136 assert(std::get<1>(t3) == 2); 137 assert(std::get<2>(t3) == 3.5); 138 } 139 { 140 std::tuple<int*> t1; 141 std::tuple<int, double> t2(2, 3.5); 142 std::tuple<int, double, int*> t3 = std::tuple_cat(t2, t1); 143 assert(std::get<0>(t3) == 2); 144 assert(std::get<1>(t3) == 3.5); 145 assert(std::get<2>(t3) == nullptr); 146 } 147 { 148 std::tuple<int*, MoveOnly> t1(nullptr, 1); 149 std::tuple<int, double> t2(2, 3.5); 150 std::tuple<int*, MoveOnly, int, double> t3 = 151 std::tuple_cat(std::move(t1), t2); 152 assert(std::get<0>(t3) == nullptr); 153 assert(std::get<1>(t3) == 1); 154 assert(std::get<2>(t3) == 2); 155 assert(std::get<3>(t3) == 3.5); 156 } 157 { 158 std::tuple<int*, MoveOnly> t1(nullptr, 1); 159 std::tuple<int, double> t2(2, 3.5); 160 std::tuple<int, double, int*, MoveOnly> t3 = 161 std::tuple_cat(t2, std::move(t1)); 162 assert(std::get<0>(t3) == 2); 163 assert(std::get<1>(t3) == 3.5); 164 assert(std::get<2>(t3) == nullptr); 165 assert(std::get<3>(t3) == 1); 166 } 167 { 168 std::tuple<MoveOnly, MoveOnly> t1(1, 2); 169 std::tuple<int*, MoveOnly> t2(nullptr, 4); 170 std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 = 171 std::tuple_cat(std::move(t1), std::move(t2)); 172 assert(std::get<0>(t3) == 1); 173 assert(std::get<1>(t3) == 2); 174 assert(std::get<2>(t3) == nullptr); 175 assert(std::get<3>(t3) == 4); 176 } 177 178 { 179 std::tuple<MoveOnly, MoveOnly> t1(1, 2); 180 std::tuple<int*, MoveOnly> t2(nullptr, 4); 181 std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 = 182 std::tuple_cat(std::tuple<>(), 183 std::move(t1), 184 std::move(t2)); 185 assert(std::get<0>(t3) == 1); 186 assert(std::get<1>(t3) == 2); 187 assert(std::get<2>(t3) == nullptr); 188 assert(std::get<3>(t3) == 4); 189 } 190 { 191 std::tuple<MoveOnly, MoveOnly> t1(1, 2); 192 std::tuple<int*, MoveOnly> t2(nullptr, 4); 193 std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 = 194 std::tuple_cat(std::move(t1), 195 std::tuple<>(), 196 std::move(t2)); 197 assert(std::get<0>(t3) == 1); 198 assert(std::get<1>(t3) == 2); 199 assert(std::get<2>(t3) == nullptr); 200 assert(std::get<3>(t3) == 4); 201 } 202 { 203 std::tuple<MoveOnly, MoveOnly> t1(1, 2); 204 std::tuple<int*, MoveOnly> t2(nullptr, 4); 205 std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 = 206 std::tuple_cat(std::move(t1), 207 std::move(t2), 208 std::tuple<>()); 209 assert(std::get<0>(t3) == 1); 210 assert(std::get<1>(t3) == 2); 211 assert(std::get<2>(t3) == nullptr); 212 assert(std::get<3>(t3) == 4); 213 } 214 { 215 std::tuple<MoveOnly, MoveOnly> t1(1, 2); 216 std::tuple<int*, MoveOnly> t2(nullptr, 4); 217 std::tuple<MoveOnly, MoveOnly, int*, MoveOnly, int> t3 = 218 std::tuple_cat(std::move(t1), 219 std::move(t2), 220 std::tuple<int>(5)); 221 assert(std::get<0>(t3) == 1); 222 assert(std::get<1>(t3) == 2); 223 assert(std::get<2>(t3) == nullptr); 224 assert(std::get<3>(t3) == 4); 225 assert(std::get<4>(t3) == 5); 226 } 227 { 228 // See bug #19616. 229 auto t1 = std::tuple_cat( 230 std::make_tuple(std::make_tuple(1)), 231 std::make_tuple() 232 ); 233 assert(t1 == std::make_tuple(std::make_tuple(1))); 234 235 auto t2 = std::tuple_cat( 236 std::make_tuple(std::make_tuple(1)), 237 std::make_tuple(std::make_tuple(2)) 238 ); 239 assert(t2 == std::make_tuple(std::make_tuple(1), std::make_tuple(2))); 240 } 241 } 242