Add QHash::insert(const QHash &other)

As opposed to unite(), this inserts one hash into the other
without duplicating elements.

Change-Id: Ifc786c48f5dc3ab18c29782e73eac3c1a3ef8981
Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Lars Knoll 2018-12-03 11:16:18 +01:00 committed by Mårten Nordheim
parent 3359b29c99
commit 7b34da9ef1
3 changed files with 111 additions and 0 deletions

View File

@ -1807,6 +1807,18 @@ uint qHash(long double key, uint seed) noexcept
\sa insertMulti()
*/
/*! \fn template <class Key, class T> void QHash<Key, T>::insert(const QHash &other)
\since 5.15
Inserts all the items in the \a other hash into this hash.
If a key is common to both hashes, its value will be replaced with the
value stored in \a other.
\note If \a other contains multiple entries with the same key then the
final value of the key is undefined.
*/
/*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::insertMulti(const Key &key, const T &value)
Inserts a new item with the \a key and a value of \a value.

View File

@ -526,6 +526,7 @@ public:
const_iterator find(const Key &key) const;
const_iterator constFind(const Key &key) const;
iterator insert(const Key &key, const T &value);
void insert(const QHash &hash);
iterator insertMulti(const Key &key, const T &value);
QHash &unite(const QHash &other);
@ -840,6 +841,31 @@ Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::insert(const K
return iterator(*node);
}
template <class Key, class T>
Q_INLINE_TEMPLATE void QHash<Key, T>::insert(const QHash &hash)
{
if (d == hash.d)
return;
detach();
QHashData::Node *i = hash.d->firstNode();
QHashData::Node *end = reinterpret_cast<QHashData::Node *>(hash.e);
while (i != end) {
Node *n = concrete(i);
Node **node = findNode(n->key, n->h);
if (*node == e) {
if (d->willGrow())
node = findNode(n->key, n->h);
createNode(n->h, n->key, n->value, node);
} else {
if (!std::is_same<T, QHashDummyValue>::value)
(*node)->value = n->value;
}
i = QHashData::nextNode(i);
}
}
template <class Key, class T>
Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::insertMulti(const Key &akey,
const T &avalue)

View File

@ -69,6 +69,7 @@ private slots:
void initializerList();
void eraseValidIteratorOnSharedHash();
void equal_range();
void insert_hash();
};
struct IdentityTracker {
@ -1643,5 +1644,77 @@ void tst_QHash::equal_range()
}
}
void tst_QHash::insert_hash()
{
{
QHash<int, int> hash;
hash.insert(1, 1);
hash.insert(2, 2);
hash.insert(0, -1);
QHash<int, int> hash2;
hash2.insert(0, 0);
hash2.insert(3, 3);
hash2.insert(4, 4);
hash.insert(hash2);
QCOMPARE(hash.count(), 5);
for (int i = 0; i < 5; ++i)
QCOMPARE(hash[i], i);
}
{
QHash<int, int> hash;
hash.insert(0, 5);
QHash<int, int> hash2;
hash.insert(hash2);
QCOMPARE(hash.count(), 1);
QCOMPARE(hash[0], 5);
}
{
QHash<int, int> hash;
QHash<int, int> hash2;
hash2.insert(0, 5);
hash.insert(hash2);
QCOMPARE(hash.count(), 1);
QCOMPARE(hash[0], 5);
QCOMPARE(hash, hash2);
}
{
QHash<int, int> hash;
hash.insert(0, 7);
hash.insert(2, 5);
hash.insert(7, 55);
// insert into ourself, nothing should happen
hash.insert(hash);
QCOMPARE(hash.count(), 3);
QCOMPARE(hash[0], 7);
QCOMPARE(hash[2], 5);
QCOMPARE(hash[7], 55);
}
{
// This will use a QMultiHash and then insert that into QHash,
// the ordering is undefined so we won't test that but make
// sure this isn't adding multiple entries with the same key
// to the QHash.
QHash<int, int> hash;
QMultiHash<int, int> hash2;
hash2.insert(0, 5);
hash2.insert(0, 6);
hash2.insert(0, 7);
hash.insert(hash2);
QCOMPARE(hash.count(), 1);
}
}
QTEST_APPLESS_MAIN(tst_QHash)
#include "tst_qhash.moc"