diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp index 8335982..771c780 100644 --- a/include/boost/move/core.hpp +++ b/include/boost/move/core.hpp @@ -153,6 +153,14 @@ >& \ // + #define BOOST_RV_REF_BEG_IF_CXX11 \ + \ + // + + #define BOOST_RV_REF_END_IF_CXX11 \ + \ + // + #define BOOST_FWD_REF(TYPE)\ const TYPE & \ // @@ -346,6 +354,19 @@ //!and ended with BOOST_RV_REF_END #define BOOST_RV_REF_END\ && \ + // + + //!This macro expands to BOOST_RV_REF_BEG if BOOST_NO_CXX11_RVALUE_REFERENCES + //!is not defined, empty otherwise + #define BOOST_RV_REF_BEG_IF_CXX11 \ + BOOST_RV_REF_BEG \ + // + + //!This macro expands to BOOST_RV_REF_END if BOOST_NO_CXX11_RVALUE_REFERENCES + //!is not defined, empty otherwise + #define BOOST_RV_REF_END_IF_CXX11 \ + BOOST_RV_REF_END \ + // //!This macro is used to achieve portable syntax in copy //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE. diff --git a/include/boost/move/unique_ptr.hpp b/include/boost/move/unique_ptr.hpp index cbac2aa..f005f34 100644 --- a/include/boost/move/unique_ptr.hpp +++ b/include/boost/move/unique_ptr.hpp @@ -219,9 +219,14 @@ struct enable_up_ptr template struct unique_moveconvert_assignable { - static const bool value = (bmupmu::extent::value == bmupmu::extent::value) && is_unique_ptr_convertible - < bmupmu::is_array::value - , typename bmupmu::pointer_type::type, typename bmupmu::pointer_type::type>::value; + static const bool t_is_array = bmupmu::is_array::value; + static const bool value = + t_is_array == bmupmu::is_array::value && + bmupmu::extent::value == bmupmu::extent::value && + is_unique_ptr_convertible + < t_is_array + , typename bmupmu::pointer_type::type, typename bmupmu::pointer_type::type + >::value; }; template @@ -290,8 +295,9 @@ struct unique_deleter_is_initializable template struct enable_up_moveconv_constr - : bmupmu::enable_if_c::value && - unique_deleter_is_initializable::value, Type> + : bmupmu::enable_if_c + < unique_moveconvert_assignable::value && unique_deleter_is_initializable::value + , Type> {}; } //namespace move_upd { @@ -538,7 +544,7 @@ class unique_ptr //! Postconditions: get() yields the value u.get() yielded before the construction. get_deleter() //! returns a reference to the stored deleter that was constructed from u.get_deleter(). template - unique_ptr( BOOST_RV_REF_BEG unique_ptr BOOST_RV_REF_END u + unique_ptr( BOOST_RV_REF_BEG_IF_CXX11 unique_ptr BOOST_RV_REF_END_IF_CXX11 u BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_moveconv_constr::type* =0) ) BOOST_NOEXCEPT : m_data(u.release(), ::boost::move_if_not_lvalue_reference(u.get_deleter())) diff --git a/test/unique_ptr_ctordtor.cpp b/test/unique_ptr_ctordtor.cpp index 1225507..a583b92 100644 --- a/test/unique_ptr_ctordtor.cpp +++ b/test/unique_ptr_ctordtor.cpp @@ -681,6 +681,107 @@ void test() } //namespace unique_ptr_ctor_pointer_deleter_void{ +//////////////////////////////// +// return_unique_single_conversion +//////////////////////////////// + +namespace return_unique_single_conversion{ + +template +bml::unique_ptr make_unique_ptr_of_t() +{ + return bml::unique_ptr(new T); +} + +template +bml::unique_ptr return_const_unique_of_t() +{ + return bml::unique_ptr (make_unique_ptr_of_t()); +} + +void test() +{ + reset_counters(); + BOOST_TEST(A::count == 0); + { + bml::unique_ptr p(return_const_unique_of_t()); + BOOST_TEST(A::count == 1); + BOOST_TEST(B::count == 0); + } + BOOST_TEST(A::count == 0); + { + bml::unique_ptr p(return_const_unique_of_t()); + BOOST_TEST(A::count == 1); + BOOST_TEST(B::count == 1); + } + BOOST_TEST(A::count == 0); +} + +} //namespace return_unique_single_conversion{ + + +//////////////////////////////// +// return_unique_array_conversion +//////////////////////////////// + +namespace return_unique_array_conversion{ + +template +bml::unique_ptr return_unique_array_of_t(std::size_t n) +{ + return bml::unique_ptr(new T[n]); +} + +template +bml::unique_ptr return_const_array_of_t(std::size_t n) +{ + return bml::unique_ptr(return_unique_array_of_t(n)); +} + +template +bml::unique_ptr return_unique_array_of_t_2() +{ + return bml::unique_ptr(new T[2]); +} + +template +bml::unique_ptr return_const_array_of_t_2() +{ + return bml::unique_ptr(return_unique_array_of_t_2()); +} + +void test() +{ + reset_counters(); + BOOST_TEST(A::count == 0); + { + bml::unique_ptr p(return_unique_array_of_t(2)); + BOOST_TEST(A::count == 2); + BOOST_TEST(B::count == 0); + } + BOOST_TEST(A::count == 0); + { + bml::unique_ptr p(return_unique_array_of_t(2)); + BOOST_TEST(A::count == 2); + BOOST_TEST(B::count == 0); + } + BOOST_TEST(A::count == 0); + { + bml::unique_ptr p(return_const_array_of_t_2()); + BOOST_TEST(A::count == 2); + BOOST_TEST(B::count == 0); + } + BOOST_TEST(A::count == 0); + { + bml::unique_ptr p(return_const_array_of_t_2()); + BOOST_TEST(A::count == 2); + BOOST_TEST(B::count == 0); + } + BOOST_TEST(A::count == 0); +} + +} //namespace return_unique_array_conversion{ + //////////////////////////////// // main //////////////////////////////// @@ -699,6 +800,8 @@ int main() unique_ptr_ctor_pointer_deleter_dfctrdelconstref::test(); unique_ptr_ctor_pointer_deleter_convert::test(); unique_ptr_ctor_pointer_deleter_void::test(); + return_unique_single_conversion::test(); + return_unique_array_conversion::test(); //Test results return boost::report_errors(); diff --git a/test/unique_ptr_functions.cpp b/test/unique_ptr_functions.cpp index 33274d2..c68d085 100644 --- a/test/unique_ptr_functions.cpp +++ b/test/unique_ptr_functions.cpp @@ -134,7 +134,7 @@ void test() //////////////////////////////// -// make_unique_single +// make_unique_array //////////////////////////////// namespace make_unique_array{