NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
weak_ptr.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_MEMORY_WEAK_PTR_HPP__
2#define NEFORCE_CORE_MEMORY_WEAK_PTR_HPP__
3
16
18NEFORCE_BEGIN_NAMESPACE__
19
25
43template <typename T>
44class weak_ptr {
45public:
46 using element_type = T;
47
48private:
49 element_type* ptr_ = nullptr;
50 inner::__smart_ptr_counter* owner_ = nullptr;
51
52 template <typename U>
53 friend class weak_ptr;
54
55 template <typename U>
56 friend class shared_ptr;
57
58 template <typename U>
59 friend struct enable_shared_from_this;
60
61 template <typename U>
62 friend class inner::smart_pointer_atomic;
63
64public:
68 weak_ptr(nullptr_t = nullptr) noexcept {}
69
75 weak_ptr(T* ptr, inner::__smart_ptr_counter* owner) noexcept :
76 ptr_(ptr),
77 owner_(owner) {
78 if (owner_ != nullptr) {
79 owner_->incref_weak();
80 }
81 }
82
90 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
91 weak_ptr(const shared_ptr<U>& shared) noexcept :
92 ptr_(shared.get()),
93 owner_(reinterpret_cast<inner::__smart_ptr_counter*>(shared.owner_)) {
94 if (owner_) {
95 owner_->incref_weak();
96 }
97 }
98
103 weak_ptr(const weak_ptr& other) noexcept :
104 ptr_(other.ptr_),
105 owner_(other.owner_) {
106 if (owner_ != nullptr) {
107 owner_->incref_weak();
108 }
109 }
110
116 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
117 weak_ptr(const weak_ptr<U>& other) noexcept :
118 ptr_(other.ptr_),
119 owner_(other.owner_) {
120 if (owner_ != nullptr) {
121 owner_->incref_weak();
122 }
123 }
124
129 weak_ptr(weak_ptr&& other) noexcept :
130 ptr_(other.ptr_),
131 owner_(other.owner_) {
132 other.ptr_ = nullptr;
133 other.owner_ = nullptr;
134 }
135
141 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
142 weak_ptr(weak_ptr<U>&& other) noexcept :
143 ptr_(other.ptr_),
144 owner_(other.owner_) {
145 other.ptr_ = nullptr;
146 other.owner_ = nullptr;
147 }
148
154
160 weak_ptr& operator=(const weak_ptr& other) noexcept {
161 if (_NEFORCE addressof(other) == this) {
162 return *this;
163 }
164 if (owner_ != nullptr) {
165 owner_->decref_weak();
166 }
167 ptr_ = other.ptr_;
168 owner_ = other.owner_;
169 if (owner_ != nullptr) {
170 owner_->incref_weak();
171 }
172 return *this;
173 }
174
181 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
182 weak_ptr& operator=(const weak_ptr<U>& other) noexcept {
183 if (owner_) {
184 owner_->decref_weak();
185 }
186 ptr_ = other.ptr_;
187 owner_ = other.owner_;
188 if (owner_) {
189 owner_->incref_weak();
190 }
191 return *this;
192 }
193
200 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
201 weak_ptr& operator=(const shared_ptr<U>& shared) noexcept {
202 if (owner_) {
203 owner_->decref_weak();
204 }
205 ptr_ = shared.get();
206 owner_ = reinterpret_cast<inner::__smart_ptr_counter*>(shared.owner_);
207 if (owner_) {
208 owner_->incref_weak();
209 }
210 return *this;
211 }
212
218 weak_ptr& operator=(weak_ptr&& other) noexcept {
219 if (_NEFORCE addressof(other) == this) {
220 return *this;
221 }
222 if (owner_ != nullptr) {
223 owner_->decref_weak();
224 }
225 ptr_ = other.ptr_;
226 owner_ = other.owner_;
227 other.ptr_ = nullptr;
228 other.owner_ = nullptr;
229 return *this;
230 }
231
238 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
239 weak_ptr& operator=(weak_ptr<U>&& other) noexcept {
240 if (owner_) {
241 owner_->decref_weak();
242 }
243 ptr_ = other.ptr_;
244 owner_ = other.owner_;
245 other.ptr_ = nullptr;
246 other.owner_ = nullptr;
247 return *this;
248 }
249
255 void reset() noexcept {
256 if (owner_ != nullptr) {
257 owner_->decref_weak();
258 owner_ = nullptr;
259 }
260 ptr_ = nullptr;
261 }
262
267 void swap(weak_ptr& other) noexcept {
268 if (_NEFORCE addressof(other) == this) {
269 return;
270 }
271 _NEFORCE swap(ptr_, other.ptr_);
272 _NEFORCE swap(owner_, other.owner_);
273 }
274
279 NEFORCE_NODISCARD long use_count() const noexcept {
280 return owner_ != nullptr ? static_cast<long>(owner_->use_count()) : 0;
281 }
282
287 NEFORCE_NODISCARD bool expired() const noexcept { return use_count() == 0; }
288
295 NEFORCE_NODISCARD shared_ptr<T> lock() const noexcept {
296 if (owner_ != nullptr && owner_->try_incref_strong()) {
297 return shared_ptr<T>(ptr_, owner_);
298 }
299 return shared_ptr<T>();
300 }
301
308 template <typename U>
309 NEFORCE_NODISCARD bool owner_equal(const weak_ptr<U>& rhs) const noexcept {
310 return owner_ == rhs.owner_;
311 }
312
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_);
322 }
323
330 template <typename U>
331 NEFORCE_NODISCARD bool owner_before(const weak_ptr<U>& rhs) const noexcept {
332 return owner_ < rhs.owner_;
333 }
334
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_);
344 }
345};
346
347template <typename T>
349 static_assert(is_base_of_v<enable_shared_from_this, T>, "weak_from_this requires derived class");
350 if (owner_ == nullptr) {
351 return weak_ptr<T>();
352 }
353 return weak_ptr<T>(static_cast<T*>(this), owner_);
354}
355
356template <typename T>
357weak_ptr<const T> enable_shared_from_this<T>::weak_from_this() const noexcept {
358 static_assert(is_base_of_v<enable_shared_from_this, T>, "weak_from_this requires derived class");
359 if (owner_ == nullptr) {
360 return weak_ptr<const T>();
361 }
362 return weak_ptr<const T>(static_cast<const T*>(this), owner_);
363}
364
365
371template <typename T>
373
380template <typename T>
382 using is_transparent = void;
383
387 NEFORCE_NODISCARD bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const noexcept {
388 return lhs.owner_before(rhs);
389 }
390
394 NEFORCE_NODISCARD bool operator()(const shared_ptr<T>& lhs, const weak_ptr<T>& rhs) const noexcept {
395 return lhs.owner_before(rhs);
396 }
397
401 NEFORCE_NODISCARD bool operator()(const weak_ptr<T>& lhs, const shared_ptr<T>& rhs) const noexcept {
402 return lhs.owner_before(rhs);
403 }
404};
405
410template <typename T>
412 using is_transparent = void;
413
417 NEFORCE_NODISCARD bool operator()(const weak_ptr<T>& lhs, const weak_ptr<T>& rhs) const noexcept {
418 return lhs.owner_before(rhs);
419 }
420
424 NEFORCE_NODISCARD bool operator()(const weak_ptr<T>& lhs, const shared_ptr<T>& rhs) const noexcept {
425 return lhs.owner_before(rhs);
426 }
427
431 NEFORCE_NODISCARD bool operator()(const shared_ptr<T>& lhs, const weak_ptr<T>& rhs) const noexcept {
432 return lhs.owner_before(rhs);
433 }
434};
435
441template <>
442struct owner_less<void> {
443 using is_transparent = void;
444
448 template <typename T, typename U>
449 NEFORCE_NODISCARD bool operator()(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) const noexcept {
450 return lhs.owner_before(rhs);
451 }
452
456 template <typename T, typename U>
457 NEFORCE_NODISCARD bool operator()(const shared_ptr<T>& lhs, const weak_ptr<U>& rhs) const noexcept {
458 return lhs.owner_before(rhs);
459 }
460
464 template <typename T, typename U>
465 NEFORCE_NODISCARD bool operator()(const weak_ptr<T>& lhs, const shared_ptr<U>& rhs) const noexcept {
466 return lhs.owner_before(rhs);
467 }
468
472 template <typename T, typename U>
473 NEFORCE_NODISCARD bool operator()(const weak_ptr<T>& lhs, const weak_ptr<U>& rhs) const noexcept {
474 return lhs.owner_before(rhs);
475 }
476};
477 // WeakPointer
479
485
492template <typename T>
493struct atomic<weak_ptr<T>> {
494public:
495 using value_type = weak_ptr<T>;
496
497 static constexpr bool is_always_lock_free = false;
498
499private:
500 inner::smart_pointer_atomic<value_type> atomic_;
501
502public:
507 NEFORCE_NODISCARD bool is_lock_free() const noexcept { return false; }
508
509 constexpr atomic() noexcept = default;
510
515 atomic(value_type value) noexcept :
516 atomic_(move(value)) {}
517
518 atomic(const atomic&) = delete;
519 void operator=(const atomic&) = delete;
520
526 value_type load(memory_order mo = memory_order_seq_cst) const noexcept { return atomic_.load(mo); }
527
531 operator value_type() const noexcept { return atomic_.load(memory_order_seq_cst); }
532
538 void store(value_type desired, memory_order mo = memory_order_seq_cst) noexcept { atomic_.swap(desired, mo); }
539
543 void operator=(value_type desired) noexcept { atomic_.swap(desired, memory_order_seq_cst); }
544
551 value_type exchange(value_type desired, memory_order mo = memory_order_seq_cst) noexcept {
552 atomic_.swap(desired, mo);
553 return desired;
554 }
555
559 bool compare_exchange_strong(value_type& expected, value_type desired, memory_order mo, memory_order mo2) noexcept {
560 return atomic_.compare_exchange_strong(expected, desired, mo, mo2);
561 }
562
566 bool compare_exchange_strong(value_type& expected, value_type desired,
567 memory_order mo = memory_order_seq_cst) noexcept {
568 return compare_exchange_strong(expected, move(desired), mo, cmpexch_failure_order(mo));
569 }
570
574 bool compare_exchange_weak(value_type& expected, value_type desired, memory_order mo, memory_order mo2) noexcept {
575 return compare_exchange_strong(expected, move(desired), mo, mo2);
576 }
577
581 bool compare_exchange_weak(value_type& expected, value_type desired,
582 memory_order mo = memory_order_seq_cst) noexcept {
583 return compare_exchange_strong(expected, move(desired), mo);
584 }
585
589 void wait(value_type mold, memory_order mo = memory_order_seq_cst) const noexcept { atomic_.wait(move(mold), mo); }
590
594 void notify_one() noexcept { atomic_.notify_one(); }
595
599 void notify_all() noexcept { atomic_.notify_all(); }
600};
601 // AtomicOperations
603
604NEFORCE_END_NAMESPACE__
605#endif // NEFORCE_CORE_MEMORY_WEAK_PTR_HPP__
共享智能指针类模板
弱智能指针类模板
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
检查观察的对象是否已被销毁
T element_type
元素类型
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()
析构函数
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
获取原子比较交换操作失败时的内存顺序
memory_order
内存顺序
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
比较交换弱版本
通用原子类型模板
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
比较弱指针和共享指针的所有权
智能指针的所有权比较器