From c15d6a155c6121bad68a3ec60be62181fb92d0f8 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 10 Dec 2019 14:55:14 +0100 Subject: QVariant: introduce ShouldDeleteVariantData flag This flag is used in QSequentialIterable and QAssociativeIterable to indicate that the data pointer in VariantData should be deleted after the variant has been constructed. The use case for this is https://codereview.qt-project.org/c/qt/qtdeclarative/+/284151, where we have a proxy iterator and cannot easily return a pointer to already owned data, as it is hard to manage its lifetime in the iterator. In contrast, it is clear that we can release the memory in the QSequentialIterable functions, as it has already been copied into the QVariant there. Change-Id: I2b33497d991cd4f752153e0ebda767b82e4bb851 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qvariant.cpp | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'src/corelib/kernel/qvariant.cpp') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 84ad555f34..a1e1c71d12 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -4520,15 +4520,24 @@ QSequentialIterable::const_iterator QSequentialIterable::end() const return it; } +static const QVariant variantFromVariantDataHelper(const QtMetaTypePrivate::VariantData &d) { + QVariant v; + if (d.metaTypeId == qMetaTypeId()) + v = *reinterpret_cast(d.data); + else + v = QVariant(d.metaTypeId, d.data, d.flags & ~QVariantConstructionFlags::ShouldDeleteVariantData); + if (d.flags & QVariantConstructionFlags::ShouldDeleteVariantData) + QMetaType::destroy(d.metaTypeId, const_cast(d.data)); + return v; +} + /*! Returns the element at position \a idx in the container. */ QVariant QSequentialIterable::at(int idx) const { const QtMetaTypePrivate::VariantData d = m_impl.at(idx); - if (d.metaTypeId == qMetaTypeId()) - return *reinterpret_cast(d.data); - return QVariant(d.metaTypeId, d.data, d.flags); + return variantFromVariantDataHelper(d); } /*! @@ -4605,9 +4614,7 @@ QSequentialIterable::const_iterator::operator=(const const_iterator &other) const QVariant QSequentialIterable::const_iterator::operator*() const { const QtMetaTypePrivate::VariantData d = m_impl.getCurrent(); - if (d.metaTypeId == qMetaTypeId()) - return *reinterpret_cast(d.data); - return QVariant(d.metaTypeId, d.data, d.flags); + return variantFromVariantDataHelper(d); } /*! @@ -4939,10 +4946,7 @@ QAssociativeIterable::const_iterator::operator=(const const_iterator &other) const QVariant QAssociativeIterable::const_iterator::operator*() const { const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue(); - QVariant v(d.metaTypeId, d.data, d.flags); - if (d.metaTypeId == qMetaTypeId()) - return *reinterpret_cast(d.data); - return v; + return variantFromVariantDataHelper(d); } /*! @@ -4951,10 +4955,7 @@ const QVariant QAssociativeIterable::const_iterator::operator*() const const QVariant QAssociativeIterable::const_iterator::key() const { const QtMetaTypePrivate::VariantData d = m_impl.getCurrentKey(); - QVariant v(d.metaTypeId, d.data, d.flags); - if (d.metaTypeId == qMetaTypeId()) - return *reinterpret_cast(d.data); - return v; + return variantFromVariantDataHelper(d); } /*! @@ -4962,11 +4963,7 @@ const QVariant QAssociativeIterable::const_iterator::key() const */ const QVariant QAssociativeIterable::const_iterator::value() const { - const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue(); - QVariant v(d.metaTypeId, d.data, d.flags); - if (d.metaTypeId == qMetaTypeId()) - return *reinterpret_cast(d.data); - return v; + return operator*(); } /*! -- cgit v1.2.3 From 9c124b1b0a3730978699b8a6420308b5e5ab4e4e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 26 Nov 2018 10:37:10 +0100 Subject: Qt 6: Deprecate QHash::insertMulti [ChangeLog][QtCore][QHash] insertMulti(), unite() and values(const Key &key) are now deprecated. Please use QMultiHash instead. Change-Id: Ic14907fd5fd38d585708e2dcf2c0200d221ebb25 Reviewed-by: Timur Pocheptsov --- src/corelib/kernel/qvariant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/kernel/qvariant.cpp') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 40a401361d..5e27119729 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -972,7 +972,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) const QVariantMap *map = v_cast(d); const auto end = map->end(); for (auto it = map->begin(); it != end; ++it) - hash->insertMulti(it.key(), it.value()); + static_cast *>(hash)->insert(it.key(), it.value()); #ifndef QT_BOOTSTRAPPED } else if (d->type == QMetaType::QCborValue) { if (!v_cast(d)->isMap()) -- cgit v1.2.3 From 43837f38b23e46b2b26599b30724902ce6eddabe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 27 Nov 2019 17:13:13 +0100 Subject: Change some uses of QMap::insertMulti to QMultiMap::insert By casting it, these are situations where we cannot change the type itself to QMultiMap. For QVariant it's a public define and for dbus it's the type of an argument to the function. Change-Id: I0f385dc857fce5de3e8254d18268fd84a6d7707c Reviewed-by: Lars Knoll --- src/corelib/kernel/qvariant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/kernel/qvariant.cpp') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 5e27119729..c00efc0afe 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -944,7 +944,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) const QVariantHash *hash = v_cast(d); const auto end = hash->end(); for (auto it = hash->begin(); it != end; ++it) - map->insertMulti(it.key(), it.value()); + static_cast *>(map)->insert(it.key(), it.value()); #ifndef QT_BOOTSTRAPPED } else if (d->type == QMetaType::QCborValue) { if (!v_cast(d)->isMap()) -- cgit v1.2.3 From d6266c757d2f2ea4ff1e71dc8545f9bf97aa3bb1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 6 Dec 2019 13:19:37 +0100 Subject: Replace usages of QVariant::value by qvariant_cast This is done automatically with a clazy check Change-Id: I3b59511d3d36d416c8eda74858ead611d327b116 Reviewed-by: Lars Knoll --- src/corelib/kernel/qvariant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/kernel/qvariant.cpp') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index c00efc0afe..f3ac3fcdba 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1544,7 +1544,7 @@ static void customStreamDebug(QDebug dbg, const QVariant &variant) { #ifndef QT_BOOTSTRAPPED QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType()); if (flags & QMetaType::PointerToQObject) - dbg.nospace() << variant.value(); + dbg.nospace() << qvariant_cast(variant); #else Q_UNUSED(dbg); Q_UNUSED(variant); -- cgit v1.2.3