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 template <class Y>
23 [[nodiscard]] explicit SharedPtr(SharedPtr<Y> const& other)
24 requires(std::convertible_to<Y*, T*>)
25 {
26 counter = (SharedCounter<T>*)other.counter;
27 if (counter) {
28 counter->addShareCount();
29 }
30 }
31
32 template <class Y>
33 [[nodiscard]] explicit SharedPtr(SharedPtr<Y>&& other)
34 requires(std::convertible_to<Y*, T*>)
35 {
36 counter = (SharedCounter<T>*)other.counter;
37 other.counter = nullptr;
38 }
39
40 template <class Y>
41 [[nodiscard]] explicit SharedPtr(WeakPtr<Y> const& other)
42 requires(std::convertible_to<Y*, T*>)
43 {
44 counter = (SharedCounter<T>*)other.counter;
45 if (other) {
46 counter->addShareCount();
47 }
48 }
49
50 ~SharedPtr() {
51 if (counter) {
52 counter->release();
53 }
54 }
55
56 template <class Y>
57 SharedPtr<T>& operator=(SharedPtr<Y> const& other)
58 requires(std::convertible_to<Y*, T*>)
59 {
60 if (counter != (SharedCounter<T>*)other.counter) {
61 counter = (SharedCounter<T>*)other.counter;
62 if (counter) {
63 counter->addShareCount();
64 }
65 }
66 return *this;
67 }
68
69 template <class Y>
70 SharedPtr<T>& operator=(SharedPtr<Y>&& other)
71 requires(std::convertible_to<Y*, T*>)
72 {
73 if (counter != (SharedCounter<T>*)other.counter) {
74 counter = (SharedCounter<T>*)other.counter;
75 other.counter = nullptr;
76 }
77 return *this;
78 }
79
80 template <class Y>
81 SharedPtr<T>& operator=(WeakPtr<Y> const& other)
82 requires(std::convertible_to<Y*, T*>)
83 {
84 counter = (SharedCounter<T>*)other.counter;
85 if (other) {
86 counter->addShareCount();
87 }
88 return *this;
89 }
90
91 [[nodiscard]] T* get() const { return counter ? counter->get() : nullptr; }
92
93 [[nodiscard]] T* operator->() const { return get(); }
94
95 [[nodiscard]] T& operator*() const { return *get(); }
96
97 [[nodiscard]] explicit operator bool() const { return get() != nullptr; }
98
99 [[nodiscard]] int use_count() const { return counter ? counter->getShareCount() : 0; }
100
101 void reset() {
102 if (counter) {
103 counter->release();
104 counter = nullptr;
105 }
106 }
107
108 SharedCounter<T>* counter;
109};
Definition SharedCounter.h:6
Definition SharedPtr.h:10
Definition WeakPtr.h:10