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