Commit f871d7f9 by Jonathan Wakely Committed by Jonathan Wakely

LWG DR 2315. weak_ptr should be movable

	* include/bits/shared_ptr.h (weak_ptr): Add move constructor and
	assignment.
	* include/bits/shared_ptr_base.h (__weak_count, __weak_ptr): Likewise.
	Use nullptr and injected class name.
	* testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust dg-error.
	* testsuite/20_util/shared_ptr/cons/void_neg.cc: Adjust dg-error.

From-SVN: r217413
parent 098c88fb
2014-11-12 Jonathan Wakely <jwakely@redhat.com> 2014-11-12 Jonathan Wakely <jwakely@redhat.com>
* include/bits/shared_ptr.h (weak_ptr): Add move constructor and
assignment.
* include/bits/shared_ptr_base.h (__weak_count, __weak_ptr): Likewise.
Use nullptr and injected class name.
* testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust dg-error.
* testsuite/20_util/shared_ptr/cons/void_neg.cc: Adjust dg-error.
2014-11-12 Jonathan Wakely <jwakely@redhat.com>
PR c++/33911 PR c++/33911
* testsuite/20_util/shared_ptr/assign/auto_ptr.cc: Use -Wno-deprecated. * testsuite/20_util/shared_ptr/assign/auto_ptr.cc: Use -Wno-deprecated.
* testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc: Likewise. * testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc: Likewise.
......
...@@ -465,19 +465,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -465,19 +465,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class weak_ptr : public __weak_ptr<_Tp> class weak_ptr : public __weak_ptr<_Tp>
{ {
public: public:
constexpr weak_ptr() noexcept constexpr weak_ptr() noexcept = default;
: __weak_ptr<_Tp>() { }
template<typename _Tp1, typename = typename template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
weak_ptr(const weak_ptr<_Tp1>& __r) noexcept weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
: __weak_ptr<_Tp>(__r) { } : __weak_ptr<_Tp>(__r) { }
weak_ptr(const weak_ptr&) noexcept = default;
template<typename _Tp1, typename = typename template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
weak_ptr(const shared_ptr<_Tp1>& __r) noexcept weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
: __weak_ptr<_Tp>(__r) { } : __weak_ptr<_Tp>(__r) { }
weak_ptr(weak_ptr&&) noexcept = default;
template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
: __weak_ptr<_Tp>(std::move(__r)) { }
weak_ptr&
operator=(const weak_ptr& __r) noexcept = default;
template<typename _Tp1> template<typename _Tp1>
weak_ptr& weak_ptr&
operator=(const weak_ptr<_Tp1>& __r) noexcept operator=(const weak_ptr<_Tp1>& __r) noexcept
...@@ -494,6 +505,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -494,6 +505,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this; return *this;
} }
weak_ptr&
operator=(weak_ptr&& __r) noexcept = default;
template<typename _Tp1>
weak_ptr&
operator=(weak_ptr<_Tp1>&& __r) noexcept
{
this->__weak_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
shared_ptr<_Tp> shared_ptr<_Tp>
lock() const noexcept lock() const noexcept
{ return shared_ptr<_Tp>(*this, std::nothrow); } { return shared_ptr<_Tp>(*this, std::nothrow); }
......
...@@ -721,55 +721,69 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -721,55 +721,69 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class __weak_count class __weak_count
{ {
public: public:
constexpr __weak_count() noexcept : _M_pi(0) constexpr __weak_count() noexcept : _M_pi(nullptr)
{ } { }
__weak_count(const __shared_count<_Lp>& __r) noexcept __weak_count(const __shared_count<_Lp>& __r) noexcept
: _M_pi(__r._M_pi) : _M_pi(__r._M_pi)
{ {
if (_M_pi != 0) if (_M_pi != nullptr)
_M_pi->_M_weak_add_ref(); _M_pi->_M_weak_add_ref();
} }
__weak_count(const __weak_count<_Lp>& __r) noexcept __weak_count(const __weak_count& __r) noexcept
: _M_pi(__r._M_pi) : _M_pi(__r._M_pi)
{ {
if (_M_pi != 0) if (_M_pi != nullptr)
_M_pi->_M_weak_add_ref(); _M_pi->_M_weak_add_ref();
} }
__weak_count(__weak_count&& __r) noexcept
: _M_pi(__r._M_pi)
{ __r._M_pi = nullptr; }
~__weak_count() noexcept ~__weak_count() noexcept
{ {
if (_M_pi != 0) if (_M_pi != nullptr)
_M_pi->_M_weak_release(); _M_pi->_M_weak_release();
} }
__weak_count<_Lp>& __weak_count&
operator=(const __shared_count<_Lp>& __r) noexcept operator=(const __shared_count<_Lp>& __r) noexcept
{ {
_Sp_counted_base<_Lp>* __tmp = __r._M_pi; _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != 0) if (__tmp != nullptr)
__tmp->_M_weak_add_ref(); __tmp->_M_weak_add_ref();
if (_M_pi != 0) if (_M_pi != nullptr)
_M_pi->_M_weak_release(); _M_pi->_M_weak_release();
_M_pi = __tmp; _M_pi = __tmp;
return *this; return *this;
} }
__weak_count<_Lp>& __weak_count&
operator=(const __weak_count<_Lp>& __r) noexcept operator=(const __weak_count& __r) noexcept
{ {
_Sp_counted_base<_Lp>* __tmp = __r._M_pi; _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != 0) if (__tmp != nullptr)
__tmp->_M_weak_add_ref(); __tmp->_M_weak_add_ref();
if (_M_pi != 0) if (_M_pi != nullptr)
_M_pi->_M_weak_release(); _M_pi->_M_weak_release();
_M_pi = __tmp; _M_pi = __tmp;
return *this; return *this;
} }
__weak_count&
operator=(__weak_count&& __r) noexcept
{
if (_M_pi != nullptr)
_M_pi->_M_weak_release();
_M_pi = __r._M_pi;
__r._M_pi = nullptr;
return *this;
}
void void
_M_swap(__weak_count<_Lp>& __r) noexcept _M_swap(__weak_count& __r) noexcept
{ {
_Sp_counted_base<_Lp>* __tmp = __r._M_pi; _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
__r._M_pi = _M_pi; __r._M_pi = _M_pi;
...@@ -778,7 +792,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -778,7 +792,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
long long
_M_get_use_count() const noexcept _M_get_use_count() const noexcept
{ return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
bool bool
_M_less(const __weak_count& __rhs) const noexcept _M_less(const __weak_count& __rhs) const noexcept
...@@ -1321,11 +1335,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1321,11 +1335,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef _Tp element_type; typedef _Tp element_type;
constexpr __weak_ptr() noexcept constexpr __weak_ptr() noexcept
: _M_ptr(0), _M_refcount() : _M_ptr(nullptr), _M_refcount()
{ } { }
__weak_ptr(const __weak_ptr&) noexcept = default; __weak_ptr(const __weak_ptr&) noexcept = default;
__weak_ptr& operator=(const __weak_ptr&) noexcept = default;
~__weak_ptr() = default; ~__weak_ptr() = default;
// The "obvious" converting constructor implementation: // The "obvious" converting constructor implementation:
...@@ -1354,6 +1368,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1354,6 +1368,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
{ } { }
__weak_ptr(__weak_ptr&& __r) noexcept
: _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
{ __r._M_ptr = nullptr; }
template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
__weak_ptr(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
: _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
{ __r._M_ptr = nullptr; }
__weak_ptr&
operator=(const __weak_ptr& __r) noexcept = default;
template<typename _Tp1> template<typename _Tp1>
__weak_ptr& __weak_ptr&
operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
...@@ -1372,6 +1399,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1372,6 +1399,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this; return *this;
} }
__weak_ptr&
operator=(__weak_ptr&& __r) noexcept
{
_M_ptr = __r._M_ptr;
_M_refcount = std::move(__r._M_refcount);
__r._M_ptr = nullptr;
return *this;
}
template<typename _Tp1>
__weak_ptr&
operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
{
_M_ptr = __r.lock().get();
_M_refcount = std::move(__r._M_refcount);
__r._M_ptr = nullptr;
return *this;
}
__shared_ptr<_Tp, _Lp> __shared_ptr<_Tp, _Lp>
lock() const noexcept lock() const noexcept
{ return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
......
...@@ -32,7 +32,7 @@ void test01() ...@@ -32,7 +32,7 @@ void test01()
{ {
X* px = 0; X* px = 0;
std::shared_ptr<X> p1(px); // { dg-error "here" } std::shared_ptr<X> p1(px); // { dg-error "here" }
// { dg-error "incomplete" "" { target *-*-* } 864 } // { dg-error "incomplete" "" { target *-*-* } 878 }
std::shared_ptr<X> p9(ap()); // { dg-error "here" } std::shared_ptr<X> p9(ap()); // { dg-error "here" }
// { dg-error "incomplete" "" { target *-*-* } 307 } // { dg-error "incomplete" "" { target *-*-* } 307 }
......
...@@ -25,5 +25,5 @@ ...@@ -25,5 +25,5 @@
void test01() void test01()
{ {
std::shared_ptr<void> p((void*)nullptr); // { dg-error "here" } std::shared_ptr<void> p((void*)nullptr); // { dg-error "here" }
// { dg-error "incomplete" "" { target *-*-* } 863 } // { dg-error "incomplete" "" { target *-*-* } 877 }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment