QAssociativeIterable: Add methods to add/remove keys and values

This way we can actually modify the container. Previously the interface
was rather useless.

Change-Id: I278aae46999862ada115c9066a010d7de5cde4ff
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2020-10-19 10:12:22 +02:00
parent 37c7ef4f4a
commit 45c248a011
3 changed files with 70 additions and 0 deletions

View File

@ -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

View File

@ -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<>

View File

@ -4355,6 +4355,16 @@ void testAssociativeIteration()
else if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<bool>())
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<int>())
QCOMPARE(mappingIter.value(5).toInt(), 44);
else if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<bool>())
QCOMPARE(mappingIter.value(5).toBool(), true);
// Test that find() does not coerce
auto container = Container();
container[0] = true;