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