implicit_deduction_guides.pass.cpp 4.5 KB

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