forked from OSchip/llvm-project
[libcxx] Allow shared_ptr's unique_ptr converting constructor to support array types.
Refs: https://bugs.llvm.org/show_bug.cgi?id=32147 Differential Revision: https://reviews.llvm.org/D80882
This commit is contained in:
parent
4c89bcadf6
commit
097d77d611
|
@ -2702,7 +2702,6 @@ public:
|
||||||
typename enable_if
|
typename enable_if
|
||||||
<
|
<
|
||||||
!is_lvalue_reference<_Dp>::value &&
|
!is_lvalue_reference<_Dp>::value &&
|
||||||
!is_array<_Yp>::value &&
|
|
||||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||||
__nat
|
__nat
|
||||||
>::type = __nat());
|
>::type = __nat());
|
||||||
|
@ -2711,7 +2710,6 @@ public:
|
||||||
typename enable_if
|
typename enable_if
|
||||||
<
|
<
|
||||||
is_lvalue_reference<_Dp>::value &&
|
is_lvalue_reference<_Dp>::value &&
|
||||||
!is_array<_Yp>::value &&
|
|
||||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||||
__nat
|
__nat
|
||||||
>::type = __nat());
|
>::type = __nat());
|
||||||
|
@ -2752,7 +2750,6 @@ public:
|
||||||
template <class _Yp, class _Dp>
|
template <class _Yp, class _Dp>
|
||||||
typename enable_if
|
typename enable_if
|
||||||
<
|
<
|
||||||
!is_array<_Yp>::value &&
|
|
||||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||||
shared_ptr&
|
shared_ptr&
|
||||||
>::type
|
>::type
|
||||||
|
@ -3132,7 +3129,6 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
||||||
typename enable_if
|
typename enable_if
|
||||||
<
|
<
|
||||||
!is_lvalue_reference<_Dp>::value &&
|
!is_lvalue_reference<_Dp>::value &&
|
||||||
!is_array<_Yp>::value &&
|
|
||||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||||
__nat
|
__nat
|
||||||
>::type)
|
>::type)
|
||||||
|
@ -3145,7 +3141,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
||||||
typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
|
typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk;
|
||||||
__cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
|
__cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
|
||||||
__enable_weak_this(__r.get(), __r.get());
|
__enable_weak_this(__r.get(), __r.get());
|
||||||
}
|
}
|
||||||
|
@ -3158,7 +3154,6 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
||||||
typename enable_if
|
typename enable_if
|
||||||
<
|
<
|
||||||
is_lvalue_reference<_Dp>::value &&
|
is_lvalue_reference<_Dp>::value &&
|
||||||
!is_array<_Yp>::value &&
|
|
||||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||||
__nat
|
__nat
|
||||||
>::type)
|
>::type)
|
||||||
|
@ -3171,7 +3166,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
||||||
typedef __shared_ptr_pointer<_Yp*,
|
typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
|
||||||
reference_wrapper<typename remove_reference<_Dp>::type>,
|
reference_wrapper<typename remove_reference<_Dp>::type>,
|
||||||
_AllocT > _CntrlBlk;
|
_AllocT > _CntrlBlk;
|
||||||
__cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
|
__cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
|
||||||
|
@ -3255,7 +3250,6 @@ template <class _Yp, class _Dp>
|
||||||
inline
|
inline
|
||||||
typename enable_if
|
typename enable_if
|
||||||
<
|
<
|
||||||
!is_array<_Yp>::value &&
|
|
||||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
|
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
|
||||||
typename shared_ptr<_Tp>::element_type*>::value,
|
typename shared_ptr<_Tp>::element_type*>::value,
|
||||||
shared_ptr<_Tp>&
|
shared_ptr<_Tp>&
|
||||||
|
|
|
@ -41,6 +41,19 @@ struct A
|
||||||
|
|
||||||
int A::count = 0;
|
int A::count = 0;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct StatefulArrayDeleter {
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
StatefulArrayDeleter(int val = 0) : state(val) {}
|
||||||
|
StatefulArrayDeleter(StatefulArrayDeleter const&) { assert(false); }
|
||||||
|
|
||||||
|
void operator()(T* ptr) {
|
||||||
|
assert(state == 42);
|
||||||
|
delete []ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -112,5 +125,82 @@ int main(int, char**)
|
||||||
assert(B::count == 0);
|
assert(B::count == 0);
|
||||||
assert(A::count == 0);
|
assert(A::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<B> p;
|
||||||
|
p = std::move(ptr);
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(B::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<A> p;
|
||||||
|
p = std::move(ptr);
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[]> ptr(new int[8]);
|
||||||
|
std::shared_ptr<int> p;
|
||||||
|
p = std::move(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TEST_STD_VER > 14
|
||||||
|
{
|
||||||
|
StatefulArrayDeleter<A> d;
|
||||||
|
std::unique_ptr<A[], StatefulArrayDeleter<A>&> u(new A[4], d);
|
||||||
|
std::shared_ptr<A[]> p;
|
||||||
|
p = std::move(u);
|
||||||
|
d.state = 42;
|
||||||
|
assert(A::count == 4);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<B[]> p;
|
||||||
|
p = std::move(ptr);
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(B::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<A[]> p;
|
||||||
|
p = std::move(ptr);
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[]> ptr(new int[8]);
|
||||||
|
std::shared_ptr<int[]> p;
|
||||||
|
p = std::move(ptr);
|
||||||
|
}
|
||||||
|
#endif // TEST_STD_VER >= 14
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
// <memory>
|
// <memory>
|
||||||
|
|
||||||
// template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);
|
// template <class Y, class D> shared_ptr(unique_ptr<Y, D>&&r);
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
@ -69,6 +69,19 @@ struct StatefulDeleter {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct StatefulArrayDeleter {
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
StatefulArrayDeleter(int val = 0) : state(val) {}
|
||||||
|
StatefulArrayDeleter(StatefulArrayDeleter const&) { assert(false); }
|
||||||
|
|
||||||
|
void operator()(T* ptr) {
|
||||||
|
assert(state == 42);
|
||||||
|
delete []ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -135,5 +148,76 @@ int main(int, char**)
|
||||||
std::shared_ptr<int> s = std::move(u);
|
std::shared_ptr<int> s = std::move(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(A::count == 0);
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<B> p(std::move(ptr));
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(B::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<A> p(std::move(ptr));
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[]> ptr(new int[8]);
|
||||||
|
std::shared_ptr<int> p(std::move(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TEST_STD_VER > 14
|
||||||
|
{
|
||||||
|
StatefulArrayDeleter<A> d;
|
||||||
|
std::unique_ptr<A[], StatefulArrayDeleter<A>&> u(new A[4], d);
|
||||||
|
std::shared_ptr<A[]> p(std::move(u));
|
||||||
|
d.state = 42;
|
||||||
|
assert(A::count == 4);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<B[]> p(std::move(ptr));
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(B::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<A[]> ptr(new A[8]);
|
||||||
|
A* raw_ptr = ptr.get();
|
||||||
|
std::shared_ptr<A[]> p(std::move(ptr));
|
||||||
|
assert(A::count == 8);
|
||||||
|
assert(p.use_count() == 1);
|
||||||
|
assert(p.get() == raw_ptr);
|
||||||
|
assert(ptr.get() == 0);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[]> ptr(new int[8]);
|
||||||
|
std::shared_ptr<int[]> p(std::move(ptr));
|
||||||
|
}
|
||||||
|
#endif // TEST_STD_VER >= 14
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue