hook_type _hook;
T* _ptr = nullptr;
weak_ptr(T* p) noexcept : _ptr(p) {}
+ void clear() noexcept {
+ _hook = {};
+ _ptr = nullptr;
+ }
+ void swap(weak_ptr&& o) noexcept {
+ _hook.swap_nodes(o._hook);
+ std::swap(_ptr, o._ptr);
+ }
public:
// Note: The default constructor's body is implemented as no-op
// rather than `noexcept = default` due to a bug with gcc 9.3.1
weak_ptr() noexcept {}
weak_ptr(std::nullptr_t) noexcept : weak_ptr() {}
weak_ptr(weak_ptr&& o) noexcept
- : _ptr(o._ptr)
{
- _hook.swap_nodes(o._hook);
- o._ptr = nullptr;
+ swap(std::move(o));
+ }
+ weak_ptr(const weak_ptr& o) noexcept {
+ if (o._ptr) {
+ swap(o._ptr->weak_from_this());
+ }
}
weak_ptr& operator=(weak_ptr&& o) noexcept {
if (this != &o) {
- this->~weak_ptr();
- new (this) weak_ptr(std::move(o));
+ clear();
+ swap(std::move(o));
+ }
+ return *this;
+ }
+ weak_ptr& operator=(const weak_ptr& o) noexcept {
+ if (this != &o) {
+ clear();
+ if (o._ptr) {
+ swap(o._ptr->weak_from_this());
+ }
}
return *this;
}