mirror of
https://github.com/boostorg/move.git
synced 2025-07-31 12:57:14 +02:00
Modify unique_ptr's constructor from convertible unique_ptr's to take the argument by value. This allows constructing unique_ptr from functions returning convertible unique_ptr's. See https://svn.boost.org/trac/boost/ticket/11259 for some details.
This commit is contained in:
@ -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.
|
||||
|
@ -219,9 +219,14 @@ struct enable_up_ptr
|
||||
template<class T, class D, class U, class E>
|
||||
struct unique_moveconvert_assignable
|
||||
{
|
||||
static const bool value = (bmupmu::extent<T>::value == bmupmu::extent<U>::value) && is_unique_ptr_convertible
|
||||
< bmupmu::is_array<T>::value
|
||||
, typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type>::value;
|
||||
static const bool t_is_array = bmupmu::is_array<T>::value;
|
||||
static const bool value =
|
||||
t_is_array == bmupmu::is_array<U>::value &&
|
||||
bmupmu::extent<T>::value == bmupmu::extent<U>::value &&
|
||||
is_unique_ptr_convertible
|
||||
< t_is_array
|
||||
, typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type
|
||||
>::value;
|
||||
};
|
||||
|
||||
template<class T, class D, class U, class E, std::size_t N>
|
||||
@ -290,8 +295,9 @@ struct unique_deleter_is_initializable<D, E, false>
|
||||
|
||||
template<class T, class D, class U, class E, class Type = bmupmu::nat>
|
||||
struct enable_up_moveconv_constr
|
||||
: bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value &&
|
||||
unique_deleter_is_initializable<D, E>::value, Type>
|
||||
: bmupmu::enable_if_c
|
||||
< unique_moveconvert_assignable<T, D, U, E>::value && unique_deleter_is_initializable<D, E>::value
|
||||
, Type>
|
||||
{};
|
||||
|
||||
} //namespace move_upd {
|
||||
@ -538,7 +544,7 @@ class unique_ptr
|
||||
//! <b>Postconditions</b>: <tt>get()</tt> yields the value <tt>u.get()</tt> yielded before the construction. <tt>get_deleter()</tt>
|
||||
//! returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>.
|
||||
template <class U, class E>
|
||||
unique_ptr( BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u
|
||||
unique_ptr( BOOST_RV_REF_BEG_IF_CXX11 unique_ptr<U, E> BOOST_RV_REF_END_IF_CXX11 u
|
||||
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_moveconv_constr<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E>::type* =0)
|
||||
) BOOST_NOEXCEPT
|
||||
: m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter()))
|
||||
|
@ -681,6 +681,107 @@ void test()
|
||||
|
||||
} //namespace unique_ptr_ctor_pointer_deleter_void{
|
||||
|
||||
////////////////////////////////
|
||||
// return_unique_single_conversion
|
||||
////////////////////////////////
|
||||
|
||||
namespace return_unique_single_conversion{
|
||||
|
||||
template<class T>
|
||||
bml::unique_ptr<T> make_unique_ptr_of_t()
|
||||
{
|
||||
return bml::unique_ptr<T>(new T);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bml::unique_ptr<T const> return_const_unique_of_t()
|
||||
{
|
||||
return bml::unique_ptr<T const> (make_unique_ptr_of_t<T>());
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
reset_counters();
|
||||
BOOST_TEST(A::count == 0);
|
||||
{
|
||||
bml::unique_ptr<const A> p(return_const_unique_of_t<A>());
|
||||
BOOST_TEST(A::count == 1);
|
||||
BOOST_TEST(B::count == 0);
|
||||
}
|
||||
BOOST_TEST(A::count == 0);
|
||||
{
|
||||
bml::unique_ptr<const A> p(return_const_unique_of_t<B>());
|
||||
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<class T>
|
||||
bml::unique_ptr<T[]> return_unique_array_of_t(std::size_t n)
|
||||
{
|
||||
return bml::unique_ptr<T[]>(new T[n]);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bml::unique_ptr<const T[]> return_const_array_of_t(std::size_t n)
|
||||
{
|
||||
return bml::unique_ptr<const T[]>(return_unique_array_of_t<T>(n));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bml::unique_ptr<T[2]> return_unique_array_of_t_2()
|
||||
{
|
||||
return bml::unique_ptr<T[2]>(new T[2]);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bml::unique_ptr<const T[2]> return_const_array_of_t_2()
|
||||
{
|
||||
return bml::unique_ptr<const T[2]>(return_unique_array_of_t_2<T>());
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
reset_counters();
|
||||
BOOST_TEST(A::count == 0);
|
||||
{
|
||||
bml::unique_ptr<const A[]> p(return_unique_array_of_t<A>(2));
|
||||
BOOST_TEST(A::count == 2);
|
||||
BOOST_TEST(B::count == 0);
|
||||
}
|
||||
BOOST_TEST(A::count == 0);
|
||||
{
|
||||
bml::unique_ptr<const volatile A[]> p(return_unique_array_of_t<volatile A>(2));
|
||||
BOOST_TEST(A::count == 2);
|
||||
BOOST_TEST(B::count == 0);
|
||||
}
|
||||
BOOST_TEST(A::count == 0);
|
||||
{
|
||||
bml::unique_ptr<const volatile A[2]> p(return_const_array_of_t_2<A>());
|
||||
BOOST_TEST(A::count == 2);
|
||||
BOOST_TEST(B::count == 0);
|
||||
}
|
||||
BOOST_TEST(A::count == 0);
|
||||
{
|
||||
bml::unique_ptr<const volatile A[]> p(return_const_array_of_t_2<A>());
|
||||
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();
|
||||
|
@ -134,7 +134,7 @@ void test()
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// make_unique_single
|
||||
// make_unique_array
|
||||
////////////////////////////////
|
||||
|
||||
namespace make_unique_array{
|
||||
|
Reference in New Issue
Block a user