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 
17 struct A
18 {
19     explicit A(int);
20     A(int, double);
21     A(int, long, double);
22 #if TEST_STD_VER >= 11
23 private:
24 #endif
25     A(char);
26 };
27 
28 struct Base {};
29 struct Derived : public Base {};
30 
31 class Abstract
32 {
33     virtual void foo() = 0;
34 };
35 
36 class AbstractDestructor
37 {
38     virtual ~AbstractDestructor() = 0;
39 };
40 
41 struct PrivateDtor {
PrivateDtorPrivateDtor42   PrivateDtor(int) {}
43 private:
~PrivateDtorPrivateDtor44   ~PrivateDtor() {}
45 };
46 
47 struct S {
48    template <class T>
49 #if TEST_STD_VER >= 11
50    explicit
51 #endif
52    operator T () const;
53 };
54 
55 template <class To>
56 struct ImplicitTo {
57   operator To();
58 };
59 
60 #if TEST_STD_VER >= 11
61 template <class To>
62 struct ExplicitTo {
63    explicit operator To ();
64 };
65 #endif
66 
67 
68 template <class T>
test_is_constructible()69 void 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 
77 template <class T, class A0>
test_is_constructible()78 void 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 
86 template <class T, class A0, class A1>
test_is_constructible()87 void 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 
95 template <class T, class A0, class A1, class A2>
test_is_constructible()96 void 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 
104 template <class T>
test_is_not_constructible()105 void 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 
113 template <class T, class A0>
test_is_not_constructible()114 void 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 
main(int,char **)122 int 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