LeviLamina
Loading...
Searching...
No Matches
WeakPtr.h
1#pragma once
2
3#include "mc/_HeaderOutputPredefine.h"
4#include "mc/common/SharedCounter.h"
5
6template <typename T>
7class SharedPtr;
8
9template <typename T>
10class WeakPtr {
11public:
12 [[nodiscard]] WeakPtr() noexcept : counter(nullptr) {}
13 [[nodiscard]] WeakPtr(std::nullptr_t) noexcept : counter(nullptr) {}
14
15 [[nodiscard]] WeakPtr(WeakPtr const& other) {
16 counter = other.counter;
17 if (counter) {
18 counter->addWeakCount();
19 }
20 }
21
22 [[nodiscard]] WeakPtr(WeakPtr&& other) noexcept {
23 counter = other.counter;
24 other.counter = nullptr;
25 }
26
27 WeakPtr& operator=(WeakPtr const& other) {
28 if (this != &other) {
29 if (counter) {
30 counter->releaseWeak();
31 }
32 counter = other.counter;
33 if (counter) {
34 counter->addWeakCount();
35 }
36 }
37 return *this;
38 }
39
40 WeakPtr& operator=(WeakPtr&& other) noexcept {
41 if (this != &other) {
42 if (counter) {
43 counter->releaseWeak();
44 }
45 counter = other.counter;
46 other.counter = nullptr;
47 }
48 return *this;
49 }
50
51 template <class Y>
52 [[nodiscard]] explicit WeakPtr(SharedPtr<Y> const& other)
53 requires(std::convertible_to<Y*, T*>)
54 {
55 counter = (SharedCounter<T>*)other.counter;
56 if (counter) {
57 counter->addWeakCount();
58 }
59 }
60
61 template <class Y>
62 [[nodiscard]] explicit WeakPtr(WeakPtr<Y> const& other)
63 requires(std::convertible_to<Y*, T*>)
64 {
65 counter = (SharedCounter<T>*)other.counter;
66 if (counter) {
67 counter->addWeakCount();
68 }
69 }
70
71 template <class Y>
72 [[nodiscard]] explicit WeakPtr(WeakPtr<Y>&& other)
73 requires(std::convertible_to<Y*, T*>)
74 {
75 counter = (SharedCounter<T>*)other.counter;
76 other.counter = nullptr;
77 }
78
79 ~WeakPtr() {
80 if (counter) {
81 counter->releaseWeak();
82 }
83 }
84
85 template <class Y>
86 WeakPtr<T>& operator=(SharedPtr<Y> const& other)
87 requires(std::convertible_to<Y*, T*>)
88 {
89 if (counter != (SharedCounter<T>*)other.counter) {
90 counter = (SharedCounter<T>*)other.counter;
91 if (counter) {
92 counter->addWeakCount();
93 }
94 }
95 return *this;
96 }
97
98 template <class Y>
99 WeakPtr<T>& operator=(WeakPtr<Y> const& other)
100 requires(std::convertible_to<Y*, T*>)
101 {
102 if (counter != (SharedCounter<T>*)other.counter) {
103 counter = (SharedCounter<T>*)other.counter;
104 if (counter) {
105 counter->addWeakCount();
106 }
107 }
108 return *this;
109 }
110
111 template <class Y>
112 WeakPtr<T>& operator=(WeakPtr<Y>&& other)
113 requires(std::convertible_to<Y*, T*>)
114 {
115 if (counter != (SharedCounter<T>*)other.counter) {
116 counter = (SharedCounter<T>*)other.counter;
117 other.counter = nullptr;
118 }
119 return *this;
120 }
121
122 [[nodiscard]] int use_count() const { return counter ? counter->getShareCount() : 0; }
123
124 [[nodiscard]] bool expired() const { return use_count() == 0; }
125
126 [[nodiscard]] SharedPtr<T> lock() const { return expired() ? SharedPtr<T>() : SharedPtr<T>(*this); }
127
128 [[nodiscard]] T* get() const { return counter ? counter->get() : nullptr; }
129
130 [[nodiscard]] T* operator->() const { return get(); }
131
132 [[nodiscard]] T& operator*() const { return *get(); }
133
134 [[nodiscard]] explicit operator bool() const { return get() != nullptr; }
135
136 SharedCounter<T>* counter;
137};
Definition SharedCounter.h:6
Definition SharedPtr.h:10