aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/ftw/qqmlrefcount_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/ftw/qqmlrefcount_p.h')
-rw-r--r--src/qml/qml/ftw/qqmlrefcount_p.h22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/qml/qml/ftw/qqmlrefcount_p.h b/src/qml/qml/ftw/qqmlrefcount_p.h
index 2914e6279c..8cd1cbdaf1 100644
--- a/src/qml/qml/ftw/qqmlrefcount_p.h
+++ b/src/qml/qml/ftw/qqmlrefcount_p.h
@@ -30,11 +30,10 @@ class Q_QML_PRIVATE_EXPORT QQmlRefCount
public:
inline QQmlRefCount();
inline void addref() const;
- inline void release() const;
inline int count() const;
private:
- inline virtual ~QQmlRefCount();
+ inline ~QQmlRefCount();
template <typename T> friend class QQmlRefCounted;
private:
@@ -44,8 +43,10 @@ private:
template <typename T>
class QQmlRefCounted : public QQmlRefCount
{
+public:
+ inline void release() const;
protected:
- ~QQmlRefCounted() = default;
+ inline ~QQmlRefCounted();
};
template<class T>
@@ -130,11 +131,22 @@ void QQmlRefCount::addref() const
refCount.ref();
}
-void QQmlRefCount::release() const
+template <typename T>
+void QQmlRefCounted<T>::release() const
{
+ static_assert(std::is_base_of_v<QQmlRefCounted, T>,
+ "QQmlRefCounted<T> must be a base of T (CRTP)");
Q_ASSERT(refCount.loadRelaxed() > 0);
if (!refCount.deref())
- delete this;
+ delete static_cast<const T *>(this);
+}
+
+template <typename T>
+QQmlRefCounted<T>::~QQmlRefCounted()
+{
+ static_assert(std::is_final_v<T> || std::has_virtual_destructor_v<T>,
+ "T must either be marked final or have a virtual dtor, "
+ "lest release() runs into UB.");
}
int QQmlRefCount::count() const