diff --git a/src/corelib/kernel/qassociativeiterable.cpp b/src/corelib/kernel/qassociativeiterable.cpp index 5e30ae291e..41db3485f0 100644 --- a/src/corelib/kernel/qassociativeiterable.cpp +++ b/src/corelib/kernel/qassociativeiterable.cpp @@ -215,6 +215,46 @@ QAssociativeIterable::iterator QAssociativeIterable::mutableFind(const QVariant return mutableEnd(); } +/*! + Returns \c true if the container has an entry with the given \a key, or + \c false otherwise. If the \a key isn't convertible to the expected type, + \c false is returned. + */ +bool QAssociativeIterable::containsKey(const QVariant &key) +{ + QtPrivate::QVariantTypeCoercer keyCoercer; + QMetaAssociation meta = metaContainer(); + if (const void *keyData = keyCoercer.convert(key, meta.keyMetaType())) + return meta.containsKey(constIterable(), keyData); + return false; +} + +/*! + Inserts a new entry with the given \a key, or resets the mapped value of + any existing entry with the given \a key to the default constructed + mapped value. The \a key is coerced to the expected type: If it isn't + convertible, a default value is inserted. + */ +void QAssociativeIterable::insertKey(const QVariant &key) +{ + QMetaAssociation meta = metaContainer(); + QtPrivate::QVariantTypeCoercer keyCoercer; + meta.insertKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType())); +} + +/*! + Removes the entry with the given \a key from the container. The \a key is + coerced to the expected type: If it isn't convertible, the default value + is removed. + */ +void QAssociativeIterable::removeKey(const QVariant &key) +{ + QMetaAssociation meta = metaContainer(); + QtPrivate::QVariantTypeCoercer keyCoercer; + meta.removeKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType())); +} + + /*! Retrieves the mapped value at the given \a key, or a default-constructed QVariant of the mapped type, if the key does not exist. If the \a key is not @@ -230,6 +270,21 @@ QVariant QAssociativeIterable::value(const QVariant &key) const return result; } +/*! + Sets the mapped value associated with \a key to \a mapped, if possible. + Inserts a new entry if none exists yet, for the given \a key. If the \a key + is not convertible to the key type, the value for the default-constructed + key type is overwritten. + */ +void QAssociativeIterable::setValue(const QVariant &key, const QVariant &mapped) +{ + QtPrivate::QVariantTypeCoercer keyCoercer; + QtPrivate::QVariantTypeCoercer mappedCoercer; + QMetaAssociation meta = metaContainer(); + meta.setMappedAtKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()), + mappedCoercer.coerce(mapped, meta.mappedMetaType())); +} + /*! \class QAssociativeIterable::const_iterator \since 5.2 diff --git a/src/corelib/kernel/qassociativeiterable.h b/src/corelib/kernel/qassociativeiterable.h index ba20af0327..4a1942fbc9 100644 --- a/src/corelib/kernel/qassociativeiterable.h +++ b/src/corelib/kernel/qassociativeiterable.h @@ -155,7 +155,12 @@ public: const_iterator constFind(const QVariant &key) const { return find(key); } iterator mutableFind(const QVariant &key); + bool containsKey(const QVariant &key); + void insertKey(const QVariant &key); + void removeKey(const QVariant &key); + QVariant value(const QVariant &key) const; + void setValue(const QVariant &key, const QVariant &mapped); }; template<> diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 4ff404e12a..d3feabfac1 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -4355,6 +4355,16 @@ void testAssociativeIteration() else if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType()) QCOMPARE(mappingIter.value(5).toBool(), true); + QVERIFY(mappingIter.containsKey("5")); + mappingIter.removeKey(QStringLiteral("5")); + QCOMPARE(mappingIter.find(5), mappingIter.end()); + + mappingIter.setValue(5, 44); + if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType()) + QCOMPARE(mappingIter.value(5).toInt(), 44); + else if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType()) + QCOMPARE(mappingIter.value(5).toBool(), true); + // Test that find() does not coerce auto container = Container(); container[0] = true;