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