diff --git a/doc/move.qbk b/doc/move.qbk index 729e92a..e22ce09 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -762,6 +762,13 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes Release Notes] +[section:release_notes_boost_1_58_01 Boost 1.58.1 Release] + + * Fixed bug: + * [@https://svn.boost.org/trac/boost/ticket/11229 Trac #11229: ['"vector incorrectly copies move-only objects using memcpy"]], + +[endsect] + [section:release_notes_boost_1_58_00 Boost 1.58 Release] * Added [macroref BOOST_MOVE_BASE BOOST_MOVE_BASE] utility. diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp index 17cfa1f..ed02361 100644 --- a/include/boost/move/detail/type_traits.hpp +++ b/include/boost/move/detail/type_traits.hpp @@ -738,6 +738,46 @@ struct is_copy_constructible static const bool value = sizeof(test(source())) == sizeof(yes_type); }; +////////////////////////////////////// +// is_copy_assignable +////////////////////////////////////// +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \ + && !defined(BOOST_INTEL_CXX_VERSION) && \ + !(defined(BOOST_MSVC) && _MSC_VER == 1800) +#define BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE +#endif + +template +struct is_copy_assignable +{ +// Intel compiler has problems with SFINAE for copy constructors and deleted functions: +// +// error: function *function_name* cannot be referenced -- it is a deleted function +// static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval()))* = 0); +// ^ +// +// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See: +// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken +#if defined(BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE) + typedef char yes_type; + struct no_type { char dummy[2]; }; + + template static typename add_reference::type source(); + template static decltype(source() = source(), yes_type() ) test(int); + template static no_type test(...); + + static const bool value = sizeof(test(0)) == sizeof(yes_type); +#else + static typename add_reference::type produce(); + + template + static no_type test(T1&, typename T1::boost_move_no_copy_constructor_or_assign* = 0); + static yes_type test(...); + + static const bool value = sizeof(test(produce())) == sizeof(yes_type); +#endif +}; + ////////////////////////////////////// // is_trivially_destructible ////////////////////////////////////// @@ -757,7 +797,12 @@ struct is_trivially_default_constructible ////////////////////////////////////// template struct is_trivially_copy_constructible -{ static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T); }; +{ + //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with + //deleted copy constructors so make sure the type is copy constructible. + static const bool value = ::boost::move_detail::is_copy_constructible::value && + BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T); +}; ////////////////////////////////////// // is_trivially_move_constructible @@ -771,7 +816,12 @@ struct is_trivially_move_constructible ////////////////////////////////////// template struct is_trivially_copy_assignable -{ static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T); }; +{ + //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with + //deleted copy constructors so make sure the type is copy constructible. + static const bool value = ::boost::move_detail::is_copy_assignable::value && + BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T); +}; ////////////////////////////////////// // is_trivially_move_assignable diff --git a/test/unique_ptr_types.cpp b/test/unique_ptr_types.cpp index 484c906..a88b46c 100644 --- a/test/unique_ptr_types.cpp +++ b/test/unique_ptr_types.cpp @@ -12,6 +12,7 @@ ////////////////////////////////////////////////////////////////////////////// #include #include +#include #include #include @@ -150,6 +151,11 @@ void test() //////////////////////////////// // main //////////////////////////////// + +#if __cplusplus >= 201103L +#include +#endif + int main() { //General @@ -157,6 +163,19 @@ int main() unique_ptr_deleter_type::test(); unique_ptr_element_type::test(); + typedef bml::unique_ptr unique_ptr_t; + BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible::value)); + BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable::value)); + BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible::value)); + BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable::value)); + #if __cplusplus >= 201103L + typedef std::unique_ptr std_unique_ptr_t; + BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible::value)); + BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable::value)); + BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible::value)); + BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable::value)); + #endif + //Test results return boost::report_errors();