FastLED 3.9.15
Loading...
Searching...
No Matches
ptr_impl.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/ptr.h"
4#include "fl/referent.h"
5
6namespace fl {
7
8// Ptr template method implementations
9
10template <typename T>
11template <typename... Args>
12inline Ptr<T> PtrTraits<T>::New(Args... args) {
13 T *ptr = new T(args...);
14 return Ptr<T>::TakeOwnership(ptr);
15}
16
17template <typename T>
19 T *ptr = new T();
20 return Ptr<T>::TakeOwnership(ptr);
21}
22
23template <typename T>
24template <typename... Args>
25inline Ptr<T> Ptr<T>::New(Args... args) {
26 return PtrTraits<T>::New(args...);
27}
28
29// Allow upcasting of Refs.
30template <typename T>
31template <typename U, typename>
32inline Ptr<T>::Ptr(const Ptr<U> &refptr) : referent_(refptr.get()) {
33 if (referent_ && isOwned()) {
34 referent_->ref();
35 }
36}
37
38template <typename T>
39inline Ptr<T>::Ptr(const Ptr &other) : referent_(other.referent_) {
40 if (referent_ && isOwned()) {
41 referent_->ref();
42 }
43}
44
45template <typename T>
46inline Ptr<T>::Ptr(Ptr &&other) noexcept : referent_(other.referent_) {
47 other.referent_ = nullptr;
48}
49
50template <typename T>
51inline Ptr<T>::~Ptr() {
52 if (referent_ && isOwned()) {
53 referent_->unref();
54 }
55}
56
57template <typename T>
58inline Ptr<T> &Ptr<T>::operator=(const Ptr &other) {
59 if (this != &other) {
60 if (referent_ && isOwned()) {
61 referent_->unref();
62 }
63 referent_ = other.referent_;
64 if (referent_ && isOwned()) {
65 referent_->ref();
66 }
67 }
68 return *this;
69}
70
71template <typename T>
72inline Ptr<T> &Ptr<T>::operator=(Ptr &&other) noexcept {
73 if (this != &other) {
74 if (referent_ && isOwned()) {
75 referent_->unref();
76 }
77 referent_ = other.referent_;
78 other.referent_ = nullptr;
79 }
80 return *this;
81}
82
83template <typename T>
84inline void Ptr<T>::reset() {
85 if (referent_ && isOwned()) {
86 referent_->unref();
87 }
88 referent_ = nullptr;
89}
90
91template <typename T>
92inline void Ptr<T>::reset(Ptr<T> &refptr) {
93 if (refptr.referent_ != referent_) {
94 if (refptr.referent_ && refptr.isOwned()) {
95 refptr.referent_->ref();
96 }
97 if (referent_ && isOwned()) {
98 referent_->unref();
99 }
100 referent_ = refptr.referent_;
101 }
102}
103
104template <typename T>
105inline T* Ptr<T>::release() {
106 T *temp = referent_;
107 referent_ = nullptr;
108 return temp;
109}
110
111template <typename T>
112inline void Ptr<T>::swap(Ptr &other) noexcept {
113 T *temp = referent_;
114 referent_ = other.referent_;
115 other.referent_ = temp;
116}
117
118template <typename T>
119inline Ptr<T>::Ptr(T *referent, bool from_heap) : referent_(referent) {
120 if (referent_ && from_heap) {
121 referent_->ref();
122 }
123}
124
125// WeakPtr template method implementations
126
127template <typename T>
128inline WeakPtr<T>::WeakPtr(const Ptr<T> &ptr) : mWeakPtr(nullptr) {
129 if (ptr) {
130 mWeakPtr = ptr->getWeakPtr();
131 if (!mWeakPtr) {
132 // No weak reference exists yet, create one
133 WeakReferent* weakRef = new WeakReferent();
134 ptr->setWeakPtr(weakRef);
135 weakRef->setReferent(ptr.get());
136 mWeakPtr = weakRef;
137 }
138 if (mWeakPtr) {
139 mWeakPtr->ref();
140 }
141 }
142}
143
144template <typename T>
145template <typename U>
146inline WeakPtr<T>::WeakPtr(const Ptr<U> &ptr) : mWeakPtr(nullptr) {
147 if (ptr) {
148 mWeakPtr = ptr->getWeakPtr();
149 if (!mWeakPtr) {
150 // No weak reference exists yet, create one
151 WeakReferent* weakRef = new WeakReferent();
152 ptr->setWeakPtr(weakRef);
153 weakRef->setReferent(ptr.get());
154 mWeakPtr = weakRef;
155 }
156 if (mWeakPtr) {
157 mWeakPtr->ref();
158 }
159 }
160}
161
162template <typename T>
163inline WeakPtr<T>::WeakPtr(const WeakPtr &other) : mWeakPtr(other.mWeakPtr) {
164 if (mWeakPtr) {
165 mWeakPtr->ref();
166 }
167}
168
169template <typename T>
170template <typename U>
171inline WeakPtr<T>::WeakPtr(const WeakPtr<U> &other) : mWeakPtr(other.mWeakPtr) {
172 if (mWeakPtr) {
173 mWeakPtr->ref();
174 }
175}
176
177template <typename T>
178inline WeakPtr<T>::WeakPtr(WeakPtr &&other) noexcept : mWeakPtr(other.mWeakPtr) {
179 other.mWeakPtr = nullptr;
180}
181
182template <typename T>
184 reset();
185}
186
187template <typename T>
189 if (this != &other) {
190 if (mWeakPtr) {
191 mWeakPtr->unref();
192 }
193 mWeakPtr = other.mWeakPtr;
194 if (mWeakPtr) {
195 mWeakPtr->ref();
196 }
197 }
198 return *this;
199}
200
201template <typename T>
202inline Ptr<T> WeakPtr<T>::lock() const {
203 if (!mWeakPtr) {
204 return Ptr<T>();
205 }
206 T *out = static_cast<T *>(mWeakPtr->getReferent());
207 if (!out) {
208 // The referent has been destroyed
209 return Ptr<T>();
210 }
211 if (out->ref_count() == 0) {
212 // This is a static object, so the refcount is 0.
213 return Ptr<T>::NoTracking(*out);
214 }
215 // This is a heap object, so we need to ref it.
216 return Ptr<T>::TakeOwnership(static_cast<T *>(out));
217}
218
219template <typename T>
220inline bool WeakPtr<T>::expired() const {
221 if (!mWeakPtr) {
222 return true;
223 }
224 if (!mWeakPtr->getReferent()) {
225 return true;
226 }
227 return false;
228}
229
230template <typename T>
231inline WeakPtr<T>::operator bool() const {
232 return mWeakPtr && mWeakPtr->getReferent();
233}
234
235template <typename T>
236inline bool WeakPtr<T>::operator!() const {
237 bool ok = *this;
238 return !ok;
239}
240
241template <typename T>
242inline bool WeakPtr<T>::operator==(const WeakPtr &other) const {
243 return mWeakPtr == other.mWeakPtr;
244}
245
246template <typename T>
247inline bool WeakPtr<T>::operator!=(const WeakPtr &other) const {
248 return !(mWeakPtr != other.mWeakPtr);
249}
250
251template <typename T>
252inline bool WeakPtr<T>::operator==(const T *other) const {
253 return lock().get() == other;
254}
255
256template <typename T>
257inline bool WeakPtr<T>::operator==(T *other) const {
258 if (!mWeakPtr) {
259 return other == nullptr;
260 }
261 return mWeakPtr->getReferent() == other;
262}
263
264template <typename T>
265inline bool WeakPtr<T>::operator==(const Ptr<T> &other) const {
266 if (!mWeakPtr) {
267 return !other;
268 }
269 return mWeakPtr->getReferent() == other.get();
270}
271
272template <typename T>
273inline bool WeakPtr<T>::operator!=(const T *other) const {
274 bool equal = *this == other;
275 return !equal;
276}
277
278template <typename T>
279inline void WeakPtr<T>::reset() {
280 if (mWeakPtr) {
281 mWeakPtr->unref();
282 mWeakPtr = nullptr;
283 }
284}
285
286template <typename T>
288 if (!referent_) {
289 return WeakPtr<T>();
290 }
291 WeakReferent *tmp = get()->getWeakPtr();
292 if (!tmp) {
293 return WeakPtr<T>();
294 }
295 T *referent = static_cast<T *>(tmp->getReferent());
296 if (!referent) {
297 return WeakPtr<T>();
298 }
299 // At this point, we know that our weak referent is valid.
300 // However, the template parameter ensures that either we have
301 // an exact type, or are at least down-castable of it.
302 WeakPtr<T> out;
303 out.mWeakPtr = tmp;
304 if (out.mWeakPtr) {
305 out.mWeakPtr->ref();
306 }
307 return out;
308}
309
310// Free function templates
311
312template <typename T, typename... Args>
313inline Ptr<T> NewPtr(Args... args) {
314 return Ptr<T>::New(args...);
315}
316
317template <typename T>
318inline Ptr<T> NewPtrNoTracking(T &obj) {
319 return Ptr<T>::NoTracking(obj);
320}
321
322} // namespace fl
void reset()
Definition ptr_impl.h:84
Ptr()
Definition ptr.h:140
T * referent_
Definition ptr.h:184
static Ptr TakeOwnership(T *ptr)
Definition ptr.h:124
void swap(Ptr &other) noexcept
Definition ptr_impl.h:112
WeakPtr< T > weakRefNoCreate() const
Definition ptr_impl.h:287
Ptr(const Ptr< U > &refptr)
Definition ptr_impl.h:32
static Ptr NoTracking(T &referent)
Definition ptr.h:130
T * release()
Definition ptr_impl.h:105
Ptr & operator=(T *referent)=delete
T * get() const
Definition ptr.h:168
bool isOwned() const
Definition ptr.h:180
Definition ptr.h:114
static Ptr< T > New()
Definition ptr_impl.h:18
WeakPtr & operator=(const WeakPtr &other)
Definition ptr_impl.h:188
bool expired() const
Definition ptr_impl.h:220
bool operator!() const
Definition ptr_impl.h:236
bool operator==(const WeakPtr &other) const
Definition ptr_impl.h:242
bool operator!=(const WeakPtr &other) const
Definition ptr_impl.h:247
void reset()
Definition ptr_impl.h:279
WeakPtr()
Definition ptr.h:191
Ptr< T > lock() const
Definition ptr_impl.h:202
WeakReferent * mWeakPtr
Definition ptr.h:234
void setReferent(Referent *referent)
Definition referent.h:26
Referent * getReferent() const
Definition referent.h:27
Ptr< T > NewPtr(Args... args)
Definition ptr_impl.h:313
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) noexcept
Definition pair.h:113
bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2)
Definition algorithm.h:95
Ptr< T > NewPtrNoTracking(Args... args)
IMPORTANT!
Definition crgb.h:20
corkscrew_args args
Definition old.h:150