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