From 48b6e192bbb023bb19c9de81c1e3d3ac3bca238c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 26 Jan 2021 10:21:39 +0100 Subject: QDeferredSharedPointer: lazy-load to determine isNull() If the content is not loaded, yet, the data is always null. If it is loaded, the result might be null. So, in order to know, we have to load. The same holds for deferred weak pointers, the hash functions, and the equality operators. Change-Id: I20eec58efe5da604187c34578ee40f769090c910 Reviewed-by: Fabian Kosmale --- src/qmlcompiler/qdeferredpointer_p.h | 58 ++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/qmlcompiler/qdeferredpointer_p.h b/src/qmlcompiler/qdeferredpointer_p.h index 6125b90afd..56672b2a9f 100644 --- a/src/qmlcompiler/qdeferredpointer_p.h +++ b/src/qmlcompiler/qdeferredpointer_p.h @@ -77,11 +77,7 @@ public: operator QSharedPointer() const { - if (m_factory && m_factory->isValid()) { - Factory localFactory; - std::swap(localFactory, *m_factory); // Swap before executing, to avoid recursion - const_cast &>(*m_data) = localFactory.create(); - } + lazyLoad(); return m_data; } @@ -90,7 +86,12 @@ public: T &operator*() const { return QSharedPointer(*this).operator*(); } T *operator->() const { return QSharedPointer(*this).operator->(); } - bool isNull() const { return m_data.isNull(); } + bool isNull() const + { + lazyLoad(); + return m_data.isNull(); + } + explicit operator bool() const noexcept { return !isNull(); } bool operator !() const noexcept { return isNull(); } @@ -98,11 +99,14 @@ public: friend size_t qHash(const QDeferredSharedPointer &ptr, size_t seed = 0) { + ptr.lazyLoad(); return qHashMulti(seed, ptr.m_factory, ptr.m_data); } friend bool operator==(const QDeferredSharedPointer &a, const QDeferredSharedPointer &b) { + a.lazyLoad(); + b.lazyLoad(); return a.m_factory == b.m_factory && a.m_data == b.m_data; } @@ -114,6 +118,15 @@ public: private: friend class QDeferredWeakPointer; + void lazyLoad() const + { + if (m_factory && m_factory->isValid()) { + Factory localFactory; + std::swap(localFactory, *m_factory); // Swap before executing, to avoid recursion + const_cast &>(*m_data) = localFactory.create(); + } + } + QSharedPointer m_data; QSharedPointer m_factory; }; @@ -137,15 +150,7 @@ public: operator QWeakPointer() const { - if (m_factory) { - auto factory = m_factory.toStrongRef(); - if (factory->isValid()) { - Factory localFactory; - std::swap(localFactory, *factory); // Swap before executing, to avoid recursion - const_cast &>(*(m_data.toStrongRef())) - = localFactory.create(); - } - } + lazyLoad(); return m_data; } @@ -161,7 +166,12 @@ public: return QWeakPointer(*this).toStrongRef(); } - bool isNull() const { return m_data.isNull(); } + bool isNull() const + { + lazyLoad(); + return m_data.isNull(); + } + explicit operator bool() const noexcept { return !isNull(); } bool operator !() const noexcept { return isNull(); } @@ -169,11 +179,14 @@ public: friend size_t qHash(const QDeferredWeakPointer &ptr, size_t seed = 0) { + ptr.lazyLoad(); return qHashMulti(seed, ptr.m_factory, ptr.m_data); } friend bool operator==(const QDeferredWeakPointer &a, const QDeferredWeakPointer &b) { + a.lazyLoad(); + b.lazyLoad(); return a.m_factory == b.m_factory && a.m_data == b.m_data; } @@ -183,6 +196,19 @@ public: } private: + void lazyLoad() const + { + if (m_factory) { + auto factory = m_factory.toStrongRef(); + if (factory->isValid()) { + Factory localFactory; + std::swap(localFactory, *factory); // Swap before executing, to avoid recursion + const_cast &>(*(m_data.toStrongRef())) + = localFactory.create(); + } + } + } + QWeakPointer m_data; QWeakPointer m_factory; }; -- cgit v1.2.3