9#ifndef QSHAREDPOINTER_H
10#error Do not include qsharedpointer_impl.h directly
14#pragma qt_sync_skip_header_check
15#pragma qt_sync_stop_processing
25#pragma qt_sync_stop_processing
29#include <QtCore/qatomic.h>
30#include <QtCore/qhashfunctions.h>
31#include <QtCore/qmetatype.h>
32#include <QtCore/qxptype_traits.h>
51template <
class X,
class T>
53template <
class X,
class T>
55template <
class X,
class T>
57template <
class X,
class T>
59template <
class X,
class T>
61template <
class X,
class T>
63template <
class X,
class T>
65template <
class X,
class T>
69template <
class X,
class T>
71template <
class X,
class T>
89 template <
class T,
typename Klass,
typename RetVal>
91 {
if (t) (t->*memberDeleter)(); }
92 template <
class T,
typename Deleter>
123 strongref.storeRelaxed(1);
124 weakref.storeRelaxed(1);
134 Q_CORE_EXPORT
void setQObjectShared(
const QObject *,
bool enable);
146 inline void *
operator new(
std::size_t,
void *ptr)
noexcept {
return ptr; }
152 template <
class T,
typename Deleter>
183 template <
class T,
typename Deleter>
192 Self *realself =
static_cast<
Self *>(self);
206 Self *d =
static_cast<
Self *>(::operator
new(
sizeof(
Self)));
216 ExternalRefCountWithCustomDeleter() =
delete;
217 ~ExternalRefCountWithCustomDeleter() =
delete;
261 ExternalRefCountWithContiguousData() =
delete;
262 ~ExternalRefCountWithContiguousData() =
delete;
275 template <
typename X>
276 using IfCompatible =
typename std::enable_if<
std::is_convertible<X*, T*>::value,
bool>::type;
288 T *
data()
const noexcept {
return value.get(); }
289 T *
get()
const noexcept {
return value.get(); }
439 template <
typename... Args>
443# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
444 typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter;
446 typename Private::DestroyerFn destroy = &Private::deleter;
448 typename Private::DestroyerFn noDestroy = &Private::noDeleter;
450 typename std::remove_cv<T>::type *ptr;
451 result.d = Private::create(&ptr, noDestroy);
454 new (ptr) T(
std::forward<Args>(arguments)...);
455 result.value.reset(ptr);
456 result.d->destroyer = destroy;
457 result.d->setQObjectShared(result.value.get(),
true);
458# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
459 internalSafetyCheckAdd(result.d, result.value.get());
461 result.enableSharedFromThis(result.data());
465 template <
typename X>
467 {
return std::less<>()(d, other.d); }
468 template <
typename X>
470 {
return std::less<>()(d, other.d); }
472 template <
typename X>
474 {
return d == other.d; }
475 template <
typename X>
477 {
return d == other.d; }
480 {
return std::hash<Data *>()(d); }
483 template <
typename X>
485 {
return lhs
.data() == rhs.data(); }
486 template <
typename X>
490 return Qt::compareThreeWay(lhs.value, rhs.data());
492 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG,
QSharedPointer<T>, QSharedPointer<X>,
494 template <
typename X>)
496 template <
typename X>
499 template <
typename X>
505 {
return lhs.
data() ==
nullptr; }
514 void deref()
noexcept
534 template <
typename X,
typename Deleter>
538# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
545#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
561 void ref()
const noexcept { d->weakref.ref(); d->strongref.ref(); }
563 inline void internalSet(Data *o, T *actual)
568 int tmp = o->strongref.loadRelaxed();
571 if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
573 tmp = o->strongref.loadRelaxed();
583 this->value.reset(actual);
584 if (!d || d->strongref.loadRelaxed() == 0)
585 this->value =
nullptr;
591 Qt::totally_ordered_wrapper<Type *> value;
599 template <
typename X>
605 template <
typename X>
608 template <
typename X>
620 bool isNull()
const noexcept {
return d ==
nullptr || d->strongref.loadRelaxed() == 0 || value ==
nullptr; }
725 {
return !(*
this ==
o); }
733 {
return !(*
this ==
o); }
735 template <
typename X>
738 template <
typename X>
751 template <
typename X>
754 template <
typename X>
758 template <
typename X>
761 template <
typename X>
790 inline void internalSet(Data *o, T *actual)
795 if (d && !d->weakref.deref())
803 inline T *internalData()
const noexcept
805 return d ==
nullptr || d->strongref.loadRelaxed() == 0 ?
nullptr : value;
814 template <
typename T>
838 inline void initializeFromSharedPointer(
const QSharedPointer<X> &ptr)
const
849template <
class T,
class X>
852 return ptr1.data() - ptr2.data();
854template <
class T,
class X>
857 return ptr1.data() - ptr2;
859template <
class T,
class X>
862 return ptr1 - ptr2.data();
869Q_INLINE_TEMPLATE size_t qHash(
const QSharedPointer<T> &ptr, size_t seed = 0)
871 return qHash(ptr.data(), seed);
876Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef()
const
878 return QWeakPointer<T>(*
this);
891 template <
class X,
class T>
899 template <
class X,
class T>
911template <
class X,
class T>
912Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(
const QSharedPointer<T> &src)
914 return qSharedPointerStaticCast<X>(src);
916template <
class X,
class T>
917Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(QSharedPointer<T> &&src)
919 return qSharedPointerStaticCast<X>(std::move(src));
921template <
class X,
class T>
922Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(
const QWeakPointer<T> &src)
924 return qSharedPointerCast<X>(src.toStrongRef());
926template <
class X,
class T>
927Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerStaticCast(
const QSharedPointer<T> &src)
929 X *ptr =
static_cast<X *>(src.data());
930 return QtSharedPointer::copyAndSetPointer(ptr, src);
932template <
class X,
class T>
933Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerStaticCast(QSharedPointer<T> &&src)
935 X *ptr =
static_cast<X *>(src.data());
936 return QtSharedPointer::movePointer(ptr, std::move(src));
938template <
class X,
class T>
939Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerStaticCast(
const QWeakPointer<T> &src)
941 return qSharedPointerStaticCast<X>(src.toStrongRef());
944template <
class X,
class T>
945Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(
const QSharedPointer<T> &src)
947 X *ptr =
dynamic_cast<X *>(src.data());
949 return QSharedPointer<X>();
950 return QtSharedPointer::copyAndSetPointer(ptr, src);
952template <
class X,
class T>
953Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(QSharedPointer<T> &&src)
955 X *ptr =
dynamic_cast<X *>(src.data());
957 return QSharedPointer<X>();
958 return QtSharedPointer::movePointer(ptr, std::move(src));
960template <
class X,
class T>
961Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(
const QWeakPointer<T> &src)
963 return qSharedPointerDynamicCast<X>(src.toStrongRef());
966template <
class X,
class T>
967Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(
const QSharedPointer<T> &src)
969 X *ptr =
const_cast<X *>(src.data());
970 return QtSharedPointer::copyAndSetPointer(ptr, src);
972template <
class X,
class T>
973Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(QSharedPointer<T> &&src)
975 X *ptr =
const_cast<X *>(src.data());
976 return QtSharedPointer::movePointer(ptr, std::move(src));
978template <
class X,
class T>
979Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(
const QWeakPointer<T> &src)
981 return qSharedPointerConstCast<X>(src.toStrongRef());
984template <
class X,
class T>
986QWeakPointer<X> qWeakPointerCast(
const QSharedPointer<T> &src)
988 return qSharedPointerCast<X>(src).toWeakRef();
992template <
class X,
class T>
993Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(
const QSharedPointer<T> &src)
995 X *ptr = qobject_cast<X *>(src.data());
997 return QSharedPointer<X>();
998 return QtSharedPointer::copyAndSetPointer(ptr, src);
1000template <
class X,
class T>
1001Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(QSharedPointer<T> &&src)
1003 X *ptr = qobject_cast<X *>(src.data());
1005 return QSharedPointer<X>();
1006 return QtSharedPointer::movePointer(ptr, std::move(src));
1008template <
class X,
class T>
1009Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(
const QWeakPointer<T> &src)
1011 return qSharedPointerObjectCast<X>(src.toStrongRef());
1014template <
class X,
class T>
1020template <
class X,
class T>
1026template <
class X,
class T>
1036QWeakPointer<
typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
1037qWeakPointerFromVariant(
const QVariant &variant)
1039 return QWeakPointer<T>(qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(QtSharedPointer::weakPointerFromVariant_internal(variant))));
1042QSharedPointer<
typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
1043qSharedPointerFromVariant(
const QVariant &variant)
1045 return qSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));
1050template <
typename X,
class T>
1053 using element_type =
typename std::shared_ptr<X>::element_type;
1054 if (
auto ptr = qobject_cast<element_type *>(src.get()))
1055 return std::shared_ptr<X>(src, ptr);
1056 return std::shared_ptr<X>();
1059template <
typename X,
class T>
1062 using element_type =
typename std::shared_ptr<X>::element_type;
1063 auto castResult = qobject_cast<element_type *>(src.get());
1069 return std::shared_ptr<X>(std::exchange(src,
nullptr), castResult);
1071 return std::shared_ptr<X>();
1074template <
typename X,
class T>
1077 return qobject_pointer_cast<X>(src);
1080template <
typename X,
class T>
1083 return qobject_pointer_cast<X>(
std::move(src));
void operator delete(void *)
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...
friend bool comparesEqual(const QSharedPointer &lhs, const QSharedPointer< X > &rhs) noexcept
T * operator->() const noexcept
Provides access to the shared pointer's members.
T & operator*() const
Provides access to the shared pointer's members.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
~QSharedPointer()
Destroys this QSharedPointer object.
bool owner_equal(const QSharedPointer< X > &other) const noexcept
operator bool() const noexcept
Returns true if the contained pointer is not \nullptr.
const value_type & const_reference
bool owner_before(const QSharedPointer< X > &other) const noexcept
friend QSharedPointer< X > QtSharedPointer::movePointer(X *ptr, QSharedPointer< Y > &&src)
friend Qt::strong_ordering compareThreeWay(const QSharedPointer &lhs, const QSharedPointer< X > &rhs) noexcept
const value_type * const_pointer
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
bool operator!() const noexcept
Returns true if this object refers to \nullptr.
QSharedPointer & operator=(const QSharedPointer &other) noexcept
Makes this object share other's pointer.
bool owner_equal(const QWeakPointer< X > &other) const noexcept
static QSharedPointer create(Args &&...arguments)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool owner_before(const QWeakPointer< X > &other) const noexcept
size_t owner_hash() const noexcept
friend QSharedPointer< X > QtSharedPointer::copyAndSetPointer(X *ptr, const QSharedPointer< Y > &src)
const value_type & const_reference
operator bool() const noexcept
Returns true if the contained pointer is not \nullptr.
~QWeakPointer()
Destroys this QWeakPointer object.
bool operator!() const noexcept
Returns true if this object refers to \nullptr.
const value_type * const_pointer
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
QSharedPointer< X > copyAndSetPointer(X *ptr, const QSharedPointer< Y > &src)
void executeDeleter(T *t, Deleter d)
Q_CORE_EXPORT void internalSafetyCheckRemove(const void *)
void executeDeleter(T *t, RetVal(Klass::*memberDeleter)())
Q_CORE_EXPORT void internalSafetyCheckAdd(const void *, const volatile void *)
QSharedPointer< X > movePointer(X *ptr, QSharedPointer< Y > &&src)
T qobject_cast(const QObject *object)
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 > qSharedPointerObjectCast(QSharedPointer< T > &&ptr)
QSharedPointer< X > qSharedPointerCast(const QSharedPointer< T > &ptr)
QSharedPointer< typename QtSharedPointer::RemovePointer< X >::Type > qobject_cast(const QWeakPointer< T > &src)
QSharedPointer< X > qSharedPointerDynamicCast(const QSharedPointer< T > &ptr)
Q_DECLARE_TYPEINFO_BODY(QSharedPointer< T >, Q_RELOCATABLE_TYPE)
Q_INLINE_TEMPLATE QSharedPointer< T >::difference_type operator-(const QSharedPointer< T > &ptr1, X *ptr2)
QSharedPointer< typename QtSharedPointer::RemovePointer< X >::Type > qobject_cast(const QSharedPointer< T > &src)
QSharedPointer< typename QtSharedPointer::RemovePointer< X >::Type > qobject_cast(QSharedPointer< T > &&src)
Q_INLINE_TEMPLATE QSharedPointer< X >::difference_type operator-(T *ptr1, const QSharedPointer< X > &ptr2)
std::shared_ptr< X > qSharedPointerObjectCast(const std::shared_ptr< T > &src)
std::shared_ptr< X > qobject_pointer_cast(std::shared_ptr< T > &&src)
std::shared_ptr< X > qSharedPointerObjectCast(std::shared_ptr< T > &&src)
std::shared_ptr< X > qobject_pointer_cast(const std::shared_ptr< T > &src)
QSharedPointer< X > qSharedPointerStaticCast(QSharedPointer< T > &&ptr)
Q_DECLARE_TYPEINFO_BODY(QWeakPointer< T >, Q_RELOCATABLE_TYPE)
QSharedPointer< X > qSharedPointerStaticCast(const QSharedPointer< T > &ptr)
void swap(QWeakPointer< T > &p1, QWeakPointer< T > &p2) noexcept
QSharedPointer< X > qSharedPointerConstCast(QSharedPointer< T > &&ptr)
QSharedPointer< X > qSharedPointerDynamicCast(QSharedPointer< T > &&ptr)
QSharedPointer< X > qSharedPointerCast(QSharedPointer< T > &&ptr)
void swap(QSharedPointer< T > &p1, QSharedPointer< T > &p2) noexcept
QSharedPointer< X > qSharedPointerObjectCast(const QSharedPointer< T > &ptr)
static T * internalData(const QWeakPointer< T > &p) noexcept
CustomDeleter(T *p, NormalDeleter)
CustomDeleter(T *p, Deleter d)
QBasicAtomicInt strongref
void(* DestroyerFn)(ExternalRefCountData *)
void * operator new(std::size_t, void *ptr) noexcept
ExternalRefCountData(Qt::Initialization)
ExternalRefCountData(DestroyerFn d)
QT6_ONLY(Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable);) inline void checkQObjectShared(...)
void operator delete(void *, void *)
void operator delete(void *ptr)
static void deleter(ExternalRefCountData *self)
static void noDeleter(ExternalRefCountData *)
ExternalRefCountData Parent
std::remove_cv< T >::type NoCVType
static ExternalRefCountData * create(NoCVType **ptr, DestroyerFn destroy)
static void safetyCheckDeleter(ExternalRefCountData *self)
static Self * create(T *ptr, Deleter userDeleter, DestroyerFn actualDeleter)
ExternalRefCountData BaseClass
CustomDeleter< T, Deleter > extra
static void safetyCheckDeleter(ExternalRefCountData *self)
static void deleter(ExternalRefCountData *self)
ExternalRefCountWithCustomDeleter Self