From 448b2a5d838d082c66ab649cc7b71c31761bf409 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 4 Mar 2020 14:54:54 +0100 Subject: Replace QFlagPointer with QTaggedPointer The latter has the advantage of allowing the use of a real type for the tag, instead of the generic flag/flag2 boolean accessors. Change-Id: Icc9e854ce4af3eb5808a4bed45aa22f377e223da Reviewed-by: Fabian Kosmale --- src/qml/qml/ftw/qfieldlist_p.h | 118 ++++++++---------------- src/qml/qml/ftw/qflagpointer_p.h | 152 ------------------------------- src/qml/qml/ftw/qlazilyallocated_p.h | 67 ++++++-------- src/qml/qml/ftw/qlinkedstringhash_p.h | 2 +- src/qml/qml/ftw/qstringhash_p.h | 14 ++- src/qml/qml/qqmlabstractbinding_p.h | 31 +++++-- src/qml/qml/qqmlbinding.cpp | 10 +- src/qml/qml/qqmlbinding_p.h | 8 +- src/qml/qml/qqmlcontext_p.h | 1 + src/qml/qml/qqmlcontextdata_p.h | 11 ++- src/qml/qml/qqmljavascriptexpression.cpp | 2 +- src/qml/qml/qqmljavascriptexpression_p.h | 22 ++++- src/qml/qml/qqmlpropertycachevector_p.h | 17 +++- src/qml/qml/qqmlvmemetaobject.cpp | 11 ++- src/quick/items/qquickanimatedsprite.cpp | 2 +- src/quick/items/qquickitem.cpp | 5 +- src/quick/items/qquickitem_p.h | 15 ++- 17 files changed, 169 insertions(+), 319 deletions(-) diff --git a/src/qml/qml/ftw/qfieldlist_p.h b/src/qml/qml/ftw/qfieldlist_p.h index 2bf07fb20d..66602daab2 100644 --- a/src/qml/qml/ftw/qfieldlist_p.h +++ b/src/qml/qml/ftw/qfieldlist_p.h @@ -52,11 +52,12 @@ // #include +#include #include // QForwardFieldList is a super simple linked list that can only prepend -template +template> class QForwardFieldList { public: @@ -72,17 +73,10 @@ public: static inline N *next(N *v); - inline bool flag() const; - inline void setFlag(); - inline void clearFlag(); - inline void setFlagValue(bool); - - inline bool flag2() const; - inline void setFlag2(); - inline void clearFlag2(); - inline void setFlag2Value(bool); + inline Tag tag() const; + inline void setTag(Tag t); private: - QFlagPointer _first; + QTaggedPointer _first; }; // QFieldList is a simple linked list, that can append and prepend and also @@ -108,8 +102,10 @@ public: inline void insertAfter(N *, QFieldList &); inline void copyAndClear(QFieldList &); - inline void copyAndClearAppend(QForwardFieldList &); - inline void copyAndClearPrepend(QForwardFieldList &); + template + inline void copyAndClearAppend(QForwardFieldList &); + template + inline void copyAndClearPrepend(QForwardFieldList &); static inline N *next(N *v); @@ -124,21 +120,21 @@ private: quint32 _count:31; }; -template -QForwardFieldList::QForwardFieldList() +template +QForwardFieldList::QForwardFieldList() { } -template -N *QForwardFieldList::first() const +template +N *QForwardFieldList::first() const { - return *_first; + return _first.data(); } -template -N *QForwardFieldList::takeFirst() +template +N *QForwardFieldList::takeFirst() { - N *value = *_first; + N *value = _first.data(); if (value) { _first = next(value); value->*nextMember = nullptr; @@ -146,85 +142,49 @@ N *QForwardFieldList::takeFirst() return value; } -template -void QForwardFieldList::prepend(N *v) +template +void QForwardFieldList::prepend(N *v) { Q_ASSERT(v->*nextMember == nullptr); - v->*nextMember = *_first; + v->*nextMember = _first.data(); _first = v; } -template -bool QForwardFieldList::isEmpty() const +template +bool QForwardFieldList::isEmpty() const { return _first.isNull(); } -template -bool QForwardFieldList::isOne() const +template +bool QForwardFieldList::isOne() const { - return *_first && _first->*nextMember == 0; + return _first.data() && _first->*nextMember == 0; } -template -bool QForwardFieldList::isMany() const +template +bool QForwardFieldList::isMany() const { - return *_first && _first->*nextMember != 0; + return _first.data() && _first->*nextMember != 0; } -template -N *QForwardFieldList::next(N *v) +template +N *QForwardFieldList::next(N *v) { Q_ASSERT(v); return v->*nextMember; } -template -bool QForwardFieldList::flag() const -{ - return _first.flag(); -} - -template -void QForwardFieldList::setFlag() -{ - _first.setFlag(); -} - -template -void QForwardFieldList::clearFlag() -{ - _first.clearFlag(); -} - -template -void QForwardFieldList::setFlagValue(bool v) -{ - _first.setFlagValue(v); -} - -template -bool QForwardFieldList::flag2() const -{ - return _first.flag2(); -} - -template -void QForwardFieldList::setFlag2() +template +Tag QForwardFieldList::tag() const { - _first.setFlag2(); + return _first.tag(); } -template -void QForwardFieldList::clearFlag2() -{ - _first.clearFlag2(); -} - -template -void QForwardFieldList::setFlag2Value(bool v) +template +void QForwardFieldList::setTag(Tag t) { - _first.setFlag2Value(v); + _first.setTag(t); } template @@ -380,7 +340,8 @@ void QFieldList::copyAndClear(QFieldList &o) } template -void QFieldList::copyAndClearAppend(QForwardFieldList &o) +template +void QFieldList::copyAndClearAppend(QForwardFieldList &o) { _first = 0; _last = 0; @@ -389,7 +350,8 @@ void QFieldList::copyAndClearAppend(QForwardFieldList -void QFieldList::copyAndClearPrepend(QForwardFieldList &o) +template +void QFieldList::copyAndClearPrepend(QForwardFieldList &o) { _first = nullptr; _last = nullptr; diff --git a/src/qml/qml/ftw/qflagpointer_p.h b/src/qml/qml/ftw/qflagpointer_p.h index a10e57aeca..5cdf973352 100644 --- a/src/qml/qml/ftw/qflagpointer_p.h +++ b/src/qml/qml/ftw/qflagpointer_p.h @@ -66,43 +66,6 @@ template <> struct QFlagPointerAlignment }; } -template -class QFlagPointer { -public: - inline QFlagPointer(); - inline QFlagPointer(T *); - inline QFlagPointer(const QFlagPointer &o); - - inline bool isNull() const; - - inline bool flag() const; - inline void setFlag(); - inline void clearFlag(); - inline void setFlagValue(bool); - - inline bool flag2() const; - inline void setFlag2(); - inline void clearFlag2(); - inline void setFlag2Value(bool); - - inline QFlagPointer &operator=(const QFlagPointer &o); - inline QFlagPointer &operator=(T *); - - inline T *operator->() const; - inline T *operator*() const; - - inline T *data() const; - - inline explicit operator bool() const; - -private: - quintptr ptr_value = 0; - - static const quintptr FlagBit = 0x1; - static const quintptr Flag2Bit = 0x2; - static const quintptr FlagsMask = FlagBit | Flag2Bit; -}; - template class QBiPointer { public: @@ -135,121 +98,6 @@ private: static const quintptr FlagsMask = FlagBit | Flag2Bit; }; -template -QFlagPointer::QFlagPointer() -{ -} - -template -QFlagPointer::QFlagPointer(T *v) -: ptr_value(quintptr(v)) -{ - Q_STATIC_ASSERT_X(Q_ALIGNOF(T) >= 4, "Type T does not have sufficient alignment"); - Q_ASSERT((ptr_value & FlagsMask) == 0); -} - -template -QFlagPointer::QFlagPointer(const QFlagPointer &o) -: ptr_value(o.ptr_value) -{ -} - -template -bool QFlagPointer::isNull() const -{ - return 0 == (ptr_value & (~FlagsMask)); -} - -template -bool QFlagPointer::flag() const -{ - return ptr_value & FlagBit; -} - -template -void QFlagPointer::setFlag() -{ - ptr_value |= FlagBit; -} - -template -void QFlagPointer::clearFlag() -{ - ptr_value &= ~FlagBit; -} - -template -void QFlagPointer::setFlagValue(bool v) -{ - if (v) setFlag(); - else clearFlag(); -} - -template -bool QFlagPointer::flag2() const -{ - return ptr_value & Flag2Bit; -} - -template -void QFlagPointer::setFlag2() -{ - ptr_value|= Flag2Bit; -} - -template -void QFlagPointer::clearFlag2() -{ - ptr_value &= ~Flag2Bit; -} - -template -void QFlagPointer::setFlag2Value(bool v) -{ - if (v) setFlag2(); - else clearFlag2(); -} - -template -QFlagPointer &QFlagPointer::operator=(const QFlagPointer &o) -{ - ptr_value = o.ptr_value; - return *this; -} - -template -QFlagPointer &QFlagPointer::operator=(T *o) -{ - Q_ASSERT((quintptr(o) & FlagsMask) == 0); - - ptr_value = quintptr(o) | (ptr_value & FlagsMask); - return *this; -} - -template -T *QFlagPointer::operator->() const -{ - return (T *)(ptr_value & ~FlagsMask); -} - -template -T *QFlagPointer::operator*() const -{ - return (T *)(ptr_value & ~FlagsMask); -} - -template -T *QFlagPointer::data() const -{ - return (T *)(ptr_value & ~FlagsMask); -} - -template -QFlagPointer::operator bool() const -{ - return data() != nullptr; -} - template QBiPointer::QBiPointer() { diff --git a/src/qml/qml/ftw/qlazilyallocated_p.h b/src/qml/qml/ftw/qlazilyallocated_p.h index 9073e41558..2bac84afb3 100644 --- a/src/qml/qml/ftw/qlazilyallocated_p.h +++ b/src/qml/qml/ftw/qlazilyallocated_p.h @@ -52,12 +52,11 @@ // #include - -#include +#include QT_BEGIN_NAMESPACE -template +template::TagType> class QLazilyAllocated { public: inline QLazilyAllocated(); @@ -70,73 +69,59 @@ public: inline T &value(); inline const T &value() const; - inline bool flag() const; - inline void setFlag(); - inline void clearFlag(); - inline void setFlagValue(bool); + inline Tag tag() const; + inline void setTag(Tag t); private: - mutable QFlagPointer d; + mutable QTaggedPointer d; }; -template -QLazilyAllocated::QLazilyAllocated() +template +QLazilyAllocated::QLazilyAllocated() { } -template -QLazilyAllocated::~QLazilyAllocated() +template +QLazilyAllocated::~QLazilyAllocated() { - delete *d; + delete d.data(); } -template -bool QLazilyAllocated::isAllocated() const +template +bool QLazilyAllocated::isAllocated() const { return !d.isNull(); } -template -T &QLazilyAllocated::value() +template +T &QLazilyAllocated::value() { if (d.isNull()) d = new T; - return *(*d); + return *d; } -template -const T &QLazilyAllocated::value() const +template +const T &QLazilyAllocated::value() const { if (d.isNull()) d = new T; - return *(*d); -} - -template -T *QLazilyAllocated::operator->() const -{ return *d; } -template -bool QLazilyAllocated::flag() const -{ - return d.flag(); -} - -template -void QLazilyAllocated::setFlag() +template +T *QLazilyAllocated::operator->() const { - d.setFlag(); + return d.data(); } -template -void QLazilyAllocated::clearFlag() +template +Tag QLazilyAllocated::tag() const { - d.clearFlag(); + return d.tag(); } -template -void QLazilyAllocated::setFlagValue(bool v) +template +void QLazilyAllocated::setTag(Tag t) { - d.setFlagValue(v); + d.setTag(t); } QT_END_NAMESPACE diff --git a/src/qml/qml/ftw/qlinkedstringhash_p.h b/src/qml/qml/ftw/qlinkedstringhash_p.h index 67ced7fbbf..495d78ea2f 100644 --- a/src/qml/qml/ftw/qlinkedstringhash_p.h +++ b/src/qml/qml/ftw/qlinkedstringhash_p.h @@ -223,7 +223,7 @@ public: { if (auto *node = iter.node()) { QHashedString key(node->key()); - while ((node = static_cast::Node *>(*node->next))) { + while ((node = static_cast::Node *>(node->next.data()))) { if (node->equals(key)) return QLinkedStringHash::iterator(node); } diff --git a/src/qml/qml/ftw/qstringhash_p.h b/src/qml/qml/ftw/qstringhash_p.h index fc73fdfa50..125e160500 100644 --- a/src/qml/qml/ftw/qstringhash_p.h +++ b/src/qml/qml/ftw/qstringhash_p.h @@ -56,6 +56,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -104,7 +105,12 @@ public: QTypedArrayData::deallocate(arrayData); } - QFlagPointer next; + enum Tag { + NodeIsCString, + NodeIsQString + }; + + QTaggedPointer next; qint32 length = 0; quint32 hash = 0; @@ -126,8 +132,8 @@ public: return QHashedString(QString::fromLatin1(ckey, length), hash); } - bool isQString() const { return next.flag(); } - void setQString(bool v) { if (v) next.setFlag(); else next.clearFlag(); } + bool isQString() const { return next.tag() == NodeIsQString; } + void setQString(bool v) { if (v) next.setTag(NodeIsQString); else next.setTag(NodeIsCString); } inline qsizetype size() const { return length; } inline const char *cStrData() const { return ckey; } @@ -712,7 +718,7 @@ typename QStringHash::Node *QStringHash::findNode(const K &key) const typename HashedForm::Type hashedKey(hashedString(key)); while (node && !node->equals(hashedKey)) - node = (*node->next); + node = node->next.data(); return (Node *)node; } diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h index fc53be3e7b..96bb0da269 100644 --- a/src/qml/qml/qqmlabstractbinding_p.h +++ b/src/qml/qml/qqmlabstractbinding_p.h @@ -92,7 +92,7 @@ public: inline QQmlAbstractBinding *nextBinding() const; inline bool canUseAccessor() const - { return m_nextBinding.flag2(); } + { return m_nextBinding.tag().testFlag(CanUseAccessor); } struct RefCount { RefCount() {} @@ -103,6 +103,20 @@ public: }; RefCount ref; + enum TargetTag { + NoTargetTag = 0x0, + UpdatingBinding = 0x1, + BindingEnabled = 0x2 + }; + Q_DECLARE_FLAGS(TargetTags, TargetTag) + + enum NextBindingTag { + NoBindingTag = 0x0, + AddedToObject = 0x1, + CanUseAccessor = 0x2 + }; + Q_DECLARE_FLAGS(NextBindingTags, NextBindingTag) + protected: friend class QQmlData; friend class QQmlValueTypeProxyBinding; @@ -116,24 +130,23 @@ protected: QQmlPropertyIndex m_targetIndex; // Pointer is the target object to which the binding binds - // flag1 is the updating flag - // flag2 is the enabled flag - QFlagPointer m_target; + QTaggedPointer m_target; // Pointer to the next binding in the linked list of bindings. - // flag1 is used for addedToObject - // flag2 indicates if an accessor is can be used (i.e. there is no interceptor on the target) - QFlagPointer m_nextBinding; + QTaggedPointer m_nextBinding; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlAbstractBinding::TargetTags) +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlAbstractBinding::NextBindingTags) + void QQmlAbstractBinding::setAddedToObject(bool v) { - m_nextBinding.setFlagValue(v); + m_nextBinding.setTag(m_nextBinding.tag().setFlag(AddedToObject, v)); } bool QQmlAbstractBinding::isAddedToObject() const { - return m_nextBinding.flag(); + return m_nextBinding.tag().testFlag(AddedToObject); } QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 0dcc17d9e8..7de94fe3d5 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -232,7 +232,7 @@ protected: QQmlPropertyData *pd = nullptr; getPropertyData(&pd, nullptr); QQmlBinding *thisPtr = this; - pd->writeProperty(*m_target, &thisPtr, flags); + pd->writeProperty(m_target.data(), &thisPtr, flags); } }; @@ -546,10 +546,10 @@ void QQmlBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags) setEnabledFlag(e); setNotifyOnValueChanged(e); - m_nextBinding.setFlag2(); // Always use accessors, only not when: + m_nextBinding.setTag(m_nextBinding.tag().setFlag(CanUseAccessor)); // Always use accessors, only not when: if (auto interceptorMetaObject = QQmlInterceptorMetaObject::get(targetObject())) { if (!m_targetIndex.isValid() || interceptorMetaObject->intercepts(m_targetIndex)) - m_nextBinding.clearFlag2(); + m_nextBinding.setTag(m_nextBinding.tag().setFlag(CanUseAccessor, false)); } if (e && !wasEnabled) @@ -606,7 +606,7 @@ bool QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const } m_targetIndex = QQmlPropertyIndex(coreIndex, valueTypeIndex); - QQmlData *data = QQmlData::get(*m_target, true); + QQmlData *data = QQmlData::get(m_target.data(), true); if (!data->propertyCache) { data->propertyCache = QQmlEnginePrivate::get(engine())->cache(m_target->metaObject()); data->propertyCache->addref(); @@ -619,7 +619,7 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD { Q_ASSERT(propertyData); - QQmlData *data = QQmlData::get(*m_target, false); + QQmlData *data = QQmlData::get(m_target.data(), false); Q_ASSERT(data); if (Q_UNLIKELY(!data->propertyCache)) { diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 8aeb87df1f..bf73c24c9e 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -153,22 +153,22 @@ private: bool QQmlBinding::updatingFlag() const { - return m_target.flag(); + return m_target.tag().testFlag(UpdatingBinding); } void QQmlBinding::setUpdatingFlag(bool v) { - m_target.setFlagValue(v); + m_target.setTag(m_target.tag().setFlag(UpdatingBinding, v)); } bool QQmlBinding::enabledFlag() const { - return m_target.flag2(); + return m_target.tag().testFlag(BindingEnabled); } void QQmlBinding::setEnabledFlag(bool v) { - m_target.setFlag2Value(v); + m_target.setTag(m_target.tag().setFlag(BindingEnabled, v)); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h index ca49cbf963..e1b2e9d41d 100644 --- a/src/qml/qml/qqmlcontext_p.h +++ b/src/qml/qml/qqmlcontext_p.h @@ -59,6 +59,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlcontextdata_p.h b/src/qml/qml/qqmlcontextdata_p.h index e31a45dea4..ccefd3a05b 100644 --- a/src/qml/qml/qqmlcontextdata_p.h +++ b/src/qml/qml/qqmlcontextdata_p.h @@ -278,6 +278,11 @@ private: // id guards struct ContextGuard : public QQmlGuard { + enum Tag { + NoTag, + ObjectWasSet + }; + inline ContextGuard() : m_context(nullptr) {} inline ContextGuard &operator=(QObject *obj); inline void objectDestroyed(QObject *) override; @@ -292,7 +297,7 @@ private: private: // Not refcounted, as it always belongs to the QQmlContextData. - QFlagPointer m_context; + QTaggedPointer m_context; QQmlNotifier m_bindings; }; @@ -404,7 +409,7 @@ private: QQmlContextData::ContextGuard &QQmlContextData::ContextGuard::operator=(QObject *obj) { QQmlGuard::operator=(obj); - m_context.setFlag(); + m_context.setTag(ObjectWasSet); m_bindings.notify(); // For alias connections return *this; } @@ -419,7 +424,7 @@ void QQmlContextData::ContextGuard::objectDestroyed(QObject *) bool QQmlContextData::ContextGuard::wasSet() const { - return m_context.flag(); + return m_context.tag() == ObjectWasSet; } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 3e204c1898..0f83baa893 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -129,7 +129,7 @@ QString QQmlJavaScriptExpression::expressionIdentifier() const void QQmlJavaScriptExpression::setNotifyOnValueChanged(bool v) { - activeGuards.setFlagValue(v); + activeGuards.setTag(v ? NotifyOnValueChanged : NoGuardTag); if (!v) clearActiveGuards(); } diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index b52e978938..f90b399b0a 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -52,6 +52,7 @@ // #include +#include #include #include @@ -175,10 +176,16 @@ protected: // activeGuards:flag1 - notifyOnValueChanged // activeGuards:flag2 - useSharedContext QBiPointer m_scopeObject; - QForwardFieldList activeGuards; - void setTranslationsCaptured(bool captured) { m_error.setFlagValue(captured); } - bool translationsCaptured() const { return m_error.flag(); } + enum GuardTag { + NoGuardTag, + NotifyOnValueChanged + }; + + QForwardFieldList activeGuards; + + void setTranslationsCaptured(bool captured) { if (captured) m_error.setTag(TranslationsCaptured); else m_error.setTag(NoTag); } + bool translationsCaptured() const { return m_error.tag() == TranslationsCaptured; } private: friend class QQmlContextData; @@ -186,8 +193,13 @@ private: friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **); friend class QQmlTranslationBinding; + enum Tag { + NoTag, + TranslationsCaptured + }; + // m_error:flag1 translationsCapturedDuringEvaluation - QFlagPointer m_error; + QTaggedPointer m_error; // Not refcounted as the context will clear the expressions when destructed. QQmlContextData *m_context; @@ -250,7 +262,7 @@ bool QQmlJavaScriptExpression::DeleteWatcher::wasDeleted() const bool QQmlJavaScriptExpression::notifyOnValueChanged() const { - return activeGuards.flag(); + return activeGuards.tag() == NotifyOnValueChanged; } QObject *QQmlJavaScriptExpression::scopeObject() const diff --git a/src/qml/qml/qqmlpropertycachevector_p.h b/src/qml/qml/qqmlpropertycachevector_p.h index 1dff7c61a6..2e09423206 100644 --- a/src/qml/qml/qqmlpropertycachevector_p.h +++ b/src/qml/qml/qqmlpropertycachevector_p.h @@ -54,16 +54,23 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QQmlPropertyCacheVector { public: + enum Tag { + NoTag, + CacheNeedsVMEMetaObject + }; + QQmlPropertyCacheVector() {} QQmlPropertyCacheVector(QQmlPropertyCacheVector &&other) : data(std::move(other.data)) {} QQmlPropertyCacheVector &operator=(QQmlPropertyCacheVector &&other) { - QVector> moved(std::move(other.data)); + QVector> moved(std::move(other.data)); data.swap(moved); return *this; } @@ -80,7 +87,7 @@ public: data.clear(); } - void append(QQmlPropertyCache *cache) { cache->addref(); data.append(cache); } + void append(QQmlPropertyCache *cache) { cache->addref(); data.append(QTaggedPointer(cache)); } QQmlPropertyCache *at(int index) const { return data.at(index).data(); } void set(int index, const QQmlRefPointer &replacement) { if (QQmlPropertyCache *oldCache = data.at(index).data()) { @@ -92,11 +99,11 @@ public: replacement->addref(); } - void setNeedsVMEMetaObject(int index) { data[index].setFlag(); } - bool needsVMEMetaObject(int index) const { return data.at(index).flag(); } + void setNeedsVMEMetaObject(int index) { data[index].setTag(CacheNeedsVMEMetaObject); } + bool needsVMEMetaObject(int index) const { return data.at(index).tag() == CacheNeedsVMEMetaObject; } private: Q_DISABLE_COPY(QQmlPropertyCacheVector) - QVector> data; + QVector> data; }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index c107f22df5..856dda1663 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -204,7 +204,12 @@ public: QQmlVMEMetaObjectEndpoint(); void tryConnect(); - QFlagPointer metaObject; + enum Tag { + NoTag, + EndPointIsConnected + }; + + QTaggedPointer metaObject; }; QQmlVMEMetaObjectEndpoint::QQmlVMEMetaObjectEndpoint() @@ -223,7 +228,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() Q_ASSERT(metaObject->compiledObject); int aliasId = this - metaObject->aliasEndpoints; - if (metaObject.flag()) { + if (metaObject.tag() == EndPointIsConnected) { // This is actually notify int sigIdx = metaObject->methodOffset() + aliasId + metaObject->compiledObject->nProperties; metaObject->activate(metaObject->object, sigIdx, nullptr); @@ -258,7 +263,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() connect(target, pd->notifyIndex(), ctxt->engine()); } - metaObject.setFlag(); + metaObject.setTag(EndPointIsConnected); } } diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index b285fe56ed..c227f8a89d 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -497,7 +497,7 @@ void QQuickAnimatedSprite::advance(int frames) void QQuickAnimatedSprite::maybeUpdate() { QQuickItemPrivate *priv = QQuickItemPrivate::get(this); - const QLazilyAllocated &extraData = priv->extra; + const auto &extraData = priv->extra; if ((extraData.isAllocated() && extraData->effectRefCount > 0) || priv->effectiveVisible) update(); } diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 93f1765811..707f149baf 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7292,10 +7292,7 @@ Qt::MouseButtons QQuickItem::acceptedMouseButtons() const void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons) { Q_D(QQuickItem); - if (buttons & Qt::LeftButton) - d->extra.setFlag(); - else - d->extra.clearFlag(); + d->extra.setTag(d->extra.tag().setFlag(QQuickItemPrivate::LeftMouseButtonAccepted, buttons & Qt::LeftButton)); buttons &= ~Qt::LeftButton; if (buttons || d->extra.isAllocated()) diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 6f39f3bdd2..395dfee496 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -397,7 +397,7 @@ public: QObjectList resourcesList; // Although acceptedMouseButtons is inside ExtraData, we actually store - // the LeftButton flag in the extra.flag() bit. This is because it is + // the LeftButton flag in the extra.tag() bit. This is because it is // extremely common to set acceptedMouseButtons to LeftButton, but very // rare to use any of the other buttons. Qt::MouseButtons acceptedMouseButtons; @@ -407,7 +407,14 @@ public: // 26 bits padding }; - QLazilyAllocated extra; + + enum ExtraDataTag { + NoTag = 0x1, + LeftMouseButtonAccepted = 0x2 + }; + Q_DECLARE_FLAGS(ExtraDataTags, ExtraDataTag) + + QLazilyAllocated extra; // Contains mask QPointer mask; // If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false) @@ -663,6 +670,8 @@ public: virtual void updatePolish() { } }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ExtraDataTags) + /* Key filters can be installed on a QQuickItem, but not removed. Currently they are only used by attached objects (which are only destroyed on Item @@ -947,7 +956,7 @@ private: Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const { - return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) | + return ((extra.tag().testFlag(LeftMouseButtonAccepted) ? Qt::LeftButton : Qt::MouseButton(0)) | (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons{})); } -- cgit v1.2.3