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>
65template <
class X,
class T>
67template <
class X,
class T>
85 template <
class T,
typename Klass,
typename RetVal>
87 {
if (t) (t->*memberDeleter)(); }
88 template <
class T,
typename Deleter>
119 strongref.storeRelaxed(1);
120 weakref.storeRelaxed(1);
130 Q_CORE_EXPORT
void setQObjectShared(
const QObject *,
bool enable);
142 inline void *
operator new(
std::size_t,
void *ptr)
noexcept {
return ptr; }
148 template <
class T,
typename Deleter>
179 template <
class T,
typename Deleter>
188 Self *realself =
static_cast<
Self *>(self);
202 Self *d =
static_cast<
Self *>(::operator
new(
sizeof(
Self)));
212 ExternalRefCountWithCustomDeleter() =
delete;
213 ~ExternalRefCountWithCustomDeleter() =
delete;
257 ExternalRefCountWithContiguousData() =
delete;
258 ~ExternalRefCountWithContiguousData() =
delete;
271 template <
typename X>
272 using IfCompatible =
typename std::enable_if<
std::is_convertible<X*, T*>::value,
bool>::type;
284 T *
data()
const noexcept {
return value.get(); }
285 T *
get()
const noexcept {
return value.get(); }
435 template <
typename... Args>
439# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
440 typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter;
442 typename Private::DestroyerFn destroy = &Private::deleter;
444 typename Private::DestroyerFn noDestroy = &Private::noDeleter;
446 typename std::remove_cv<T>::type *ptr;
447 result.d = Private::create(&ptr, noDestroy);
450 new (ptr) T(
std::forward<Args>(arguments)...);
451 result.value.reset(ptr);
452 result.d->destroyer = destroy;
453 result.d->setQObjectShared(result.value.get(),
true);
454# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
455 internalSafetyCheckAdd(result.d, result.value.get());
457 result.enableSharedFromThis(result.data());
461 template <
typename X>
463 {
return std::less<>()(d, other.d); }
464 template <
typename X>
466 {
return std::less<>()(d, other.d); }
468 template <
typename X>
470 {
return d == other.d; }
471 template <
typename X>
473 {
return d == other.d; }
476 {
return std::hash<Data *>()(d); }
479 template <
typename X>
481 {
return lhs
.data() == rhs.data(); }
482 template <
typename X>
486 return Qt::compareThreeWay(lhs.value, rhs.data());
488 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG,
QSharedPointer<T>, QSharedPointer<X>,
490 template <
typename X>)
492 template <
typename X>
495 template <
typename X>
501 {
return lhs.
data() ==
nullptr; }
510 void deref()
noexcept
530 template <
typename X,
typename Deleter>
534# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
541#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
557 void ref()
const noexcept { d->weakref.ref(); d->strongref.ref(); }
559 inline void internalSet(Data *o, T *actual)
564 int tmp = o->strongref.loadRelaxed();
567 if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
569 tmp = o->strongref.loadRelaxed();
579 this->value.reset(actual);
580 if (!d || d->strongref.loadRelaxed() == 0)
581 this->value =
nullptr;
587 Qt::totally_ordered_wrapper<Type *> value;
595 template <
typename X>
601 template <
typename X>
604 template <
typename X>
616 bool isNull()
const noexcept {
return d ==
nullptr || d->strongref.loadRelaxed() == 0 || value ==
nullptr; }
721 {
return !(*
this ==
o); }
729 {
return !(*
this ==
o); }
731 template <
typename X>
734 template <
typename X>
747 template <
typename X>
750 template <
typename X>
754 template <
typename X>
757 template <
typename X>
786 inline void internalSet(Data *o, T *actual)
791 if (d && !d->weakref.deref())
799 inline T *internalData()
const noexcept
801 return d ==
nullptr || d->strongref.loadRelaxed() == 0 ?
nullptr : value;
810 template <
typename T>
834 inline void initializeFromSharedPointer(
const QSharedPointer<X> &ptr)
const
845template <
class T,
class X>
848 return ptr1.data() - ptr2.data();
850template <
class T,
class X>
853 return ptr1.data() - ptr2;
855template <
class T,
class X>
858 return ptr1 - ptr2.data();
865Q_INLINE_TEMPLATE size_t qHash(
const QSharedPointer<T> &ptr, size_t seed = 0)
867 return qHash(ptr.data(), seed);
872Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef()
const
874 return QWeakPointer<T>(*
this);
887 template <
class X,
class T>
895 template <
class X,
class T>
907template <
class X,
class T>
908Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(
const QSharedPointer<T> &src)
910 X *ptr =
static_cast<X *>(src.data());
911 return QtSharedPointer::copyAndSetPointer(ptr, src);
913template <
class X,
class T>
914Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(QSharedPointer<T> &&src)
916 X *ptr =
static_cast<X *>(src.data());
917 return QtSharedPointer::movePointer(ptr, std::move(src));
919template <
class X,
class T>
920Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(
const QWeakPointer<T> &src)
922 return qSharedPointerCast<X>(src.toStrongRef());
925template <
class X,
class T>
926Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(
const QSharedPointer<T> &src)
928 X *ptr =
dynamic_cast<X *>(src.data());
930 return QSharedPointer<X>();
931 return QtSharedPointer::copyAndSetPointer(ptr, src);
933template <
class X,
class T>
934Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(QSharedPointer<T> &&src)
936 X *ptr =
dynamic_cast<X *>(src.data());
938 return QSharedPointer<X>();
939 return QtSharedPointer::movePointer(ptr, std::move(src));
941template <
class X,
class T>
942Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(
const QWeakPointer<T> &src)
944 return qSharedPointerDynamicCast<X>(src.toStrongRef());
947template <
class X,
class T>
948Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(
const QSharedPointer<T> &src)
950 X *ptr =
const_cast<X *>(src.data());
951 return QtSharedPointer::copyAndSetPointer(ptr, src);
953template <
class X,
class T>
954Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(QSharedPointer<T> &&src)
956 X *ptr =
const_cast<X *>(src.data());
957 return QtSharedPointer::movePointer(ptr, std::move(src));
959template <
class X,
class T>
960Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(
const QWeakPointer<T> &src)
962 return qSharedPointerConstCast<X>(src.toStrongRef());
965template <
class X,
class T>
967QWeakPointer<X> qWeakPointerCast(
const QSharedPointer<T> &src)
969 return qSharedPointerCast<X>(src).toWeakRef();
973template <
class X,
class T>
974Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(
const QSharedPointer<T> &src)
976 X *ptr = qobject_cast<X *>(src.data());
978 return QSharedPointer<X>();
979 return QtSharedPointer::copyAndSetPointer(ptr, src);
981template <
class X,
class T>
982Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(QSharedPointer<T> &&src)
984 X *ptr = qobject_cast<X *>(src.data());
986 return QSharedPointer<X>();
987 return QtSharedPointer::movePointer(ptr, std::move(src));
989template <
class X,
class T>
990Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(
const QWeakPointer<T> &src)
992 return qSharedPointerObjectCast<X>(src.toStrongRef());
995template <
class X,
class T>
1001template <
class X,
class T>
1007template <
class X,
class T>
1017QWeakPointer<
typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
1018qWeakPointerFromVariant(
const QVariant &variant)
1020 return QWeakPointer<T>(qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(QtSharedPointer::weakPointerFromVariant_internal(variant))));
1023QSharedPointer<
typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
1024qSharedPointerFromVariant(
const QVariant &variant)
1026 return qSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));
1031template <
typename X,
class T>
1034 using element_type =
typename std::shared_ptr<X>::element_type;
1035 if (
auto ptr = qobject_cast<element_type *>(src.get()))
1036 return std::shared_ptr<X>(src, ptr);
1037 return std::shared_ptr<X>();
1040template <
typename X,
class T>
1043 using element_type =
typename std::shared_ptr<X>::element_type;
1044 auto castResult = qobject_cast<element_type *>(src.get());
1050 return std::shared_ptr<X>(std::exchange(src,
nullptr), castResult);
1052 return std::shared_ptr<X>();
1055template <
typename X,
class T>
1058 return qobject_pointer_cast<X>(src);
1061template <
typename X,
class T>
1064 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)
Q_DECLARE_TYPEINFO_BODY(QWeakPointer< T >, Q_RELOCATABLE_TYPE)
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