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

source code of libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp