@@ -47,6 +47,11 @@ class shared_ptr
4747
4848 shared_ptr_wrapper (std::shared_ptr<T> &&ptr) noexcept : ptr_{std::move (ptr)} {}
4949
50+ shared_ptr_wrapper (const shared_ptr_wrapper &) = default ;
51+ shared_ptr_wrapper &operator =(const shared_ptr_wrapper &) = default ;
52+ shared_ptr_wrapper (shared_ptr_wrapper &&) = default ;
53+ shared_ptr_wrapper &operator =(shared_ptr_wrapper &&) = default ;
54+
5055 virtual ~shared_ptr_wrapper () {}
5156
5257 virtual void CopyTo (PlacementBuffer &buffer) const noexcept
@@ -98,20 +103,20 @@ class shared_ptr
98103 typename std::enable_if<std::is_convertible<U *, pointer>::value>::type * = nullptr >
99104 shared_ptr (shared_ptr<U> &&other) noexcept
100105 {
101- other.wrapper ().template MoveTo <T>(buffer_);
106+ std::move ( other) .wrapper ().template MoveTo <T>(buffer_);
102107 }
103108
104109 shared_ptr (const shared_ptr &other) noexcept { other.wrapper ().CopyTo (buffer_); }
105110
106111 shared_ptr (unique_ptr<T> &&other) noexcept
107112 {
108- std::shared_ptr<T> ptr_ (other.release ());
113+ std::shared_ptr<T> ptr_ (std::move ( other) .release ());
109114 new (buffer_.data ) shared_ptr_wrapper{std::move (ptr_)};
110115 }
111116
112117 shared_ptr (std::unique_ptr<T> &&other) noexcept
113118 {
114- std::shared_ptr<T> ptr_ (other.release ());
119+ std::shared_ptr<T> ptr_ (std::move ( other) .release ());
115120 new (buffer_.data ) shared_ptr_wrapper{std::move (ptr_)};
116121 }
117122
@@ -155,10 +160,15 @@ class shared_ptr
155160
156161 void swap (shared_ptr<T> &other) noexcept
157162 {
158- shared_ptr<T> tmp{std::move (other)};
163+ if (this == &other)
164+ {
165+ return ;
166+ }
159167
160- wrapper ().MoveTo (other.buffer_ );
161- tmp.wrapper ().MoveTo (buffer_);
168+ // Swap the live wrapper objects (object-level swap), not the raw
169+ // PlacementBuffer bytes. This preserves object lifetime correctness and
170+ // avoids moving `other` as an object.
171+ std::swap (wrapper (), other.wrapper ());
162172 }
163173
164174 template <typename U>
0 commit comments