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