diff options
author | Howard Hinnant <hhinnant@apple.com> | 2010-09-07 23:11:28 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2010-09-07 23:11:28 +0000 |
commit | bfc4026f4c259763d32be8103f9386d4b92af316 (patch) | |
tree | 6efc8f4c4d2475dbb4b6a8a6b1cbe19ee5725da9 | |
parent | 978f007a8018f9511788b8b50ff639a764408017 (diff) | |
download | bcm5719-llvm-bfc4026f4c259763d32be8103f9386d4b92af316.tar.gz bcm5719-llvm-bfc4026f4c259763d32be8103f9386d4b92af316.zip |
Made a stab at has_copy_constructor. Got it mostly working for g++-4.0, but only works for scalar types on clang. Ultimately this needs a compiler-supported is_constructible which clang is missing, and won't be able to use until it gets variadic templates.
llvm-svn: 113304
3 files changed, 71 insertions, 9 deletions
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 9ae3d6f6ab9..0f45f489dab 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -761,10 +761,6 @@ template <class _Tp> struct has_nothrow_copy_constructor template <class _Tp> struct has_nothrow_move_constructor : public has_nothrow_copy_constructor<_Tp> {}; -// has_copy_constructor - -template <class _Tp> struct has_copy_constructor : public true_type {}; - // has_copy_assign template <class _Tp> struct has_copy_assign; @@ -1732,6 +1728,24 @@ struct __is_constructible0_imp<false, _A[]> #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE +// has_copy_constructor + +#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE + +template <class _Tp> +struct has_copy_constructor + : public is_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type> + {}; + +#else // _LIBCPP_HAS_NO_ADVANCED_SFINAE + +template <class _Tp> +struct has_copy_constructor + : public has_nothrow_copy_constructor<_Tp> + {}; + +#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE + template <class _Tp> struct __is_zero_default_constructible : public integral_constant<bool, is_scalar<_Tp>::value || is_empty<_Tp>::value> {}; diff --git a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_copy_constructor.pass.cpp b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_copy_constructor.pass.cpp index 7acb69509fe..f3364c1cf1f 100644 --- a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_copy_constructor.pass.cpp +++ b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_copy_constructor.pass.cpp @@ -13,7 +13,55 @@ #include <type_traits> +template <class T, bool Result> +void test_has_copy_constructor() +{ + static_assert(std::has_copy_constructor<T>::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(const A&); +}; + int main() { -#error has_copy_constructor not implemented + test_has_copy_constructor<char[3], false>(); + test_has_copy_constructor<char[], false>(); + test_has_copy_constructor<void, false>(); + test_has_copy_constructor<Abstract, false>(); + + test_has_copy_constructor<A, true>(); + test_has_copy_constructor<int&, true>(); + test_has_copy_constructor<Union, true>(); + test_has_copy_constructor<Empty, true>(); + test_has_copy_constructor<int, true>(); + test_has_copy_constructor<double, true>(); + test_has_copy_constructor<int*, true>(); + test_has_copy_constructor<const int*, true>(); + test_has_copy_constructor<NotEmpty, true>(); + test_has_copy_constructor<bit_zero, true>(); } diff --git a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_copy_constructor.pass.cpp b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_copy_constructor.pass.cpp index f2ebadd4e12..8dbd3e8eebf 100644 --- a/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_copy_constructor.pass.cpp +++ b/libcxx/test/utilities/meta/meta.unary/meta.unary.prop/has_nothrow_copy_constructor.pass.cpp @@ -61,11 +61,11 @@ struct A int main() { -// test_has_not_nothrow_copy_constructor<void>(); + test_has_not_nothrow_copy_constructor<void>(); test_has_not_nothrow_copy_constructor<A>(); test_has_not_nothrow_copy_constructor<Abstract>(); -// test_has_not_nothrow_copy_constructor<char[3]>(); -// test_has_not_nothrow_copy_constructor<char[]>(); + test_has_not_nothrow_copy_constructor<char[3]>(); + test_has_not_nothrow_copy_constructor<char[]>(); test_has_nothrow_copy_constructor<int&>(); test_has_nothrow_copy_constructor<Union>(); @@ -74,6 +74,6 @@ int main() test_has_nothrow_copy_constructor<double>(); test_has_nothrow_copy_constructor<int*>(); test_has_nothrow_copy_constructor<const int*>(); -// test_has_nothrow_copy_constructor<NotEmpty>(); + test_has_nothrow_copy_constructor<NotEmpty>(); test_has_nothrow_copy_constructor<bit_zero>(); } |