From f871d7f9f458d833fc2c388d2756a7a82cf2be40 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 12 Nov 2014 11:54:08 +0000 Subject: [PATCH] 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 --- libstdc++-v3/ChangeLog | 9 +++ libstdc++-v3/include/bits/shared_ptr.h | 30 ++++++- libstdc++-v3/include/bits/shared_ptr_base.h | 78 +++++++++++++++---- .../20_util/shared_ptr/cons/43820_neg.cc | 2 +- .../20_util/shared_ptr/cons/void_neg.cc | 2 +- 5 files changed, 99 insertions(+), 22 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2657b06d984..30a3ba6e5ae 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2014-11-12 Jonathan Wakely + + * 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 PR c++/33911 diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index f611e53c179..c2d56eb7170 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -465,19 +465,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class weak_ptr : public __weak_ptr<_Tp> { public: - constexpr weak_ptr() noexcept - : __weak_ptr<_Tp>() { } + constexpr weak_ptr() noexcept = default; template::value>::type> - weak_ptr(const weak_ptr<_Tp1>& __r) noexcept + weak_ptr(const shared_ptr<_Tp1>& __r) noexcept : __weak_ptr<_Tp>(__r) { } + weak_ptr(const weak_ptr&) noexcept = default; + template::value>::type> - weak_ptr(const shared_ptr<_Tp1>& __r) noexcept + weak_ptr(const weak_ptr<_Tp1>& __r) noexcept : __weak_ptr<_Tp>(__r) { } + weak_ptr(weak_ptr&&) noexcept = default; + + template::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 weak_ptr& operator=(const weak_ptr<_Tp1>& __r) noexcept @@ -494,6 +505,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + weak_ptr& + operator=(weak_ptr&& __r) noexcept = default; + + template + weak_ptr& + operator=(weak_ptr<_Tp1>&& __r) noexcept + { + this->__weak_ptr<_Tp>::operator=(std::move(__r)); + return *this; + } + shared_ptr<_Tp> lock() const noexcept { return shared_ptr<_Tp>(*this, std::nothrow); } diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 6f85ffad955..ea74000eb09 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -721,55 +721,69 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class __weak_count { public: - constexpr __weak_count() noexcept : _M_pi(0) + constexpr __weak_count() noexcept : _M_pi(nullptr) { } __weak_count(const __shared_count<_Lp>& __r) noexcept : _M_pi(__r._M_pi) { - if (_M_pi != 0) + if (_M_pi != nullptr) _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) { - if (_M_pi != 0) + if (_M_pi != nullptr) _M_pi->_M_weak_add_ref(); } + __weak_count(__weak_count&& __r) noexcept + : _M_pi(__r._M_pi) + { __r._M_pi = nullptr; } + ~__weak_count() noexcept { - if (_M_pi != 0) + if (_M_pi != nullptr) _M_pi->_M_weak_release(); } - __weak_count<_Lp>& + __weak_count& operator=(const __shared_count<_Lp>& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; - if (__tmp != 0) + if (__tmp != nullptr) __tmp->_M_weak_add_ref(); - if (_M_pi != 0) + if (_M_pi != nullptr) _M_pi->_M_weak_release(); _M_pi = __tmp; return *this; } - __weak_count<_Lp>& - operator=(const __weak_count<_Lp>& __r) noexcept + __weak_count& + operator=(const __weak_count& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; - if (__tmp != 0) + if (__tmp != nullptr) __tmp->_M_weak_add_ref(); - if (_M_pi != 0) + if (_M_pi != nullptr) _M_pi->_M_weak_release(); _M_pi = __tmp; 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 - _M_swap(__weak_count<_Lp>& __r) noexcept + _M_swap(__weak_count& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; __r._M_pi = _M_pi; @@ -778,7 +792,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION long _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 _M_less(const __weak_count& __rhs) const noexcept @@ -1321,11 +1335,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Tp element_type; constexpr __weak_ptr() noexcept - : _M_ptr(0), _M_refcount() + : _M_ptr(nullptr), _M_refcount() { } __weak_ptr(const __weak_ptr&) noexcept = default; - __weak_ptr& operator=(const __weak_ptr&) noexcept = default; + ~__weak_ptr() = default; // The "obvious" converting constructor implementation: @@ -1354,6 +1368,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _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::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 __weak_ptr& operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept @@ -1372,6 +1399,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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 + __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> lock() const noexcept { return __shared_ptr(*this, std::nothrow); } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc index 8bbb59133db..be33279510a 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc @@ -32,7 +32,7 @@ void test01() { X* px = 0; std::shared_ptr p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 864 } + // { dg-error "incomplete" "" { target *-*-* } 878 } std::shared_ptr p9(ap()); // { dg-error "here" } // { dg-error "incomplete" "" { target *-*-* } 307 } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc index 1ea114c7085..17e036f5f44 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc @@ -25,5 +25,5 @@ void test01() { std::shared_ptr p((void*)nullptr); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 863 } + // { dg-error "incomplete" "" { target *-*-* } 877 } } -- 2.30.2