tuple_cat.pass.cpp 8.5 KB

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