File indexing completed on 2025-01-18 10:07:36
0001
0002
0003
0004
0005
0006 #ifndef Q_QDOC
0007
0008 #ifndef QSHAREDPOINTER_H
0009 #error Do not include qsharedpointer_impl.h directly
0010 #endif
0011
0012 #if 0
0013 #pragma qt_sync_skip_header_check
0014 #pragma qt_sync_stop_processing
0015 #endif
0016
0017 #if 0
0018
0019
0020
0021
0022 QT_BEGIN_NAMESPACE
0023 QT_END_NAMESPACE
0024 #pragma qt_sync_stop_processing
0025 #endif
0026
0027 #include <new>
0028 #include <QtCore/qatomic.h>
0029 #include <QtCore/qhashfunctions.h>
0030 #include <QtCore/qmetatype.h> // for IsPointerToTypeDerivedFromQObject
0031 #include <QtCore/qxptype_traits.h>
0032
0033 #include <memory>
0034
0035 QT_BEGIN_NAMESPACE
0036
0037 class QObject;
0038 template <class T>
0039 T qobject_cast(const QObject *object);
0040
0041
0042
0043
0044 template <class T> class QWeakPointer;
0045 template <class T> class QSharedPointer;
0046 template <class T> class QEnableSharedFromThis;
0047
0048 class QVariant;
0049
0050 template <class X, class T>
0051 QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &ptr);
0052 template <class X, class T>
0053 QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &ptr);
0054 template <class X, class T>
0055 QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &ptr);
0056
0057 #ifndef QT_NO_QOBJECT
0058 template <class X, class T>
0059 QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &ptr);
0060 #endif
0061
0062 namespace QtPrivate {
0063 struct EnableInternalData;
0064 }
0065
0066 namespace QtSharedPointer {
0067 template <class T> class ExternalRefCount;
0068
0069 template <class X, class Y> QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
0070
0071
0072 Q_CORE_EXPORT void internalSafetyCheckAdd(const void *, const volatile void *);
0073 Q_CORE_EXPORT void internalSafetyCheckRemove(const void *);
0074
0075 template <class T, typename Klass, typename RetVal>
0076 inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)())
0077 { if (t) (t->*memberDeleter)(); }
0078 template <class T, typename Deleter>
0079 inline void executeDeleter(T *t, Deleter d)
0080 { d(t); }
0081 struct NormalDeleter {};
0082
0083
0084 template <class T> struct RemovePointer;
0085 template <class T> struct RemovePointer<T *> { typedef T Type; };
0086 template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; };
0087 template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; };
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 struct ExternalRefCountData
0100 {
0101 typedef void (*DestroyerFn)(ExternalRefCountData *);
0102 QBasicAtomicInt weakref;
0103 QBasicAtomicInt strongref;
0104 DestroyerFn destroyer;
0105
0106 inline ExternalRefCountData(DestroyerFn d)
0107 : destroyer(d)
0108 {
0109 strongref.storeRelaxed(1);
0110 weakref.storeRelaxed(1);
0111 }
0112 inline ExternalRefCountData(Qt::Initialization) { }
0113 ~ExternalRefCountData() { Q_ASSERT(!weakref.loadRelaxed()); Q_ASSERT(strongref.loadRelaxed() <= 0); }
0114
0115 void destroy() { destroyer(this); }
0116
0117 #ifndef QT_NO_QOBJECT
0118 Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *);
0119 QT6_ONLY(
0120 Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable);
0121 )
0122 QT6_ONLY(Q_CORE_EXPORT void checkQObjectShared(const QObject *);)
0123 #endif
0124 inline void checkQObjectShared(...) { }
0125 inline void setQObjectShared(...) { }
0126
0127
0128
0129
0130 inline void *operator new(std::size_t) = delete;
0131
0132 inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
0133 inline void operator delete(void *ptr) { ::operator delete(ptr); }
0134 inline void operator delete(void *, void *) { }
0135 };
0136
0137
0138 template <class T, typename Deleter>
0139 struct CustomDeleter
0140 {
0141 Deleter deleter;
0142 T *ptr;
0143
0144 CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {}
0145 void execute() { executeDeleter(ptr, deleter); }
0146 };
0147
0148
0149
0150
0151
0152
0153
0154
0155 template <class T>
0156 struct CustomDeleter<T, NormalDeleter>
0157 {
0158 T *ptr;
0159
0160 CustomDeleter(T *p, NormalDeleter) : ptr(p) {}
0161 void execute() { delete ptr; }
0162 };
0163
0164
0165
0166
0167
0168
0169 template <class T, typename Deleter>
0170 struct ExternalRefCountWithCustomDeleter: public ExternalRefCountData
0171 {
0172 typedef ExternalRefCountWithCustomDeleter Self;
0173 typedef ExternalRefCountData BaseClass;
0174 CustomDeleter<T, Deleter> extra;
0175
0176 static inline void deleter(ExternalRefCountData *self)
0177 {
0178 Self *realself = static_cast<Self *>(self);
0179 realself->extra.execute();
0180
0181
0182 realself->extra.~CustomDeleter<T, Deleter>();
0183 }
0184 static void safetyCheckDeleter(ExternalRefCountData *self)
0185 {
0186 internalSafetyCheckRemove(self);
0187 deleter(self);
0188 }
0189
0190 static inline Self *create(T *ptr, Deleter userDeleter, DestroyerFn actualDeleter)
0191 {
0192 Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
0193
0194
0195 new (&d->extra) CustomDeleter<T, Deleter>(ptr, userDeleter);
0196 new (d) BaseClass(actualDeleter);
0197
0198 return d;
0199 }
0200 private:
0201
0202 ExternalRefCountWithCustomDeleter() = delete;
0203 ~ExternalRefCountWithCustomDeleter() = delete;
0204 Q_DISABLE_COPY(ExternalRefCountWithCustomDeleter)
0205 };
0206
0207
0208
0209
0210
0211 template <class T>
0212 struct ExternalRefCountWithContiguousData: public ExternalRefCountData
0213 {
0214 typedef ExternalRefCountData Parent;
0215 typedef typename std::remove_cv<T>::type NoCVType;
0216 NoCVType data;
0217
0218 static void deleter(ExternalRefCountData *self)
0219 {
0220 ExternalRefCountWithContiguousData *that =
0221 static_cast<ExternalRefCountWithContiguousData *>(self);
0222 that->data.~T();
0223 Q_UNUSED(that);
0224 }
0225 static void safetyCheckDeleter(ExternalRefCountData *self)
0226 {
0227 internalSafetyCheckRemove(self);
0228 deleter(self);
0229 }
0230 static void noDeleter(ExternalRefCountData *) { }
0231
0232 static inline ExternalRefCountData *create(NoCVType **ptr, DestroyerFn destroy)
0233 {
0234 ExternalRefCountWithContiguousData *d =
0235 static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
0236
0237
0238
0239 new (d) Parent(destroy);
0240
0241 *ptr = &d->data;
0242 return d;
0243 }
0244
0245 private:
0246
0247 ExternalRefCountWithContiguousData() = delete;
0248 ~ExternalRefCountWithContiguousData() = delete;
0249 Q_DISABLE_COPY(ExternalRefCountWithContiguousData)
0250 };
0251
0252 #ifndef QT_NO_QOBJECT
0253 Q_CORE_EXPORT QWeakPointer<QObject> weakPointerFromVariant_internal(const QVariant &variant);
0254 Q_CORE_EXPORT QSharedPointer<QObject> sharedPointerFromVariant_internal(const QVariant &variant);
0255 #endif
0256 }
0257
0258 template <class T> class QSharedPointer
0259 {
0260 typedef QtSharedPointer::ExternalRefCountData Data;
0261 template <typename X>
0262 using IfCompatible = typename std::enable_if<std::is_convertible<X*, T*>::value, bool>::type;
0263
0264 public:
0265 typedef T Type;
0266 typedef T element_type;
0267 typedef T value_type;
0268 typedef value_type *pointer;
0269 typedef const value_type *const_pointer;
0270 typedef value_type &reference;
0271 typedef const value_type &const_reference;
0272 typedef qptrdiff difference_type;
0273
0274 T *data() const noexcept { return value; }
0275 T *get() const noexcept { return value; }
0276 bool isNull() const noexcept { return !data(); }
0277 explicit operator bool() const noexcept { return !isNull(); }
0278 bool operator !() const noexcept { return isNull(); }
0279 T &operator*() const { return *data(); }
0280 T *operator->() const noexcept { return data(); }
0281
0282 Q_NODISCARD_CTOR
0283 constexpr QSharedPointer() noexcept : value(nullptr), d(nullptr) { }
0284 ~QSharedPointer() { deref(); }
0285
0286 Q_NODISCARD_CTOR
0287 constexpr QSharedPointer(std::nullptr_t) noexcept : value(nullptr), d(nullptr) { }
0288
0289 template <class X, IfCompatible<X> = true>
0290 Q_NODISCARD_CTOR
0291 inline explicit QSharedPointer(X *ptr) : value(ptr)
0292 { internalConstruct(ptr, QtSharedPointer::NormalDeleter()); }
0293
0294 template <class X, typename Deleter, IfCompatible<X> = true>
0295 Q_NODISCARD_CTOR
0296 inline QSharedPointer(X *ptr, Deleter deleter) : value(ptr)
0297 { internalConstruct(ptr, deleter); }
0298
0299 template <typename Deleter>
0300 Q_NODISCARD_CTOR
0301 QSharedPointer(std::nullptr_t, Deleter deleter) : value(nullptr)
0302 { internalConstruct(static_cast<T *>(nullptr), deleter); }
0303
0304 Q_NODISCARD_CTOR
0305 QSharedPointer(const QSharedPointer &other) noexcept : value(other.value), d(other.d)
0306 { if (d) ref(); }
0307 QSharedPointer &operator=(const QSharedPointer &other) noexcept
0308 {
0309 QSharedPointer copy(other);
0310 swap(copy);
0311 return *this;
0312 }
0313 Q_NODISCARD_CTOR
0314 QSharedPointer(QSharedPointer &&other) noexcept
0315 : value(other.value), d(other.d)
0316 {
0317 other.d = nullptr;
0318 other.value = nullptr;
0319 }
0320 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedPointer)
0321
0322 template <class X, IfCompatible<X> = true>
0323 Q_NODISCARD_CTOR
0324 QSharedPointer(QSharedPointer<X> &&other) noexcept
0325 : value(other.value), d(other.d)
0326 {
0327 other.d = nullptr;
0328 other.value = nullptr;
0329 }
0330
0331 template <class X, IfCompatible<X> = true>
0332 QSharedPointer &operator=(QSharedPointer<X> &&other) noexcept
0333 {
0334 QSharedPointer moved(std::move(other));
0335 swap(moved);
0336 return *this;
0337 }
0338
0339 template <class X, IfCompatible<X> = true>
0340 Q_NODISCARD_CTOR
0341 QSharedPointer(const QSharedPointer<X> &other) noexcept : value(other.value), d(other.d)
0342 { if (d) ref(); }
0343
0344 template <class X, IfCompatible<X> = true>
0345 inline QSharedPointer &operator=(const QSharedPointer<X> &other)
0346 {
0347 QSharedPointer copy(other);
0348 swap(copy);
0349 return *this;
0350 }
0351
0352 template <class X, IfCompatible<X> = true>
0353 Q_NODISCARD_CTOR
0354 inline QSharedPointer(const QWeakPointer<X> &other) : value(nullptr), d(nullptr)
0355 { *this = other; }
0356
0357 template <class X, IfCompatible<X> = true>
0358 inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
0359 { internalSet(other.d, other.value); return *this; }
0360
0361 inline void swap(QSharedPointer &other) noexcept
0362 { this->internalSwap(other); }
0363
0364 inline void reset() { clear(); }
0365 inline void reset(T *t)
0366 { QSharedPointer copy(t); swap(copy); }
0367 template <typename Deleter>
0368 inline void reset(T *t, Deleter deleter)
0369 { QSharedPointer copy(t, deleter); swap(copy); }
0370
0371 template <class X>
0372 QSharedPointer<X> staticCast() const
0373 {
0374 return qSharedPointerCast<X, T>(*this);
0375 }
0376
0377 template <class X>
0378 QSharedPointer<X> dynamicCast() const
0379 {
0380 return qSharedPointerDynamicCast<X, T>(*this);
0381 }
0382
0383 template <class X>
0384 QSharedPointer<X> constCast() const
0385 {
0386 return qSharedPointerConstCast<X, T>(*this);
0387 }
0388
0389 #ifndef QT_NO_QOBJECT
0390 template <class X>
0391 QSharedPointer<X> objectCast() const
0392 {
0393 return qSharedPointerObjectCast<X, T>(*this);
0394 }
0395 #endif
0396
0397 inline void clear() { QSharedPointer copy; swap(copy); }
0398
0399 [[nodiscard]] QWeakPointer<T> toWeakRef() const;
0400
0401 template <typename... Args>
0402 [[nodiscard]] static QSharedPointer create(Args && ...arguments)
0403 {
0404 typedef QtSharedPointer::ExternalRefCountWithContiguousData<T> Private;
0405 # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
0406 typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter;
0407 # else
0408 typename Private::DestroyerFn destroy = &Private::deleter;
0409 # endif
0410 typename Private::DestroyerFn noDestroy = &Private::noDeleter;
0411 QSharedPointer result(Qt::Uninitialized);
0412 typename std::remove_cv<T>::type *ptr;
0413 result.d = Private::create(&ptr, noDestroy);
0414
0415
0416 new (ptr) T(std::forward<Args>(arguments)...);
0417 result.value = ptr;
0418 result.d->destroyer = destroy;
0419 result.d->setQObjectShared(result.value, true);
0420 # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
0421 internalSafetyCheckAdd(result.d, result.value);
0422 # endif
0423 result.enableSharedFromThis(result.data());
0424 return result;
0425 }
0426
0427 #define DECLARE_COMPARE_SET(T1, A1, T2, A2) \
0428 friend bool operator==(T1, T2) noexcept \
0429 { return A1 == A2; } \
0430 friend bool operator!=(T1, T2) noexcept \
0431 { return A1 != A2; }
0432
0433 #define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2) \
0434 template <typename X> \
0435 friend bool operator==(T1, T2) noexcept \
0436 { return A1 == A2; } \
0437 template <typename X> \
0438 friend bool operator!=(T1, T2) noexcept \
0439 { return A1 != A2; }
0440
0441 DECLARE_TEMPLATE_COMPARE_SET(const QSharedPointer &p1, p1.data(), const QSharedPointer<X> &p2, p2.data())
0442 DECLARE_TEMPLATE_COMPARE_SET(const QSharedPointer &p1, p1.data(), X *ptr, ptr)
0443 DECLARE_TEMPLATE_COMPARE_SET(X *ptr, ptr, const QSharedPointer &p2, p2.data())
0444 DECLARE_COMPARE_SET(const QSharedPointer &p1, p1.data(), std::nullptr_t, nullptr)
0445 DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QSharedPointer &p2, p2.data())
0446 #undef DECLARE_TEMPLATE_COMPARE_SET
0447 #undef DECLARE_COMPARE_SET
0448
0449 template <typename X>
0450 bool owner_before(const QSharedPointer<X> &other) const noexcept
0451 { return std::less<>()(d, other.d); }
0452 template <typename X>
0453 bool owner_before(const QWeakPointer<X> &other) const noexcept
0454 { return std::less<>()(d, other.d); }
0455
0456 template <typename X>
0457 bool owner_equal(const QSharedPointer<X> &other) const noexcept
0458 { return d == other.d; }
0459 template <typename X>
0460 bool owner_equal(const QWeakPointer<X> &other) const noexcept
0461 { return d == other.d; }
0462
0463 size_t owner_hash() const noexcept
0464 { return std::hash<Data *>()(d); }
0465
0466 private:
0467 Q_NODISCARD_CTOR
0468 explicit QSharedPointer(Qt::Initialization) {}
0469
0470 void deref() noexcept
0471 { deref(d); }
0472 static void deref(Data *dd) noexcept
0473 {
0474 if (!dd) return;
0475 if (!dd->strongref.deref()) {
0476 dd->destroy();
0477 }
0478 if (!dd->weakref.deref())
0479 delete dd;
0480 }
0481
0482 template <class X>
0483 inline void enableSharedFromThis(const QEnableSharedFromThis<X> *ptr)
0484 {
0485 ptr->initializeFromSharedPointer(constCast<typename std::remove_cv<T>::type>());
0486 }
0487
0488 inline void enableSharedFromThis(...) {}
0489
0490 template <typename X, typename Deleter>
0491 inline void internalConstruct(X *ptr, Deleter deleter)
0492 {
0493 typedef QtSharedPointer::ExternalRefCountWithCustomDeleter<X, Deleter> Private;
0494 # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
0495 typename Private::DestroyerFn actualDeleter = &Private::safetyCheckDeleter;
0496 # else
0497 typename Private::DestroyerFn actualDeleter = &Private::deleter;
0498 # endif
0499 d = Private::create(ptr, deleter, actualDeleter);
0500
0501 #ifdef QT_SHAREDPOINTER_TRACK_POINTERS
0502 internalSafetyCheckAdd(d, ptr);
0503 #endif
0504 enableSharedFromThis(ptr);
0505 }
0506
0507 void internalSwap(QSharedPointer &other) noexcept
0508 {
0509 qt_ptr_swap(d, other.d);
0510 qt_ptr_swap(this->value, other.value);
0511 }
0512
0513 template <class X> friend class QSharedPointer;
0514 template <class X> friend class QWeakPointer;
0515 template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
0516 void ref() const noexcept { d->weakref.ref(); d->strongref.ref(); }
0517
0518 inline void internalSet(Data *o, T *actual)
0519 {
0520 if (o) {
0521
0522
0523 int tmp = o->strongref.loadRelaxed();
0524 while (tmp > 0) {
0525
0526 if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
0527 break;
0528 tmp = o->strongref.loadRelaxed();
0529 }
0530
0531 if (tmp > 0)
0532 o->weakref.ref();
0533 else
0534 o = nullptr;
0535 }
0536
0537 qt_ptr_swap(d, o);
0538 qt_ptr_swap(this->value, actual);
0539 if (!d || d->strongref.loadRelaxed() == 0)
0540 this->value = nullptr;
0541
0542
0543 deref(o);
0544 }
0545
0546 Type *value;
0547 Data *d;
0548 };
0549
0550 template <class T>
0551 class QWeakPointer
0552 {
0553 typedef QtSharedPointer::ExternalRefCountData Data;
0554 template <typename X>
0555 using IfCompatible = typename std::enable_if<std::is_convertible<X*, T*>::value, bool>::type;
0556
0557 template <typename X>
0558 using IfVirtualBase = typename std::enable_if<qxp::is_virtual_base_of_v<T, X>, bool>::type;
0559
0560 template <typename X>
0561 using IfNotVirtualBase = typename std::enable_if<!qxp::is_virtual_base_of_v<T, X>, bool>::type;
0562
0563 public:
0564 typedef T element_type;
0565 typedef T value_type;
0566 typedef value_type *pointer;
0567 typedef const value_type *const_pointer;
0568 typedef value_type &reference;
0569 typedef const value_type &const_reference;
0570 typedef qptrdiff difference_type;
0571
0572 bool isNull() const noexcept { return d == nullptr || d->strongref.loadRelaxed() == 0 || value == nullptr; }
0573 explicit operator bool() const noexcept { return !isNull(); }
0574 bool operator !() const noexcept { return isNull(); }
0575
0576 Q_NODISCARD_CTOR
0577 constexpr QWeakPointer() noexcept : d(nullptr), value(nullptr) { }
0578 inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
0579
0580 Q_NODISCARD_CTOR
0581 QWeakPointer(const QWeakPointer &other) noexcept : d(other.d), value(other.value)
0582 { if (d) d->weakref.ref(); }
0583 Q_NODISCARD_CTOR
0584 QWeakPointer(QWeakPointer &&other) noexcept
0585 : d(other.d), value(other.value)
0586 {
0587 other.d = nullptr;
0588 other.value = nullptr;
0589 }
0590 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QWeakPointer)
0591
0592 template <class X, IfCompatible<X> = true, IfNotVirtualBase<X> = true>
0593 Q_NODISCARD_CTOR
0594 QWeakPointer(QWeakPointer<X> &&other) noexcept
0595 : d(std::exchange(other.d, nullptr)),
0596 value(std::exchange(other.value, nullptr))
0597 {
0598 }
0599
0600 template <class X, IfCompatible<X> = true, IfVirtualBase<X> = true>
0601 Q_NODISCARD_CTOR
0602 QWeakPointer(QWeakPointer<X> &&other) noexcept
0603 : d(other.d), value(other.toStrongRef().get())
0604 {
0605 other.d = nullptr;
0606 other.value = nullptr;
0607 }
0608
0609 template <class X, IfCompatible<X> = true>
0610 QWeakPointer &operator=(QWeakPointer<X> &&other) noexcept
0611 {
0612 QWeakPointer moved(std::move(other));
0613 swap(moved);
0614 return *this;
0615 }
0616
0617 QWeakPointer &operator=(const QWeakPointer &other) noexcept
0618 {
0619 QWeakPointer copy(other);
0620 swap(copy);
0621 return *this;
0622 }
0623
0624 void swap(QWeakPointer &other) noexcept
0625 {
0626 qt_ptr_swap(this->d, other.d);
0627 qt_ptr_swap(this->value, other.value);
0628 }
0629
0630 Q_NODISCARD_CTOR
0631 inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data())
0632 { if (d) d->weakref.ref();}
0633 inline QWeakPointer &operator=(const QSharedPointer<T> &o)
0634 {
0635 internalSet(o.d, o.value);
0636 return *this;
0637 }
0638
0639 template <class X, IfCompatible<X> = true>
0640 Q_NODISCARD_CTOR
0641 inline QWeakPointer(const QWeakPointer<X> &o) : d(nullptr), value(nullptr)
0642 { *this = o; }
0643
0644 template <class X, IfCompatible<X> = true>
0645 inline QWeakPointer &operator=(const QWeakPointer<X> &o)
0646 {
0647
0648
0649 *this = o.toStrongRef();
0650 return *this;
0651 }
0652
0653 template <class X, IfCompatible<X> = true>
0654 Q_NODISCARD_CTOR
0655 inline QWeakPointer(const QSharedPointer<X> &o) : d(nullptr), value(nullptr)
0656 { *this = o; }
0657
0658 template <class X, IfCompatible<X> = true>
0659 inline QWeakPointer &operator=(const QSharedPointer<X> &o)
0660 {
0661 internalSet(o.d, o.data());
0662 return *this;
0663 }
0664
0665 inline void clear() { *this = QWeakPointer(); }
0666
0667 [[nodiscard]] QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); }
0668
0669 [[nodiscard]] QSharedPointer<T> lock() const { return toStrongRef(); }
0670
0671 template <class X>
0672 bool operator==(const QWeakPointer<X> &o) const noexcept
0673 { return d == o.d && value == static_cast<const T *>(o.value); }
0674
0675 template <class X>
0676 bool operator!=(const QWeakPointer<X> &o) const noexcept
0677 { return !(*this == o); }
0678
0679 template <class X>
0680 bool operator==(const QSharedPointer<X> &o) const noexcept
0681 { return d == o.d; }
0682
0683 template <class X>
0684 bool operator!=(const QSharedPointer<X> &o) const noexcept
0685 { return !(*this == o); }
0686
0687 template <typename X>
0688 friend bool operator==(const QSharedPointer<X> &p1, const QWeakPointer &p2) noexcept
0689 { return p2 == p1; }
0690 template <typename X>
0691 friend bool operator!=(const QSharedPointer<X> &p1, const QWeakPointer &p2) noexcept
0692 { return p2 != p1; }
0693
0694 friend bool operator==(const QWeakPointer &p, std::nullptr_t)
0695 { return p.isNull(); }
0696 friend bool operator==(std::nullptr_t, const QWeakPointer &p)
0697 { return p.isNull(); }
0698 friend bool operator!=(const QWeakPointer &p, std::nullptr_t)
0699 { return !p.isNull(); }
0700 friend bool operator!=(std::nullptr_t, const QWeakPointer &p)
0701 { return !p.isNull(); }
0702
0703 template <typename X>
0704 bool owner_before(const QWeakPointer<X> &other) const noexcept
0705 { return std::less<>()(d, other.d); }
0706 template <typename X>
0707 bool owner_before(const QSharedPointer<X> &other) const noexcept
0708 { return std::less<>()(d, other.d); }
0709
0710 template <typename X>
0711 bool owner_equal(const QWeakPointer<X> &other) const noexcept
0712 { return d == other.d; }
0713 template <typename X>
0714 bool owner_equal(const QSharedPointer<X> &other) const noexcept
0715 { return d == other.d; }
0716
0717 size_t owner_hash() const noexcept
0718 { return std::hash<Data *>()(d); }
0719
0720 private:
0721 friend struct QtPrivate::EnableInternalData;
0722 template <class X> friend class QSharedPointer;
0723 template <class X> friend class QWeakPointer;
0724 template <class X> friend class QPointer;
0725
0726 template <class X>
0727 inline QWeakPointer &assign(X *ptr)
0728 { return *this = QWeakPointer<T>(ptr, true); }
0729
0730 #ifndef QT_NO_QOBJECT
0731 template <class X, IfCompatible<X> = true>
0732 Q_NODISCARD_CTOR
0733 inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : nullptr), value(ptr)
0734 { }
0735 #endif
0736
0737 inline void internalSet(Data *o, T *actual)
0738 {
0739 if (d == o) return;
0740 if (o)
0741 o->weakref.ref();
0742 if (d && !d->weakref.deref())
0743 delete d;
0744 d = o;
0745 value = actual;
0746 }
0747
0748
0749
0750 inline T *internalData() const noexcept
0751 {
0752 return d == nullptr || d->strongref.loadRelaxed() == 0 ? nullptr : value;
0753 }
0754
0755 Data *d;
0756 T *value;
0757 };
0758
0759 namespace QtPrivate {
0760 struct EnableInternalData {
0761 template <typename T>
0762 static T *internalData(const QWeakPointer<T> &p) noexcept { return p.internalData(); }
0763 };
0764
0765
0766 template <typename T>
0767 struct EnableInternalDataWrap : EnableInternalData {};
0768 }
0769
0770 template <class T>
0771 class QEnableSharedFromThis
0772 {
0773 protected:
0774 QEnableSharedFromThis() = default;
0775 QEnableSharedFromThis(const QEnableSharedFromThis &) {}
0776 QEnableSharedFromThis &operator=(const QEnableSharedFromThis &) { return *this; }
0777
0778 public:
0779 inline QSharedPointer<T> sharedFromThis() { return QSharedPointer<T>(weakPointer); }
0780 inline QSharedPointer<const T> sharedFromThis() const { return QSharedPointer<const T>(weakPointer); }
0781
0782 private:
0783 template <class X> friend class QSharedPointer;
0784 template <class X>
0785 inline void initializeFromSharedPointer(const QSharedPointer<X> &ptr) const
0786 {
0787 weakPointer = ptr;
0788 }
0789
0790 mutable QWeakPointer<T> weakPointer;
0791 };
0792
0793
0794
0795
0796 template <class T, class X>
0797 Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
0798 {
0799 return ptr1.data() - ptr2.data();
0800 }
0801 template <class T, class X>
0802 Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2)
0803 {
0804 return ptr1.data() - ptr2;
0805 }
0806 template <class T, class X>
0807 Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2)
0808 {
0809 return ptr1 - ptr2.data();
0810 }
0811
0812
0813
0814
0815 template <class T, class X>
0816 Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
0817 {
0818 using CT = typename std::common_type<T *, X *>::type;
0819 return std::less<CT>()(ptr1.data(), ptr2.data());
0820 }
0821 template <class T, class X>
0822 Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2)
0823 {
0824 using CT = typename std::common_type<T *, X *>::type;
0825 return std::less<CT>()(ptr1.data(), ptr2);
0826 }
0827 template <class T, class X>
0828 Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
0829 {
0830 using CT = typename std::common_type<T *, X *>::type;
0831 return std::less<CT>()(ptr1, ptr2.data());
0832 }
0833
0834
0835
0836
0837 template <class T>
0838 Q_INLINE_TEMPLATE size_t qHash(const QSharedPointer<T> &ptr, size_t seed = 0)
0839 {
0840 return qHash(ptr.data(), seed);
0841 }
0842
0843
0844 template <class T>
0845 Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
0846 {
0847 return QWeakPointer<T>(*this);
0848 }
0849
0850 template <class T>
0851 inline void swap(QSharedPointer<T> &p1, QSharedPointer<T> &p2) noexcept
0852 { p1.swap(p2); }
0853
0854 template <class T>
0855 inline void swap(QWeakPointer<T> &p1, QWeakPointer<T> &p2) noexcept
0856 { p1.swap(p2); }
0857
0858 namespace QtSharedPointer {
0859
0860 template <class X, class T>
0861 Q_INLINE_TEMPLATE QSharedPointer<X> copyAndSetPointer(X *ptr, const QSharedPointer<T> &src)
0862 {
0863 QSharedPointer<X> result;
0864 result.internalSet(src.d, ptr);
0865 return result;
0866 }
0867 }
0868
0869
0870 template <class X, class T>
0871 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
0872 {
0873 X *ptr = static_cast<X *>(src.data());
0874 return QtSharedPointer::copyAndSetPointer(ptr, src);
0875 }
0876 template <class X, class T>
0877 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &src)
0878 {
0879 return qSharedPointerCast<X, T>(src.toStrongRef());
0880 }
0881
0882 template <class X, class T>
0883 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
0884 {
0885 X *ptr = dynamic_cast<X *>(src.data());
0886 if (!ptr)
0887 return QSharedPointer<X>();
0888 return QtSharedPointer::copyAndSetPointer(ptr, src);
0889 }
0890 template <class X, class T>
0891 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
0892 {
0893 return qSharedPointerDynamicCast<X, T>(src.toStrongRef());
0894 }
0895
0896 template <class X, class T>
0897 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
0898 {
0899 X *ptr = const_cast<X *>(src.data());
0900 return QtSharedPointer::copyAndSetPointer(ptr, src);
0901 }
0902 template <class X, class T>
0903 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
0904 {
0905 return qSharedPointerConstCast<X, T>(src.toStrongRef());
0906 }
0907
0908 template <class X, class T>
0909 Q_INLINE_TEMPLATE
0910 QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
0911 {
0912 return qSharedPointerCast<X, T>(src).toWeakRef();
0913 }
0914
0915 #ifndef QT_NO_QOBJECT
0916 template <class X, class T>
0917 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
0918 {
0919 X *ptr = qobject_cast<X *>(src.data());
0920 return QtSharedPointer::copyAndSetPointer(ptr, src);
0921 }
0922 template <class X, class T>
0923 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
0924 {
0925 return qSharedPointerObjectCast<X>(src.toStrongRef());
0926 }
0927
0928 template <class X, class T>
0929 inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
0930 qobject_cast(const QSharedPointer<T> &src)
0931 {
0932 return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
0933 }
0934 template <class X, class T>
0935 inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
0936 qobject_cast(const QWeakPointer<T> &src)
0937 {
0938 return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
0939 }
0940
0941
0942
0943 template<typename T>
0944 QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
0945 qWeakPointerFromVariant(const QVariant &variant)
0946 {
0947 return QWeakPointer<T>(qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(QtSharedPointer::weakPointerFromVariant_internal(variant))));
0948 }
0949 template<typename T>
0950 QSharedPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
0951 qSharedPointerFromVariant(const QVariant &variant)
0952 {
0953 return qSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));
0954 }
0955
0956
0957
0958 template <typename X, class T>
0959 std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
0960 {
0961 using element_type = typename std::shared_ptr<X>::element_type;
0962 return std::shared_ptr<X>(src, qobject_cast<element_type *>(src.get()));
0963 }
0964
0965 template <typename X, class T>
0966 std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
0967 {
0968 using element_type = typename std::shared_ptr<X>::element_type;
0969 auto castResult = qobject_cast<element_type *>(src.get());
0970 if (castResult) {
0971
0972
0973
0974
0975 return std::shared_ptr<X>(std::exchange(src, nullptr), castResult);
0976 }
0977 return std::shared_ptr<X>();
0978 }
0979
0980 template <typename X, class T>
0981 std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
0982 {
0983 return qobject_pointer_cast<X>(src);
0984 }
0985
0986 template <typename X, class T>
0987 std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
0988 {
0989 return qobject_pointer_cast<X>(std::move(src));
0990 }
0991
0992 #endif
0993
0994 template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_RELOCATABLE_TYPE);
0995 template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_RELOCATABLE_TYPE);
0996
0997
0998 QT_END_NAMESPACE
0999
1000 #endif