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