QMap: deprecate insertMulti, unite and friends
insertMulti and unite will silently transform a QMap into a multi-map which is not behavior we want to keep around anymore and as such is being deprecated. QMap functions that only make sense in a multi-map scenario are also deprecated and the implementation is moved to QMultiMap where it makes sense. Use QMultiMap if multiple keys are desired and insert(const QMap &) if a non multi-map-converting unite is desired. [ChangeLog][QtCore][QMap] insertMulti(), unite(), values(Key), uniqueKeys(), count(Key) is now deprecated. Please use QMultiMap instead. Task-number: QTBUG-35544 Change-Id: I158c938ceefb5aaba0e6e7513b2c26a64d29d521 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
cd5ce46dc5
commit
4ec6748c6a
@ -468,10 +468,9 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\snippet code/src_corelib_tools_qmap.cpp 9
|
||||
|
||||
However, you can store multiple values per key by using
|
||||
insertMulti() instead of insert() (or using the convenience
|
||||
subclass QMultiMap). If you want to retrieve all the values for a
|
||||
single key, you can use values(const Key &key), which returns a
|
||||
QList<T>:
|
||||
using the subclass QMultiMap. If you want
|
||||
to retrieve all the values for a single key, you can use
|
||||
values(const Key &key), which returns a QList<T>:
|
||||
|
||||
\snippet code/src_corelib_tools_qmap.cpp 10
|
||||
|
||||
@ -676,9 +675,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
/*! \fn template <class Key, class T> int QMap<Key, T>::remove(const Key &key)
|
||||
|
||||
Removes all the items that have the key \a key from the map.
|
||||
Returns the number of items removed which is usually 1 but will be
|
||||
0 if the key isn't in the map, or \> 1 if insertMulti() has been
|
||||
used with the \a key.
|
||||
Returns the number of items removed which will be 1 if the key
|
||||
exists in the map, and 0 otherwise.
|
||||
|
||||
\sa clear(), take(), QMultiMap::remove()
|
||||
*/
|
||||
@ -742,28 +740,26 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
|
||||
/*! \fn template <class Key, class T> QList<Key> QMap<Key, T>::uniqueKeys() const
|
||||
\since 4.2
|
||||
\obsolete
|
||||
|
||||
Returns a list containing all the keys in the map in ascending
|
||||
order. Keys that occur multiple times in the map (because items
|
||||
were inserted with insertMulti(), or unite() was used) occur only
|
||||
once in the returned list.
|
||||
|
||||
\sa keys(), values()
|
||||
\sa QMultiMap::uniqueKeys()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QList<Key> QMap<Key, T>::keys() const
|
||||
|
||||
Returns a list containing all the keys in the map in ascending
|
||||
order. Keys that occur multiple times in the map (because items
|
||||
were inserted with insertMulti(), or unite() was used) also
|
||||
occur multiple times in the list.
|
||||
|
||||
To obtain a list of unique keys, where each key from the map only
|
||||
occurs once, use uniqueKeys().
|
||||
order. Keys that occur multiple times in the map (because the
|
||||
method is operating on a QMultiMap) also occur multiple times
|
||||
in the list.
|
||||
|
||||
The order is guaranteed to be the same as that used by values().
|
||||
|
||||
\sa uniqueKeys(), values(), key()
|
||||
\sa QMultiMap::uniqueKeys(), values(), key()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QList<Key> QMap<Key, T>::keys(const T &value) const
|
||||
@ -806,6 +802,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QList<T> QMap<Key, T>::values(const Key &key) const
|
||||
\obsolete
|
||||
|
||||
\overload
|
||||
|
||||
@ -813,14 +810,15 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\a key, from the most recently inserted to the least recently
|
||||
inserted one.
|
||||
|
||||
\sa count(), insertMulti()
|
||||
\sa QMultiMap::values()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QMap<Key, T>::count(const Key &key) const
|
||||
\obsolete
|
||||
|
||||
Returns the number of items associated with key \a key.
|
||||
|
||||
\sa contains(), insertMulti(), QMultiMap::count()
|
||||
\sa QMultiMap::count()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QMap<Key, T>::count() const
|
||||
@ -1118,7 +1116,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
If there are multiple items with the key \a key, the most
|
||||
recently inserted item's value is replaced with \a value.
|
||||
|
||||
\sa insertMulti()
|
||||
\sa QMultiMap::insert()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const Key &key, const T &value)
|
||||
@ -1147,7 +1145,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\b {Note:} Be careful with the hint. Providing an iterator from an older shared instance might
|
||||
crash but there is also a risk that it will silently corrupt both the map and the \a pos map.
|
||||
|
||||
\sa insertMulti()
|
||||
\sa QMultiMap::insert()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> void QMap<Key, T>::insert(const QMap<Key, T> &map)
|
||||
@ -1161,10 +1159,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\note If \a map contains multiple entries with the same key then the
|
||||
final value of the key is undefined.
|
||||
|
||||
\sa insertMulti()
|
||||
\sa QMultiMap::insert()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const Key &key, const T &value)
|
||||
\obsolete
|
||||
|
||||
Inserts a new item with the key \a key and a value of \a value.
|
||||
|
||||
@ -1173,12 +1172,13 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
different from insert(), which overwrites the value of an
|
||||
existing item.)
|
||||
|
||||
\sa insert(), values()
|
||||
\sa QMultiMap::insert()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, const Key &key, const T &value)
|
||||
\overload
|
||||
\since 5.1
|
||||
\obsolete
|
||||
Inserts a new item with the key \a key and value \a value and with hint \a pos
|
||||
suggesting where to do the insert.
|
||||
|
||||
@ -1192,17 +1192,18 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\b {Note:} Be careful with the hint. Providing an iterator from an older shared instance might
|
||||
crash but there is also a risk that it will silently corrupt both the map and the \a pos map.
|
||||
|
||||
\sa insert()
|
||||
\sa QMultiMap::insert()
|
||||
*/
|
||||
|
||||
|
||||
/*! \fn template <class Key, class T> QMap<Key, T> &QMap<Key, T>::unite(const QMap<Key, T> &other)
|
||||
\obsolete
|
||||
|
||||
Inserts all the items in the \a other map into this map. If a
|
||||
key is common to both maps, the resulting map will contain the
|
||||
key multiple times.
|
||||
|
||||
\sa insertMulti()
|
||||
\sa QMultiMap::unite()
|
||||
*/
|
||||
|
||||
/*! \typedef QMap::Iterator
|
||||
@ -1285,9 +1286,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
|
||||
Unlike QHash, which stores its items in an arbitrary order, QMap
|
||||
stores its items ordered by key. Items that share the same key
|
||||
(because they were inserted using QMap::insertMulti(), or due to a
|
||||
unite()) will appear consecutively, from the most recently to the
|
||||
least recently inserted value.
|
||||
(because the map is a QMultiMap) will appear consecutively,
|
||||
from the most recently to the least recently inserted value.
|
||||
|
||||
Let's see a few examples of things we can do with a
|
||||
QMap::iterator that we cannot do with a QMap::const_iterator.
|
||||
@ -1533,9 +1533,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
|
||||
Unlike QHash, which stores its items in an arbitrary order, QMap
|
||||
stores its items ordered by key. Items that share the same key
|
||||
(because they were inserted using QMap::insertMulti()) will
|
||||
appear consecutively, from the most recently to the least
|
||||
recently inserted value.
|
||||
(because the map is a QMultiMap) will appear consecutively,
|
||||
from the most recently to the least recently inserted value.
|
||||
|
||||
Multiple iterators can be used on the same map. If you add items
|
||||
to the map, existing iterators will remain valid. If you remove
|
||||
@ -1907,20 +1906,20 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\reentrant
|
||||
|
||||
QMultiMap\<Key, T\> is one of Qt's generic \l{container classes}.
|
||||
It inherits QMap and extends it with a few convenience functions
|
||||
that make it more suitable than QMap for storing multi-valued
|
||||
maps. A multi-valued map is a map that allows multiple values
|
||||
with the same key; QMap normally doesn't allow that, unless you
|
||||
call QMap::insertMulti().
|
||||
It inherits QMap and extends it with a few functions
|
||||
that make it able to store multi-valued maps. A multi-valued map
|
||||
is a map that allows multiple values with the same key; QMap
|
||||
doesn't allow that.
|
||||
|
||||
Because QMultiMap inherits QMap, all of QMap's functionality also
|
||||
applies to QMultiMap. For example, you can use isEmpty() to test
|
||||
whether the map is empty, and you can traverse a QMultiMap using
|
||||
QMap's iterator classes (for example, QMapIterator). But in
|
||||
addition, it provides an insert() function that corresponds to
|
||||
QMap::insertMulti(), and a replace() function that corresponds to
|
||||
QMap::insert(). It also provides convenient operator+() and
|
||||
operator+=().
|
||||
addition, it provides an insert() function that inserts but does
|
||||
not overwrite any previous value if the key already exists,
|
||||
and a replace() function that corresponds which does overwite
|
||||
an existing value if they key is already in the map.
|
||||
It also provides convenient operator+() and operator+=().
|
||||
|
||||
Example:
|
||||
\snippet code/src_corelib_tools_qmap.cpp 25
|
||||
@ -2109,4 +2108,24 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
\sa QMap::constFind()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QList<T> QMultiMap<Key, T>::values(const Key &key) const
|
||||
|
||||
Returns a list containing all the values associated with key
|
||||
\a key, from the most recently inserted to the least recently
|
||||
inserted one.
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QMultiMap<Key, T>::count(const Key &key) const
|
||||
|
||||
Returns the number of items associated with key \a key.
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QList<Key> QMultiMap<Key, T>::uniqueKeys() const
|
||||
\since 4.2
|
||||
|
||||
Returns a list containing all the keys in the map in ascending
|
||||
order. Keys that occur multiple times in the map occur only
|
||||
once in the returned list.
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -380,12 +380,15 @@ public:
|
||||
T &operator[](const Key &key);
|
||||
const T operator[](const Key &key) const;
|
||||
|
||||
QList<Key> uniqueKeys() const;
|
||||
QList<Key> keys() const;
|
||||
QList<Key> keys(const T &value) const;
|
||||
QList<T> values() const;
|
||||
QList<T> values(const Key &key) const;
|
||||
int count(const Key &key) const;
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QList<Key> uniqueKeys() const;
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QList<T> values(const Key &key) const;
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") int count(const Key &key) const;
|
||||
#endif
|
||||
|
||||
|
||||
inline const Key &firstKey() const { Q_ASSERT(!isEmpty()); return constBegin().key(); }
|
||||
inline const Key &lastKey() const { Q_ASSERT(!isEmpty()); return (constEnd() - 1).key(); }
|
||||
@ -452,6 +455,7 @@ public:
|
||||
{ return i != o.i; }
|
||||
#endif
|
||||
friend class QMap<Key, T>;
|
||||
friend class QMultiMap<Key, T>;
|
||||
};
|
||||
friend class iterator;
|
||||
|
||||
@ -514,6 +518,7 @@ public:
|
||||
inline bool operator!=(const iterator &o) const { return operator!=(const_iterator(o)); }
|
||||
#endif
|
||||
friend class QMap<Key, T>;
|
||||
friend class QMultiMap<Key, T>;
|
||||
};
|
||||
friend class const_iterator;
|
||||
|
||||
@ -579,9 +584,11 @@ public:
|
||||
iterator insert(const Key &key, const T &value);
|
||||
iterator insert(const_iterator pos, const Key &key, const T &value);
|
||||
void insert(const QMap<Key, T> &map);
|
||||
iterator insertMulti(const Key &key, const T &value);
|
||||
iterator insertMulti(const_iterator pos, const Key &akey, const T &avalue);
|
||||
QMap<Key, T> &unite(const QMap<Key, T> &other);
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const_iterator pos, const Key &akey, const T &avalue);
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QMap<Key, T> &unite(const QMap<Key, T> &other);
|
||||
#endif
|
||||
|
||||
// STL compatibility
|
||||
typedef Key key_type;
|
||||
@ -610,6 +617,8 @@ private:
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
friend class QMultiMap<Key, T>;
|
||||
};
|
||||
|
||||
template <class Key, class T>
|
||||
@ -671,23 +680,6 @@ Q_INLINE_TEMPLATE T &QMap<Key, T>::operator[](const Key &akey)
|
||||
return n->value;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const
|
||||
{
|
||||
Node *firstNode;
|
||||
Node *lastNode;
|
||||
d->nodeRange(akey, &firstNode, &lastNode);
|
||||
|
||||
const_iterator ci_first(firstNode);
|
||||
const const_iterator ci_last(lastNode);
|
||||
int cnt = 0;
|
||||
while (ci_first != ci_last) {
|
||||
++cnt;
|
||||
++ci_first;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE bool QMap<Key, T>::contains(const Key &akey) const
|
||||
{
|
||||
@ -832,75 +824,6 @@ Q_INLINE_TEMPLATE void QMap<Key, T>::insert(const QMap<Key, T> &map)
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const Key &akey,
|
||||
const T &avalue)
|
||||
{
|
||||
detach();
|
||||
Node* y = d->end();
|
||||
Node* x = static_cast<Node *>(d->root());
|
||||
bool left = true;
|
||||
while (x != nullptr) {
|
||||
left = !qMapLessThanKey(x->key, akey);
|
||||
y = x;
|
||||
x = left ? x->leftNode() : x->rightNode();
|
||||
}
|
||||
Node *z = d->createNode(akey, avalue, y, left);
|
||||
return iterator(z);
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, const Key &akey, const T &avalue)
|
||||
{
|
||||
if (d->ref.isShared())
|
||||
return this->insertMulti(akey, avalue);
|
||||
|
||||
Q_ASSERT_X(isValidIterator(pos), "QMap::insertMulti", "The specified const_iterator argument 'pos' is invalid");
|
||||
|
||||
if (pos == constEnd()) {
|
||||
// Hint is that the Node is larger than (or equal to) the largest value.
|
||||
Node *n = static_cast<Node *>(pos.i->left);
|
||||
if (n) {
|
||||
while (n->right)
|
||||
n = static_cast<Node *>(n->right);
|
||||
|
||||
if (!qMapLessThanKey(n->key, akey))
|
||||
return this->insertMulti(akey, avalue); // ignore hint
|
||||
Node *z = d->createNode(akey, avalue, n, false); // insert right most
|
||||
return iterator(z);
|
||||
}
|
||||
return this->insertMulti(akey, avalue);
|
||||
} else {
|
||||
// Hint indicates that the node should be less (or equal to) the hint given
|
||||
// but larger than the previous value.
|
||||
Node *next = const_cast<Node*>(pos.i);
|
||||
if (qMapLessThanKey(next->key, akey))
|
||||
return this->insertMulti(akey, avalue); // ignore hint
|
||||
|
||||
if (pos == constBegin()) {
|
||||
// There is no previous value (insert left most)
|
||||
Node *z = d->createNode(akey, avalue, begin().i, true);
|
||||
return iterator(z);
|
||||
} else {
|
||||
Node *prev = const_cast<Node*>(pos.i->previousNode());
|
||||
if (!qMapLessThanKey(prev->key, akey))
|
||||
return this->insertMulti(akey, avalue); // ignore hint
|
||||
|
||||
// Hint is ok - do insert
|
||||
if (prev->right == nullptr) {
|
||||
Node *z = d->createNode(akey, avalue, prev, false);
|
||||
return iterator(z);
|
||||
}
|
||||
if (next->left == nullptr) {
|
||||
Node *z = d->createNode(akey, avalue, next, true);
|
||||
return iterator(z);
|
||||
}
|
||||
Q_ASSERT(false); // We should have prev->right == nullptr or next->left == nullptr.
|
||||
return this->insertMulti(akey, avalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::constFind(const Key &akey) const
|
||||
@ -923,19 +846,6 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::find(const Key &
|
||||
return iterator(n ? n : d->end());
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE QMap<Key, T> &QMap<Key, T>::unite(const QMap<Key, T> &other)
|
||||
{
|
||||
QMap<Key, T> copy(other);
|
||||
const_iterator it = copy.constEnd();
|
||||
const const_iterator b = copy.constBegin();
|
||||
while (it != b) {
|
||||
--it;
|
||||
insertMulti(it.key(), it.value());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
QPair<typename QMap<Key, T>::iterator, typename QMap<Key, T>::iterator> QMap<Key, T>::equal_range(const Key &akey)
|
||||
{
|
||||
@ -1051,26 +961,6 @@ Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::detach_helper()
|
||||
d->recalcMostLeftNode();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE QList<Key> QMap<Key, T>::uniqueKeys() const
|
||||
{
|
||||
QList<Key> res;
|
||||
res.reserve(size()); // May be too much, but assume short lifetime
|
||||
const_iterator i = begin();
|
||||
if (i != end()) {
|
||||
for (;;) {
|
||||
const Key &aKey = i.key();
|
||||
res.append(aKey);
|
||||
do {
|
||||
if (++i == end())
|
||||
goto break_out_of_outer_loop;
|
||||
} while (!qMapLessThanKey(aKey, i.key())); // loop while (key == i.key())
|
||||
}
|
||||
}
|
||||
break_out_of_outer_loop:
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE QList<Key> QMap<Key, T>::keys() const
|
||||
{
|
||||
@ -1123,21 +1013,6 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values() const
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values(const Key &akey) const
|
||||
{
|
||||
QList<T> res;
|
||||
Node *n = d->findNode(akey);
|
||||
if (n) {
|
||||
const_iterator it(n);
|
||||
do {
|
||||
res.append(*it);
|
||||
++it;
|
||||
} while (it != constEnd() && !qMapLessThanKey<Key>(akey, it.key()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::lowerBound(const Key &akey) const
|
||||
{
|
||||
@ -1234,15 +1109,20 @@ public:
|
||||
QMultiMap(QMap<Key, T> &&other) noexcept : QMap<Key, T>(std::move(other)) {}
|
||||
void swap(QMultiMap<Key, T> &other) noexcept { QMap<Key, T>::swap(other); }
|
||||
|
||||
QList<Key> uniqueKeys() const;
|
||||
QList<T> values(const Key &key) const;
|
||||
|
||||
using typename QMap<Key, T>::iterator;
|
||||
using typename QMap<Key, T>::const_iterator;
|
||||
|
||||
inline typename QMap<Key, T>::iterator replace(const Key &key, const T &value)
|
||||
{ return QMap<Key, T>::insert(key, value); }
|
||||
inline typename QMap<Key, T>::iterator insert(const Key &key, const T &value)
|
||||
{ return QMap<Key, T>::insertMulti(key, value); }
|
||||
inline typename QMap<Key, T>::iterator insert(typename QMap<Key, T>::const_iterator pos, const Key &key, const T &value)
|
||||
{ return QMap<Key, T>::insertMulti(pos, key, value); }
|
||||
iterator insert(const Key &key, const T &value);
|
||||
iterator insert(const_iterator pos, const Key &key, const T &value);
|
||||
|
||||
QMultiMap &unite(const QMultiMap &other);
|
||||
inline QMultiMap &operator+=(const QMultiMap &other)
|
||||
{ this->unite(other); return *this; }
|
||||
{ return unite(other); }
|
||||
inline QMultiMap operator+(const QMultiMap &other) const
|
||||
{ QMultiMap result = *this; result += other; return result; }
|
||||
|
||||
@ -1251,11 +1131,18 @@ public:
|
||||
using QMap<Key, T>::count;
|
||||
using QMap<Key, T>::find;
|
||||
using QMap<Key, T>::constFind;
|
||||
using QMap<Key, T>::values;
|
||||
using QMap<Key, T>::size;
|
||||
using QMap<Key, T>::detach;
|
||||
using QMap<Key, T>::erase;
|
||||
using QMap<Key, T>::isValidIterator;
|
||||
using typename QMap<Key, T>::Node;
|
||||
|
||||
bool contains(const Key &key, const T &value) const;
|
||||
|
||||
int remove(const Key &key, const T &value);
|
||||
|
||||
int count(const Key &key) const;
|
||||
int count(const Key &key, const T &value) const;
|
||||
|
||||
typename QMap<Key, T>::iterator find(const Key &key, const T &value) {
|
||||
@ -1285,6 +1172,123 @@ private:
|
||||
const T operator[](const Key &key) const;
|
||||
};
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE QList<Key> QMultiMap<Key, T>::uniqueKeys() const
|
||||
{
|
||||
QList<Key> res;
|
||||
res.reserve(size()); // May be too much, but assume short lifetime
|
||||
const_iterator i = this->begin();
|
||||
if (i != this->end()) {
|
||||
for (;;) {
|
||||
const Key &aKey = i.key();
|
||||
res.append(aKey);
|
||||
do {
|
||||
if (++i == this->end())
|
||||
goto break_out_of_outer_loop;
|
||||
} while (!qMapLessThanKey(aKey, i.key())); // loop while (key == i.key())
|
||||
}
|
||||
}
|
||||
break_out_of_outer_loop:
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE QList<T> QMultiMap<Key, T>::values(const Key &akey) const
|
||||
{
|
||||
QList<T> res;
|
||||
Node *n = this->d->findNode(akey);
|
||||
if (n) {
|
||||
const_iterator it(n);
|
||||
do {
|
||||
res.append(*it);
|
||||
++it;
|
||||
} while (it != this->constEnd() && !qMapLessThanKey<Key>(akey, it.key()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const Key &akey,
|
||||
const T &avalue)
|
||||
{
|
||||
detach();
|
||||
Node* y = this->d->end();
|
||||
Node* x = static_cast<Node *>(this->d->root());
|
||||
bool left = true;
|
||||
while (x != nullptr) {
|
||||
left = !qMapLessThanKey(x->key, akey);
|
||||
y = x;
|
||||
x = left ? x->leftNode() : x->rightNode();
|
||||
}
|
||||
Node *z = this->d->createNode(akey, avalue, y, left);
|
||||
return iterator(z);
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator pos, const Key &akey, const T &avalue)
|
||||
{
|
||||
if (this->d->ref.isShared())
|
||||
return insert(akey, avalue);
|
||||
|
||||
Q_ASSERT_X(isValidIterator(pos), "QMap::insert", "The specified const_iterator argument 'pos' is invalid");
|
||||
|
||||
if (pos == this->constEnd()) {
|
||||
// Hint is that the Node is larger than (or equal to) the largest value.
|
||||
Node *n = static_cast<Node *>(pos.i->left);
|
||||
if (n) {
|
||||
while (n->right)
|
||||
n = static_cast<Node *>(n->right);
|
||||
|
||||
if (!qMapLessThanKey(n->key, akey))
|
||||
return insert(akey, avalue); // ignore hint
|
||||
Node *z = this->d->createNode(akey, avalue, n, false); // insert right most
|
||||
return iterator(z);
|
||||
}
|
||||
return insert(akey, avalue);
|
||||
} else {
|
||||
// Hint indicates that the node should be less (or equal to) the hint given
|
||||
// but larger than the previous value.
|
||||
Node *next = const_cast<Node*>(pos.i);
|
||||
if (qMapLessThanKey(next->key, akey))
|
||||
return insert(akey, avalue); // ignore hint
|
||||
|
||||
if (pos == this->constBegin()) {
|
||||
// There is no previous value (insert left most)
|
||||
Node *z = this->d->createNode(akey, avalue, this->begin().i, true);
|
||||
return iterator(z);
|
||||
} else {
|
||||
Node *prev = const_cast<Node*>(pos.i->previousNode());
|
||||
if (!qMapLessThanKey(prev->key, akey))
|
||||
return insert(akey, avalue); // ignore hint
|
||||
|
||||
// Hint is ok - do insert
|
||||
if (prev->right == nullptr) {
|
||||
Node *z = this->d->createNode(akey, avalue, prev, false);
|
||||
return iterator(z);
|
||||
}
|
||||
if (next->left == nullptr) {
|
||||
Node *z = this->d->createNode(akey, avalue, next, true);
|
||||
return iterator(z);
|
||||
}
|
||||
Q_ASSERT(false); // We should have prev->right == nullptr or next->left == nullptr.
|
||||
return insert(akey, avalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE QMultiMap<Key, T> &QMultiMap<Key, T>::unite(const QMultiMap<Key, T> &other)
|
||||
{
|
||||
QMultiMap<Key, T> copy(other);
|
||||
const_iterator it = copy.constEnd();
|
||||
const const_iterator b = copy.constBegin();
|
||||
while (it != b) {
|
||||
--it;
|
||||
insert(it.key(), it.value());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE bool QMultiMap<Key, T>::contains(const Key &key, const T &value) const
|
||||
{
|
||||
@ -1299,7 +1303,7 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::remove(const Key &key, const T &value)
|
||||
typename QMap<Key, T>::iterator end(QMap<Key, T>::end());
|
||||
while (i != end && !qMapLessThanKey<Key>(key, i.key())) {
|
||||
if (i.value() == value) {
|
||||
i = this->erase(i);
|
||||
i = erase(i);
|
||||
++n;
|
||||
} else {
|
||||
++i;
|
||||
@ -1308,6 +1312,23 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::remove(const Key &key, const T &value)
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &akey) const
|
||||
{
|
||||
QMultiMap::Node *firstNode;
|
||||
QMultiMap::Node *lastNode;
|
||||
this->d->nodeRange(akey, &firstNode, &lastNode);
|
||||
|
||||
const_iterator ci_first(firstNode);
|
||||
const const_iterator ci_last(lastNode);
|
||||
int cnt = 0;
|
||||
while (ci_first != ci_last) {
|
||||
++cnt;
|
||||
++ci_first;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &key, const T &value) const
|
||||
{
|
||||
@ -1322,6 +1343,44 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &key, const T &value) c
|
||||
return n;
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
template<class Key, class T>
|
||||
QList<Key> QMap<Key, T>::uniqueKeys() const
|
||||
{
|
||||
return static_cast<const QMultiMap<Key, T> *>(this)->uniqueKeys();
|
||||
}
|
||||
|
||||
template<class Key, class T>
|
||||
QList<T> QMap<Key, T>::values(const Key &key) const
|
||||
{
|
||||
return static_cast<const QMultiMap<Key, T> *>(this)->values(key);
|
||||
}
|
||||
|
||||
template<class Key, class T>
|
||||
int QMap<Key, T>::count(const Key &key) const
|
||||
{
|
||||
return static_cast<const QMultiMap<Key, T> *>(this)->count(key);
|
||||
}
|
||||
|
||||
template<class Key, class T>
|
||||
typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const Key &key, const T &value)
|
||||
{
|
||||
return static_cast<QMultiMap<Key, T> *>(this)->insert(key, value);
|
||||
}
|
||||
|
||||
template<class Key, class T>
|
||||
typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, const Key &akey, const T &avalue)
|
||||
{
|
||||
return static_cast<QMultiMap<Key, T> *>(this)->insert(pos, akey, avalue);
|
||||
}
|
||||
|
||||
template<class Key, class T>
|
||||
QMap<Key, T> &QMap<Key, T>::unite(const QMap<Key, T> &other)
|
||||
{
|
||||
return static_cast<QMultiMap<Key, T> *>(this)->unite(other);
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_DECLARE_ASSOCIATIVE_ITERATOR(Map)
|
||||
Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Map)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user