16#include "pw_allocator/config.h"
19#if PW_ALLOCATOR_HAS_ATOMICS
24#include "pw_allocator/internal/control_block.h"
25#include "pw_allocator/internal/managed_ptr.h"
26#include "pw_allocator/shared_ptr.h"
37class WeakPtr final :
public ::pw::allocator::internal::WeakManagedPtr<T> {
39 using Base = ::pw::allocator::internal::WeakManagedPtr<T>;
40 using ControlBlock = ::pw::allocator::internal::ControlBlock;
43 using element_type =
typename Base::element_type;
59 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
69 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
80 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
98 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
105 template <
typename U,
106 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
113 template <
typename U,
114 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
128 template <
typename U,
129 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
132 static_cast<const allocator::internal::BaseManagedPtr&
>(*this));
139 void reset() noexcept;
143 std::swap(control_block_, other.control_block_);
149 return control_block_ ==
nullptr ? 0 : control_block_->num_shared();
162 template <typename PtrType>
164 return control_block_ < other.control_block();
172 ControlBlock* control_block()
const {
return control_block_; }
174 ControlBlock* control_block_ =
nullptr;
180template <
typename U,
typename>
182 Base::template CheckAssignable<U>();
183 control_block_ = other.control_block_;
184 if (control_block_ !=
nullptr) {
185 control_block_->IncrementWeak();
191template <
typename U,
typename>
193 Base::template CheckAssignable<U>();
194 control_block_ = other.control_block_;
195 if (control_block_ !=
nullptr) {
196 control_block_->IncrementWeak();
202template <
typename U,
typename>
204 Base::template CheckAssignable<U>();
205 control_block_ = other.control_block_;
206 other.control_block_ =
nullptr;
212 if (control_block_ ==
nullptr ||
213 control_block_->DecrementWeak() != ControlBlock::Action::kFree) {
216 Allocator* allocator = control_block_->allocator();
217 Base::Deallocate(allocator, control_block_);
218 control_block_ =
nullptr;
223 if (control_block_ ==
nullptr || !control_block_->IncrementShared()) {
226 void* data = control_block_->data();
227 auto* t = std::launder(
reinterpret_cast<element_type*
>(data));
Definition: allocator.h:36
Definition: shared_ptr.h:60
Definition: weak_ptr.h:37
WeakPtr(const SharedPtr< U > &other) noexcept
Definition: weak_ptr.h:70
WeakPtr(WeakPtr< U > &&other) noexcept
Definition: weak_ptr.h:81
WeakPtr(const WeakPtr< U > &other) noexcept
Definition: weak_ptr.h:60
WeakPtr(const WeakPtr &other) noexcept
Copy-constructs a WeakPtr<T> from a WeakPtr<T>.
Definition: weak_ptr.h:52
WeakPtr & operator=(const SharedPtr< U > &other) noexcept
int32_t use_count() const noexcept
Definition: weak_ptr.h:148
constexpr WeakPtr & operator=(const WeakPtr &other) noexcept
Copy-assigns a WeakPtr<T> from a WeakPtr<T>.
Definition: weak_ptr.h:88
constexpr WeakPtr() noexcept=default
Creates an empty (nullptr) instance.
WeakPtr & operator=(const WeakPtr< U > &other) noexcept
bool expired() const noexcept
Definition: weak_ptr.h:154
WeakPtr & operator=(WeakPtr< U > &&other) noexcept
void swap(WeakPtr &other) noexcept
Swaps the managed pointer and deallocator of this and another object.
Definition: weak_ptr.h:142
bool owner_before(const PtrType &other) const noexcept
Definition: weak_ptr.h:163
void reset() noexcept
Definition: weak_ptr.h:211
SharedPtr< T > Lock() const noexcept
Definition: weak_ptr.h:222
The Pigweed namespace.
Definition: alignment.h:27