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