//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // type_traits // XFAIL: apple-clang-6.0 // The Apple-6 compiler gets is_constructible wrong. // template // struct is_constructible; // MODULES_DEFINES: _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE #define _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE #include #include "test_macros.h" #if TEST_STD_VER >= 11 && defined(_LIBCPP_VERSION) #define LIBCPP11_STATIC_ASSERT(...) static_assert(__VA_ARGS__) #else #define LIBCPP11_STATIC_ASSERT(...) ((void)0) #endif struct A { explicit A(int); A(int, double); A(int, long, double); #if TEST_STD_VER >= 11 private: #endif A(char); }; struct Base {}; struct Derived : public Base {}; class Abstract { virtual void foo() = 0; }; class AbstractDestructor { virtual ~AbstractDestructor() = 0; }; struct PrivateDtor { PrivateDtor(int) {} private: ~PrivateDtor() {} }; struct S { template #if TEST_STD_VER >= 11 explicit #endif operator T () const; }; template struct ImplicitTo { operator To(); }; #if TEST_STD_VER >= 11 template struct ExplicitTo { explicit operator To (); }; #endif template void test_is_constructible() { static_assert( (std::is_constructible::value), ""); LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible::type::value), ""); #if TEST_STD_VER > 14 static_assert( std::is_constructible_v, ""); #endif } template void test_is_constructible() { static_assert(( std::is_constructible::value), ""); LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible::type::value), ""); #if TEST_STD_VER > 14 static_assert(( std::is_constructible_v), ""); #endif } template void test_is_constructible() { static_assert(( std::is_constructible::value), ""); LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible::type::value), ""); #if TEST_STD_VER > 14 static_assert(( std::is_constructible_v), ""); #endif } template void test_is_constructible() { static_assert(( std::is_constructible::value), ""); LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible::type::value), ""); #if TEST_STD_VER > 14 static_assert(( std::is_constructible_v), ""); #endif } template void test_is_not_constructible() { static_assert((!std::is_constructible::value), ""); LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible::type::value), ""); #if TEST_STD_VER > 14 static_assert((!std::is_constructible_v), ""); #endif } template void test_is_not_constructible() { static_assert((!std::is_constructible::value), ""); LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible::type::value), ""); #if TEST_STD_VER > 14 static_assert((!std::is_constructible_v), ""); #endif } #if TEST_STD_VER >= 11 template (std::declval()))> constexpr bool clang_disallows_valid_static_cast_test(int) { return false; }; constexpr bool clang_disallows_valid_static_cast_test(long) { return true; } static constexpr bool clang_disallows_valid_static_cast_bug = clang_disallows_valid_static_cast_test(0); #endif int main() { typedef Base B; typedef Derived D; test_is_constructible (); test_is_constructible (); test_is_constructible (); test_is_constructible (); test_is_constructible (); test_is_constructible (); test_is_not_constructible (); #if TEST_STD_VER >= 11 test_is_not_constructible (); #else test_is_constructible (); #endif test_is_not_constructible (); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible (); test_is_not_constructible (); // LWG 2738 test_is_not_constructible (); test_is_not_constructible (); test_is_not_constructible (); test_is_not_constructible (); test_is_not_constructible (); test_is_constructible(); test_is_not_constructible(); test_is_constructible(); test_is_constructible(); #if TEST_STD_VER >= 11 test_is_constructible(); test_is_constructible(); test_is_constructible(); #endif #if TEST_STD_VER >= 11 test_is_constructible(); test_is_constructible(); test_is_constructible(); test_is_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_constructible(); test_is_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_constructible(); test_is_constructible(); test_is_not_constructible(); test_is_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_constructible(); test_is_constructible(); test_is_not_constructible(); test_is_not_constructible(); // test that T must also be destructible test_is_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_not_constructible(); test_is_constructible>(); test_is_constructible>(); test_is_constructible>(); test_is_constructible>(); test_is_not_constructible(); test_is_not_constructible(); test_is_constructible>(); test_is_constructible&>(); test_is_constructible(); test_is_constructible&>(); test_is_constructible>(); test_is_constructible&>(); test_is_constructible>(); test_is_constructible&>(); test_is_constructible>(); test_is_constructible>(); test_is_constructible>(); // Binding through reference-compatible type is required to perform // direct-initialization as described in [over.match.ref] p. 1 b. 1: test_is_constructible>(); test_is_constructible>(); static_assert(std::is_constructible>::value, ""); #ifdef __clang__ #if defined(CLANG_TEST_VER) && CLANG_TEST_VER < 400 static_assert(clang_disallows_valid_static_cast_bug, "bug still exists"); #endif // FIXME Clang disallows this construction because it thinks that // 'static_cast(declval>())' is ill-formed. LIBCPP_STATIC_ASSERT( clang_disallows_valid_static_cast_bug != std::__libcpp_is_constructible>::value, ""); ((void)clang_disallows_valid_static_cast_bug); // Prevent unused warning #else static_assert(clang_disallows_valid_static_cast_bug == false, ""); LIBCPP_STATIC_ASSERT(std::__libcpp_is_constructible>::value, ""); #endif #ifdef __clang__ // FIXME Clang and GCC disagree on the validity of this expression. test_is_constructible>(); static_assert(std::is_constructible>::value, ""); LIBCPP_STATIC_ASSERT( clang_disallows_valid_static_cast_bug != std::__libcpp_is_constructible>::value, ""); #else test_is_not_constructible>(); test_is_not_constructible>(); #endif // Binding through temporary behaves like copy-initialization, // see [dcl.init.ref] p. 5, very last sub-bullet: test_is_not_constructible>(); test_is_not_constructible>(); // TODO: Remove this workaround once Clang <= 3.7 are no longer used regularly. // In those compiler versions the __is_constructible builtin gives the wrong // results for abominable function types. #if (defined(TEST_APPLE_CLANG_VER) && TEST_APPLE_CLANG_VER < 703) \ || (defined(TEST_CLANG_VER) && TEST_CLANG_VER < 308) #define WORKAROUND_CLANG_BUG #endif #if !defined(WORKAROUND_CLANG_BUG) test_is_not_constructible(); test_is_not_constructible (); test_is_not_constructible (); test_is_not_constructible (); test_is_not_constructible (); #endif #endif // TEST_STD_VER >= 11 }