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 { 53 PrivateDtor(int) {} 54 private: 55 ~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> 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> 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> 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> 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> 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&>()))> 131 constexpr bool clang_disallows_valid_static_cast_test(int) { return false; }; 132 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 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