• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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