1#ifndef NEFORCE_CORE_MEMORY_WEAK_PTR_HPP__
2#define NEFORCE_CORE_MEMORY_WEAK_PTR_HPP__
18NEFORCE_BEGIN_NAMESPACE__
50 inner::__smart_ptr_counter* owner_ =
nullptr;
53 friend class weak_ptr;
56 friend class shared_ptr;
59 friend struct enable_shared_from_this;
62 friend class inner::smart_pointer_atomic;
75 weak_ptr(T* ptr, inner::__smart_ptr_counter* owner) noexcept :
78 if (owner_ !=
nullptr) {
79 owner_->incref_weak();
90 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
91 weak_ptr(
const shared_ptr<U>& shared) noexcept :
93 owner_(
reinterpret_cast<inner::__smart_ptr_counter*
>(shared.owner_)) {
95 owner_->incref_weak();
105 owner_(other.owner_) {
106 if (owner_ !=
nullptr) {
107 owner_->incref_weak();
116 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
119 owner_(other.owner_) {
120 if (owner_ !=
nullptr) {
121 owner_->incref_weak();
131 owner_(other.owner_) {
132 other.ptr_ =
nullptr;
133 other.owner_ =
nullptr;
141 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
144 owner_(other.owner_) {
145 other.ptr_ =
nullptr;
146 other.owner_ =
nullptr;
164 if (owner_ !=
nullptr) {
165 owner_->decref_weak();
168 owner_ = other.owner_;
169 if (owner_ !=
nullptr) {
170 owner_->incref_weak();
181 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
182 weak_ptr&
operator=(
const weak_ptr<U>& other)
noexcept {
184 owner_->decref_weak();
187 owner_ = other.owner_;
189 owner_->incref_weak();
200 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
201 weak_ptr&
operator=(
const shared_ptr<U>& shared)
noexcept {
203 owner_->decref_weak();
206 owner_ =
reinterpret_cast<inner::__smart_ptr_counter*
>(shared.owner_);
208 owner_->incref_weak();
222 if (owner_ !=
nullptr) {
223 owner_->decref_weak();
226 owner_ = other.owner_;
227 other.ptr_ =
nullptr;
228 other.owner_ =
nullptr;
238 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
241 owner_->decref_weak();
244 owner_ = other.owner_;
245 other.ptr_ =
nullptr;
246 other.owner_ =
nullptr;
256 if (owner_ !=
nullptr) {
257 owner_->decref_weak();
267 void swap(weak_ptr& other)
noexcept {
271 _NEFORCE
swap(ptr_, other.ptr_);
272 _NEFORCE
swap(owner_, other.owner_);
280 return owner_ !=
nullptr ?
static_cast<long>(owner_->use_count()) : 0;
295 NEFORCE_NODISCARD shared_ptr<T>
lock() const noexcept {
296 if (owner_ !=
nullptr && owner_->try_incref_strong()) {
297 return shared_ptr<T>(ptr_, owner_);
299 return shared_ptr<T>();
308 template <
typename U>
309 NEFORCE_NODISCARD
bool owner_equal(
const weak_ptr<U>& rhs)
const noexcept {
310 return owner_ == rhs.owner_;
319 template <
typename U>
320 NEFORCE_NODISCARD
bool owner_equal(
const shared_ptr<U>& rhs)
const noexcept {
321 return owner_ ==
reinterpret_cast<inner::__smart_ptr_counter*
>(rhs.owner_);
330 template <
typename U>
331 NEFORCE_NODISCARD
bool owner_before(
const weak_ptr<U>& rhs)
const noexcept {
332 return owner_ < rhs.owner_;
341 template <
typename U>
342 NEFORCE_NODISCARD
bool owner_before(
const shared_ptr<U>& rhs)
const noexcept {
343 return owner_ < reinterpret_cast<inner::__smart_ptr_counter*>(rhs.owner_);
350 if (owner_ ==
nullptr) {
351 return weak_ptr<T>();
353 return weak_ptr<T>(
static_cast<T*
>(
this), owner_);
359 if (owner_ ==
nullptr) {
360 return weak_ptr<const T>();
362 return weak_ptr<const T>(
static_cast<const T*
>(
this), owner_);
388 return lhs.owner_before(rhs);
395 return lhs.owner_before(rhs);
402 return lhs.owner_before(rhs);
418 return lhs.owner_before(rhs);
425 return lhs.owner_before(rhs);
432 return lhs.owner_before(rhs);
448 template <
typename T,
typename U>
450 return lhs.owner_before(rhs);
456 template <
typename T,
typename U>
458 return lhs.owner_before(rhs);
464 template <
typename T,
typename U>
466 return lhs.owner_before(rhs);
472 template <
typename T,
typename U>
474 return lhs.owner_before(rhs);
497 static constexpr bool is_always_lock_free =
false;
500 inner::smart_pointer_atomic<value_type> atomic_;
509 constexpr atomic() noexcept = default;
515 atomic(value_type value) noexcept :
516 atomic_(
move(value)) {}
519 void operator=(
const atomic&) =
delete;
552 atomic_.swap(desired, mo);
560 return atomic_.compare_exchange_strong(expected, desired, mo, mo2);
604NEFORCE_END_NAMESPACE__
bool owner_before(const weak_ptr< U > &rhs) const noexcept
比较所有权顺序
weak_ptr(T *ptr, inner::__smart_ptr_counter *owner) noexcept
从原始指针和控制块构造弱指针(供 enable_shared_from_this 内部使用)
bool expired() const noexcept
检查观察的对象是否已被销毁
weak_ptr(weak_ptr &&other) noexcept
移动构造函数
weak_ptr & operator=(weak_ptr< U > &&other) noexcept
类型转换移动赋值运算符
weak_ptr(const weak_ptr &other) noexcept
拷贝构造函数
weak_ptr(weak_ptr< U > &&other) noexcept
类型转换移动构造函数
weak_ptr & operator=(const weak_ptr &other) noexcept
拷贝赋值运算符
bool owner_equal(const shared_ptr< U > &rhs) const noexcept
与共享指针检查所有权是否相等
weak_ptr(const shared_ptr< U > &shared) noexcept
共享智能指针构造函数
weak_ptr & operator=(weak_ptr &&other) noexcept
移动赋值运算符
shared_ptr< T > lock() const noexcept
尝试获取共享智能指针
weak_ptr & operator=(const shared_ptr< U > &shared) noexcept
共享智能指针赋值运算符
weak_ptr(nullptr_t=nullptr) noexcept
默认构造函数
bool owner_equal(const weak_ptr< U > &rhs) const noexcept
检查所有权是否相等
void swap(weak_ptr &other) noexcept
交换两个弱指针
bool owner_before(const shared_ptr< U > &rhs) const noexcept
与共享指针比较所有权顺序
weak_ptr & operator=(const weak_ptr< U > &other) noexcept
类型转换拷贝赋值运算符
long use_count() const noexcept
获取观察对象的引用计数
void reset() noexcept
重置弱指针
weak_ptr(const weak_ptr< U > &other) noexcept
类型转换拷贝构造函数
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr bool is_base_of_v
is_base_of的便捷变量模板
decltype(nullptr) nullptr_t
空指针类型
constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
weak_ptr< T > weak_from_this() noexcept
获取指向 this 的弱指针
value_type exchange(value_type desired, memory_order mo=memory_order_seq_cst) noexcept
交换操作
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order mo=memory_order_seq_cst) noexcept
简化比较交换弱版本
void store(value_type desired, memory_order mo=memory_order_seq_cst) noexcept
原子存储
bool is_lock_free() const noexcept
检查是否无锁
void wait(value_type mold, memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order mo=memory_order_seq_cst) noexcept
简化比较交换强版本
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order mo, memory_order mo2) noexcept
比较交换强版本
void notify_one() noexcept
通知一个等待者
void notify_all() noexcept
通知所有等待者
value_type load(memory_order mo=memory_order_seq_cst) const noexcept
原子加载
void operator=(value_type desired) noexcept
赋值操作符
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order mo, memory_order mo2) noexcept
比较交换弱版本
void is_transparent
支持透明比较
bool operator()(const shared_ptr< T > &lhs, const weak_ptr< T > &rhs) const noexcept
比较共享指针和弱指针的所有权
bool operator()(const shared_ptr< T > &lhs, const shared_ptr< T > &rhs) const noexcept
比较两个共享指针的所有权
bool operator()(const weak_ptr< T > &lhs, const shared_ptr< T > &rhs) const noexcept
比较弱指针和共享指针的所有权
bool operator()(const shared_ptr< T > &lhs, const weak_ptr< U > &rhs) const noexcept
比较共享指针和弱指针的所有权
bool operator()(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) const noexcept
比较两个共享指针的所有权
bool operator()(const weak_ptr< T > &lhs, const weak_ptr< U > &rhs) const noexcept
比较两个弱指针的所有权
void is_transparent
支持透明比较
bool operator()(const weak_ptr< T > &lhs, const shared_ptr< U > &rhs) const noexcept
比较弱指针和共享指针的所有权
bool operator()(const weak_ptr< T > &lhs, const weak_ptr< T > &rhs) const noexcept
比较两个弱指针的所有权
bool operator()(const shared_ptr< T > &lhs, const weak_ptr< T > &rhs) const noexcept
比较共享指针和弱指针的所有权
bool operator()(const weak_ptr< T > &lhs, const shared_ptr< T > &rhs) const noexcept
比较弱指针和共享指针的所有权
void is_transparent
支持透明比较