Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_shared_ptr.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2005 Frerich Raabe <raabe@kde.org>
3 * SPDX-FileCopyrightText: 2006, 2010 Cyrille Berger <cberger@cberger.net>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#ifndef KIS_SHAREDPTR_H
9#define KIS_SHAREDPTR_H
10
11#include <QtGlobal>
12
13#include <kis_debug.h>
14
16
17template<class T>
19
55template<class T>
57{
58 friend class KisWeakSharedPtr<T>;
59public:
60 using element_type = T;
62
66 inline KisSharedPtr()
67 : d(0) { }
68
73 inline KisSharedPtr(T* p)
74 : d(p) {
75 ref();
76 }
77
79
80 // Free the pointer and set it to new value
81 void attach(T* p);
82
83 // Free the pointer
84 void clear();
85
91 : d(o.d) {
92 ref();
93 }
94
99 inline ~KisSharedPtr() {
100 deref();
101 }
102
104 attach(o.d);
105 return *this;
106 }
107 inline bool operator== (const T* p) const {
108 return (d == p);
109 }
110 inline bool operator!= (const T* p) const {
111 return (d != p);
112 }
113 inline bool operator== (const KisSharedPtr& o) const {
114 return (d == o.d);
115 }
116 inline bool operator!= (const KisSharedPtr& o) const {
117 return (d != o.d);
118 }
119
121 attach(p);
122 return *this;
123 }
124
125 inline operator const T*() const {
126 return d;
127 }
128
129 template< class T2> inline operator KisSharedPtr<T2>() const {
130 return KisSharedPtr<T2>(d);
131 }
132
139 inline T* data() {
140 return d;
141 }
142
146 inline const T* data() const {
147 return d;
148 }
149
153 inline const T* constData() const {
154 return d;
155 }
156
157 inline const T& operator*() const {
158 Q_ASSERT(d);
159 return *d;
160 }
161 inline T& operator*() {
162 Q_ASSERT(d);
163 return *d;
164 }
165
166 inline const T* operator->() const {
167 Q_ASSERT(d);
168 return d;
169 }
170 inline T* operator->() {
171 Q_ASSERT(d);
172 return d;
173 }
174
178 inline bool isNull() const {
179 return (d == 0);
180 }
181
182 inline static void ref(const KisSharedPtr<T>* sp, T* t)
183 {
184#ifndef HAVE_MEMORY_LEAK_TRACKER
185 Q_UNUSED(sp);
186#else
188#endif
189 if (t) {
190 t->ref();
191 }
192 }
193
194 inline static bool deref(const KisSharedPtr<T>* sp, T* t)
195 {
196#ifndef HAVE_MEMORY_LEAK_TRACKER
197 Q_UNUSED(sp);
198#else
200#endif
201 if (t && !t->deref()) {
202 delete t;
203 return false;
204 }
205 return true;
206 }
207
208private:
209 inline void ref() const
210 {
211 ref(this, d);
212 }
213
214 inline void deref() const
215 {
216 bool v = deref(this, d);
217#ifndef NDEBUG
218 if (!v) {
219 d = 0;
220 }
221#else
222 Q_UNUSED(v);
223#endif
224 }
225
226private:
227 mutable T* d;
228};
229
236template<class T>
238{
239 friend class KisSharedPtr<T>;
240public:
241 using element_type = T;
242
247 : d(0), weakReference(0) { }
248
253 inline KisWeakSharedPtr(T* p) {
254 load(p);
255 }
256
258 load(o.d);
259 }
260
266 if (o.isConsistent()) {
267 load(o.d);
268 }
269 else {
270 d = 0;
271 weakReference = 0;
272 }
273 }
274
276 detach();
277 }
278
280 attach(o);
281 return *this;
282 }
283
284 inline bool operator== (const T* p) const {
285 return (d == p);
286 }
287 inline bool operator!= (const T* p) const {
288 return (d != p);
289 }
290 inline bool operator== (const KisWeakSharedPtr& o) const {
291 return (d == o.d);
292 }
293 inline bool operator!= (const KisWeakSharedPtr& o) const {
294 return (d != o.d);
295 }
296
298 attach(p);
299 return *this;
300 }
301
302 template< class T2> inline operator KisWeakSharedPtr<T2>() const {
303 return KisWeakSharedPtr<T2>(d);
304 }
305
312 inline T* data() {
313 if (!isConsistent()) {
314 warnKrita.noquote() << kisBacktrace();
315 Q_ASSERT_X(0, "KisWeakSharedPtr", "Weak pointer is not valid!");
316 }
317
318 return d;
319 }
320
324 inline const T* data() const {
325 if (!isConsistent()) {
326 warnKrita.noquote() << kisBacktrace();
327 Q_ASSERT_X(0, "KisWeakSharedPtr", "Weak pointer is not valid!");
328 }
329
330 return d;
331 }
332
336 inline const T* constData() const {
337 if (!isConsistent()) {
338 warnKrita.noquote() << kisBacktrace();
339 Q_ASSERT_X(0, "KisWeakSharedPtr", "Weak pointer is not valid!");
340 }
341
342 return d;
343 }
344
348 inline operator const T*() const {
354 return isConsistent() ? d : 0;
355 }
356
357 inline const T& operator*() const {
358 if (!isValid()) {
359 warnKrita.noquote() << kisBacktrace();
360 Q_ASSERT_X(0, "KisWeakSharedPtr", "Weak pointer is not valid!");
361 }
362
363 return *d;
364 }
365
366 inline T& operator*() {
367 if (!isValid()) {
368 warnKrita.noquote() << kisBacktrace();
369 Q_ASSERT_X(0, "KisWeakSharedPtr", "Weak pointer is not valid!");
370 }
371
372 return *d;
373 }
374
375 inline const T* operator->() const {
376 if (!isValid()) {
377 warnKrita.noquote() << kisBacktrace();
378 Q_ASSERT_X(0, "KisWeakSharedPtr", "Weak pointer is not valid!");
379 }
380
381 return d;
382 }
383
384 inline T* operator->() {
385 if (!isValid()) {
386 warnKrita.noquote() << kisBacktrace();
387 Q_ASSERT_X(0, "KisWeakSharedPtr", "Weak pointer is not valid!");
388 }
389
390 return d;
391 }
392
396 inline bool isNull() const {
397 return (d == 0);
398 }
399
404 inline bool isValid() const {
405 Q_ASSERT(!d || weakReference);
406
407 return d && weakReference && isOdd((int)*weakReference);
408 }
409
419 return KisSharedPtr<T>(*this);
420 }
421
422private:
423 static const qint32 WEAK_REF = 2;
424 static inline bool isOdd(const qint32 &x) {
425 return x & 0x01;
426 }
427
428 inline bool isConsistent() const {
429 Q_ASSERT(!d || weakReference);
430
431 return !d || (weakReference && isOdd((int)*weakReference));
432 }
433
434 void load(T* newValue) {
435 d = newValue;
436
437 if (d) {
438 weakReference = d->sharedWeakReference();
439 weakReference->fetchAndAddOrdered(WEAK_REF);
440 }
441 else {
442 weakReference = 0;
443 }
444 }
445
446 // see note in kis_shared.cc
447 inline void attach(T* newValue) {
448 detach();
449 load(newValue);
450 }
451
452 inline void attach(const KisWeakSharedPtr& o) {
453 detach();
454 if (o.isConsistent()) {
455 load(o.d);
456 }
457 else {
458 d = 0;
459 weakReference = 0;
460 }
461 }
462
463 // see note in kis_shared.cc
464 void detach() {
465 d = 0;
466
467 if (weakReference &&
468 weakReference->fetchAndAddOrdered(-WEAK_REF) <= WEAK_REF) {
469
470 // sanity check:
471 Q_ASSERT((int)*weakReference == 0);
472
473 delete weakReference;
474 weakReference = 0;
475 }
476 }
477
478 mutable T* d;
479 QAtomicInt *weakReference;
480};
481
482
483template <class T>
485 : d(o.d)
486{
487 if (o.isValid()) {
488 ref();
489
494 Q_ASSERT(o.isConsistent());
495 }
496 else {
497 d = 0;
498 }
499}
500
501
502template <class T>
503Q_INLINE_TEMPLATE void KisSharedPtr<T>::attach(T* p)
504{
505 if (d != p) {
506 ref(this, p);
507 T* old = d;
508 d = p;
509 deref(this, old);
510 }
511}
512
513template <class T>
514Q_INLINE_TEMPLATE void KisSharedPtr<T>::clear()
515{
516 attach((T*)0);
517}
518
519#endif
const Params2D p
qreal v
static KisMemoryLeakTracker * instance()
void dereference(const void *what, const void *bywho)
void reference(const void *what, const void *bywho, const char *whatName=0)
const T * constData() const
void attach(T *p)
KisSharedPtr & operator=(const KisSharedPtr &o)
KisSharedPtr(const KisWeakSharedPtr< T > &o)
const T * operator->() const
KisSharedPtr(const KisSharedPtr< T > &o)
static void ref(const KisSharedPtr< T > *sp, T *t)
static bool deref(const KisSharedPtr< T > *sp, T *t)
bool isNull() const
bool operator!=(const T *p) const
bool operator==(const T *p) const
void deref() const
void ref() const
const T & operator*() const
const T * data() const
const T * data() const
bool operator==(const T *p) const
bool isConsistent() const
const T * operator->() const
void load(T *newValue)
void attach(const KisWeakSharedPtr &o)
friend class KisSharedPtr< T >
KisWeakSharedPtr(const KisWeakSharedPtr< T > &o)
bool isNull() const
const T & operator*() const
static const qint32 WEAK_REF
KisSharedPtr< T > toStrongRef() const
toStrongRef returns a KisSharedPtr which may be dereferenced.
KisWeakSharedPtr(const KisSharedPtr< T > &o)
static bool isOdd(const qint32 &x)
QAtomicInt * weakReference
bool operator!=(const T *p) const
KisWeakSharedPtr & operator=(const KisWeakSharedPtr &o)
void attach(T *newValue)
const T * constData() const
bool isValid() const
QString kisBacktrace()
Definition kis_debug.cpp:51
#define warnKrita
Definition kis_debug.h:87
#define isOdd(x)