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

source code of libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp