xref: /llvm-project/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/deduct.pass.cpp (revision eb12ad9d7ff64398add1a9cc84e56cc20aed09f8)
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)
test_primary_template()40 void 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(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(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<>
test_empty_specialization()159 void 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 
main(int,char **)191 int main(int, char**) {
192   test_primary_template();
193   test_empty_specialization();
194 
195   return 0;
196 }
197