NIM 跨平台 C++ SDK
载入中...
搜索中...
未找到
ne_stl_smart_ptr.h
浏览该文件的文档.
1#ifndef NE_STL_INCLUDENE_STL_SHARED_PTR_H
2#define NE_STL_INCLUDENE_STL_SHARED_PTR_H
3
4#include "ne_stl_build.h"
5#include "ne_stl_memory.h"
6
7namespace nstd {
8
9namespace {
10
11typedef struct _cblock {
12 _cblock() {}
13 ~_cblock() {}
16
17} cblock;
18void cblock_release(cblock*& ptr) {
20}
21template <class TObj>
22void object_release(TObj*& ptr) {
24}
25} // namespace
26
27template <class T>
28class _weak_ptr;
29
30template <class T>
32 template <class TObj>
33 friend class _weak_ptr;
34 template <class TObj>
35 friend class _shared_ptr;
36
37public:
38 using element_type = std::remove_extent_t<T>;
40 : data_(nullptr)
41 , release_(object_release<T>)
42 , release_block_(cblock_release) {}
43
44 explicit _shared_ptr(T* data)
45 : data_(data)
46 , release_(object_release<T>)
47 , release_block_(cblock_release) {
48 if (data_) {
49 cblock_ = memory::new_obj<cblock>();
50 }
51 }
52 _shared_ptr(std::nullptr_t)
53 : data_(nullptr)
54 , release_(object_release<T>)
55 , release_block_(cblock_release) {}
57 cblock* temp_cblock = sp.cblock_;
58 if (temp_cblock) {
59 int current_count = temp_cblock->shared_count.load();
60 while (current_count > 0) {
61 if (temp_cblock->shared_count.compare_exchange(current_count, current_count + 1)) {
62 data_ = sp.data_;
63 cblock_ = temp_cblock;
64 release_ = sp.release_;
66 return;
67 }
68 current_count = temp_cblock->shared_count.load();
69 }
70 }
71 data_ = nullptr;
72 cblock_ = nullptr;
73 release_ = object_release<T>;
74 release_block_ = cblock_release;
75 }
76 template <class D>
78 cblock* temp_cblock = sp.cblock_;
79 if (temp_cblock) {
80 int current_count = temp_cblock->shared_count.load();
81 while (current_count > 0) {
82 if (temp_cblock->shared_count.compare_exchange(current_count, current_count + 1)) {
83 data_ = dynamic_cast<T*>(sp.data_);
84 cblock_ = temp_cblock;
85 release_ = reinterpret_cast<void (*)(T*&)>(sp.release_);
87 return;
88 }
89 current_count = temp_cblock->shared_count.load();
90 }
91 }
92 data_ = nullptr;
93 cblock_ = nullptr;
94 release_ = object_release<T>;
95 release_block_ = cblock_release;
96 }
98 : data_(wp.data_)
99 , cblock_(wp.cblock_)
100 , release_(wp.release_)
101 , release_block_(cblock_release) {
102 if (cblock_) {
103 cblock_->shared_count.operator++();
104 }
105 }
108 if (this == &sp)
109 return *this;
111 data_ = sp.data_;
112 cblock_ = sp.cblock_;
113 release_ = sp.release_;
115 if (cblock_) {
116 cblock_->shared_count.operator++();
117 }
118 return *this;
119 }
120 _shared_ptr& operator=(std::nullptr_t) {
121 reset();
122 return *this;
123 }
124 inline operator bool() const { return data_ != nullptr; }
125 inline bool operator==(std::nullptr_t) const { return !this->operator bool(); }
126 inline bool operator!=(std::nullptr_t) const { return this->operator bool(); }
127
128 inline long use_count() const { return cblock_ ? cblock_->shared_count.load() : 0; }
129
130 T* get() const { return data_; }
131
132 T* operator->() const { return data_; }
133
134 T& operator*() const {
135 assert(*this);
136 return *data_;
137 }
138
139 void reset() {
141 data_ = nullptr;
142 cblock_ = nullptr;
143 }
144
145 void reset(T* data) {
147 data_ = data;
148 cblock_ = memory::new_obj<cblock>();
149 }
150
151private:
152 inline void dec_shared_count() {
153 if (!cblock_) {
154 return;
155 }
156 int new_count = cblock_->shared_count.operator--();
157 if (new_count == 0) {
158 if (release_ != nullptr)
160 int weak_count_val = cblock_->weak_count.load();
161 if (weak_count_val <= 0 && release_block_ != nullptr) {
163 }
164 }
165 }
166
167private:
168 T* data_{nullptr};
169 nstd::cblock* cblock_{nullptr};
170 void (*release_)(T*& pdata){nullptr};
171 void (*release_block_)(nstd::cblock*& pdata){nullptr};
172};
173template <class T>
175public:
177 : data_(nullptr)
178 , cblock_(nullptr)
179 , release_(nullptr)
180 , release_block_(nullptr) {}
182 : data_(wp.data_)
183 , cblock_(wp.cblock_)
184 , release_(wp.release_)
186 if (cblock_) {
187 cblock_->weak_count.operator++();
188 }
189 }
191 : data_(sp.data_)
192 , cblock_(sp.cblock_)
193 , release_(sp.release_)
195 if (cblock_) {
196 cblock_->weak_count.operator++();
197 }
198 }
201 _weak_ptr tmp(wp);
202 swap(tmp);
203 return *this;
204 }
205 inline _shared_ptr<T> lock() const { return expired() ? _shared_ptr<T>(nullptr) : _shared_ptr<T>(*this); }
206 inline bool expired() const { return cblock_ == nullptr || cblock_->shared_count <= 0; }
207 inline void reset() {
209 data_ = nullptr;
210 cblock_ = nullptr;
211 release_block_ = nullptr;
212 }
213
214private:
215 inline void dec_weak_count() {
216 if (cblock_ == nullptr) {
217 return;
218 }
219 int new_weak_count = cblock_->weak_count.operator--();
220 int shared_count_val = cblock_->shared_count.load();
221 if (shared_count_val <= 0 && new_weak_count == 0 && release_block_ != nullptr) {
223 cblock_ = nullptr;
224 }
225 }
226
227private:
229 nstd::cblock* cblock_;
230 void (*release_)(T*& pdata);
231 void (*release_block_)(nstd::cblock*& pdata);
232 template <class Y>
233 friend class _shared_ptr;
234};
235template <class T>
237template <class T, class... TArgs>
239 return nstd::shared_ptr<T>(memory::new_obj<T>(args...));
240}
241template <class T1, class T2>
243 // dynamic_cast for shared_ptr that properly respects the reference count control block
244 const auto ptr = dynamic_cast<typename shared_ptr<T1>::element_type*>(other.get());
245 if (ptr) {
246 return shared_ptr<T1>(other);
247 }
248 return (shared_ptr<T1>());
249}
250template <class T>
252} // namespace nstd
253
254#endif // !NE_STL_INCLUDENE_STL_SHARED_PTR_H
Definition: ne_stl_smart_ptr.h:31
_shared_ptr(const _weak_ptr< T > &wp)
Definition: ne_stl_smart_ptr.h:97
_shared_ptr & operator=(const _shared_ptr &sp)
Definition: ne_stl_smart_ptr.h:107
_shared_ptr(std::nullptr_t)
Definition: ne_stl_smart_ptr.h:52
void dec_shared_count()
Definition: ne_stl_smart_ptr.h:152
nstd::cblock * cblock_
Definition: ne_stl_smart_ptr.h:169
void(* release_)(T *&pdata)
Definition: ne_stl_smart_ptr.h:170
void reset(T *data)
Definition: ne_stl_smart_ptr.h:145
T * get() const
Definition: ne_stl_smart_ptr.h:130
void reset()
Definition: ne_stl_smart_ptr.h:139
T * data_
Definition: ne_stl_smart_ptr.h:168
_shared_ptr(const _shared_ptr &sp)
Definition: ne_stl_smart_ptr.h:56
long use_count() const
Definition: ne_stl_smart_ptr.h:128
~_shared_ptr()
Definition: ne_stl_smart_ptr.h:106
_shared_ptr(const _shared_ptr< D > &sp)
Definition: ne_stl_smart_ptr.h:77
T & operator*() const
Definition: ne_stl_smart_ptr.h:134
bool operator!=(std::nullptr_t) const
Definition: ne_stl_smart_ptr.h:126
bool operator==(std::nullptr_t) const
Definition: ne_stl_smart_ptr.h:125
_shared_ptr(T *data)
Definition: ne_stl_smart_ptr.h:44
std::remove_extent_t< T > element_type
Definition: ne_stl_smart_ptr.h:38
void(* release_block_)(nstd::cblock *&pdata)
Definition: ne_stl_smart_ptr.h:171
T * operator->() const
Definition: ne_stl_smart_ptr.h:132
_shared_ptr()
Definition: ne_stl_smart_ptr.h:39
_shared_ptr & operator=(std::nullptr_t)
Definition: ne_stl_smart_ptr.h:120
Definition: ne_stl_smart_ptr.h:174
T * data_
Definition: ne_stl_smart_ptr.h:228
_weak_ptr(const _shared_ptr< T > &sp)
Definition: ne_stl_smart_ptr.h:190
nstd::cblock * cblock_
Definition: ne_stl_smart_ptr.h:229
~_weak_ptr()
Definition: ne_stl_smart_ptr.h:199
_weak_ptr(const _weak_ptr &wp)
Definition: ne_stl_smart_ptr.h:181
void(* release_block_)(nstd::cblock *&pdata)
Definition: ne_stl_smart_ptr.h:231
void reset()
Definition: ne_stl_smart_ptr.h:207
void dec_weak_count()
Definition: ne_stl_smart_ptr.h:215
_weak_ptr & operator=(const _weak_ptr &wp)
Definition: ne_stl_smart_ptr.h:200
bool expired() const
Definition: ne_stl_smart_ptr.h:206
_shared_ptr< T > lock() const
Definition: ne_stl_smart_ptr.h:205
void(* release_)(T *&pdata)
Definition: ne_stl_smart_ptr.h:230
_weak_ptr()
Definition: ne_stl_smart_ptr.h:176
Definition: ne_stl_any.h:10
nstd::shared_ptr< T > make_shared(TArgs &&... args)
Definition: ne_stl_smart_ptr.h:238
shared_ptr< T1 > dynamic_pointer_cast(const shared_ptr< T2 > &other) noexcept
Definition: ne_stl_smart_ptr.h:242
nstd::atomic_int shared_count
Definition: ne_stl_smart_ptr.h:15
nstd::atomic_int weak_count
Definition: ne_stl_smart_ptr.h:14
unsigned char bool
Definition: stdbool.h:27
static bool delete_obj(TObject *&object)
Definition: ne_stl_memory.h:47