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