Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -1541,43 +1541,57 @@ // is_destructible +// if it's a reference, return true +// if it's a function, return false +// if it's void, return false +// if it's an array of unknown bound, return false +// Otherwise, return "std::declval<_Up&>().~_Up()" is well-formed +// where _Up is remove_all_extents<_Tp>::type + +template +struct __is_destructor_wellformed { + template ().~_Tp1())> + static char __test (int); + + template + static __two __test (...); + + static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char); + }; + +template +struct __destructible_imp; + template -struct __destructible_test -{ - _Tp __t; -}; +struct __destructible_imp<_Tp, false> + : public _VSTD::integral_constant::type>::value> {}; template -decltype((_VSTD::declval<__destructible_test<_Tp> >().~__destructible_test<_Tp>(), true_type())) -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -__is_destructible_test(_Tp&&); -#else -__is_destructible_test(_Tp&); -#endif +struct __destructible_imp<_Tp, true> + : public _VSTD::true_type {}; -false_type -__is_destructible_test(__any); +template +struct __destructible_false; -template ::value || is_abstract<_Tp>::value - || is_function<_Tp>::value> -struct __destructible_imp - : public common_type - < - decltype(__is_destructible_test(declval<_Tp>())) - >::type {}; +template +struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, _VSTD::is_reference<_Tp>::value> {}; template -struct __destructible_imp<_Tp, true> - : public false_type {}; +struct __destructible_false<_Tp, true> : public _VSTD::false_type {}; template struct is_destructible - : public __destructible_imp<_Tp> {}; + : public __destructible_false<_Tp, _VSTD::is_function<_Tp>::value> {}; template struct is_destructible<_Tp[]> - : public false_type {}; + : public _VSTD::false_type {}; +template <> +struct is_destructible + : public _VSTD::false_type {}; + // move #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES Index: test/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp =================================================================== --- test/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp +++ test/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp @@ -24,6 +24,16 @@ A(char); }; +class Abstract +{ + virtual void foo() = 0; +}; + +class AbstractDestructor +{ + virtual ~AbstractDestructor() = 0; +}; + template void test_is_constructible() { @@ -71,4 +81,6 @@ test_is_not_constructible (); test_is_not_constructible (); test_is_not_constructible (); + test_is_not_constructible (); + test_is_not_constructible (); } Index: test/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp =================================================================== --- test/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp +++ test/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp @@ -49,9 +49,14 @@ class Abstract { - virtual ~Abstract() = 0; + virtual void foo() = 0; }; +class AbstractDestructor +{ + virtual ~AbstractDestructor() = 0; +}; + struct A { ~A(); @@ -72,10 +77,11 @@ test_is_destructible(); test_is_destructible(); test_is_destructible(); + test_is_destructible(); test_is_not_destructible(); test_is_not_destructible(); - test_is_not_destructible(); + test_is_not_destructible(); #if __has_feature(cxx_access_control_sfinae) test_is_not_destructible(); #endif