diff options
Diffstat (limited to 'src/corelib/tools/qsharedpointer_impl.h')
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 415 |
1 files changed, 182 insertions, 233 deletions
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index b6aad5ff73..456be91d03 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -1,42 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2022 Intel Corporation. +// Copyright (C) 2019 Klarälvdalens Datakonsult AB. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef Q_QDOC @@ -61,16 +26,18 @@ QT_END_NAMESPACE #include <new> #include <QtCore/qatomic.h> -#include <QtCore/qobject.h> // for qobject_cast -#if QT_DEPRECATED_SINCE(5, 6) -#include <QtCore/qhash.h> -#endif #include <QtCore/qhashfunctions.h> +#include <QtCore/qmetatype.h> // for IsPointerToTypeDerivedFromQObject +#include <QtCore/qxptype_traits.h> #include <memory> QT_BEGIN_NAMESPACE +class QObject; +template <class T> +T qobject_cast(const QObject *object); + // // forward declarations // @@ -107,7 +74,7 @@ namespace QtSharedPointer { template <class T, typename Klass, typename RetVal> inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)()) - { (t->*memberDeleter)(); } + { if (t) (t->*memberDeleter)(); } template <class T, typename Deleter> inline void executeDeleter(T *t, Deleter d) { d(t); } @@ -149,12 +116,20 @@ namespace QtSharedPointer { #ifndef QT_NO_QOBJECT Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *); + QT6_ONLY( Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable); - Q_CORE_EXPORT void checkQObjectShared(const QObject *); + ) + QT6_ONLY(Q_CORE_EXPORT void checkQObjectShared(const QObject *);) #endif inline void checkQObjectShared(...) { } inline void setQObjectShared(...) { } + // Normally, only subclasses of ExternalRefCountData are allocated + // One exception exists in getAndRef; that uses the global operator new + // to prevent a mismatch with the custom operator delete + inline void *operator new(std::size_t) = delete; + // placement new + inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; } inline void operator delete(void *ptr) { ::operator delete(ptr); } inline void operator delete(void *, void *) { } }; @@ -282,7 +257,6 @@ namespace QtSharedPointer { template <class T> class QSharedPointer { - typedef T *QSharedPointer:: *RestrictedBool; typedef QtSharedPointer::ExternalRefCountData Data; template <typename X> using IfCompatible = typename std::enable_if<std::is_convertible<X*, T*>::value, bool>::type; @@ -300,27 +274,34 @@ public: T *data() const noexcept { return value; } T *get() const noexcept { return value; } bool isNull() const noexcept { return !data(); } - operator RestrictedBool() const noexcept { return isNull() ? nullptr : &QSharedPointer::value; } + explicit operator bool() const noexcept { return !isNull(); } bool operator !() const noexcept { return isNull(); } T &operator*() const { return *data(); } T *operator->() const noexcept { return data(); } - Q_DECL_CONSTEXPR QSharedPointer() noexcept : value(nullptr), d(nullptr) { } + Q_NODISCARD_CTOR + constexpr QSharedPointer() noexcept : value(nullptr), d(nullptr) { } ~QSharedPointer() { deref(); } - Q_DECL_CONSTEXPR QSharedPointer(std::nullptr_t) noexcept : value(nullptr), d(nullptr) { } + Q_NODISCARD_CTOR + constexpr QSharedPointer(std::nullptr_t) noexcept : value(nullptr), d(nullptr) { } template <class X, IfCompatible<X> = true> + Q_NODISCARD_CTOR inline explicit QSharedPointer(X *ptr) : value(ptr) // noexcept { internalConstruct(ptr, QtSharedPointer::NormalDeleter()); } template <class X, typename Deleter, IfCompatible<X> = true> + Q_NODISCARD_CTOR inline QSharedPointer(X *ptr, Deleter deleter) : value(ptr) // throws { internalConstruct(ptr, deleter); } template <typename Deleter> - QSharedPointer(std::nullptr_t, Deleter) : value(nullptr), d(nullptr) { } + Q_NODISCARD_CTOR + QSharedPointer(std::nullptr_t, Deleter deleter) : value(nullptr) + { internalConstruct(static_cast<T *>(nullptr), deleter); } + Q_NODISCARD_CTOR QSharedPointer(const QSharedPointer &other) noexcept : value(other.value), d(other.d) { if (d) ref(); } QSharedPointer &operator=(const QSharedPointer &other) noexcept @@ -329,20 +310,17 @@ public: swap(copy); return *this; } + Q_NODISCARD_CTOR QSharedPointer(QSharedPointer &&other) noexcept : value(other.value), d(other.d) { other.d = nullptr; other.value = nullptr; } - QSharedPointer &operator=(QSharedPointer &&other) noexcept - { - QSharedPointer moved(std::move(other)); - swap(moved); - return *this; - } + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedPointer) template <class X, IfCompatible<X> = true> + Q_NODISCARD_CTOR QSharedPointer(QSharedPointer<X> &&other) noexcept : value(other.value), d(other.d) { @@ -359,6 +337,7 @@ public: } template <class X, IfCompatible<X> = true> + Q_NODISCARD_CTOR QSharedPointer(const QSharedPointer<X> &other) noexcept : value(other.value), d(other.d) { if (d) ref(); } @@ -371,6 +350,7 @@ public: } template <class X, IfCompatible<X> = true> + Q_NODISCARD_CTOR inline QSharedPointer(const QWeakPointer<X> &other) : value(nullptr), d(nullptr) { *this = other; } @@ -416,10 +396,10 @@ public: inline void clear() { QSharedPointer copy; swap(copy); } - QWeakPointer<T> toWeakRef() const; + [[nodiscard]] QWeakPointer<T> toWeakRef() const; template <typename... Args> - static QSharedPointer create(Args && ...arguments) + [[nodiscard]] static QSharedPointer create(Args && ...arguments) { typedef QtSharedPointer::ExternalRefCountWithContiguousData<T> Private; # ifdef QT_SHAREDPOINTER_TRACK_POINTERS @@ -444,7 +424,47 @@ public: return result; } +#define DECLARE_COMPARE_SET(T1, A1, T2, A2) \ + friend bool operator==(T1, T2) noexcept \ + { return A1 == A2; } \ + friend bool operator!=(T1, T2) noexcept \ + { return A1 != A2; } + +#define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2) \ + template <typename X> \ + friend bool operator==(T1, T2) noexcept \ + { return A1 == A2; } \ + template <typename X> \ + friend bool operator!=(T1, T2) noexcept \ + { return A1 != A2; } + + DECLARE_TEMPLATE_COMPARE_SET(const QSharedPointer &p1, p1.data(), const QSharedPointer<X> &p2, p2.data()) + DECLARE_TEMPLATE_COMPARE_SET(const QSharedPointer &p1, p1.data(), X *ptr, ptr) + DECLARE_TEMPLATE_COMPARE_SET(X *ptr, ptr, const QSharedPointer &p2, p2.data()) + DECLARE_COMPARE_SET(const QSharedPointer &p1, p1.data(), std::nullptr_t, nullptr) + DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QSharedPointer &p2, p2.data()) +#undef DECLARE_TEMPLATE_COMPARE_SET +#undef DECLARE_COMPARE_SET + + template <typename X> + bool owner_before(const QSharedPointer<X> &other) const noexcept + { return std::less<>()(d, other.d); } + template <typename X> + bool owner_before(const QWeakPointer<X> &other) const noexcept + { return std::less<>()(d, other.d); } + + template <typename X> + bool owner_equal(const QSharedPointer<X> &other) const noexcept + { return d == other.d; } + template <typename X> + bool owner_equal(const QWeakPointer<X> &other) const noexcept + { return d == other.d; } + + size_t owner_hash() const noexcept + { return std::hash<Data *>()(d); } + private: + Q_NODISCARD_CTOR explicit QSharedPointer(Qt::Initialization) {} void deref() noexcept @@ -470,11 +490,6 @@ private: template <typename X, typename Deleter> inline void internalConstruct(X *ptr, Deleter deleter) { - if (!ptr) { - d = nullptr; - return; - } - typedef QtSharedPointer::ExternalRefCountWithCustomDeleter<X, Deleter> Private; # ifdef QT_SHAREDPOINTER_TRACK_POINTERS typename Private::DestroyerFn actualDeleter = &Private::safetyCheckDeleter; @@ -486,23 +501,18 @@ private: #ifdef QT_SHAREDPOINTER_TRACK_POINTERS internalSafetyCheckAdd(d, ptr); #endif - d->setQObjectShared(ptr, true); enableSharedFromThis(ptr); } void internalSwap(QSharedPointer &other) noexcept { - qSwap(d, other.d); - qSwap(this->value, other.value); + qt_ptr_swap(d, other.d); + qt_ptr_swap(this->value, other.value); } -#if defined(Q_NO_TEMPLATE_FRIENDS) -public: -#else template <class X> friend class QSharedPointer; template <class X> friend class QWeakPointer; template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src); -#endif void ref() const noexcept { d->weakref.ref(); d->strongref.ref(); } inline void internalSet(Data *o, T *actual) @@ -518,16 +528,14 @@ public: tmp = o->strongref.loadRelaxed(); // failed, try again } - if (tmp > 0) { + if (tmp > 0) o->weakref.ref(); - } else { - o->checkQObjectShared(actual); + else o = nullptr; - } } - qSwap(d, o); - qSwap(this->value, actual); + qt_ptr_swap(d, o); + qt_ptr_swap(this->value, actual); if (!d || d->strongref.loadRelaxed() == 0) this->value = nullptr; @@ -542,11 +550,16 @@ public: template <class T> class QWeakPointer { - typedef T *QWeakPointer:: *RestrictedBool; typedef QtSharedPointer::ExternalRefCountData Data; template <typename X> using IfCompatible = typename std::enable_if<std::is_convertible<X*, T*>::value, bool>::type; + template <typename X> + using IfVirtualBase = typename std::enable_if<qxp::is_virtual_base_of_v<T, X>, bool>::type; + + template <typename X> + using IfNotVirtualBase = typename std::enable_if<!qxp::is_virtual_base_of_v<T, X>, bool>::type; + public: typedef T element_type; typedef T value_type; @@ -557,42 +570,50 @@ public: typedef qptrdiff difference_type; bool isNull() const noexcept { return d == nullptr || d->strongref.loadRelaxed() == 0 || value == nullptr; } - operator RestrictedBool() const noexcept { return isNull() ? nullptr : &QWeakPointer::value; } + explicit operator bool() const noexcept { return !isNull(); } bool operator !() const noexcept { return isNull(); } -#if QT_DEPRECATED_SINCE(5, 14) - QT_DEPRECATED_X("Use toStrongRef() instead, and data() on the returned QSharedPointer") - T *data() const noexcept { return internalData(); } -#endif - - inline QWeakPointer() noexcept : d(nullptr), value(nullptr) { } + Q_NODISCARD_CTOR + constexpr QWeakPointer() noexcept : d(nullptr), value(nullptr) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } -#ifndef QT_NO_QOBJECT - // special constructor that is enabled only if X derives from QObject -#if QT_DEPRECATED_SINCE(5, 0) - template <class X, IfCompatible<X> = true> - QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : nullptr), value(ptr) - { } -#endif -#endif - -#if QT_DEPRECATED_SINCE(5, 0) - template <class X, IfCompatible<X> = true> - QT_DEPRECATED inline QWeakPointer &operator=(X *ptr) - { return *this = QWeakPointer(ptr); } -#endif - + Q_NODISCARD_CTOR QWeakPointer(const QWeakPointer &other) noexcept : d(other.d), value(other.value) { if (d) d->weakref.ref(); } + Q_NODISCARD_CTOR QWeakPointer(QWeakPointer &&other) noexcept : d(other.d), value(other.value) { other.d = nullptr; other.value = nullptr; } - QWeakPointer &operator=(QWeakPointer &&other) noexcept - { QWeakPointer moved(std::move(other)); swap(moved); return *this; } + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QWeakPointer) + + template <class X, IfCompatible<X> = true, IfNotVirtualBase<X> = true> + Q_NODISCARD_CTOR + QWeakPointer(QWeakPointer<X> &&other) noexcept + : d(std::exchange(other.d, nullptr)), + value(std::exchange(other.value, nullptr)) + { + } + + template <class X, IfCompatible<X> = true, IfVirtualBase<X> = true> + Q_NODISCARD_CTOR + QWeakPointer(QWeakPointer<X> &&other) noexcept + : d(other.d), value(other.toStrongRef().get()) // must go through QSharedPointer, see below + { + other.d = nullptr; + other.value = nullptr; + } + + template <class X, IfCompatible<X> = true> + QWeakPointer &operator=(QWeakPointer<X> &&other) noexcept + { + QWeakPointer moved(std::move(other)); + swap(moved); + return *this; + } + QWeakPointer &operator=(const QWeakPointer &other) noexcept { QWeakPointer copy(other); @@ -602,10 +623,11 @@ public: void swap(QWeakPointer &other) noexcept { - qSwap(this->d, other.d); - qSwap(this->value, other.value); + qt_ptr_swap(this->d, other.d); + qt_ptr_swap(this->value, other.value); } + Q_NODISCARD_CTOR inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data()) { if (d) d->weakref.ref();} inline QWeakPointer &operator=(const QSharedPointer<T> &o) @@ -615,6 +637,7 @@ public: } template <class X, IfCompatible<X> = true> + Q_NODISCARD_CTOR inline QWeakPointer(const QWeakPointer<X> &o) : d(nullptr), value(nullptr) { *this = o; } @@ -627,15 +650,8 @@ public: return *this; } - template <class X> - bool operator==(const QWeakPointer<X> &o) const noexcept - { return d == o.d && value == static_cast<const T *>(o.value); } - - template <class X> - bool operator!=(const QWeakPointer<X> &o) const noexcept - { return !(*this == o); } - template <class X, IfCompatible<X> = true> + Q_NODISCARD_CTOR inline QWeakPointer(const QSharedPointer<X> &o) : d(nullptr), value(nullptr) { *this = o; } @@ -646,6 +662,20 @@ public: return *this; } + inline void clear() { *this = QWeakPointer(); } + + [[nodiscard]] QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); } + // std::weak_ptr compatibility: + [[nodiscard]] QSharedPointer<T> lock() const { return toStrongRef(); } + + template <class X> + bool operator==(const QWeakPointer<X> &o) const noexcept + { return d == o.d && value == static_cast<const T *>(o.value); } + + template <class X> + bool operator!=(const QWeakPointer<X> &o) const noexcept + { return !(*this == o); } + template <class X> bool operator==(const QSharedPointer<X> &o) const noexcept { return d == o.d; } @@ -654,31 +684,52 @@ public: bool operator!=(const QSharedPointer<X> &o) const noexcept { return !(*this == o); } - inline void clear() { *this = QWeakPointer(); } + template <typename X> + friend bool operator==(const QSharedPointer<X> &p1, const QWeakPointer &p2) noexcept + { return p2 == p1; } + template <typename X> + friend bool operator!=(const QSharedPointer<X> &p1, const QWeakPointer &p2) noexcept + { return p2 != p1; } + + friend bool operator==(const QWeakPointer &p, std::nullptr_t) + { return p.isNull(); } + friend bool operator==(std::nullptr_t, const QWeakPointer &p) + { return p.isNull(); } + friend bool operator!=(const QWeakPointer &p, std::nullptr_t) + { return !p.isNull(); } + friend bool operator!=(std::nullptr_t, const QWeakPointer &p) + { return !p.isNull(); } - inline QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); } - // std::weak_ptr compatibility: - inline QSharedPointer<T> lock() const { return toStrongRef(); } + template <typename X> + bool owner_before(const QWeakPointer<X> &other) const noexcept + { return std::less<>()(d, other.d); } + template <typename X> + bool owner_before(const QSharedPointer<X> &other) const noexcept + { return std::less<>()(d, other.d); } -#if defined(QWEAKPOINTER_ENABLE_ARROW) - inline T *operator->() const { return data(); } -#endif + template <typename X> + bool owner_equal(const QWeakPointer<X> &other) const noexcept + { return d == other.d; } + template <typename X> + bool owner_equal(const QSharedPointer<X> &other) const noexcept + { return d == other.d; } + + size_t owner_hash() const noexcept + { return std::hash<Data *>()(d); } private: friend struct QtPrivate::EnableInternalData; -#if defined(Q_NO_TEMPLATE_FRIENDS) -public: -#else template <class X> friend class QSharedPointer; + template <class X> friend class QWeakPointer; template <class X> friend class QPointer; -#endif template <class X> inline QWeakPointer &assign(X *ptr) - { return *this = QWeakPointer<X>(ptr, true); } + { return *this = QWeakPointer<T>(ptr, true); } #ifndef QT_NO_QOBJECT template <class X, IfCompatible<X> = true> + Q_NODISCARD_CTOR inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : nullptr), value(ptr) { } #endif @@ -694,8 +745,8 @@ public: value = actual; } - // ### Qt 6: remove users of this API; no one should ever access - // a weak pointer's data but the weak pointer itself + // ### TODO - QTBUG-88102: remove all users of this API; no one should ever + // access a weak pointer's data but the weak pointer itself inline T *internalData() const noexcept { return d == nullptr || d->strongref.loadRelaxed() == 0 ? nullptr : value; @@ -728,12 +779,8 @@ public: inline QSharedPointer<T> sharedFromThis() { return QSharedPointer<T>(weakPointer); } inline QSharedPointer<const T> sharedFromThis() const { return QSharedPointer<const T>(weakPointer); } -#ifndef Q_NO_TEMPLATE_FRIENDS private: template <class X> friend class QSharedPointer; -#else -public: -#endif template <class X> inline void initializeFromSharedPointer(const QSharedPointer<X> &ptr) const { @@ -744,100 +791,6 @@ public: }; // -// operator== and operator!= -// -template <class T, class X> -bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) noexcept -{ - return ptr1.data() == ptr2.data(); -} -template <class T, class X> -bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) noexcept -{ - return ptr1.data() != ptr2.data(); -} - -template <class T, class X> -bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2) noexcept -{ - return ptr1.data() == ptr2; -} -template <class T, class X> -bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2) noexcept -{ - return ptr1 == ptr2.data(); -} -template <class T, class X> -bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2) noexcept -{ - return !(ptr1 == ptr2); -} -template <class T, class X> -bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2) noexcept -{ - return !(ptr2 == ptr1); -} - -template <class T, class X> -bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) noexcept -{ - return ptr2 == ptr1; -} -template <class T, class X> -bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) noexcept -{ - return ptr2 != ptr1; -} - -template<class T> -inline bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t) noexcept -{ - return lhs.isNull(); -} - -template<class T> -inline bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t) noexcept -{ - return !lhs.isNull(); -} - -template<class T> -inline bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs) noexcept -{ - return rhs.isNull(); -} - -template<class T> -inline bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs) noexcept -{ - return !rhs.isNull(); -} - -template<class T> -inline bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t) noexcept -{ - return lhs.isNull(); -} - -template<class T> -inline bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t) noexcept -{ - return !lhs.isNull(); -} - -template<class T> -inline bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs) noexcept -{ - return rhs.isNull(); -} - -template<class T> -inline bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs) noexcept -{ - return !rhs.isNull(); -} - -// // operator- // template <class T, class X> @@ -884,7 +837,7 @@ Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2) template <class T> Q_INLINE_TEMPLATE size_t qHash(const QSharedPointer<T> &ptr, size_t seed = 0) { - return QT_PREPEND_NAMESPACE(qHash)(ptr.data(), seed); + return qHash(ptr.data(), seed); } @@ -985,8 +938,8 @@ qobject_cast(const QWeakPointer<T> &src) return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src); } -/// ### Qt 6: make this use toStrongRef() (once support for storing -/// non-managed QObjects in QWeakPointer is removed) +/// ### TODO - QTBUG-88102: make this use toStrongRef() (once support for +/// storing non-managed QObjects in QWeakPointer is removed) template<typename T> QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type> qWeakPointerFromVariant(const QVariant &variant) @@ -1015,15 +968,11 @@ std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src) using element_type = typename std::shared_ptr<X>::element_type; auto castResult = qobject_cast<element_type *>(src.get()); if (castResult) { - auto result = std::shared_ptr<X>(std::move(src), castResult); -#if __cplusplus <= 201703L // C++2a's move aliasing constructor will leave src empty. // Before C++2a we don't really know if the compiler has support for it. // The move aliasing constructor is the resolution for LWG2996, // which does not impose a feature-testing macro. So: clear src. - src.reset(); -#endif - return result; + return std::shared_ptr<X>(std::exchange(src, nullptr), castResult); } return std::shared_ptr<X>(); } @@ -1042,8 +991,8 @@ std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src) #endif -template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_MOVABLE_TYPE); -template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_MOVABLE_TYPE); +template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_RELOCATABLE_TYPE); +template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_RELOCATABLE_TYPE); QT_END_NAMESPACE |