diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 7a3b81fc6e3a..cf6d091d2eff 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -1637,6 +1637,80 @@ struct __is_constructible : public false_type {}; +template +struct has_default_constructor + : public is_constructible<_Tp> + {}; + +#else // _LIBCPP_HAS_NO_ADVANCED_SFINAE + +// template struct is_constructible0; + +// main is_constructible0 test + +template +decltype((_STD::move(_Tp()), true_type())) +__is_constructible0_test(_Tp&); + +false_type +__is_constructible0_test(__any); + +template +struct __is_constructible0_imp // false, _Tp is not a scalar + : public common_type + < + decltype(__is_constructible0_test(declval<_Tp&>())) + >::type + {}; + +// handle scalars and reference types + +// Scalars are default constructible, references are not + +template +struct __is_constructible0_imp + : public is_scalar<_Tp> + {}; + +// Treat scalars and reference types separately + +template +struct __is_constructible0_void_check + : public __is_constructible0_imp::value || is_reference<_Tp>::value, + _Tp> + {}; + +// If any of T or Args is void, is_constructible should be false + +template +struct __is_constructible0_void_check + : public false_type + {}; + +// has_default_constructor entry point + +template +struct has_default_constructor + : public __is_constructible0_void_check::value + || is_abstract<_Tp>::value, + _Tp> + {}; + +// Array types are default constructible if their element type +// is default constructible + +template +struct __is_constructible0_imp + : public has_default_constructor::type> + {}; + +// Incomplete array types are not constructible + +template +struct __is_constructible0_imp + : public false_type + {}; + #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE template struct __is_zero_default_constructible diff --git a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_default_constructor.pass.cpp b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_default_constructor.pass.cpp index d253a821e761..0bcda49d14c8 100644 --- a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_default_constructor.pass.cpp +++ b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_default_constructor.pass.cpp @@ -13,7 +13,58 @@ #include +template +void test_has_default_constructor() +{ + static_assert(std::has_default_constructor::value == Result, ""); + static_assert(std::has_default_constructor::value == Result, ""); + static_assert(std::has_default_constructor::value == Result, ""); + static_assert(std::has_default_constructor::value == Result, ""); +} + +class Empty +{ +}; + +class NotEmpty +{ +public: + virtual ~NotEmpty(); +}; + +union Union {}; + +struct bit_zero +{ + int : 0; +}; + +class Abstract +{ +public: + virtual ~Abstract() = 0; +}; + +struct A +{ + A(); +}; + int main() { -#error has_default_constructor not implemented + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); + test_has_default_constructor(); } diff --git a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_default_constructor.pass.cpp b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_default_constructor.pass.cpp index 8a5336d0dd69..0edf406b0bbd 100644 --- a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_default_constructor.pass.cpp +++ b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_default_constructor.pass.cpp @@ -37,6 +37,7 @@ class Empty class NotEmpty { +public: virtual ~NotEmpty(); }; @@ -49,6 +50,7 @@ struct bit_zero class Abstract { +public: virtual ~Abstract() = 0; };