deduct.pass.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. // UNSUPPORTED: c++98, c++03, c++11, c++14
  9. // UNSUPPORTED: libcpp-no-deduction-guides
  10. // UNSUPPORTED: apple-clang-9
  11. // GCC's implementation of class template deduction is still immature and runs
  12. // into issues with libc++. However GCC accepts this code when compiling
  13. // against libstdc++.
  14. // XFAIL: gcc-5, gcc-6, gcc-7
  15. // <tuple>
  16. // Test that the constructors offered by std::tuple are formulated
  17. // so they're compatible with implicit deduction guides, or if that's not
  18. // possible that they provide explicit guides to make it work.
  19. #include <tuple>
  20. #include <memory>
  21. #include <cassert>
  22. #include "test_macros.h"
  23. #include "archetypes.h"
  24. // Overloads
  25. // using A = Allocator
  26. // using AT = std::allocator_arg_t
  27. // ---------------
  28. // (1) tuple(const Types&...) -> tuple<Types...>
  29. // (2) tuple(pair<T1, T2>) -> tuple<T1, T2>;
  30. // (3) explicit tuple(const Types&...) -> tuple<Types...>
  31. // (4) tuple(AT, A const&, Types const&...) -> tuple<Types...>
  32. // (5) explicit tuple(AT, A const&, Types const&...) -> tuple<Types...>
  33. // (6) tuple(AT, A, pair<T1, T2>) -> tuple<T1, T2>
  34. // (7) tuple(tuple const& t) -> decltype(t)
  35. // (8) tuple(tuple&& t) -> decltype(t)
  36. // (9) tuple(AT, A const&, tuple const& t) -> decltype(t)
  37. // (10) tuple(AT, A const&, tuple&& t) -> decltype(t)
  38. void test_primary_template()
  39. {
  40. const std::allocator<int> A;
  41. const auto AT = std::allocator_arg;
  42. { // Testing (1)
  43. int x = 101;
  44. std::tuple t1(42);
  45. ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
  46. std::tuple t2(x, 0.0, nullptr);
  47. ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, decltype(nullptr)>);
  48. }
  49. { // Testing (2)
  50. std::pair<int, char> p1(1, 'c');
  51. std::tuple t1(p1);
  52. ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>);
  53. std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr));
  54. std::tuple t2(p2);
  55. ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>);
  56. int i = 3;
  57. std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c');
  58. std::tuple t3(p3);
  59. ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>);
  60. std::pair<int&, char> p4(i, 'c');
  61. std::tuple t4(p4);
  62. ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>);
  63. std::tuple t5(std::pair<int, char>(1, 'c'));
  64. ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>);
  65. }
  66. { // Testing (3)
  67. using T = ExplicitTestTypes::TestType;
  68. static_assert(!std::is_convertible<T const&, T>::value, "");
  69. std::tuple t1(T{});
  70. ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
  71. const T v{};
  72. std::tuple t2(T{}, 101l, v);
  73. ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
  74. }
  75. { // Testing (4)
  76. int x = 101;
  77. std::tuple t1(AT, A, 42);
  78. ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
  79. std::tuple t2(AT, A, 42, 0.0, x);
  80. ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, int>);
  81. }
  82. { // Testing (5)
  83. using T = ExplicitTestTypes::TestType;
  84. static_assert(!std::is_convertible<T const&, T>::value, "");
  85. std::tuple t1(AT, A, T{});
  86. ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
  87. const T v{};
  88. std::tuple t2(AT, A, T{}, 101l, v);
  89. ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
  90. }
  91. { // Testing (6)
  92. std::pair<int, char> p1(1, 'c');
  93. std::tuple t1(AT, A, p1);
  94. ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>);
  95. std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr));
  96. std::tuple t2(AT, A, p2);
  97. ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>);
  98. int i = 3;
  99. std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c');
  100. std::tuple t3(AT, A, p3);
  101. ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>);
  102. std::pair<int&, char> p4(i, 'c');
  103. std::tuple t4(AT, A, p4);
  104. ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>);
  105. std::tuple t5(AT, A, std::pair<int, char>(1, 'c'));
  106. ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>);
  107. }
  108. { // Testing (7)
  109. using Tup = std::tuple<int, decltype(nullptr)>;
  110. const Tup t(42, nullptr);
  111. std::tuple t1(t);
  112. ASSERT_SAME_TYPE(decltype(t1), Tup);
  113. }
  114. { // Testing (8)
  115. using Tup = std::tuple<void*, unsigned, char>;
  116. std::tuple t1(Tup(nullptr, 42, 'a'));
  117. ASSERT_SAME_TYPE(decltype(t1), Tup);
  118. }
  119. { // Testing (9)
  120. using Tup = std::tuple<int, decltype(nullptr)>;
  121. const Tup t(42, nullptr);
  122. std::tuple t1(AT, A, t);
  123. ASSERT_SAME_TYPE(decltype(t1), Tup);
  124. }
  125. { // Testing (10)
  126. using Tup = std::tuple<void*, unsigned, char>;
  127. std::tuple t1(AT, A, Tup(nullptr, 42, 'a'));
  128. ASSERT_SAME_TYPE(decltype(t1), Tup);
  129. }
  130. }
  131. // Overloads
  132. // using A = Allocator
  133. // using AT = std::allocator_arg_t
  134. // ---------------
  135. // (1) tuple() -> tuple<>
  136. // (2) tuple(AT, A const&) -> tuple<>
  137. // (3) tuple(tuple const&) -> tuple<>
  138. // (4) tuple(tuple&&) -> tuple<>
  139. // (5) tuple(AT, A const&, tuple const&) -> tuple<>
  140. // (6) tuple(AT, A const&, tuple&&) -> tuple<>
  141. void test_empty_specialization()
  142. {
  143. std::allocator<int> A;
  144. const auto AT = std::allocator_arg;
  145. { // Testing (1)
  146. std::tuple t1{};
  147. ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
  148. }
  149. { // Testing (2)
  150. std::tuple t1{AT, A};
  151. ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
  152. }
  153. { // Testing (3)
  154. const std::tuple<> t{};
  155. std::tuple t1(t);
  156. ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
  157. }
  158. { // Testing (4)
  159. std::tuple t1(std::tuple<>{});
  160. ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
  161. }
  162. { // Testing (5)
  163. const std::tuple<> t{};
  164. std::tuple t1(AT, A, t);
  165. ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
  166. }
  167. { // Testing (6)
  168. std::tuple t1(AT, A, std::tuple<>{});
  169. ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
  170. }
  171. }
  172. int main(int, char**) {
  173. test_primary_template();
  174. test_empty_specialization();
  175. return 0;
  176. }