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 // type_traits
10
11 // template <class T, class... Args>
12 // struct is_constructible;
13
14 // UNSUPPORTED: gcc-5, gcc-6, gcc-7, gcc-8, gcc-9
15
16 #include <type_traits>
17 #include "test_macros.h"
18
19 #if TEST_STD_VER >= 11 && defined(_LIBCPP_VERSION)
20 #define LIBCPP11_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
21 #else
22 #define LIBCPP11_STATIC_ASSERT(...) ((void)0)
23 #endif
24
25 struct A
26 {
27 explicit A(int);
28 A(int, double);
29 A(int, long, double);
30 #if TEST_STD_VER >= 11
31 private:
32 #endif
33 A(char);
34 };
35
36 struct Base {};
37 struct Derived : public Base {};
38
39 class Abstract
40 {
41 virtual void foo() = 0;
42 };
43
44 class AbstractDestructor
45 {
46 virtual ~AbstractDestructor() = 0;
47 };
48
49 struct PrivateDtor {
PrivateDtorPrivateDtor50 PrivateDtor(int) {}
51 private:
~PrivateDtorPrivateDtor52 ~PrivateDtor() {}
53 };
54
55 struct S {
56 template <class T>
57 #if TEST_STD_VER >= 11
58 explicit
59 #endif
60 operator T () const;
61 };
62
63 template <class To>
64 struct ImplicitTo {
65 operator To();
66 };
67
68 #if TEST_STD_VER >= 11
69 template <class To>
70 struct ExplicitTo {
71 explicit operator To ();
72 };
73 #endif
74
75
76 template <class T>
test_is_constructible()77 void test_is_constructible()
78 {
79 static_assert( (std::is_constructible<T>::value), "");
80 #if TEST_STD_VER > 14
81 static_assert( std::is_constructible_v<T>, "");
82 #endif
83 }
84
85 template <class T, class A0>
test_is_constructible()86 void test_is_constructible()
87 {
88 static_assert(( std::is_constructible<T, A0>::value), "");
89 #if TEST_STD_VER > 14
90 static_assert(( std::is_constructible_v<T, A0>), "");
91 #endif
92 }
93
94 template <class T, class A0, class A1>
test_is_constructible()95 void test_is_constructible()
96 {
97 static_assert(( std::is_constructible<T, A0, A1>::value), "");
98 #if TEST_STD_VER > 14
99 static_assert(( std::is_constructible_v<T, A0, A1>), "");
100 #endif
101 }
102
103 template <class T, class A0, class A1, class A2>
test_is_constructible()104 void test_is_constructible()
105 {
106 static_assert(( std::is_constructible<T, A0, A1, A2>::value), "");
107 #if TEST_STD_VER > 14
108 static_assert(( std::is_constructible_v<T, A0, A1, A2>), "");
109 #endif
110 }
111
112 template <class T>
test_is_not_constructible()113 void test_is_not_constructible()
114 {
115 static_assert((!std::is_constructible<T>::value), "");
116 #if TEST_STD_VER > 14
117 static_assert((!std::is_constructible_v<T>), "");
118 #endif
119 }
120
121 template <class T, class A0>
test_is_not_constructible()122 void test_is_not_constructible()
123 {
124 static_assert((!std::is_constructible<T, A0>::value), "");
125 #if TEST_STD_VER > 14
126 static_assert((!std::is_constructible_v<T, A0>), "");
127 #endif
128 }
129
main(int,char **)130 int main(int, char**)
131 {
132 typedef Base B;
133 typedef Derived D;
134
135 test_is_constructible<int> ();
136 test_is_constructible<int, const int> ();
137 test_is_constructible<A, int> ();
138 test_is_constructible<A, int, double> ();
139 test_is_constructible<A, int, long, double> ();
140 test_is_constructible<int&, int&> ();
141
142 test_is_not_constructible<A> ();
143 #if TEST_STD_VER >= 11
144 test_is_not_constructible<A, char> ();
145 #else
146 test_is_constructible<A, char> ();
147 #endif
148 test_is_not_constructible<A, void> ();
149 test_is_not_constructible<int, void()>();
150 test_is_not_constructible<int, void(&)()>();
151 test_is_not_constructible<int, void() const>();
152 test_is_not_constructible<int&, void>();
153 test_is_not_constructible<int&, void()>();
154 test_is_not_constructible<int&, void() const>();
155 test_is_not_constructible<int&, void(&)()>();
156
157 test_is_not_constructible<void> ();
158 test_is_not_constructible<const void> (); // LWG 2738
159 test_is_not_constructible<volatile void> ();
160 test_is_not_constructible<const volatile void> ();
161 test_is_not_constructible<int&> ();
162 test_is_not_constructible<Abstract> ();
163 test_is_not_constructible<AbstractDestructor> ();
164 test_is_constructible<int, S>();
165 test_is_not_constructible<int&, S>();
166
167 test_is_constructible<void(&)(), void(&)()>();
168 test_is_constructible<void(&)(), void()>();
169 #if TEST_STD_VER >= 11
170 test_is_constructible<void(&&)(), void(&&)()>();
171 test_is_constructible<void(&&)(), void()>();
172 test_is_constructible<void(&&)(), void(&)()>();
173 #endif
174
175 #if TEST_STD_VER >= 11
176 test_is_constructible<int const&, int>();
177 test_is_constructible<int const&, int&&>();
178
179 test_is_constructible<int&&, double&>();
180 test_is_constructible<void(&)(), void(&&)()>();
181
182 test_is_not_constructible<int&, int>();
183 test_is_not_constructible<int&, int const&>();
184 test_is_not_constructible<int&, int&&>();
185
186 test_is_constructible<int&&, int>();
187 test_is_constructible<int&&, int&&>();
188 test_is_not_constructible<int&&, int&>();
189 test_is_not_constructible<int&&, int const&&>();
190
191 test_is_constructible<Base, Derived>();
192 test_is_constructible<Base&, Derived&>();
193 test_is_not_constructible<Derived&, Base&>();
194 test_is_constructible<Base const&, Derived const&>();
195 #ifndef TEST_COMPILER_GCC
196 test_is_not_constructible<Derived const&, Base const&>();
197 test_is_not_constructible<Derived const&, Base>();
198 #endif
199
200 test_is_constructible<Base&&, Derived>();
201 test_is_constructible<Base&&, Derived&&>();
202 #ifndef TEST_COMPILER_GCC
203 test_is_not_constructible<Derived&&, Base&&>();
204 test_is_not_constructible<Derived&&, Base>();
205 #endif
206
207 // test that T must also be destructible
208 test_is_constructible<PrivateDtor&, PrivateDtor&>();
209 test_is_not_constructible<PrivateDtor, int>();
210
211 test_is_not_constructible<void() const, void() const>();
212 test_is_not_constructible<void() const, void*>();
213
214 test_is_constructible<int&, ImplicitTo<int&>>();
215 test_is_constructible<const int&, ImplicitTo<int&&>>();
216 test_is_constructible<int&&, ImplicitTo<int&&>>();
217 test_is_constructible<const int&, ImplicitTo<int>>();
218
219 test_is_not_constructible<B&&, B&>();
220 test_is_not_constructible<B&&, D&>();
221 test_is_constructible<B&&, ImplicitTo<D&&>>();
222 test_is_constructible<B&&, ImplicitTo<D&&>&>();
223 test_is_constructible<int&&, double&>();
224 test_is_constructible<const int&, ImplicitTo<int&>&>();
225 test_is_constructible<const int&, ImplicitTo<int&>>();
226 test_is_constructible<const int&, ExplicitTo<int&>&>();
227 test_is_constructible<const int&, ExplicitTo<int&>>();
228
229 test_is_constructible<const int&, ExplicitTo<int&>&>();
230 test_is_constructible<const int&, ExplicitTo<int&>>();
231
232
233 // Binding through reference-compatible type is required to perform
234 // direct-initialization as described in [over.match.ref] p. 1 b. 1:
235 //
236 // But the rvalue to lvalue reference binding isn't allowed according to
237 // [over.match.ref] despite Clang accepting it.
238 test_is_constructible<int&, ExplicitTo<int&>>();
239 #ifndef TEST_COMPILER_GCC
240 test_is_constructible<const int&, ExplicitTo<int&&>>();
241 #endif
242
243 static_assert(std::is_constructible<int&&, ExplicitTo<int&&>>::value, "");
244
245 #ifdef __clang__
246 // FIXME Clang and GCC disagree on the validity of this expression.
247 test_is_constructible<const int&, ExplicitTo<int>>();
248 static_assert(std::is_constructible<int&&, ExplicitTo<int>>::value, "");
249 #else
250 test_is_not_constructible<const int&, ExplicitTo<int>>();
251 test_is_not_constructible<int&&, ExplicitTo<int>>();
252 #endif
253
254 // Binding through temporary behaves like copy-initialization,
255 // see [dcl.init.ref] p. 5, very last sub-bullet:
256 test_is_not_constructible<const int&, ExplicitTo<double&&>>();
257 test_is_not_constructible<int&&, ExplicitTo<double&&>>();
258
259 test_is_not_constructible<void()>();
260 test_is_not_constructible<void() const> ();
261 test_is_not_constructible<void() volatile> ();
262 test_is_not_constructible<void() &> ();
263 test_is_not_constructible<void() &&> ();
264 #endif // TEST_STD_VER >= 11
265
266 return 0;
267 }
268