// Copyright (C) 2021 The Qt Company Ltd.// Copyright (C) 2022 Intel Corporation.// Copyright (C) 2019 Klar?lvdalens Datakonsult AB.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndefQ_QDOC#ifndefQSHAREDPOINTER_H#errorDo not include qsharedpointer_impl.h directly#endif#if0#pragmaqt_sync_skip_header_check#pragmaqt_sync_stop_processing#endif#if0// These macros are duplicated here to make syncqt not complain a about// this header, as we have a "qt_sync_stop_processing" below, which in turn// is here because this file contains a template mess and duplicates the// classes found in qsharedpointer.h
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
#pragmaqt_sync_stop_processing#endif#include<new>#include<QtCore/qatomic.h>#include<QtCore/qhashfunctions.h>#include<QtCore/qmetatype.h>// for IsPointerToTypeDerivedFromQObject#include<QtCore/qxptype_traits.h>#include<memory>
QT_BEGIN_NAMESPACE
classQObject;template<classT>
T qobject_cast(const QObject *object);//// forward declarations//template<classT>classQWeakPointer;template<classT>classQSharedPointer;template<classT>classQEnableSharedFromThis;classQVariant;template<classX,classT>
QSharedPointer<X>qSharedPointerCast(const QSharedPointer<T>&ptr);template<classX,classT>
QSharedPointer<X>qSharedPointerDynamicCast(const QSharedPointer<T>&ptr);template<classX,classT>
QSharedPointer<X>qSharedPointerConstCast(const QSharedPointer<T>&ptr);#ifndefQT_NO_QOBJECTtemplate<classX,classT>
QSharedPointer<X>qSharedPointerObjectCast(const QSharedPointer<T>&ptr);#endifnamespace QtPrivate {structEnableInternalData;}namespace QtSharedPointer {template<classT>classExternalRefCount;template<classX,classY> QSharedPointer<X>copyAndSetPointer(X * ptr,const QSharedPointer<Y>&src);// used in debug mode to verify the reuse of pointers
Q_CORE_EXPORT voidinternalSafetyCheckAdd(constvoid*,constvolatilevoid*);
Q_CORE_EXPORT voidinternalSafetyCheckRemove(constvoid*);template<classT,typenameKlass,typenameRetVal>inlinevoidexecuteDeleter(T *t,RetVal(Klass::*memberDeleter)()){if(t)(t->*memberDeleter)();}template<classT,typenameDeleter>inlinevoidexecuteDeleter(T *t, Deleter d){d(t);}structNormalDeleter{};// this uses partial template specializationtemplate<classT>structRemovePointer;template<classT>structRemovePointer<T *>{typedef T Type;};template<classT>structRemovePointer<QSharedPointer<T>>{typedef T Type;};template<classT>structRemovePointer<QWeakPointer<T>>{typedef T Type;};// This class is the d-pointer of QSharedPointer and QWeakPointer.//// It is a reference-counted reference counter. "strongref" is the inner// reference counter, and it tracks the lifetime of the pointer itself.// "weakref" is the outer reference counter and it tracks the lifetime of// the ExternalRefCountData object.//// The deleter is stored in the destroyer member and is always a pointer to// a static function in ExternalRefCountWithCustomDeleter or in// ExternalRefCountWithContiguousDatastructExternalRefCountData{typedefvoid(*DestroyerFn)(ExternalRefCountData *);
QBasicAtomicInt weakref;
QBasicAtomicInt strongref;
DestroyerFn destroyer;inlineExternalRefCountData(DestroyerFn d):destroyer(d){
strongref.storeRelaxed(1);
weakref.storeRelaxed(1);}inlineExternalRefCountData(Qt::Initialization){}~ExternalRefCountData(){Q_ASSERT(!weakref.loadRelaxed());Q_ASSERT(strongref.loadRelaxed()<=0);}voiddestroy(){destroyer(this);}#ifndefQT_NO_QOBJECT
Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *);QT6_ONLY(
Q_CORE_EXPORT voidsetQObjectShared(const QObject *,bool enable);)QT6_ONLY(Q_CORE_EXPORT voidcheckQObjectShared(const QObject *);)#endifinlinevoidcheckQObjectShared(...){}inlinevoidsetQObjectShared(...){}// Normally, only subclasses of ExternalRefCountData are allocated// One exception exists in getAndRef; that uses the global operator new// to prevent a mismatch with the custom operator deleteinlinevoid*operatornew(std::size_t)=delete;// placement newinlinevoid*operatornew(std::size_t,void*ptr)noexcept{return ptr;}inlinevoidoperatordelete(void*ptr){::operatordelete(ptr);}inlinevoidoperatordelete(void*,void*){}};// sizeof(ExternalRefCountData) = 12 (32-bit) / 16 (64-bit)template<classT,typenameDeleter>structCustomDeleter{
Deleter deleter;
T *ptr;CustomDeleter(T *p, Deleter d):deleter(d),ptr(p){}voidexecute(){executeDeleter(ptr, deleter);}};// sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*) + padding// for Deleter = stateless functor: 8 (32-bit) / 16 (64-bit) due to padding// for Deleter = function pointer: 8 (32-bit) / 16 (64-bit)// for Deleter = PMF: 12 (32-bit) / 24 (64-bit) (GCC)// This specialization of CustomDeleter for a deleter of type NormalDeleter// is an optimization: instead of storing a pointer to a function that does// the deleting, we simply delete the pointer ourselves.template<classT>structCustomDeleter<T, NormalDeleter>{
T *ptr;CustomDeleter(T *p, NormalDeleter):ptr(p){}voidexecute(){delete ptr;}};// sizeof(CustomDeleter specialization) = sizeof(void*)// This class extends ExternalRefCountData and implements// the static function that deletes the object. The pointer and the// custom deleter are kept in the "extra" member so we can construct// and destruct it independently of the full structure.template<classT,typenameDeleter>structExternalRefCountWithCustomDeleter:publicExternalRefCountData{typedef ExternalRefCountWithCustomDeleter Self;typedef ExternalRefCountData BaseClass;
CustomDeleter<T, Deleter> extra;staticinlinevoiddeleter(ExternalRefCountData *self){
Self *realself =static_cast<Self *>(self);
realself->extra.execute();// delete the deleter too
realself->extra.~CustomDeleter<T, Deleter>();}staticvoidsafetyCheckDeleter(ExternalRefCountData *self){internalSafetyCheckRemove(self);deleter(self);}staticinline Self *create(T *ptr, Deleter userDeleter, DestroyerFn actualDeleter){
Self *d =static_cast<Self *>(::operatornew(sizeof(Self)));// initialize the two sub-objectsnew(&d->extra)CustomDeleter<T, Deleter>(ptr, userDeleter);new(d)BaseClass(actualDeleter);// can't throwreturn d;}private:// prevent constructionExternalRefCountWithCustomDeleter()=delete;~ExternalRefCountWithCustomDeleter()=delete;Q_DISABLE_COPY(ExternalRefCountWithCustomDeleter)};// This class extends ExternalRefCountData and adds a "T"// member. That way, when the create() function is called, we allocate// memory for both QSharedPointer's d-pointer and the actual object being// tracked.template<classT>structExternalRefCountWithContiguousData:publicExternalRefCountData{typedef ExternalRefCountData Parent;typedeftypenamestd::remove_cv<T>::type NoCVType;
NoCVType data;staticvoiddeleter(ExternalRefCountData *self){
ExternalRefCountWithContiguousData *that =static_cast<ExternalRefCountWithContiguousData *>(self);
that->data.~T();Q_UNUSED(that);// MSVC warns if T has a trivial destructor}staticvoidsafetyCheckDeleter(ExternalRefCountData *self){internalSafetyCheckRemove(self);deleter(self);}staticvoidnoDeleter(ExternalRefCountData *){}staticinline ExternalRefCountData *create(NoCVType **ptr, DestroyerFn destroy){
ExternalRefCountWithContiguousData *d =static_cast<ExternalRefCountWithContiguousData *>(::operatornew(sizeof(ExternalRefCountWithContiguousData)));// initialize the d-pointer sub-object// leave d->data uninitializednew(d)Parent(destroy);// can't throw*ptr =&d->data;return d;}private:// prevent constructionExternalRefCountWithContiguousData()=delete;~ExternalRefCountWithContiguousData()=delete;Q_DISABLE_COPY(ExternalRefCountWithContiguousData)};#ifndefQT_NO_QOBJECT
Q_CORE_EXPORT QWeakPointer<QObject>weakPointerFromVariant_internal(const QVariant &variant);
Q_CORE_EXPORT QSharedPointer<QObject>sharedPointerFromVariant_internal(const QVariant &variant);#endif}// namespace QtSharedPointertemplate<classT>classQSharedPointer{typedef QtSharedPointer::ExternalRefCountData Data;template<typenameX>using IfCompatible =typenamestd::enable_if<std::is_convertible<X*, T*>::value,bool>::type;public:typedef T Type;typedef T element_type;typedef T value_type;typedef value_type *pointer;typedefconst value_type *const_pointer;typedef value_type &reference;typedefconst value_type &const_reference;typedef qptrdiff difference_type;
T *data()constnoexcept{return value;}
T *get()constnoexcept{return value;}boolisNull()constnoexcept{return!data();}explicitoperatorbool()constnoexcept{return!isNull();}booloperator!()constnoexcept{returnisNull();}
T &operator*()const{return*data();}
T *operator->()constnoexcept{returndata();}
Q_NODISCARD_CTOR
constexprQSharedPointer()noexcept:value(nullptr),d(nullptr){}~QSharedPointer(){deref();}
Q_NODISCARD_CTOR
constexprQSharedPointer(std::nullptr_t)noexcept:value(nullptr),d(nullptr){}template<classX, IfCompatible<X>=true>
Q_NODISCARD_CTOR
inlineexplicitQSharedPointer(X *ptr):value(ptr)// noexcept{internalConstruct(ptr,QtSharedPointer::NormalDeleter());}template<classX,typenameDeleter, IfCompatible<X>=true>
Q_NODISCARD_CTOR
inlineQSharedPointer(X *ptr, Deleter deleter):value(ptr)// throws{internalConstruct(ptr, deleter);}template<typenameDeleter>
Q_NODISCARD_CTOR
QSharedPointer(std::nullptr_t, Deleter deleter):value(nullptr){internalConstruct(static_cast<T *>(nullptr), deleter);}
Q_NODISCARD_CTOR
QSharedPointer(const QSharedPointer &other)noexcept:value(other.value),d(other.d){if(d)ref();}
QSharedPointer &operator=(const QSharedPointer &other)noexcept{
QSharedPointer copy(other);swap(copy);return*this;}
Q_NODISCARD_CTOR
QSharedPointer(QSharedPointer &&other)noexcept:value(other.value),d(other.d){
other.d =nullptr;
other.value =nullptr;}QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedPointer)template<classX, IfCompatible<X>=true>
Q_NODISCARD_CTOR
QSharedPointer(QSharedPointer<X>&&other)noexcept:value(other.value),d(other.d){
other.d =nullptr;
other.value =nullptr;}template<classX, IfCompatible<X>=true>
QSharedPointer &operator=(QSharedPointer<X>&&other)noexcept{
QSharedPointer moved(std::move(other));swap(moved);return*this;}template<classX, IfCompatible<X>=true>
Q_NODISCARD_CTOR
QSharedPointer(const QSharedPointer<X>&other)noexcept:value(other.value),d(other.d){if(d)ref();}template<classX, IfCompatible<X>=true>inline QSharedPointer &operator=(const QSharedPointer<X>&other){
QSharedPointer copy(other);swap(copy);return*this;}template<classX, IfCompatible<X>=true>
Q_NODISCARD_CTOR
inlineQSharedPointer(const QWeakPointer<X>&other):value(nullptr),d(nullptr){*this= other;}template<classX, IfCompatible<X>=true>inline QSharedPointer<T>&operator=(const QWeakPointer<X>&other){internalSet(other.d, other.value);return*this;}inlinevoidswap(QSharedPointer &other)noexcept{this->internalSwap(other);}inlinevoidreset(){clear();}inlinevoidreset(T *t){ QSharedPointer copy(t);swap(copy);}template<typenameDeleter>inlinevoidreset(T *t, Deleter deleter){ QSharedPointer copy(t, deleter);swap(copy);}template<classX>
QSharedPointer<X>staticCast()const{returnqSharedPointerCast<X, T>(*this);}template<classX>
QSharedPointer<X>dynamicCast()const{returnqSharedPointerDynamicCast<X, T>(*this);}template<classX>
QSharedPointer<X>constCast()const{returnqSharedPointerConstCast<X, T>(*this);}#ifndefQT_NO_QOBJECTtemplate<classX>
QSharedPointer<X>objectCast()const{returnqSharedPointerObjectCast<X, T>(*this);}#endifinlinevoidclear(){ QSharedPointer copy;swap(copy);}[[nodiscard]] QWeakPointer<T>toWeakRef()const;template<typename... Args>[[nodiscard]]static QSharedPointer create(Args &&...arguments){typedef QtSharedPointer::ExternalRefCountWithContiguousData<T> Private;#ifdefQT_SHAREDPOINTER_TRACK_POINTERStypenamePrivate::DestroyerFn destroy =&Private::safetyCheckDeleter;#elsetypenamePrivate::DestroyerFn destroy =&Private::deleter;#endiftypenamePrivate::DestroyerFn noDestroy =&Private::noDeleter;
QSharedPointer result(Qt::Uninitialized);typenamestd::remove_cv<T>::type *ptr;
result.d =Private::create(&ptr, noDestroy);// now initialize the datanew(ptr)T(std::forward<Args>(arguments)...);
result.value = ptr;
result.d->destroyer = destroy;
result.d->setQObjectShared(result.value,true);#ifdefQT_SHAREDPOINTER_TRACK_POINTERSinternalSafetyCheckAdd(result.d, result.value);#endif
result.enableSharedFromThis(result.data());return result;}#defineDECLARE_COMPARE_SET(T1, A1, T2, A2)\friendbooloperator==(T1, T2)noexcept\{return A1 == A2;}\friendbooloperator!=(T1, T2)noexcept\{return A1 != A2;}#defineDECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2)\template<typenameX>\friendbooloperator==(T1, T2)noexcept\{return A1 == A2;}\template<typenameX>\friendbooloperator!=(T1, T2)noexcept\{return A1 != A2;}DECLARE_TEMPLATE_COMPARE_SET(const QSharedPointer &p1, p1.data(),const QSharedPointer<X>&p2, p2.data())DECLARE_TEMPLATE_COMPARE_SET(const QSharedPointer &p1, p1.data(), X *ptr, ptr)DECLARE_TEMPLATE_COMPARE_SET(X *ptr, ptr,const QSharedPointer &p2, p2.data())DECLARE_COMPARE_SET(const QSharedPointer &p1, p1.data(), std::nullptr_t,nullptr)DECLARE_COMPARE_SET(std::nullptr_t,nullptr,const QSharedPointer &p2, p2.data())#undefDECLARE_TEMPLATE_COMPARE_SET#undefDECLARE_COMPARE_SETtemplate<typenameX>boolowner_before(const QSharedPointer<X>&other)constnoexcept{return std::less<>()(d, other.d);}template<typenameX>boolowner_before(const QWeakPointer<X>&other)constnoexcept{return std::less<>()(d, other.d);}template<typenameX>boolowner_equal(const QSharedPointer<X>&other)constnoexcept{return d == other.d;}template<typenameX>boolowner_equal(const QWeakPointer<X>&other)constnoexcept{return d == other.d;}
size_t owner_hash()constnoexcept{return std::hash<Data *>()(d);}private:
Q_NODISCARD_CTOR
explicitQSharedPointer(Qt::Initialization){}voidderef()noexcept{deref(d);}staticvoidderef(Data *dd)noexcept{if(!dd)return;if(!dd->strongref.deref()){
dd->destroy();}if(!dd->weakref.deref())delete dd;}template<classX>inlinevoidenableSharedFromThis(const QEnableSharedFromThis<X>*ptr){
ptr->initializeFromSharedPointer(constCast<typenamestd::remove_cv<T>::type>());}inlinevoidenableSharedFromThis(...){}template<typenameX,typenameDeleter>inlinevoidinternalConstruct(X *ptr, Deleter deleter){typedef QtSharedPointer::ExternalRefCountWithCustomDeleter<X, Deleter> Private;#ifdefQT_SHAREDPOINTER_TRACK_POINTERStypenamePrivate::DestroyerFn actualDeleter =&Private::safetyCheckDeleter;#elsetypenamePrivate::DestroyerFn actualDeleter =&Private::deleter;#endif
d =Private::create(ptr, deleter, actualDeleter);#ifdefQT_SHAREDPOINTER_TRACK_POINTERSinternalSafetyCheckAdd(d, ptr);#endifenableSharedFromThis(ptr);}voidinternalSwap(QSharedPointer &other)noexcept{qt_ptr_swap(d, other.d);qt_ptr_swap(this->value, other.value);}template<classX>friendclassQSharedPointer;template<classX>friendclassQWeakPointer;template<classX,classY>friend QSharedPointer<X>QtSharedPointer::copyAndSetPointer(X * ptr,const QSharedPointer<Y>&src);voidref()constnoexcept{ d->weakref.ref(); d->strongref.ref();}inlinevoidinternalSet(Data *o, T *actual){if(o){// increase the strongref, but never up from zero// or less (-1 is used by QWeakPointer on untracked QObject)int tmp = o->strongref.loadRelaxed();while(tmp >0){// try to increment from "tmp" to "tmp + 1"if(o->strongref.testAndSetRelaxed(tmp, tmp +1))break;// succeeded
tmp = o->strongref.loadRelaxed();// failed, try again}if(tmp >0)
o->weakref.ref();else
o =nullptr;}qt_ptr_swap(d, o);qt_ptr_swap(this->value, actual);if(!d || d->strongref.loadRelaxed()==0)this->value =nullptr;// dereference saved dataderef(o);}
Type *value;
Data *d;};template<classT>classQWeakPointer{typedef QtSharedPointer::ExternalRefCountData Data;template<typenameX>using IfCompatible =typenamestd::enable_if<std::is_convertible<X*, T*>::value,bool>::type;template<typenameX>using IfVirtualBase =typenamestd::enable_if<qxp::is_virtual_base_of_v<T, X>,bool>::type;template<typenameX>using IfNotVirtualBase =typenamestd::enable_if<!qxp::is_virtual_base_of_v<T, X>,bool>::type;public:typedef T element_type;typedef T value_type;typedef value_type *pointer;typedefconst value_type *const_pointer;typedef value_type &reference;typedefconst value_type &const_reference;typedef qptrdiff difference_type;boolisNull()constnoexcept{return d ==nullptr|| d->strongref.loadRelaxed()==0|| value ==nullptr;}explicitoperatorbool()constnoexcept{return!isNull();}booloperator!()constnoexcept{returnisNull();}
Q_NODISCARD_CTOR
constexprQWeakPointer()noexcept:d(nullptr),value(nullptr){}inline~QWeakPointer(){if(d &&!d->weakref.deref())delete d;}
Q_NODISCARD_CTOR
QWeakPointer(const QWeakPointer &other)noexcept:d(other.d),value(other.value){if(d) d->weakref.ref();}
Q_NODISCARD_CTOR
QWeakPointer(QWeakPointer &&other)noexcept:d(other.d),value(other.value){
other.d =nullptr;
other.value =nullptr;}QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QWeakPointer)template<classX, IfCompatible<X>=true, IfNotVirtualBase<X>=true>
Q_NODISCARD_CTOR
QWeakPointer(QWeakPointer<X>&&other)noexcept:d(std::exchange(other.d,nullptr)),value(std::exchange(other.value,nullptr)){}template<classX, IfCompatible<X>=true, IfVirtualBase<X>=true>
Q_NODISCARD_CTOR
QWeakPointer(QWeakPointer<X>&&other)noexcept:d(other.d),value(other.toStrongRef().get())// must go through QSharedPointer, see below{
other.d =nullptr;
other.value =nullptr;}template<classX, IfCompatible<X>=true>
QWeakPointer &operator=(QWeakPointer<X>&&other)noexcept{
QWeakPointer moved(std::move(other));swap(moved);return*this;}
QWeakPointer &operator=(const QWeakPointer &other)noexcept{
QWeakPointer copy(other);swap(copy);return*this;}voidswap(QWeakPointer &other)noexcept{qt_ptr_swap(this->d, other.d);qt_ptr_swap(this->value, other.value);}
Q_NODISCARD_CTOR
inlineQWeakPointer(const QSharedPointer<T>&o):d(o.d),value(o.data()){if(d) d->weakref.ref();}inline QWeakPointer &operator=(const QSharedPointer<T>&o){internalSet(o.d, o.value);return*this;}template<classX, IfCompatible<X>=true>
Q_NODISCARD_CTOR
inlineQWeakPointer(const QWeakPointer<X>&o):d(nullptr),value(nullptr){*this= o;}template<classX, IfCompatible<X>=true>inline QWeakPointer &operator=(const QWeakPointer<X>&o){// conversion between X and T could require access to the virtual table// so force the operation to go through QSharedPointer*this= o.toStrongRef();return*this;}template<classX, IfCompatible<X>=true>
Q_NODISCARD_CTOR
inlineQWeakPointer(const QSharedPointer<X>&o):d(nullptr),value(nullptr){*this= o;}template<classX, IfCompatible<X>=true>inline QWeakPointer &operator=(const QSharedPointer<X>&o){internalSet(o.d, o.data());return*this;}inlinevoidclear(){*this=QWeakPointer();}[[nodiscard]] QSharedPointer<T>toStrongRef()const{returnQSharedPointer<T>(*this);}// std::weak_ptr compatibility:[[nodiscard]] QSharedPointer<T>lock()const{returntoStrongRef();}template<classX>booloperator==(const QWeakPointer<X>&o)constnoexcept{return d == o.d && value ==static_cast<const T *>(o.value);}template<classX>booloperator!=(const QWeakPointer<X>&o)constnoexcept{return!(*this== o);}template<classX>booloperator==(const QSharedPointer<X>&o)constnoexcept{return d == o.d;}template<classX>booloperator!=(const QSharedPointer<X>&o)constnoexcept{return!(*this== o);}template<typenameX>friendbooloperator==(const QSharedPointer<X>&p1,const QWeakPointer &p2)noexcept{return p2 == p1;}template<typenameX>friendbooloperator!=(const QSharedPointer<X>&p1,const QWeakPointer &p2)noexcept{return p2 != p1;}friendbooloperator==(const QWeakPointer &p, std::nullptr_t){return p.isNull();}friendbooloperator==(std::nullptr_t,const QWeakPointer &p){return p.isNull();}friendbooloperator!=(const QWeakPointer &p, std::nullptr_t){return!p.isNull();}friendbooloperator!=(std::nullptr_t,const QWeakPointer &p){return!p.isNull();}template<typenameX>boolowner_before(const QWeakPointer<X>&other)constnoexcept{return std::less<>()(d, other.d);}template<typenameX>boolowner_before(const QSharedPointer<X>&other)constnoexcept{return std::less<>()(d, other.d);}template<typenameX>boolowner_equal(const QWeakPointer<X>&other)constnoexcept{return d == other.d;}template<typenameX>boolowner_equal(const QSharedPointer<X>&other)constnoexcept{return d == other.d;}
size_t owner_hash()constnoexcept{return std::hash<Data *>()(d);}private:friendstructQtPrivate::EnableInternalData;template<classX>friendclassQSharedPointer;template<classX>friendclassQWeakPointer;template<classX>friendclassQPointer;template<classX>inline QWeakPointer &assign(X *ptr){return*this=QWeakPointer<T>(ptr,true);}#ifndefQT_NO_QOBJECTtemplate<classX, IfCompatible<X>=true>
Q_NODISCARD_CTOR
inlineQWeakPointer(X *ptr,bool):d(ptr ?Data::getAndRef(ptr):nullptr),value(ptr){}#endifinlinevoidinternalSet(Data *o, T *actual){if(d == o)return;if(o)
o->weakref.ref();if(d &&!d->weakref.deref())delete d;
d = o;
value = actual;}// ### TODO - QTBUG-88102: remove all users of this API; no one should ever// access a weak pointer's data but the weak pointer itselfinline T *internalData()constnoexcept{return d ==nullptr|| d->strongref.loadRelaxed()==0?nullptr: value;}
Data *d;
T *value;};namespace QtPrivate {structEnableInternalData{template<typenameT>static T *internalData(const QWeakPointer<T>&p)noexcept{return p.internalData();}};// hack to delay name lookup to instantiation time by making// EnableInternalData a dependent name:template<typenameT>structEnableInternalDataWrap:EnableInternalData{};}template<classT>classQEnableSharedFromThis{protected:QEnableSharedFromThis()=default;QEnableSharedFromThis(const QEnableSharedFromThis &){}
QEnableSharedFromThis &operator=(const QEnableSharedFromThis &){return*this;}public:inline QSharedPointer<T>sharedFromThis(){returnQSharedPointer<T>(weakPointer);}inline QSharedPointer<const T>sharedFromThis()const{returnQSharedPointer<const T>(weakPointer);}private:template<classX>friendclassQSharedPointer;template<classX>inlinevoidinitializeFromSharedPointer(const QSharedPointer<X>&ptr)const{
weakPointer = ptr;}mutable QWeakPointer<T> weakPointer;};//// operator-//template<classT,classX>
Q_INLINE_TEMPLATE typenameQSharedPointer<T>::difference_type operator-(const QSharedPointer<T>&ptr1,const QSharedPointer<X>&ptr2){return ptr1.data()- ptr2.data();}template<classT,classX>
Q_INLINE_TEMPLATE typenameQSharedPointer<T>::difference_type operator-(const QSharedPointer<T>&ptr1, X *ptr2){return ptr1.data()- ptr2;}template<classT,classX>
Q_INLINE_TEMPLATE typenameQSharedPointer<X>::difference_type operator-(T *ptr1,const QSharedPointer<X>&ptr2){return ptr1 - ptr2.data();}//// operator<//template<classT,classX>
Q_INLINE_TEMPLATE booloperator<(const QSharedPointer<T>&ptr1,const QSharedPointer<X>&ptr2){using CT =typenamestd::common_type<T *, X *>::type;return std::less<CT>()(ptr1.data(), ptr2.data());}template<classT,classX>
Q_INLINE_TEMPLATE booloperator<(const QSharedPointer<T>&ptr1, X *ptr2){using CT =typenamestd::common_type<T *, X *>::type;return std::less<CT>()(ptr1.data(), ptr2);}template<classT,classX>
Q_INLINE_TEMPLATE booloperator<(T *ptr1,const QSharedPointer<X>&ptr2){using CT =typenamestd::common_type<T *, X *>::type;return std::less<CT>()(ptr1, ptr2.data());}//// qHash//template<classT>
Q_INLINE_TEMPLATE size_t qHash(const QSharedPointer<T>&ptr, size_t seed =0){returnqHash(ptr.data(), seed);}template<classT>
Q_INLINE_TEMPLATE QWeakPointer<T>QSharedPointer<T>::toWeakRef()const{returnQWeakPointer<T>(*this);}template<classT>inlinevoidswap(QSharedPointer<T>&p1, QSharedPointer<T>&p2)noexcept{ p1.swap(p2);}template<classT>inlinevoidswap(QWeakPointer<T>&p1, QWeakPointer<T>&p2)noexcept{ p1.swap(p2);}namespace QtSharedPointer {// helper functions:template<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>copyAndSetPointer(X *ptr,const QSharedPointer<T>&src){
QSharedPointer<X> result;
result.internalSet(src.d, ptr);return result;}}// cast operatorstemplate<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerCast(const QSharedPointer<T>&src){
X *ptr =static_cast<X *>(src.data());// if you get an error in this line, the cast is invalidreturnQtSharedPointer::copyAndSetPointer(ptr, src);}template<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerCast(const QWeakPointer<T>&src){returnqSharedPointerCast<X, T>(src.toStrongRef());}template<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerDynamicCast(const QSharedPointer<T>&src){
X *ptr =dynamic_cast<X *>(src.data());// if you get an error in this line, the cast is invalidif(!ptr)returnQSharedPointer<X>();returnQtSharedPointer::copyAndSetPointer(ptr, src);}template<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerDynamicCast(const QWeakPointer<T>&src){returnqSharedPointerDynamicCast<X, T>(src.toStrongRef());}template<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerConstCast(const QSharedPointer<T>&src){
X *ptr =const_cast<X *>(src.data());// if you get an error in this line, the cast is invalidreturnQtSharedPointer::copyAndSetPointer(ptr, src);}template<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerConstCast(const QWeakPointer<T>&src){returnqSharedPointerConstCast<X, T>(src.toStrongRef());}template<classX,classT>
Q_INLINE_TEMPLATE
QWeakPointer<X>qWeakPointerCast(const QSharedPointer<T>&src){returnqSharedPointerCast<X, T>(src).toWeakRef();}#ifndefQT_NO_QOBJECTtemplate<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerObjectCast(const QSharedPointer<T>&src){
X *ptr =qobject_cast<X *>(src.data());returnQtSharedPointer::copyAndSetPointer(ptr, src);}template<classX,classT>
Q_INLINE_TEMPLATE QSharedPointer<X>qSharedPointerObjectCast(const QWeakPointer<T>&src){returnqSharedPointerObjectCast<X>(src.toStrongRef());}template<classX,classT>inline QSharedPointer<typenameQtSharedPointer::RemovePointer<X>::Type>qobject_cast(const QSharedPointer<T>&src){return qSharedPointerObjectCast<typenameQtSharedPointer::RemovePointer<X>::Type, T>(src);}template<classX,classT>inline QSharedPointer<typenameQtSharedPointer::RemovePointer<X>::Type>qobject_cast(const QWeakPointer<T>&src){return qSharedPointerObjectCast<typenameQtSharedPointer::RemovePointer<X>::Type, T>(src);}/// ### TODO - QTBUG-88102: make this use toStrongRef() (once support for/// storing non-managed QObjects in QWeakPointer is removed)template<typenameT>
QWeakPointer<typenamestd::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>qWeakPointerFromVariant(const QVariant &variant){returnQWeakPointer<T>(qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(QtSharedPointer::weakPointerFromVariant_internal(variant))));}template<typenameT>
QSharedPointer<typenamestd::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>qSharedPointerFromVariant(const QVariant &variant){returnqSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));}// std::shared_ptr helperstemplate<typenameX,classT>
std::shared_ptr<X>qobject_pointer_cast(const std::shared_ptr<T>&src){using element_type =typenamestd::shared_ptr<X>::element_type;return std::shared_ptr<X>(src,qobject_cast<element_type *>(src.get()));}template<typenameX,classT>
std::shared_ptr<X>qobject_pointer_cast(std::shared_ptr<T>&&src){using element_type =typenamestd::shared_ptr<X>::element_type;auto castResult =qobject_cast<element_type *>(src.get());if(castResult){// C++2a's move aliasing constructor will leave src empty.// Before C++2a we don't really know if the compiler has support for it.// The move aliasing constructor is the resolution for LWG2996,// which does not impose a feature-testing macro. So: clear src.return std::shared_ptr<X>(std::exchange(src,nullptr), castResult);}return std::shared_ptr<X>();}template<typenameX,classT>
std::shared_ptr<X>qSharedPointerObjectCast(const std::shared_ptr<T>&src){returnqobject_pointer_cast<X>(src);}template<typenameX,classT>
std::shared_ptr<X>qSharedPointerObjectCast(std::shared_ptr<T>&&src){returnqobject_pointer_cast<X>(std::move(src));}#endiftemplate<typenameT>Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_RELOCATABLE_TYPE);template<typenameT>Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
#endif