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 <cassert> 26 #include <functional> 27 #include <memory> 28 29 #include "test_macros.h" 30 #include "archetypes.h" 31 32 33 // Overloads 34 // using A = Allocator 35 // using AT = std::allocator_arg_t 36 // --------------- 37 // (1) tuple(const Types&...) -> tuple<Types...> 38 // (2) tuple(pair<T1, T2>) -> tuple<T1, T2>; 39 // (3) explicit tuple(const Types&...) -> tuple<Types...> 40 // (4) tuple(AT, A const&, Types const&...) -> tuple<Types...> 41 // (5) explicit tuple(AT, A const&, Types const&...) -> tuple<Types...> 42 // (6) tuple(AT, A, pair<T1, T2>) -> tuple<T1, T2> 43 // (7) tuple(tuple const& t) -> decltype(t) 44 // (8) tuple(tuple&& t) -> decltype(t) 45 // (9) tuple(AT, A const&, tuple const& t) -> decltype(t) 46 // (10) tuple(AT, A const&, tuple&& t) -> decltype(t) 47 void test_primary_template() 48 { 49 const std::allocator<int> A; 50 const auto AT = std::allocator_arg; 51 { // Testing (1) 52 int x = 101; 53 std::tuple t1(42); 54 ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>); 55 std::tuple t2(x, 0.0, nullptr); 56 ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, decltype(nullptr)>); 57 } 58 { // Testing (2) 59 std::pair<int, char> p1(1, 'c'); 60 std::tuple t1(p1); 61 ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>); 62 63 std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr)); 64 std::tuple t2(p2); 65 ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>); 66 67 int i = 3; 68 std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c'); 69 std::tuple t3(p3); 70 ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>); 71 72 std::pair<int&, char> p4(i, 'c'); 73 std::tuple t4(p4); 74 ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>); 75 76 std::tuple t5(std::pair<int, char>(1, 'c')); 77 ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>); 78 } 79 { // Testing (3) 80 using T = ExplicitTestTypes::TestType; 81 static_assert(!std::is_convertible<T const&, T>::value, ""); 82 83 std::tuple t1(T{}); 84 ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>); 85 86 const T v{}; 87 std::tuple t2(T{}, 101l, v); 88 ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>); 89 } 90 { // Testing (4) 91 int x = 101; 92 std::tuple t1(AT, A, 42); 93 ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>); 94 95 std::tuple t2(AT, A, 42, 0.0, x); 96 ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, int>); 97 } 98 { // Testing (5) 99 using T = ExplicitTestTypes::TestType; 100 static_assert(!std::is_convertible<T const&, T>::value, ""); 101 102 std::tuple t1(AT, A, T{}); 103 ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>); 104 105 const T v{}; 106 std::tuple t2(AT, A, T{}, 101l, v); 107 ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>); 108 } 109 { // Testing (6) 110 std::pair<int, char> p1(1, 'c'); 111 std::tuple t1(AT, A, p1); 112 ASSERT_SAME_TYPE(decltype(t1), std::tuple<int, char>); 113 114 std::pair<int, std::tuple<char, long, void*>> p2(1, std::tuple<char, long, void*>('c', 3l, nullptr)); 115 std::tuple t2(AT, A, p2); 116 ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, std::tuple<char, long, void*>>); 117 118 int i = 3; 119 std::pair<std::reference_wrapper<int>, char> p3(std::ref(i), 'c'); 120 std::tuple t3(AT, A, p3); 121 ASSERT_SAME_TYPE(decltype(t3), std::tuple<std::reference_wrapper<int>, char>); 122 123 std::pair<int&, char> p4(i, 'c'); 124 std::tuple t4(AT, A, p4); 125 ASSERT_SAME_TYPE(decltype(t4), std::tuple<int&, char>); 126 127 std::tuple t5(AT, A, std::pair<int, char>(1, 'c')); 128 ASSERT_SAME_TYPE(decltype(t5), std::tuple<int, char>); 129 } 130 { // Testing (7) 131 using Tup = std::tuple<int, decltype(nullptr)>; 132 const Tup t(42, nullptr); 133 134 std::tuple t1(t); 135 ASSERT_SAME_TYPE(decltype(t1), Tup); 136 } 137 { // Testing (8) 138 using Tup = std::tuple<void*, unsigned, char>; 139 std::tuple t1(Tup(nullptr, 42, 'a')); 140 ASSERT_SAME_TYPE(decltype(t1), Tup); 141 } 142 { // Testing (9) 143 using Tup = std::tuple<int, decltype(nullptr)>; 144 const Tup t(42, nullptr); 145 146 std::tuple t1(AT, A, t); 147 ASSERT_SAME_TYPE(decltype(t1), Tup); 148 } 149 { // Testing (10) 150 using Tup = std::tuple<void*, unsigned, char>; 151 std::tuple t1(AT, A, Tup(nullptr, 42, 'a')); 152 ASSERT_SAME_TYPE(decltype(t1), Tup); 153 } 154 } 155 156 // Overloads 157 // using A = Allocator 158 // using AT = std::allocator_arg_t 159 // --------------- 160 // (1) tuple() -> tuple<> 161 // (2) tuple(AT, A const&) -> tuple<> 162 // (3) tuple(tuple const&) -> tuple<> 163 // (4) tuple(tuple&&) -> tuple<> 164 // (5) tuple(AT, A const&, tuple const&) -> tuple<> 165 // (6) tuple(AT, A const&, tuple&&) -> tuple<> 166 void test_empty_specialization() 167 { 168 std::allocator<int> A; 169 const auto AT = std::allocator_arg; 170 { // Testing (1) 171 std::tuple t1{}; 172 ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); 173 } 174 { // Testing (2) 175 std::tuple t1{AT, A}; 176 ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); 177 } 178 { // Testing (3) 179 const std::tuple<> t{}; 180 std::tuple t1(t); 181 ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); 182 } 183 { // Testing (4) 184 std::tuple t1(std::tuple<>{}); 185 ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); 186 } 187 { // Testing (5) 188 const std::tuple<> t{}; 189 std::tuple t1(AT, A, t); 190 ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); 191 } 192 { // Testing (6) 193 std::tuple t1(AT, A, std::tuple<>{}); 194 ASSERT_SAME_TYPE(decltype(t1), std::tuple<>); 195 } 196 } 197 198 int main(int, char**) { 199 test_primary_template(); 200 test_empty_specialization(); 201 202 return 0; 203 } 204