1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // type_traits
11 // XFAIL: apple-clang-6.0
12 // The Apple-6 compiler gets is_constructible<void ()> wrong.
13
14 // template <class T, class... Args>
15 // struct is_constructible;
16
17 // MODULES_DEFINES: _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
18 #define _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
19 #include <type_traits>
20 #include "test_macros.h"
21
22 #if TEST_STD_VER >= 11 && defined(_LIBCPP_VERSION)
23 #define LIBCPP11_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
24 #else
25 #define LIBCPP11_STATIC_ASSERT(...) ((void)0)
26 #endif
27
28
29 struct A
30 {
31 explicit A(int);
32 A(int, double);
33 A(int, long, double);
34 #if TEST_STD_VER >= 11
35 private:
36 #endif
37 A(char);
38 };
39
40 struct Base {};
41 struct Derived : public Base {};
42
43 class Abstract
44 {
45 virtual void foo() = 0;
46 };
47
48 class AbstractDestructor
49 {
50 virtual ~AbstractDestructor() = 0;
51 };
52
53 struct PrivateDtor {
PrivateDtorPrivateDtor54 PrivateDtor(int) {}
55 private:
~PrivateDtorPrivateDtor56 ~PrivateDtor() {}
57 };
58
59 struct S {
60 template <class T>
61 #if TEST_STD_VER >= 11
62 explicit
63 #endif
64 operator T () const;
65 };
66
67 template <class To>
68 struct ImplicitTo {
69 operator To();
70 };
71
72 #if TEST_STD_VER >= 11
73 template <class To>
74 struct ExplicitTo {
75 explicit operator To ();
76 };
77 #endif
78
79
80 template <class T>
test_is_constructible()81 void test_is_constructible()
82 {
83 static_assert( (std::is_constructible<T>::value), "");
84 LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T>::type::value), "");
85 #if TEST_STD_VER > 14
86 static_assert( std::is_constructible_v<T>, "");
87 #endif
88 }
89
90 template <class T, class A0>
test_is_constructible()91 void test_is_constructible()
92 {
93 static_assert(( std::is_constructible<T, A0>::value), "");
94 LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0>::type::value), "");
95 #if TEST_STD_VER > 14
96 static_assert(( std::is_constructible_v<T, A0>), "");
97 #endif
98 }
99
100 template <class T, class A0, class A1>
test_is_constructible()101 void test_is_constructible()
102 {
103 static_assert(( std::is_constructible<T, A0, A1>::value), "");
104 LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0, A1>::type::value), "");
105 #if TEST_STD_VER > 14
106 static_assert(( std::is_constructible_v<T, A0, A1>), "");
107 #endif
108 }
109
110 template <class T, class A0, class A1, class A2>
test_is_constructible()111 void test_is_constructible()
112 {
113 static_assert(( std::is_constructible<T, A0, A1, A2>::value), "");
114 LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0, A1, A2>::type::value), "");
115 #if TEST_STD_VER > 14
116 static_assert(( std::is_constructible_v<T, A0, A1, A2>), "");
117 #endif
118 }
119
120 template <class T>
test_is_not_constructible()121 void test_is_not_constructible()
122 {
123 static_assert((!std::is_constructible<T>::value), "");
124 LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible<T>::type::value), "");
125 #if TEST_STD_VER > 14
126 static_assert((!std::is_constructible_v<T>), "");
127 #endif
128 }
129
130 template <class T, class A0>
test_is_not_constructible()131 void test_is_not_constructible()
132 {
133 static_assert((!std::is_constructible<T, A0>::value), "");
134 LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible<T, A0>::type::value), "");
135 #if TEST_STD_VER > 14
136 static_assert((!std::is_constructible_v<T, A0>), "");
137 #endif
138 }
139
140 #if TEST_STD_VER >= 11
141 template <class T = int, class = decltype(static_cast<T&&>(std::declval<double&>()))>
clang_disallows_valid_static_cast_test(int)142 constexpr bool clang_disallows_valid_static_cast_test(int) { return false; };
143
clang_disallows_valid_static_cast_test(long)144 constexpr bool clang_disallows_valid_static_cast_test(long) { return true; }
145
146 static constexpr bool clang_disallows_valid_static_cast_bug =
147 clang_disallows_valid_static_cast_test(0);
148 #endif
149
150
main()151 int main()
152 {
153 typedef Base B;
154 typedef Derived D;
155
156 test_is_constructible<int> ();
157 test_is_constructible<int, const int> ();
158 test_is_constructible<A, int> ();
159 test_is_constructible<A, int, double> ();
160 test_is_constructible<A, int, long, double> ();
161 test_is_constructible<int&, int&> ();
162
163 test_is_not_constructible<A> ();
164 #if TEST_STD_VER >= 11
165 test_is_not_constructible<A, char> ();
166 #else
167 test_is_constructible<A, char> ();
168 #endif
169 test_is_not_constructible<A, void> ();
170 test_is_not_constructible<int, void()>();
171 test_is_not_constructible<int, void(&)()>();
172 test_is_not_constructible<int, void() const>();
173 test_is_not_constructible<int&, void>();
174 test_is_not_constructible<int&, void()>();
175 test_is_not_constructible<int&, void() const>();
176 test_is_not_constructible<int&, void(&)()>();
177
178 test_is_not_constructible<void> ();
179 test_is_not_constructible<const void> (); // LWG 2738
180 test_is_not_constructible<volatile void> ();
181 test_is_not_constructible<const volatile void> ();
182 test_is_not_constructible<int&> ();
183 test_is_not_constructible<Abstract> ();
184 test_is_not_constructible<AbstractDestructor> ();
185 test_is_constructible<int, S>();
186 test_is_not_constructible<int&, S>();
187
188 test_is_constructible<void(&)(), void(&)()>();
189 test_is_constructible<void(&)(), void()>();
190 #if TEST_STD_VER >= 11
191 test_is_constructible<void(&&)(), void(&&)()>();
192 test_is_constructible<void(&&)(), void()>();
193 test_is_constructible<void(&&)(), void(&)()>();
194 #endif
195
196 #if TEST_STD_VER >= 11
197 test_is_constructible<int const&, int>();
198 test_is_constructible<int const&, int&&>();
199
200 test_is_constructible<int&&, double&>();
201 test_is_constructible<void(&)(), void(&&)()>();
202
203 test_is_not_constructible<int&, int>();
204 test_is_not_constructible<int&, int const&>();
205 test_is_not_constructible<int&, int&&>();
206
207 test_is_constructible<int&&, int>();
208 test_is_constructible<int&&, int&&>();
209 test_is_not_constructible<int&&, int&>();
210 test_is_not_constructible<int&&, int const&&>();
211
212 test_is_constructible<Base, Derived>();
213 test_is_constructible<Base&, Derived&>();
214 test_is_not_constructible<Derived&, Base&>();
215 test_is_constructible<Base const&, Derived const&>();
216 test_is_not_constructible<Derived const&, Base const&>();
217 test_is_not_constructible<Derived const&, Base>();
218
219 test_is_constructible<Base&&, Derived>();
220 test_is_constructible<Base&&, Derived&&>();
221 test_is_not_constructible<Derived&&, Base&&>();
222 test_is_not_constructible<Derived&&, Base>();
223
224 // test that T must also be destructible
225 test_is_constructible<PrivateDtor&, PrivateDtor&>();
226 test_is_not_constructible<PrivateDtor, int>();
227
228 test_is_not_constructible<void() const, void() const>();
229 test_is_not_constructible<void() const, void*>();
230
231 test_is_constructible<int&, ImplicitTo<int&>>();
232 test_is_constructible<const int&, ImplicitTo<int&&>>();
233 test_is_constructible<int&&, ImplicitTo<int&&>>();
234 test_is_constructible<const int&, ImplicitTo<int>>();
235
236 test_is_not_constructible<B&&, B&>();
237 test_is_not_constructible<B&&, D&>();
238 test_is_constructible<B&&, ImplicitTo<D&&>>();
239 test_is_constructible<B&&, ImplicitTo<D&&>&>();
240 test_is_constructible<int&&, double&>();
241 test_is_constructible<const int&, ImplicitTo<int&>&>();
242 test_is_constructible<const int&, ImplicitTo<int&>>();
243 test_is_constructible<const int&, ExplicitTo<int&>&>();
244 test_is_constructible<const int&, ExplicitTo<int&>>();
245
246 test_is_constructible<const int&, ExplicitTo<int&>&>();
247 test_is_constructible<const int&, ExplicitTo<int&>>();
248 test_is_constructible<int&, ExplicitTo<int&>>();
249 test_is_constructible<const int&, ExplicitTo<int&&>>();
250
251 // Binding through reference-compatible type is required to perform
252 // direct-initialization as described in [over.match.ref] p. 1 b. 1:
253 test_is_constructible<int&, ExplicitTo<int&>>();
254 test_is_constructible<const int&, ExplicitTo<int&&>>();
255
256 static_assert(std::is_constructible<int&&, ExplicitTo<int&&>>::value, "");
257 #ifdef __clang__
258 #if defined(CLANG_TEST_VER) && CLANG_TEST_VER < 400
259 static_assert(clang_disallows_valid_static_cast_bug, "bug still exists");
260 #endif
261 // FIXME Clang disallows this construction because it thinks that
262 // 'static_cast<int&&>(declval<ExplicitTo<int&&>>())' is ill-formed.
263 LIBCPP_STATIC_ASSERT(
264 clang_disallows_valid_static_cast_bug !=
265 std::__libcpp_is_constructible<int&&, ExplicitTo<int&&>>::value, "");
266 ((void)clang_disallows_valid_static_cast_bug); // Prevent unused warning
267 #else
268 static_assert(clang_disallows_valid_static_cast_bug == false, "");
269 LIBCPP_STATIC_ASSERT(std::__libcpp_is_constructible<int&&, ExplicitTo<int&&>>::value, "");
270 #endif
271
272 #ifdef __clang__
273 // FIXME Clang and GCC disagree on the validity of this expression.
274 test_is_constructible<const int&, ExplicitTo<int>>();
275 static_assert(std::is_constructible<int&&, ExplicitTo<int>>::value, "");
276 LIBCPP_STATIC_ASSERT(
277 clang_disallows_valid_static_cast_bug !=
278 std::__libcpp_is_constructible<int&&, ExplicitTo<int>>::value, "");
279 #else
280 test_is_not_constructible<const int&, ExplicitTo<int>>();
281 test_is_not_constructible<int&&, ExplicitTo<int>>();
282 #endif
283
284 // Binding through temporary behaves like copy-initialization,
285 // see [dcl.init.ref] p. 5, very last sub-bullet:
286 test_is_not_constructible<const int&, ExplicitTo<double&&>>();
287 test_is_not_constructible<int&&, ExplicitTo<double&&>>();
288
289
290 // TODO: Remove this workaround once Clang <= 3.7 are no longer used regularly.
291 // In those compiler versions the __is_constructible builtin gives the wrong
292 // results for abominable function types.
293 #if (defined(TEST_APPLE_CLANG_VER) && TEST_APPLE_CLANG_VER < 703) \
294 || (defined(TEST_CLANG_VER) && TEST_CLANG_VER < 308)
295 #define WORKAROUND_CLANG_BUG
296 #endif
297 #if !defined(WORKAROUND_CLANG_BUG)
298 test_is_not_constructible<void()>();
299 test_is_not_constructible<void() const> ();
300 test_is_not_constructible<void() volatile> ();
301 test_is_not_constructible<void() &> ();
302 test_is_not_constructible<void() &&> ();
303 #endif
304 #endif // TEST_STD_VER >= 11
305 }
306