Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qsharedpointer_impl.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2022 Intel Corporation.
3// Copyright (C) 2019 Klarälvdalens Datakonsult AB.
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#ifndef Q_QDOC
7
8#ifndef QSHAREDPOINTER_H
9#error Do not include qsharedpointer_impl.h directly
10#endif
11
12#if 0
13#pragma qt_sync_skip_header_check
14#pragma qt_sync_stop_processing
15#endif
16
17#if 0
18// These macros are duplicated here to make syncqt not complain a about
19// this header, as we have a "qt_sync_stop_processing" below, which in turn
20// is here because this file contains a template mess and duplicates the
21// classes found in qsharedpointer.h
24#pragma qt_sync_stop_processing
25#endif
26
27#include <new>
28#include <QtCore/qatomic.h>
29#include <QtCore/qhashfunctions.h>
30#include <QtCore/qmetatype.h> // for IsPointerToTypeDerivedFromQObject
31
32#include <memory>
33
35
36class QObject;
37template <class T>
38T qobject_cast(const QObject *object);
39
40//
41// forward declarations
42//
43template <class T> class QWeakPointer;
44template <class T> class QSharedPointer;
45template <class T> class QEnableSharedFromThis;
46
47class QVariant;
48
49template <class X, class T>
51template <class X, class T>
53template <class X, class T>
55
56#ifndef QT_NO_QOBJECT
57template <class X, class T>
59#endif
60
61namespace QtPrivate {
62struct EnableInternalData;
63}
64
65namespace QtSharedPointer {
66 template <class T> class ExternalRefCount;
67
68 template <class X, class Y> QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
69
70 // used in debug mode to verify the reuse of pointers
71 Q_CORE_EXPORT void internalSafetyCheckAdd(const void *, const volatile void *);
72 Q_CORE_EXPORT void internalSafetyCheckRemove(const void *);
73
74 template <class T, typename Klass, typename RetVal>
75 inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)())
76 { if (t) (t->*memberDeleter)(); }
77 template <class T, typename Deleter>
78 inline void executeDeleter(T *t, Deleter d)
79 { d(t); }
80 struct NormalDeleter {};
81
82 // this uses partial template specialization
83 template <class T> struct RemovePointer;
84 template <class T> struct RemovePointer<T *> { typedef T Type; };
85 template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; };
86 template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; };
87
88 // This class is the d-pointer of QSharedPointer and QWeakPointer.
89 //
90 // It is a reference-counted reference counter. "strongref" is the inner
91 // reference counter, and it tracks the lifetime of the pointer itself.
92 // "weakref" is the outer reference counter and it tracks the lifetime of
93 // the ExternalRefCountData object.
94 //
95 // The deleter is stored in the destroyer member and is always a pointer to
96 // a static function in ExternalRefCountWithCustomDeleter or in
97 // ExternalRefCountWithContiguousData
99 {
104
106 : destroyer(d)
107 {
110 }
113
114 void destroy() { destroyer(this); }
115
116#ifndef QT_NO_QOBJECT
117 Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *);
118 Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable);
119 Q_CORE_EXPORT void checkQObjectShared(const QObject *);
120#endif
121 inline void checkQObjectShared(...) { }
122 inline void setQObjectShared(...) { }
123
124 // Normally, only subclasses of ExternalRefCountData are allocated
125 // One exception exists in getAndRef; that uses the global operator new
126 // to prevent a mismatch with the custom operator delete
127 inline void *operator new(std::size_t) = delete;
128 // placement new
129 inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
130 inline void operator delete(void *ptr) { ::operator delete(ptr); }
131 inline void operator delete(void *, void *) { }
132 };
133 // sizeof(ExternalRefCountData) = 12 (32-bit) / 16 (64-bit)
134
135 template <class T, typename Deleter>
137 {
138 Deleter deleter;
139 T *ptr;
140
141 CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {}
143 };
144 // sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*) + padding
145 // for Deleter = stateless functor: 8 (32-bit) / 16 (64-bit) due to padding
146 // for Deleter = function pointer: 8 (32-bit) / 16 (64-bit)
147 // for Deleter = PMF: 12 (32-bit) / 24 (64-bit) (GCC)
148
149 // This specialization of CustomDeleter for a deleter of type NormalDeleter
150 // is an optimization: instead of storing a pointer to a function that does
151 // the deleting, we simply delete the pointer ourselves.
152 template <class T>
154 {
155 T *ptr;
156
158 void execute() { delete ptr; }
159 };
160 // sizeof(CustomDeleter specialization) = sizeof(void*)
161
162 // This class extends ExternalRefCountData and implements
163 // the static function that deletes the object. The pointer and the
164 // custom deleter are kept in the "extra" member so we can construct
165 // and destruct it independently of the full structure.
166 template <class T, typename Deleter>
168 {
172
173 static inline void deleter(ExternalRefCountData *self)
174 {
175 Self *realself = static_cast<Self *>(self);
176 realself->extra.execute();
177
178 // delete the deleter too
179 realself->extra.~CustomDeleter<T, Deleter>();
180 }
182 {
184 deleter(self);
185 }
186
187 static inline Self *create(T *ptr, Deleter userDeleter, DestroyerFn actualDeleter)
188 {
189 Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
190
191 // initialize the two sub-objects
192 new (&d->extra) CustomDeleter<T, Deleter>(ptr, userDeleter);
193 new (d) BaseClass(actualDeleter); // can't throw
194
195 return d;
196 }
197 private:
198 // prevent construction
202 };
203
204 // This class extends ExternalRefCountData and adds a "T"
205 // member. That way, when the create() function is called, we allocate
206 // memory for both QSharedPointer's d-pointer and the actual object being
207 // tracked.
208 template <class T>
210 {
212 typedef typename std::remove_cv<T>::type NoCVType;
214
215 static void deleter(ExternalRefCountData *self)
216 {
218 static_cast<ExternalRefCountWithContiguousData *>(self);
219 that->data.~T();
220 Q_UNUSED(that); // MSVC warns if T has a trivial destructor
221 }
223 {
225 deleter(self);
226 }
228
230 {
232 static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
233
234 // initialize the d-pointer sub-object
235 // leave d->data uninitialized
236 new (d) Parent(destroy); // can't throw
237
238 *ptr = &d->data;
239 return d;
240 }
241
242 private:
243 // prevent construction
247 };
248
249#ifndef QT_NO_QOBJECT
252#endif
253} // namespace QtSharedPointer
254
255template <class T> class QSharedPointer
256{
258 template <typename X>
259 using IfCompatible = typename std::enable_if<std::is_convertible<X*, T*>::value, bool>::type;
260
261public:
262 typedef T Type;
263 typedef T element_type;
264 typedef T value_type;
266 typedef const value_type *const_pointer;
270
271 T *data() const noexcept { return value; }
272 T *get() const noexcept { return value; }
273 bool isNull() const noexcept { return !data(); }
274 explicit operator bool() const noexcept { return !isNull(); }
275 bool operator !() const noexcept { return isNull(); }
276 T &operator*() const { return *data(); }
277 T *operator->() const noexcept { return data(); }
278
280 constexpr QSharedPointer() noexcept : value(nullptr), d(nullptr) { }
282
284 constexpr QSharedPointer(std::nullptr_t) noexcept : value(nullptr), d(nullptr) { }
285
286 template <class X, IfCompatible<X> = true>
288 inline explicit QSharedPointer(X *ptr) : value(ptr) // noexcept
290
291 template <class X, typename Deleter, IfCompatible<X> = true>
293 inline QSharedPointer(X *ptr, Deleter deleter) : value(ptr) // throws
294 { internalConstruct(ptr, deleter); }
295
296 template <typename Deleter>
298 QSharedPointer(std::nullptr_t, Deleter deleter) : value(nullptr)
299 { internalConstruct(static_cast<T *>(nullptr), deleter); }
300
302 QSharedPointer(const QSharedPointer &other) noexcept : value(other.value), d(other.d)
303 { if (d) ref(); }
305 {
307 swap(copy);
308 return *this;
309 }
312 : value(other.value), d(other.d)
313 {
314 other.d = nullptr;
315 other.value = nullptr;
316 }
317 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedPointer)
318
319 template <class X, IfCompatible<X> = true>
322 : value(other.value), d(other.d)
323 {
324 other.d = nullptr;
325 other.value = nullptr;
326 }
327
328 template <class X, IfCompatible<X> = true>
330 {
331 QSharedPointer moved(std::move(other));
332 swap(moved);
333 return *this;
334 }
335
336 template <class X, IfCompatible<X> = true>
339 { if (d) ref(); }
340
341 template <class X, IfCompatible<X> = true>
343 {
345 swap(copy);
346 return *this;
347 }
348
349 template <class X, IfCompatible<X> = true>
352 { *this = other; }
353
354 template <class X, IfCompatible<X> = true>
356 { internalSet(other.d, other.value); return *this; }
357
358 inline void swap(QSharedPointer &other) noexcept
359 { this->internalSwap(other); }
360
361 inline void reset() { clear(); }
362 inline void reset(T *t)
364 template <typename Deleter>
365 inline void reset(T *t, Deleter deleter)
366 { QSharedPointer copy(t, deleter); swap(copy); }
367
368 template <class X>
370 {
371 return qSharedPointerCast<X, T>(*this);
372 }
373
374 template <class X>
376 {
377 return qSharedPointerDynamicCast<X, T>(*this);
378 }
379
380 template <class X>
382 {
383 return qSharedPointerConstCast<X, T>(*this);
384 }
385
386#ifndef QT_NO_QOBJECT
387 template <class X>
389 {
390 return qSharedPointerObjectCast<X, T>(*this);
391 }
392#endif
393
394 inline void clear() { QSharedPointer copy; swap(copy); }
395
396 [[nodiscard]] QWeakPointer<T> toWeakRef() const;
397
398 template <typename... Args>
399 [[nodiscard]] static QSharedPointer create(Args && ...arguments)
400 {
402# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
403 typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter;
404# else
405 typename Private::DestroyerFn destroy = &Private::deleter;
406# endif
407 typename Private::DestroyerFn noDestroy = &Private::noDeleter;
409 typename std::remove_cv<T>::type *ptr;
410 result.d = Private::create(&ptr, noDestroy);
411
412 // now initialize the data
413 new (ptr) T(std::forward<Args>(arguments)...);
414 result.value = ptr;
415 result.d->destroyer = destroy;
416 result.d->setQObjectShared(result.value, true);
417# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
418 internalSafetyCheckAdd(result.d, result.value);
419# endif
420 result.enableSharedFromThis(result.data());
421 return result;
422 }
423
424#define DECLARE_COMPARE_SET(T1, A1, T2, A2) \
425 friend bool operator==(T1, T2) noexcept \
426 { return A1 == A2; } \
427 friend bool operator!=(T1, T2) noexcept \
428 { return A1 != A2; }
429
430#define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2) \
431 template <typename X> \
432 friend bool operator==(T1, T2) noexcept \
433 { return A1 == A2; } \
434 template <typename X> \
435 friend bool operator!=(T1, T2) noexcept \
436 { return A1 != A2; }
437
441 DECLARE_COMPARE_SET(const QSharedPointer &p1, p1.data(), std::nullptr_t, nullptr)
442 DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QSharedPointer &p2, p2.data())
443#undef DECLARE_TEMPLATE_COMPARE_SET
444#undef DECLARE_COMPARE_SET
445
446private:
449
450 void deref() noexcept
451 { deref(d); }
452 static void deref(Data *dd) noexcept
453 {
454 if (!dd) return;
455 if (!dd->strongref.deref()) {
456 dd->destroy();
457 }
458 if (!dd->weakref.deref())
459 delete dd;
460 }
461
462 template <class X>
464 {
465 ptr->initializeFromSharedPointer(constCast<typename std::remove_cv<T>::type>());
466 }
467
468 inline void enableSharedFromThis(...) {}
469
470 template <typename X, typename Deleter>
471 inline void internalConstruct(X *ptr, Deleter deleter)
472 {
474# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
475 typename Private::DestroyerFn actualDeleter = &Private::safetyCheckDeleter;
476# else
477 typename Private::DestroyerFn actualDeleter = &Private::deleter;
478# endif
479 d = Private::create(ptr, deleter, actualDeleter);
480
481#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
482 internalSafetyCheckAdd(d, ptr);
483#endif
484 d->setQObjectShared(ptr, true);
486 }
487
489 {
490 qt_ptr_swap(d, other.d);
491 qt_ptr_swap(this->value, other.value);
492 }
493
494 template <class X> friend class QSharedPointer;
495 template <class X> friend class QWeakPointer;
496 template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
497 void ref() const noexcept { d->weakref.ref(); d->strongref.ref(); }
498
499 inline void internalSet(Data *o, T *actual)
500 {
501 if (o) {
502 // increase the strongref, but never up from zero
503 // or less (-1 is used by QWeakPointer on untracked QObject)
504 int tmp = o->strongref.loadRelaxed();
505 while (tmp > 0) {
506 // try to increment from "tmp" to "tmp + 1"
507 if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
508 break; // succeeded
509 tmp = o->strongref.loadRelaxed(); // failed, try again
510 }
511
512 if (tmp > 0) {
513 o->weakref.ref();
514 } else {
515 o->checkQObjectShared(actual);
516 o = nullptr;
517 }
518 }
519
520 qt_ptr_swap(d, o);
521 qt_ptr_swap(this->value, actual);
522 if (!d || d->strongref.loadRelaxed() == 0)
523 this->value = nullptr;
524
525 // dereference saved data
526 deref(o);
527 }
528
531};
532
533template <class T>
535{
537 template <typename X>
538 using IfCompatible = typename std::enable_if<std::is_convertible<X*, T*>::value, bool>::type;
539
540public:
541 typedef T element_type;
542 typedef T value_type;
544 typedef const value_type *const_pointer;
548
549 bool isNull() const noexcept { return d == nullptr || d->strongref.loadRelaxed() == 0 || value == nullptr; }
550 explicit operator bool() const noexcept { return !isNull(); }
551 bool operator !() const noexcept { return isNull(); }
552
554 constexpr QWeakPointer() noexcept : d(nullptr), value(nullptr) { }
555 inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
556
558 QWeakPointer(const QWeakPointer &other) noexcept : d(other.d), value(other.value)
559 { if (d) d->weakref.ref(); }
562 : d(other.d), value(other.value)
563 {
564 other.d = nullptr;
565 other.value = nullptr;
566 }
567 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QWeakPointer)
568
569 template <class X, IfCompatible<X> = true>
572 : d(other.d), value(other.value)
573 {
574 other.d = nullptr;
575 other.value = nullptr;
576 }
577
578 template <class X, IfCompatible<X> = true>
580 {
581 QWeakPointer moved(std::move(other));
582 swap(moved);
583 return *this;
584 }
585
587 {
589 swap(copy);
590 return *this;
591 }
592
593 void swap(QWeakPointer &other) noexcept
594 {
595 qt_ptr_swap(this->d, other.d);
596 qt_ptr_swap(this->value, other.value);
597 }
598
600 inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data())
601 { if (d) d->weakref.ref();}
603 {
604 internalSet(o.d, o.value);
605 return *this;
606 }
607
608 template <class X, IfCompatible<X> = true>
611 { *this = o; }
612
613 template <class X, IfCompatible<X> = true>
615 {
616 // conversion between X and T could require access to the virtual table
617 // so force the operation to go through QSharedPointer
618 *this = o.toStrongRef();
619 return *this;
620 }
621
622 template <class X, IfCompatible<X> = true>
625 { *this = o; }
626
627 template <class X, IfCompatible<X> = true>
629 {
630 internalSet(o.d, o.data());
631 return *this;
632 }
633
634 inline void clear() { *this = QWeakPointer(); }
635
636 [[nodiscard]] QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); }
637 // std::weak_ptr compatibility:
638 [[nodiscard]] QSharedPointer<T> lock() const { return toStrongRef(); }
639
640 template <class X>
641 bool operator==(const QWeakPointer<X> &o) const noexcept
642 { return d == o.d && value == static_cast<const T *>(o.value); }
643
644 template <class X>
645 bool operator!=(const QWeakPointer<X> &o) const noexcept
646 { return !(*this == o); }
647
648 template <class X>
649 bool operator==(const QSharedPointer<X> &o) const noexcept
650 { return d == o.d; }
651
652 template <class X>
653 bool operator!=(const QSharedPointer<X> &o) const noexcept
654 { return !(*this == o); }
655
656 template <typename X>
657 friend bool operator==(const QSharedPointer<X> &p1, const QWeakPointer &p2) noexcept
658 { return p2 == p1; }
659 template <typename X>
660 friend bool operator!=(const QSharedPointer<X> &p1, const QWeakPointer &p2) noexcept
661 { return p2 != p1; }
662
663 friend bool operator==(const QWeakPointer &p, std::nullptr_t)
664 { return p.isNull(); }
665 friend bool operator==(std::nullptr_t, const QWeakPointer &p)
666 { return p.isNull(); }
667 friend bool operator!=(const QWeakPointer &p, std::nullptr_t)
668 { return !p.isNull(); }
669 friend bool operator!=(std::nullptr_t, const QWeakPointer &p)
670 { return !p.isNull(); }
671
672private:
674 template <class X> friend class QSharedPointer;
675 template <class X> friend class QWeakPointer;
676 template <class X> friend class QPointer;
677
678 template <class X>
679 inline QWeakPointer &assign(X *ptr)
680 { return *this = QWeakPointer<X>(ptr, true); }
681
682#ifndef QT_NO_QOBJECT
683 template <class X, IfCompatible<X> = true>
685 inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : nullptr), value(ptr)
686 { }
687#endif
688
689 inline void internalSet(Data *o, T *actual)
690 {
691 if (d == o) return;
692 if (o)
693 o->weakref.ref();
694 if (d && !d->weakref.deref())
695 delete d;
696 d = o;
697 value = actual;
698 }
699
700 // ### TODO - QTBUG-88102: remove all users of this API; no one should ever
701 // access a weak pointer's data but the weak pointer itself
702 inline T *internalData() const noexcept
703 {
704 return d == nullptr || d->strongref.loadRelaxed() == 0 ? nullptr : value;
705 }
706
707 Data *d;
708 T *value;
709};
710
711namespace QtPrivate {
713 template <typename T>
714 static T *internalData(const QWeakPointer<T> &p) noexcept { return p.internalData(); }
715};
716// hack to delay name lookup to instantiation time by making
717// EnableInternalData a dependent name:
718template <typename T>
720}
721
722template <class T>
724{
725protected:
729
730public:
731 inline QSharedPointer<T> sharedFromThis() { return QSharedPointer<T>(weakPointer); }
732 inline QSharedPointer<const T> sharedFromThis() const { return QSharedPointer<const T>(weakPointer); }
733
734private:
735 template <class X> friend class QSharedPointer;
736 template <class X>
737 inline void initializeFromSharedPointer(const QSharedPointer<X> &ptr) const
738 {
739 weakPointer = ptr;
740 }
741
742 mutable QWeakPointer<T> weakPointer;
743};
744
745//
746// operator-
747//
748template <class T, class X>
749Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
750{
751 return ptr1.data() - ptr2.data();
752}
753template <class T, class X>
754Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2)
755{
756 return ptr1.data() - ptr2;
757}
758template <class T, class X>
759Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2)
760{
761 return ptr1 - ptr2.data();
762}
763
764//
765// operator<
766//
767template <class T, class X>
768Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
769{
770 using CT = typename std::common_type<T *, X *>::type;
771 return std::less<CT>()(ptr1.data(), ptr2.data());
772}
773template <class T, class X>
774Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2)
775{
776 using CT = typename std::common_type<T *, X *>::type;
777 return std::less<CT>()(ptr1.data(), ptr2);
778}
779template <class T, class X>
780Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
781{
782 using CT = typename std::common_type<T *, X *>::type;
783 return std::less<CT>()(ptr1, ptr2.data());
784}
785
786//
787// qHash
788//
789template <class T>
790Q_INLINE_TEMPLATE size_t qHash(const QSharedPointer<T> &ptr, size_t seed = 0)
791{
792 return qHash(ptr.data(), seed);
793}
794
795
796template <class T>
798{
799 return QWeakPointer<T>(*this);
800}
801
802template <class T>
804{ p1.swap(p2); }
805
806template <class T>
807inline void swap(QWeakPointer<T> &p1, QWeakPointer<T> &p2) noexcept
808{ p1.swap(p2); }
809
810namespace QtSharedPointer {
811// helper functions:
812 template <class X, class T>
814 {
816 result.internalSet(src.d, ptr);
817 return result;
818 }
819}
820
821// cast operators
822template <class X, class T>
824{
825 X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
827}
828template <class X, class T>
830{
831 return qSharedPointerCast<X, T>(src.toStrongRef());
832}
833
834template <class X, class T>
836{
837 X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
838 if (!ptr)
839 return QSharedPointer<X>();
841}
842template <class X, class T>
844{
845 return qSharedPointerDynamicCast<X, T>(src.toStrongRef());
846}
847
848template <class X, class T>
850{
851 X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
853}
854template <class X, class T>
856{
857 return qSharedPointerConstCast<X, T>(src.toStrongRef());
858}
859
860template <class X, class T>
861Q_INLINE_TEMPLATE
863{
864 return qSharedPointerCast<X, T>(src).toWeakRef();
865}
866
867#ifndef QT_NO_QOBJECT
868template <class X, class T>
870{
871 X *ptr = qobject_cast<X *>(src.data());
873}
874template <class X, class T>
876{
877 return qSharedPointerObjectCast<X>(src.toStrongRef());
878}
879
880template <class X, class T>
883{
884 return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
885}
886template <class X, class T>
889{
890 return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
891}
892
895template<typename T>
898{
900}
901template<typename T>
904{
905 return qSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));
906}
907
908// std::shared_ptr helpers
909
910template <typename X, class T>
911std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
912{
913 using element_type = typename std::shared_ptr<X>::element_type;
914 return std::shared_ptr<X>(src, qobject_cast<element_type *>(src.get()));
915}
916
917template <typename X, class T>
918std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
919{
920 using element_type = typename std::shared_ptr<X>::element_type;
921 auto castResult = qobject_cast<element_type *>(src.get());
922 if (castResult) {
923 // C++2a's move aliasing constructor will leave src empty.
924 // Before C++2a we don't really know if the compiler has support for it.
925 // The move aliasing constructor is the resolution for LWG2996,
926 // which does not impose a feature-testing macro. So: clear src.
927 return std::shared_ptr<X>(std::exchange(src, nullptr), castResult);
928 }
929 return std::shared_ptr<X>();
930}
931
932template <typename X, class T>
933std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
934{
935 return qobject_pointer_cast<X>(src);
936}
937
938template <typename X, class T>
939std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
940{
941 return qobject_pointer_cast<X>(std::move(src));
942}
943
944#endif
945
948
949
951
952#endif
bool ref() noexcept
bool deref() noexcept
void storeRelaxed(T newValue) noexcept
T loadRelaxed() const noexcept
QSharedPointer< T > sharedFromThis()
QEnableSharedFromThis(const QEnableSharedFromThis &)
QEnableSharedFromThis & operator=(const QEnableSharedFromThis &)
QEnableSharedFromThis()=default
QSharedPointer< const T > sharedFromThis() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
\inmodule QtCore
Definition qobject.h:90
void swap(QPixmap &other) noexcept
Definition qpixmap.h:43
\inmodule QtCore
Definition qpointer.h:18
\inmodule QtCore
Q_NODISCARD_CTOR QSharedPointer(X *ptr)
Creates a QSharedPointer that points to ptr.
Q_NODISCARD_CTOR QSharedPointer(X *ptr, Deleter deleter)
Creates a QSharedPointer that points to ptr.
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
static void deref(Data *dd) noexcept
Q_NODISCARD_CTOR QSharedPointer(const QSharedPointer &other) noexcept
Creates a QSharedPointer object that shares other's pointer.
QSharedPointer & operator=(QSharedPointer< X > &&other) noexcept
Move-assigns other to this QSharedPointer instance.
QSharedPointer< X > constCast() const
Performs a \tt const_cast from this pointer's type to \tt X and returns a QSharedPointer that shares ...
DECLARE_TEMPLATE_COMPARE_SET(const QSharedPointer &p1, p1.data(), const QSharedPointer< X > &p2, p2.data()) private
bool operator!() const noexcept
Returns true if this object refers to \nullptr.
void enableSharedFromThis(const QEnableSharedFromThis< X > *ptr)
friend class QSharedPointer
Creates a QSharedPointer that is null (the object is holding a reference to \nullptr).
QWeakPointer< T > toWeakRef() const
Returns a weak reference object that shares the pointer referenced by this object.
QSharedPointer< X > objectCast() const
QSharedPointer< T > & operator=(const QWeakPointer< X > &other)
Q_NODISCARD_CTOR QSharedPointer(const QSharedPointer< X > &other) noexcept
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *t, Deleter deleter)
void internalSet(Data *o, T *actual)
QSharedPointer< X > dynamicCast() const
Performs a dynamic cast from this pointer's type to \tt X and returns a QSharedPointer that shares th...
~QSharedPointer()
Destroys this QSharedPointer object.
Q_NODISCARD_CTOR QSharedPointer(QSharedPointer &&other) noexcept
Move-constructs a QSharedPointer instance, making it point at the same object that other was pointing...
void enableSharedFromThis(...)
const value_type & const_reference
void deref() noexcept
Q_NODISCARD_CTOR QSharedPointer(std::nullptr_t, Deleter deleter)
T * get() const noexcept
Q_NODISCARD_CTOR QSharedPointer(const QWeakPointer< X > &other)
void internalConstruct(X *ptr, Deleter deleter)
const value_type * const_pointer
void internalSwap(QSharedPointer &other) noexcept
Q_NODISCARD_CTOR constexpr QSharedPointer(std::nullptr_t) noexcept
static QSharedPointer create(Args &&...arguments)
This is an overloaded member function, provided for convenience. It differs from the above function o...
T & operator*() const
Provides access to the shared pointer's members.
QSharedPointer & operator=(const QSharedPointer &other) noexcept
Makes this object share other's pointer.
QSharedPointer< X > staticCast() const
Performs a static cast from this pointer's type to \tt X and returns a QSharedPointer that shares the...
T * operator->() const noexcept
Provides access to the shared pointer's members.
Q_NODISCARD_CTOR QSharedPointer(QSharedPointer< X > &&other) noexcept
Move-constructs a QSharedPointer instance, making it point at the same object that other was pointing...
void swap(QSharedPointer &other) noexcept
QSharedPointer & operator=(const QSharedPointer< X > &other)
void ref() const noexcept
void clear()
Clears this QSharedPointer object, dropping the reference that it may have had to the pointer.
Q_NODISCARD_CTOR constexpr QSharedPointer() noexcept
\inmodule QtCore
Definition qvariant.h:64
\inmodule QtCore
friend bool operator==(const QWeakPointer &p, std::nullptr_t)
const value_type & const_reference
friend bool operator!=(const QWeakPointer &p, std::nullptr_t)
Q_NODISCARD_CTOR QWeakPointer(QWeakPointer &&other) noexcept
Q_NODISCARD_CTOR QWeakPointer(const QWeakPointer &other) noexcept
Creates a QWeakPointer that holds a weak reference to the pointer referenced by other.
QWeakPointer & operator=(QWeakPointer< X > &&other) noexcept
friend bool operator==(const QSharedPointer< X > &p1, const QWeakPointer &p2) noexcept
QWeakPointer & operator=(const QSharedPointer< X > &o)
QWeakPointer & operator=(const QWeakPointer &other) noexcept
Makes this object share other's pointer.
friend bool operator==(std::nullptr_t, const QWeakPointer &p)
friend bool operator!=(const QSharedPointer< X > &p1, const QWeakPointer &p2) noexcept
bool operator==(const QSharedPointer< X > &o) const noexcept
void clear()
Clears this QWeakPointer object, dropping the reference that it may have had to the pointer.
QSharedPointer< T > toStrongRef() const
Promotes this weak reference to a strong one and returns a QSharedPointer object holding that referen...
QWeakPointer & operator=(const QSharedPointer< T > &o)
Makes this object share other's pointer.
bool operator!() const noexcept
Returns true if this object refers to \nullptr.
bool operator==(const QWeakPointer< X > &o) const noexcept
Q_NODISCARD_CTOR constexpr QWeakPointer() noexcept
QWeakPointer & operator=(const QWeakPointer< X > &o)
QSharedPointer< T > lock() const
bool operator!=(const QWeakPointer< X > &o) const noexcept
const value_type * const_pointer
Q_NODISCARD_CTOR QWeakPointer(const QWeakPointer< X > &o)
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
friend class QWeakPointer
Creates a QWeakPointer that points to nothing.
~QWeakPointer()
Destroys this QWeakPointer object.
bool operator!=(const QSharedPointer< X > &o) const noexcept
friend bool operator!=(std::nullptr_t, const QWeakPointer &p)
value_type * pointer
Q_NODISCARD_CTOR QWeakPointer(const QSharedPointer< T > &o)
Creates a QWeakPointer that holds a weak reference to the pointer referenced by other.
value_type & reference
Q_NODISCARD_CTOR QWeakPointer(QWeakPointer< X > &&other) noexcept
Q_NODISCARD_CTOR QWeakPointer(const QSharedPointer< X > &o)
void swap(QWeakPointer &other) noexcept
QPixmap p2
QPixmap p1
[0]
QList< QVariant > arguments
Combined button and popup list for selecting options.
\macro QT_NAMESPACE
QSharedPointer< X > copyAndSetPointer(X *ptr, const QSharedPointer< Y > &src)
Q_CORE_EXPORT QWeakPointer< QObject > weakPointerFromVariant_internal(const QVariant &variant)
Q_CORE_EXPORT void internalSafetyCheckRemove(const void *)
void executeDeleter(T *t, RetVal(Klass::*memberDeleter)())
Q_CORE_EXPORT void internalSafetyCheckAdd(const void *, const volatile void *)
Q_CORE_EXPORT QSharedPointer< QObject > sharedPointerFromVariant_internal(const QVariant &variant)
constexpr Initialization Uninitialized
Initialization
static jboolean copy(JNIEnv *, jobject)
#define Q_NODISCARD_CTOR
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static ControlElement< T > * ptr(QWidget *widget)
GLenum src
GLenum type
GLboolean enable
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
#define X(name)
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QSharedPointer< X > qSharedPointerConstCast(const QSharedPointer< T > &ptr)
Q_INLINE_TEMPLATE QSharedPointer< T >::difference_type operator-(const QSharedPointer< T > &ptr1, const QSharedPointer< X > &ptr2)
QSharedPointer< X > qSharedPointerCast(const QSharedPointer< T > &ptr)
QWeakPointer< typename std::enable_if< QtPrivate::IsPointerToTypeDerivedFromQObject< T * >::Value, T >::type > qWeakPointerFromVariant(const QVariant &variant)
Q_INLINE_TEMPLATE size_t qHash(const QSharedPointer< T > &ptr, size_t seed=0)
#define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2)
QSharedPointer< X > qSharedPointerDynamicCast(const QSharedPointer< T > &ptr)
Q_INLINE_TEMPLATE bool operator<(const QSharedPointer< T > &ptr1, const QSharedPointer< X > &ptr2)
std::shared_ptr< X > qobject_pointer_cast(const std::shared_ptr< T > &src)
T qobject_cast(const QObject *object)
Definition qobject.h:394
QSharedPointer< typename std::enable_if< QtPrivate::IsPointerToTypeDerivedFromQObject< T * >::Value, T >::type > qSharedPointerFromVariant(const QVariant &variant)
#define DECLARE_COMPARE_SET(T1, A1, T2, A2)
QSharedPointer< X > qSharedPointerObjectCast(const QSharedPointer< T > &ptr)
Q_INLINE_TEMPLATE QWeakPointer< X > qWeakPointerCast(const QSharedPointer< T > &src)
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
Definition qswap.h:43
#define Q_UNUSED(x)
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
Definition qtypeinfo.h:150
ptrdiff_t qptrdiff
Definition qtypes.h:69
QObject::connect nullptr
QVariant variant
[1]
QSharedPointer< T > other(t)
[5]
this swap(other)
static T * internalData(const QWeakPointer< T > &p) noexcept
void(* DestroyerFn)(ExternalRefCountData *)
Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable)
Q_CORE_EXPORT void checkQObjectShared(const QObject *)
static Q_CORE_EXPORT ExternalRefCountData * getAndRef(const QObject *)
static void deleter(ExternalRefCountData *self)
static ExternalRefCountData * create(NoCVType **ptr, DestroyerFn destroy)
static void safetyCheckDeleter(ExternalRefCountData *self)
static Self * create(T *ptr, Deleter userDeleter, DestroyerFn actualDeleter)
static void safetyCheckDeleter(ExternalRefCountData *self)
static void deleter(ExternalRefCountData *self)
Definition moc.h:24