QMultiMap: add range erase

Also remove duplication by centralizing the main code for
erase(), and implement erase(pos) in terms of erase(first, last).

Change-Id: Ie0272ebac92fd7da48c31f9d68e69a2faa583bbc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Giuseppe D'Angelo 2020-06-17 16:18:55 +02:00
parent 4fc539bd84
commit bd2bcd4e1d
3 changed files with 82 additions and 48 deletions

View File

@ -65,6 +65,8 @@ public:
using T = typename Map::mapped_type;
using value_type = typename Map::value_type;
using size_type = typename Map::size_type;
using iterator = typename Map::iterator;
using const_iterator = typename Map::const_iterator;
Map m;
@ -165,6 +167,47 @@ public:
{
return m.count(key);
}
// Used in erase. Allocates a new QMapData and copies, from this->m,
// the elements not in the [first, last) range. The return contains
// the new QMapData and an iterator in its map pointing at the first
// element after the erase.
struct EraseResult {
QMapData *data;
iterator it;
};
EraseResult erase(const_iterator first, const_iterator last) const
{
EraseResult result;
result.data = new QMapData;
result.it = result.data->m.end();
const auto newDataEnd = result.it;
auto i = m.begin();
const auto e = m.end();
// copy over all the elements before first
while (i != first) {
result.it = result.data->m.insert(newDataEnd, *i);
++i;
}
// skip until last
while (i != last)
++i;
// copy from last to the end
while (i != e) {
result.data->m.insert(newDataEnd, *i);
++i;
}
if (result.it != newDataEnd)
++result.it;
return result;
}
};
//
@ -531,36 +574,21 @@ public:
const_key_value_iterator constKeyValueEnd() const { return const_key_value_iterator(end()); }
iterator erase(const_iterator it)
{
return erase(it, std::next(it));
}
iterator erase(const_iterator afirst, const_iterator alast)
{
if (!d)
return iterator();
if (!d.isShared())
return iterator(d->m.erase(it.i));
return iterator(d->m.erase(afirst.i, alast.i));
MapData *newData = new MapData;
const auto newDataEnd = newData->m.end();
auto i = d->m.begin();
auto e = d->m.end();
size_type steps = 0;
while (i != it.i) {
newData->m.insert(newDataEnd, *i);
++i;
++steps;
}
if (i != e)
++i;
while (i != e)
newData->m.insert(newDataEnd, *i);
d.reset(newData);
auto result = std::next(d->m.begin(), steps);
return iterator(result);
auto result = d->erase(afirst.i, alast.i);
d.reset(result.data);
return iterator(result.it);
}
// more Qt
@ -1138,36 +1166,21 @@ public:
const_key_value_iterator constKeyValueEnd() const { return const_key_value_iterator(end()); }
iterator erase(const_iterator it)
{
return erase(it, std::next(it));
}
iterator erase(const_iterator afirst, const_iterator alast)
{
if (!d)
return iterator();
if (!d.isShared())
return iterator(d->m.erase(it.i));
return iterator(d->m.erase(afirst.i, alast.i));
auto newData = new MapData;
const auto newDataEnd = newData->m.end();
auto i = d->m.begin();
auto e = d->m.end();
size_type steps = 0;
while (i != it.i) {
newData->m.insert(newDataEnd, *i);
++i;
++steps;
}
if (i != e)
++i;
while (i != e)
newData->m.insert(newDataEnd, *i++);
d.reset(newData);
auto result = std::next(d->m.begin(), steps);
return iterator(result);
auto result = d->erase(afirst.i, alast.i);
d.reset(result.data);
return iterator(result.it);
}
// more Qt

View File

@ -660,6 +660,16 @@
\sa remove()
*/
/*! \fn template <class Key, class T> QMap<Key, T>::iterator QMap<Key, T>::erase(const_iterator first, const_iterator last)
\since 6.0
Removes the (key, value) pairs pointed to by the iterator range
[\a first, \a last) from the map.
Returns an iterator to the item in the map following the last removed element.
\sa remove()
*/
/*! \fn template <class Key, class T> QMap<Key, T>::iterator QMap<Key, T>::find(const Key &key)
Returns an iterator pointing to the item with key \a key in the

View File

@ -664,6 +664,17 @@
\sa remove()
*/
/*! \fn template <class Key, class T> QMultiMap<Key, T>::iterator QMultiMap<Key, T>::erase(const_iterator first, const_iterator last)
\since 6.0
Removes the (key, value) pairs pointed to by the iterator range
[\a first, \a last) from the multi map.
Returns an iterator to the item in the multi map following the last
removed element.
\sa remove()
*/
/*! \fn template <class Key, class T> QMultiMap<Key, T>::iterator QMultiMap<Key, T>::find(const Key &key)
Returns an iterator pointing to the item with key \a key in the