Long Live QMap as a refcounted std::map!

... and QMultiMap as std::multimap.

Just use the implementation from the STL; we can't really claim that
our code is much better than STL's, or does things any differently
(de facto they're both red-black trees).

Decouple QMultiMap from QMap, by making it NOT inherit from
QMap any longer. This completes the deprecation started in 5.15:
QMap now does not store duplicated keys any more.

Something to establish is where to put the
QExplictlySharedDataPointer replcement that is in there as an
ad-hoc solution. There's a number of patches in-flight by Marc
that try to introduce the same (or very similar) functionality.

Miscellanea changes to the Q(Multi)Map code itself:

* consistently use size_type instead of int;
* pass iterators by value;
* drop QT_STRICT_ITERATORS;
* iterators implictly convert to const_iterators, and APIs
  take const_iterators;
* iterators are just bidirectional and not random access;
* added noexcept where it makes sense;
* "inline" dropped (churn);
* qMapLessThanKey dropped (undocumented, 0 hits in Qt, 1 hit in KDE);
* operator== on Q(Multi)Map requires operator== on the key type
  (we're checking for equality, not equivalence!).

Very few breakages occur in qtbase.

[ChangeLog][Potentially Source-Incompatible Changes] QMap does not
support multiple equivalent keys any more. Any related functionality
has been removed from QMap, following the deprecation that happened
in Qt 5.15. Use QMultiMap for this use case.

[ChangeLog][Potentially Source-Incompatible Changes] QMap and
QMultiMap iterators random-access API have been removed. Note that
the iterators have always been just bidirectional; moving
an iterator by N positions can still be achieved using std::next
or std::advance, at the same cost as before (O(N)).

[ChangeLog][Potentially Source-Incompatible Changes] QMultiMap does
not inherit from QMap any more. Amongst other things, this means
that iterators on a QMultiMap now belong to the QMultiMap class
(and not to the QMap class); new Java iterators have been added.

Change-Id: I5a0fe9b020f92c21b37065a1defff783b5d2b7a9
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
bb10
Giuseppe D'Angelo 2020-07-22 14:07:48 +02:00
parent 7d27316d9f
commit 14090760a8
24 changed files with 3434 additions and 2173 deletions

View File

@ -296,7 +296,7 @@ void MainWindow::on_printPreviewAction_triggered()
void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer)
{
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
const QString family = (pageMap.begin() + index).key();
const QString family = std::next(pageMap.begin(), index).key();
const StyleItems items = pageMap.value(family);
// Find the dimensions of the text on each page.

View File

@ -112,7 +112,7 @@ qt_add_tool(${target_name}
../src/corelib/tools/qlist.cpp ../src/corelib/tools/qlist.h
../src/corelib/text/qlocale.cpp ../src/corelib/text/qlocale.h
../src/corelib/text/qlocale_tools.cpp ../src/corelib/text/qlocale_tools_p.h
../src/corelib/tools/qmap.cpp ../src/corelib/tools/qmap.h
../src/corelib/tools/qmap.h
../src/corelib/text/qregularexpression.cpp ../src/corelib/text/qregularexpression.h
../src/corelib/tools/qringbuffer.cpp # special case
../src/corelib/text/qstring.cpp ../src/corelib/text/qstring.h

View File

@ -30,7 +30,7 @@ QOBJS = \
qarraydata.o qbitarray.o qbytearray.o qbytearraylist.o qbytearraymatcher.o \
qcalendar.o qgregoriancalendar.o qromancalendar.o \
qcryptographichash.o qdatetime.o qhash.o \
qlocale.o qlocale_tools.o qmap.o qregularexpression.o qringbuffer.o \
qlocale.o qlocale_tools.o qregularexpression.o qringbuffer.o \
qstringbuilder.o qstring.o qstringconverter.o qstringlist.o qversionnumber.o \
qvsnprintf.o \
pcre2_auto_possess.o pcre2_chartables.o pcre2_compile.o pcre2_config.o \
@ -129,7 +129,6 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp \
$(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp \
$(SOURCE_PATH)/src/corelib/tools/qhash.cpp \
$(SOURCE_PATH)/src/corelib/tools/qmap.cpp \
$(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp \
$(SOURCE_PATH)/src/corelib/tools/qversionnumber.cpp \
$(SOURCE_PATH)/src/3rdparty/pcre2/src/pcre2_auto_possess.c \

View File

@ -99,7 +99,6 @@ QTOBJS= \
qlocale_win.obj \
qversionnumber.obj \
qmalloc.obj \
qmap.obj \
qoperatingsystemversion.obj \
qoperatingsystemversion_win.obj \
qromancalendar.obj \

View File

@ -149,7 +149,6 @@ SOURCES += \
qlocale_tools.cpp \
qlogging.cpp \
qmalloc.cpp \
qmap.cpp \
qmetatype.cpp \
qnumeric.cpp \
qregularexpression.cpp \

View File

@ -213,7 +213,7 @@ qt_add_module(Core
tools/qline.cpp tools/qline.h
tools/qlist.cpp tools/qlist.h
tools/qmakearray_p.h
tools/qmap.cpp tools/qmap.h
tools/qmap.h
tools/qmargins.cpp tools/qmargins.h
tools/qmessageauthenticationcode.cpp tools/qmessageauthenticationcode.h
tools/qoffsetstringarray_p.h

View File

@ -183,6 +183,35 @@ while (i.findNext(widget)) {
}
//! [28]
//! [26multi]
QMultiMap<int, QWidget *> multimap;
...
QMultiMapIterator<int, QWidget *> i(multimap);
while (i.hasNext()) {
i.next();
qDebug() << i.key() << ": " << i.value();
}
//! [26multi]
//! [27multi]
QMultiMapIterator<int, QWidget *> i(multimap);
i.toBack();
while (i.hasPrevious()) {
i.previous();
qDebug() << i.key() << ": " << i.value();
}
//! [27multi]
//! [28multi]
QMultiMapIterator<int, QWidget *> i(multimap);
while (i.findNext(widget)) {
qDebug() << "Found widget " << widget << " under key "
<< i.key();
}
//! [28multi]
//! [29]
QHash<int, QWidget *> hash;
@ -244,6 +273,46 @@ while (i.hasNext()) {
//! [35]
//! [32multi]
QMultiMap<int, QWidget *> multimap;
...
QMutableMultiMapIterator<int, QWidget *> i(multimap);
while (i.hasNext()) {
i.next();
qDebug() << i.key() << ": " << i.value();
}
//! [32multi]
//! [33multi]
QMutableMultiMapIterator<int, QWidget *> i(multimap);
i.toBack();
while (i.hasPrevious()) {
i.previous();
qDebug() << i.key() << ": " << i.value();
}
//! [33multi]
//! [34multi]
QMutableMultiMapIterator<int, QWidget *> i(multimap);
while (i.findNext(widget)) {
qDebug() << "Found widget " << widget << " under key "
<< i.key();
}
//! [34multi]
//! [35multi]
QMutableMultiMapIterator<QString, QString> i(multimap);
while (i.hasNext()) {
i.next();
if (i.key() == i.value())
i.remove();
}
//! [35multi]
//! [36]
QHash<int, QWidget *> hash;
...

View File

@ -0,0 +1,324 @@
/****************************************************************************
**
** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
//! [0]
QMultiMap<QString, int> multimap;
//! [0]
//! [2]
multimap.insert("a", 1);
multimap.insert("b", 3);
multimap.insert("c", 7);
multimap.insert("c", -5);
//! [2]
//! [3]
int num2 = multimap.value("a"); // 1
int num3 = multimap.value("thirteen"); // not found; 0
int num3 = 0;
auto it = multimap.value("b");
if (it != multimap.end()) {
num3 = it.value();
}
//! [3]
//! [4]
int timeout = 30;
if (multimap.contains("TIMEOUT"))
timeout = multimap.value("TIMEOUT");
// better:
auto it = multimap.find("TIMEOUT");
if (it != multimap.end())
timeout = it.value();
//! [4]
//! [5]
int timeout = multimap.value("TIMEOUT", 30);
//! [5]
//! [7]
QMultiMapIterator<QString, int> i(multimap);
while (i.hasNext()) {
i.next();
cout << i.key() << ": " << i.value() << Qt::endl;
}
//! [7]
//! [8]
auto i = multimap.constBegin();
while (i != multimap.constEnd()) {
cout << i.key() << ": " << i.value() << Qt::endl;
++i;
}
//! [8]
//! [9]
multimap.insert("plenty", 100);
multimap.insert("plenty", 2000);
// multimap.size() == 2
//! [9]
//! [10]
QList<int> values = multimap.values("plenty");
for (int i = 0; i < values.size(); ++i)
cout << values.at(i) << Qt::endl;
//! [10]
//! [11]
QMultiMap<QString, int>::iterator i = multimap.find("plenty");
while (i != map.end() && i.key() == "plenty") {
cout << i.value() << Qt::endl;
++i;
}
// better:
auto [i, end] = multimap.equal_range("plenty");
while (i != end) {
cout << i.value() << Qt::endl;
++i;
}
//! [11]
//! [12]
QMap<QString, int> multimap;
...
foreach (int value, multimap)
cout << value << Qt::endl;
//! [12]
//! [13]
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class Employee
{
public:
Employee() {}
Employee(const QString &name, QDate dateOfBirth);
...
private:
QString myName;
QDate myDateOfBirth;
};
inline bool operator<(const Employee &e1, const Employee &e2)
{
if (e1.name() != e2.name())
return e1.name() < e2.name();
return e1.dateOfBirth() < e2.dateOfBirth();
}
#endif // EMPLOYEE_H
//! [13]
//! [15]
QMultiMap<int, QString> multimap;
multimap.insert(1, "one");
multimap.insert(5, "five");
multimap.insert(5, "five (2)");
multimap.insert(10, "ten");
multimap.lowerBound(0); // returns iterator to (1, "one")
multimap.lowerBound(1); // returns iterator to (1, "one")
multimap.lowerBound(2); // returns iterator to (5, "five")
multimap.lowerBound(5); // returns iterator to (5, "five")
multimap.lowerBound(6); // returns iterator to (10, "ten")
multimap.lowerBound(10); // returns iterator to (10, "ten")
multimap.lowerBound(999); // returns end()
//! [15]
//! [16]
QMap<QString, int> multimap;
...
QMap<QString, int>::const_iterator i = multimap.lowerBound("HDR");
QMap<QString, int>::const_iterator upperBound = multimap.upperBound("HDR");
while (i != upperBound) {
cout << i.value() << Qt::endl;
++i;
}
//! [16]
//! [17]
QMultiMap<int, QString> multimap;
multimap.insert(1, "one");
multimap.insert(5, "five");
multimap.insert(5, "five (2)");
multimap.insert(10, "ten");
multimap.upperBound(0); // returns iterator to (1, "one")
multimap.upperBound(1); // returns iterator to (5, "five")
multimap.upperBound(2); // returns iterator to (5, "five")
multimap.lowerBound(5); // returns iterator to (5, "five (2)")
multimap.lowerBound(6); // returns iterator to (10, "ten")
multimap.upperBound(10); // returns end()
multimap.upperBound(999); // returns end()
//! [17]
//! [18]
QMultiMap<QString, int> multimap;
multimap.insert("January", 1);
multimap.insert("February", 2);
...
multimap.insert("December", 12);
QMap<QString, int>::iterator i;
for (i = multimap.begin(); i != multimap.end(); ++i)
cout << i.key() << ": " << i.value() << Qt::endl;
//! [18]
//! [19]
QMultiMap<QString, int>::iterator i;
for (i = multimap.begin(); i != multimap.end(); ++i)
i.value() += 2;
//! [19]
//! [20]
QMultiMap<QString, int>::iterator i = multimap.begin();
while (i != multimap.end()) {
if (i.key().startsWith('_'))
i = multimap.erase(i);
else
++i;
}
//! [20]
//! [21]
QMultiMap<QString, int>::iterator i = multimap.begin();
while (i != multimap.end()) {
QMap<QString, int>::iterator prev = i;
++i;
if (prev.key().startsWith('_'))
multimap.erase(prev);
}
//! [21]
//! [22]
// WRONG
while (i != multimap.end()) {
if (i.key().startsWith('_'))
multimap.erase(i);
++i;
}
//! [22]
//! [23]
if (i.key() == "Hello")
i.value() = "Bonjour";
//! [23]
//! [24]
QMultiMap<QString, int> multi;
multimap.insert("January", 1);
multimap.insert("February", 2);
...
multimap.insert("December", 12);
QMultiMap<QString, int>::const_iterator i;
for (i = multimap.constBegin(); i != multimap.constEnd(); ++i)
cout << i.key() << ": " << i.value() << Qt::endl;
//! [24]
//! [25]
QMultiMap<QString, int> map1, map2, map3;
map1.insert("plenty", 100);
map1.insert("plenty", 2000);
// map1.size() == 2
map2.insert("plenty", 5000);
// map2.size() == 1
map3 = map1 + map2;
// map3.size() == 3
//! [25]
//! [keyiterator1]
for (QMultiMap<int, QString>::const_iterator it = multimap.cbegin(), end = multimap.cend(); it != end; ++it) {
cout << "The key: " << it.key() << Qt::endl
cout << "The value: " << it.value() << Qt::endl;
cout << "Also the value: " << (*it) << Qt::endl;
}
//! [keyiterator1]
//! [keyiterator2]
// Inefficient, keys() is expensive
QList<int> keys = multimap.keys();
int numPrimes = std::count_if(multimap.cbegin(), multimap.cend(), isPrimeNumber);
qDeleteAll(multimap2.keys());
// Efficient, no memory allocation needed
int numPrimes = std::count_if(multimap.keyBegin(), multimap.keyEnd(), isPrimeNumber);
qDeleteAll(multimap2.keyBegin(), multimap2.keyEnd());
//! [keyiterator2]

View File

@ -924,7 +924,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
const QVariantHash *hash = v_cast<QVariantHash>(d);
const auto end = hash->end();
for (auto it = hash->begin(); it != end; ++it)
static_cast<QMultiMap<QString, QVariant> *>(map)->insert(it.key(), it.value());
map->insert(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
} else if (d->type().id() == QMetaType::QCborValue) {
if (!v_cast<QCborValue>(d)->isMap())

View File

@ -808,7 +808,7 @@ namespace QtPrivate {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantMap l;
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
static_cast<QMultiMap<QString, QVariant> &>(l).insert(it.key().toString(), it.value());
l.insert(it.key().toString(), it.value());
return l;
}
return QVariantValueHelper<QVariantMap>::invoke(v);

View File

@ -709,15 +709,15 @@
\class QMapIterator
\inmodule QtCore
\brief The QMapIterator class provides a Java-style const iterator for QMap and QMultiMap.
\brief The QMapIterator class provides a Java-style const iterator for QMap.
QMap has both \l{Java-style iterators} and \l{STL-style
iterators}. The Java-style iterators are more high-level and
easier to use than the STL-style iterators; on the other hand,
they are slightly less efficient.
QMapIterator\<Key, T\> allows you to iterate over a QMap (or a
QMultiMap). If you want to modify the map as you iterate over
QMapIterator\<Key, T\> allows you to iterate over a QMap.
If you want to modify the map as you iterate over
it, use QMutableMapIterator instead.
The QMapIterator constructor takes a QMap as argument. After
@ -757,6 +757,57 @@
\sa QMutableMapIterator, QMap::const_iterator
*/
/*!
\class QMultiMapIterator
\inmodule QtCore
\brief The QMultiMapIterator class provides a Java-style const iterator for QMultiMap.
QMultiMap has both \l{Java-style iterators} and \l{STL-style
iterators}. The Java-style iterators are more high-level and
easier to use than the STL-style iterators; on the other hand,
they are slightly less efficient.
QMultiMapIterator\<Key, T\> allows you to iterate over a QMultiMap.
If you want to modify the map as you iterate over
it, use QMutableMultiMapIterator instead.
The QMultiMapIterator constructor takes a QMultiMap as argument. After
construction, the iterator is located at the very beginning of
the map (before the first item). Here's how to iterate over all
the elements sequentially:
\snippet code/doc_src_qiterator.cpp 26multi
The next() function returns the next item in the map and
advances the iterator. The key() and value() functions return the
key and value of the last item that was jumped over.
Unlike STL-style iterators, Java-style iterators point \e between
items rather than directly \e at items. The first call to next()
advances the iterator to the position between the first and
second item, and returns the first item; the second call to
next() advances the iterator to the position between the second
and third item; and so on.
\image javaiterators1.png
Here's how to iterate over the elements in reverse order:
\snippet code/doc_src_qiterator.cpp 27multi
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop. For example:
\snippet code/doc_src_qiterator.cpp 28multi
Multiple iterators can be used on the same map. If the map is
modified while a QMultiMapIterator is active, the QMultiMapIterator will
continue iterating over the original map, ignoring the modified
copy.
\sa QMutableMultiMapIterator, QMultiMapIterator::const_iterator
*/
/*!
\class QHashIterator
\inmodule QtCore
@ -809,7 +860,7 @@
\class QMutableMapIterator
\inmodule QtCore
\brief The QMutableMapIterator class provides a Java-style non-const iterator for QMap and QMultiMap.
\brief The QMutableMapIterator class provides a Java-style non-const iterator for QMap.
QMap has both \l{Java-style iterators} and \l{STL-style
iterators}. The Java-style iterators are more high-level and
@ -817,7 +868,7 @@
they are slightly less efficient.
QMutableMapIterator\<Key, T\> allows you to iterate over a QMap
(or a QMultiMap) and modify the map. If you don't want to modify
and modify the map. If you don't want to modify
the map (or have a const QMap), use the slightly faster
QMapIterator instead.
@ -870,6 +921,71 @@
\sa QMapIterator, QMap::iterator
*/
/*!
\class QMutableMultiMapIterator
\inmodule QtCore
\brief The QMutableMultiMapIterator class provides a Java-style non-const iterator for QMultiMap.
QMultiMap has both \l{Java-style iterators} and \l{STL-style
iterators}. The Java-style iterators are more high-level and
easier to use than the STL-style iterators; on the other hand,
they are slightly less efficient.
QMutableMultiMapIterator\<Key, T\> allows you to iterate over a QMultiMap
and modify the map. If you don't want to modify
the map (or have a const QMultiMap), use the slightly faster
QMultiMapIterator instead.
The QMutableMultiMapIterator constructor takes a QMultiMap as argument.
After construction, the iterator is located at the very beginning
of the map (before the first item). Here's how to iterate over
all the elements sequentially:
\snippet code/doc_src_qiterator.cpp 32multi
The next() function returns the next item in the map and
advances the iterator. The key() and value() functions return the
key and value of the last item that was jumped over.
Unlike STL-style iterators, Java-style iterators point \e between
items rather than directly \e at items. The first call to next()
advances the iterator to the position between the first and
second item, and returns the first item; the second call to
next() advances the iterator to the position between the second
and third item; and so on.
\image javaiterators1.png
Here's how to iterate over the elements in reverse order:
\snippet code/doc_src_qiterator.cpp 33multi
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop. For example:
\snippet code/doc_src_qiterator.cpp 34multi
If you want to remove items as you iterate over the map, use
remove(). If you want to modify the value of an item, use
setValue().
Example:
\snippet code/doc_src_qiterator.cpp 35multi
The example removes all (key, value) pairs where the key and the
value are the same.
Only one mutable iterator can be active on a given map at any
time. Furthermore, no changes should be done directly to the map
while the iterator is active (as opposed to through the
iterator), since this could invalidate the iterator and lead to
undefined behavior.
\sa QMultiMapIterator, QMultiMap::iterator
*/
/*!
\class QMutableHashIterator
\inmodule QtCore
@ -933,6 +1049,8 @@
/*! \fn template <class Key, class T> QMapIterator<Key, T>::QMapIterator(const QMap<Key, T> &map)
\fn template <class Key, class T> QMutableMapIterator<Key, T>::QMutableMapIterator(QMap<Key, T> &map)
\fn template <class Key, class T> QMultiMapIterator<Key, T>::QMultiMapIterator(const QMultiMap<Key, T> &map)
\fn template <class Key, class T> QMutableMultiMapIterator<Key, T>::QMutableMultiMapIterator(QMultiMap<Key, T> &map)
Constructs an iterator for traversing \a map. The iterator is set
to be at the front of the map (before the first item).
@ -951,6 +1069,8 @@
/*! \fn template <class Key, class T> QMapIterator &QMapIterator<Key, T>::operator=(const QMap<Key, T> &map)
\fn template <class Key, class T> QMutableMapIterator &QMutableMapIterator<Key, T>::operator=(QMap<Key, T> &map)
\fn template <class Key, class T> QMultiMapIterator &QMultiMapIterator<Key, T>::operator=(const QMultiMap<Key, T> &map)
\fn template <class Key, class T> QMutableMultiMapIterator &QMutableMultiMapIterator<Key, T>::operator=(QMultiMap<Key, T> &map)
Makes the iterator operate on \a map. The iterator is set to be
at the front of the map (before the first item).
@ -968,8 +1088,10 @@
*/
/*! \fn template <class Key, class T> void QMapIterator<Key, T>::toFront()
\fn template <class Key, class T> void QMultiMapIterator<Key, T>::toFront()
\fn template <class Key, class T> void QHashIterator<Key, T>::toFront()
\fn template <class Key, class T> void QMutableMapIterator<Key, T>::toFront()
\fn template <class Key, class T> void QMutableMultiMapIterator<Key, T>::toFront()
\fn template <class Key, class T> void QMutableHashIterator<Key, T>::toFront()
Moves the iterator to the front of the container (before the
@ -979,7 +1101,9 @@
*/
/*! \fn template <class Key, class T> void QMapIterator<Key, T>::toBack()
\fn template <class Key, class T> void QMultiMapIterator<Key, T>::toBack()
\fn template <class Key, class T> void QMutableMapIterator<Key, T>::toBack()
\fn template <class Key, class T> void QMutableMultiMapIterator<Key, T>::toBack()
Moves the iterator to the back of the container (after the last
item).
@ -998,7 +1122,9 @@
*/
/*! \fn template <class Key, class T> bool QMapIterator<Key, T>::hasNext() const
\fn template <class Key, class T> bool QMultiMapIterator<Key, T>::hasNext() const
\fn template <class Key, class T> bool QMutableMapIterator<Key, T>::hasNext() const
\fn template <class Key, class T> bool QMutableMultiMapIterator<Key, T>::hasNext() const
Returns \c true if there is at least one item ahead of the iterator,
i.e. the iterator is \e not at the back of the container;
@ -1019,6 +1145,7 @@
*/
/*! \fn template <class Key, class T> QMapIterator<Key, T>::Item QMapIterator<Key, T>::next()
\fn template <class Key, class T> QMultiMapIterator<Key, T>::Item QMultiMapIterator<Key, T>::next()
Returns the next item and advances the iterator by one position.
@ -1032,6 +1159,7 @@
*/
/*! \fn template <class Key, class T> QMutableMapIterator<Key, T>::Item QMutableMapIterator<Key, T>::next()
\fn template <class Key, class T> QMutableMultiMapIterator<Key, T>::Item QMutableMultiMapIterator<Key, T>::next()
Returns the next item and advances the iterator by one position.
@ -1073,6 +1201,7 @@
*/
/*! \fn template <class Key, class T> QMapIterator<Key, T>::Item QMapIterator<Key, T>::peekNext() const
\fn template <class Key, class T> QMutableMapIterator<Key, T>::Item QMutableMapIterator<Key, T>::peekNext()
Returns the next item without moving the iterator.
@ -1086,6 +1215,7 @@
*/
/*! \fn template <class Key, class T> QMutableMapIterator<Key, T>::Item QMutableMapIterator<Key, T>::peekNext() const
\fn template <class Key, class T> QMutableMultiMapIterator<Key, T>::Item QMutableMultiMapIterator<Key, T>::peekNext()
Returns a reference to the next item without moving the iterator.
@ -1127,7 +1257,9 @@
*/
/*! \fn template <class Key, class T> bool QMapIterator<Key, T>::hasPrevious() const
\fn template <class Key, class T> bool QMultiMapIterator<Key, T>::hasPrevious() const
\fn template <class Key, class T> bool QMutableMapIterator<Key, T>::hasPrevious() const
\fn template <class Key, class T> bool QMutableMultiMapIterator<Key, T>::hasPrevious() const
Returns \c true if there is at least one item behind the iterator,
i.e. the iterator is \e not at the front of the container;
@ -1160,6 +1292,8 @@
/*! \fn template <class Key, class T> QMapIterator<Key, T>::Item QMapIterator<Key, T>::previous()
\fn template <class Key, class T> QMutableMapIterator<Key, T>::Item QMutableMapIterator<Key, T>::previous()
\fn template <class Key, class T> QMultiMapIterator<Key, T>::Item QMultiMapIterator<Key, T>::previous()
\fn template <class Key, class T> QMutableMultiMapIterator<Key, T>::Item QMutableMultiMapIterator<Key, T>::previous()
Returns the previous item and moves the iterator back by one
position.
@ -1207,6 +1341,8 @@
/*! \fn template <class Key, class T> QMapIterator<Key, T>::Item QMapIterator<Key, T>::peekPrevious() const
\fn template <class Key, class T> QMutableMapIterator<Key, T>::Item QMutableMapIterator<Key, T>::peekPrevious() const
\fn template <class Key, class T> QMultiMapIterator<Key, T>::Item QMultiMapIterator<Key, T>::peekPrevious() const
\fn template <class Key, class T> QMutableMultiMapIterator<Key, T>::Item QMutableMultiMapIterator<Key, T>::peekPrevious() const
Returns the previous item without moving the iterator.
@ -1250,6 +1386,7 @@
*/
/*! \fn template <class Key, class T> const T &QMapIterator<Key, T>::value() const
\fn template <class Key, class T> const T &QMultiMapIterator<Key, T>::value() const
Returns the value of the last item that was jumped over using one
of the traversal functions (next(), previous(), findNext(),
@ -1264,6 +1401,7 @@
/*!
\fn template <class Key, class T> const T &QMutableMapIterator<Key, T>::value() const
\fn template <class Key, class T> const T &QMutableMultiMapIterator<Key, T>::value() const
Returns the value of the last item that was jumped over using one
of the traversal functions (next(), previous(), findNext(),
@ -1295,6 +1433,7 @@
/*!
\fn template <class Key, class T> T &QMutableMapIterator<Key, T>::value()
\fn template <class Key, class T> T &QMutableMultiMapIterator<Key, T>::value()
\fn template <class Key, class T> T &QMutableHashIterator<Key, T>::value()
\overload
@ -1305,6 +1444,8 @@
/*! \fn template <class Key, class T> const Key &QMapIterator<Key, T>::key() const
\fn template <class Key, class T> const Key &QMutableMapIterator<Key, T>::key() const
\fn template <class Key, class T> const Key &QMultiMapIterator<Key, T>::key() const
\fn template <class Key, class T> const Key &QMutableMultiMapIterator<Key, T>::key() const
Returns the key of the last item that was jumped over using one
of the traversal functions (next(), previous(), findNext(),
@ -1328,6 +1469,8 @@
/*! \fn template <class Key, class T> bool QMapIterator<Key, T>::findNext(const T &value)
\fn template <class Key, class T> bool QMutableMapIterator<Key, T>::findNext(const T &value)
\fn template <class Key, class T> bool QMultiMapIterator<Key, T>::findNext(const T &value)
\fn template <class Key, class T> bool QMutableMultiMapIterator<Key, T>::findNext(const T &value)
Searches for \a value starting from the current iterator position
forward. Returns \c true if a (key, value) pair with value \a value
@ -1354,6 +1497,8 @@
/*! \fn template <class Key, class T> bool QMapIterator<Key, T>::findPrevious(const T &value)
\fn template <class Key, class T> bool QMutableMapIterator<Key, T>::findPrevious(const T &value)
\fn template <class Key, class T> bool QMultiMapIterator<Key, T>::findPrevious(const T &value)
\fn template <class Key, class T> bool QMutableMultiMapIterator<Key, T>::findPrevious(const T &value)
Searches for \a value starting from the current iterator position
backward. Returns \c true if a (key, value) pair with value \a value
@ -1397,6 +1542,7 @@
*/
/*! \fn template <class Key, class T> void QMutableMapIterator<Key, T>::remove()
\fn template <class Key, class T> void QMutableMultiMapIterator<Key, T>::remove()
Removes the last item that was jumped over using one of the
traversal functions (next(), previous(), findNext(), findPrevious()).
@ -1413,6 +1559,7 @@
*/
/*! \fn template <class Key, class T> void QMutableMapIterator<Key, T>::setValue(const T &value)
\fn template <class Key, class T> void QMutableMultiMapIterator<Key, T>::setValue(const T &value)
Replaces the value of the last item that was jumped over using
one of the traversal functions with \a value.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,6 @@ SOURCES += \
tools/qline.cpp \
tools/qlist.cpp \
tools/qpoint.cpp \
tools/qmap.cpp \
tools/qmargins.cpp \
tools/qmessageauthenticationcode.cpp \
tools/qcontiguouscache.cpp \

View File

@ -2157,7 +2157,7 @@ QList<StyleRule> StyleSelector::styleRulesForNode(NodePtr node)
}
rules.reserve(weightedRules.count());
QMap<uint, StyleRule>::const_iterator it = weightedRules.constBegin();
QMultiMap<uint, StyleRule>::const_iterator it = weightedRules.constBegin();
for ( ; it != weightedRules.constEnd() ; ++it)
rules += *it;

View File

@ -119,7 +119,6 @@ qt_extend_target(Bootstrap
../../corelib/tools/qcryptographichash.cpp
../../corelib/tools/qhash.cpp
../../corelib/tools/qline.cpp
../../corelib/tools/qmap.cpp
../../corelib/tools/qpoint.cpp
../../corelib/tools/qrect.cpp
../../corelib/tools/qringbuffer.cpp

View File

@ -104,7 +104,6 @@ SOURCES += \
../../corelib/tools/qcommandlineoption.cpp \
../../corelib/tools/qcryptographichash.cpp \
../../corelib/tools/qhash.cpp \
../../corelib/tools/qmap.cpp \
../../corelib/tools/qringbuffer.cpp \
../../corelib/tools/qpoint.cpp \
../../corelib/tools/qrect.cpp \

View File

@ -2207,7 +2207,7 @@ int QWizard::addPage(QWizardPage *page)
Q_D(QWizard);
int theid = 0;
if (!d->pageMap.isEmpty())
theid = (d->pageMap.constEnd() - 1).key() + 1;
theid = d->pageMap.lastKey() + 1;
setPage(theid, page);
return theid;
}

View File

@ -274,8 +274,8 @@ bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
ContextIterator contextEnd = contexts.end();
for (ContextIterator context = contexts.begin(); context != contextEnd; ++context) {
Qt::GestureType gestureType = context.value();
const QMap<Qt::GestureType, QGestureRecognizer *> &const_recognizers = m_recognizers;
QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
const QMultiMap<Qt::GestureType, QGestureRecognizer *> &const_recognizers = m_recognizers;
QMultiMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
typeToRecognizerIterator = const_recognizers.lowerBound(gestureType),
typeToRecognizerEnd = const_recognizers.upperBound(gestureType);
for (; typeToRecognizerIterator != typeToRecognizerEnd; ++typeToRecognizerIterator) {

View File

@ -4290,10 +4290,10 @@ void tst_QVariant::iterateContainerElements()
QAssociativeIterable iter = var.value<QAssociativeIterable>();
QAssociativeIterable::const_iterator it = iter.begin();
QAssociativeIterable::const_iterator end = iter.end();
QCOMPARE(*(mapping.begin() + 1), (*(it + 1)).toString());
QCOMPARE(*(++mapping.begin()), (*(it + 1)).toString());
int i = 0;
for ( ; it != end; ++it, ++i) {
QCOMPARE(*(mapping.begin() + i), (*it).toString());
QCOMPARE(*(std::next(mapping.begin(), i)), (*it).toString());
}
QVariantList nums;

View File

@ -2609,6 +2609,7 @@ class LessThanComparable
{
public:
bool operator<(const LessThanComparable &) const { return true; }
bool operator==(const LessThanComparable &) const { return true; }
};
class EqualsComparable
@ -2937,20 +2938,6 @@ void tst_Collections::forwardDeclared()
}
}
class alignas(4) Aligned4
{
char i;
public:
Aligned4(int i = 0) : i(i) {}
enum { PreferredAlignment = 4 };
inline bool operator==(const Aligned4 &other) const { return i == other.i; }
inline bool operator<(const Aligned4 &other) const { return i < other.i; }
friend inline size_t qHash(const Aligned4 &a) { return qHash(a.i); }
};
static_assert(alignof(Aligned4) % 4 == 0);
#if defined(Q_PROCESSOR_ARM)
# if defined(Q_COMPILER_ALIGNAS) && defined(__BIGGEST_ALIGNMENT__)
// On ARM __BIGGEST_ALIGNMENT__ must be multiplied by 8 to
@ -2963,18 +2950,29 @@ static_assert(alignof(Aligned4) % 4 == 0);
# define BIGGEST_ALIGNMENT_TO_TEST 128
#endif
class alignas(BIGGEST_ALIGNMENT_TO_TEST) AlignedBiggest
template <size_t Alignment>
class alignas(Alignment) AlignedClass
{
char i;
public:
AlignedBiggest(int i = 0) : i(i) {}
AlignedClass(int i = 0) : i(i) {}
enum { PreferredAlignment = BIGGEST_ALIGNMENT_TO_TEST };
enum { PreferredAlignment = Alignment };
inline bool operator==(const AlignedBiggest &other) const { return i == other.i; }
inline bool operator<(const AlignedBiggest &other) const { return i < other.i; }
friend inline int qHash(const AlignedBiggest &a) { return qHash(a.i); }
inline bool operator==(const AlignedClass &other) const { return i == other.i; }
inline bool operator<(const AlignedClass &other) const { return i < other.i; }
friend inline int qHash(const AlignedClass &a) { return qHash(a.i); }
};
using Aligned4 = AlignedClass<4>;
static_assert(alignof(Aligned4) % 4 == 0);
using AlignedStdMax = AlignedClass<alignof(std::max_align_t)>;
static_assert(alignof(AlignedStdMax) % alignof(std::max_align_t) == 0);
using AlignedBiggest = AlignedClass<BIGGEST_ALIGNMENT_TO_TEST>;
static_assert(BIGGEST_ALIGNMENT_TO_TEST > alignof(std::max_align_t), "Not overly aligned");
static_assert(alignof(AlignedBiggest) % BIGGEST_ALIGNMENT_TO_TEST == 0);
template<typename C>
@ -3032,18 +3030,29 @@ void testAssociativeContainerAlignment()
void tst_Collections::alignment()
{
testVectorAlignment<QList<Aligned4>>();
testVectorAlignment<QList<AlignedBiggest>>();
testContiguousCacheAlignment<QContiguousCache<Aligned4>>();
testContiguousCacheAlignment<QContiguousCache<AlignedBiggest>>();
testAssociativeContainerAlignment<QMap<Aligned4, Aligned4>>();
testAssociativeContainerAlignment<QMap<Aligned4, AlignedBiggest>>();
testAssociativeContainerAlignment<QMap<AlignedBiggest, Aligned4>>();
testAssociativeContainerAlignment<QMap<AlignedBiggest, AlignedBiggest>>();
testAssociativeContainerAlignment<QHash<Aligned4, Aligned4>>();
testAssociativeContainerAlignment<QHash<Aligned4, AlignedBiggest>>();
testAssociativeContainerAlignment<QHash<AlignedBiggest, Aligned4>>();
testAssociativeContainerAlignment<QHash<AlignedBiggest, AlignedBiggest>>();
testVectorAlignment<QList<Aligned4> >();
testVectorAlignment<QList<AlignedStdMax> >();
testVectorAlignment<QList<AlignedBiggest> >();
testContiguousCacheAlignment<QContiguousCache<Aligned4> >();
testContiguousCacheAlignment<QContiguousCache<AlignedStdMax> >();
testContiguousCacheAlignment<QContiguousCache<AlignedBiggest> >();
// there's no guarentee that std::map supports over-aligned types
testAssociativeContainerAlignment<QMap<Aligned4, Aligned4> >();
testAssociativeContainerAlignment<QMap<Aligned4, AlignedStdMax> >();
testAssociativeContainerAlignment<QMap<AlignedStdMax, Aligned4> >();
testAssociativeContainerAlignment<QMap<AlignedStdMax, AlignedStdMax> >();
testAssociativeContainerAlignment<QHash<Aligned4, Aligned4> >();
testAssociativeContainerAlignment<QHash<Aligned4, AlignedStdMax> >();
testAssociativeContainerAlignment<QHash<Aligned4, AlignedBiggest> >();
testAssociativeContainerAlignment<QHash<AlignedStdMax, Aligned4> >();
testAssociativeContainerAlignment<QHash<AlignedStdMax, AlignedStdMax> >();
testAssociativeContainerAlignment<QHash<AlignedStdMax, AlignedBiggest> >();
testAssociativeContainerAlignment<QHash<AlignedBiggest, Aligned4> >();
testAssociativeContainerAlignment<QHash<AlignedBiggest, AlignedStdMax> >();
testAssociativeContainerAlignment<QHash<AlignedBiggest, AlignedBiggest> >();
}
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS

View File

@ -36,8 +36,8 @@ class tst_QMap : public QObject
{
Q_OBJECT
protected:
template <class KEY, class VALUE>
void sanityCheckTree(const QMap<KEY, VALUE> &m, int calledFromLine);
template <class Map>
void sanityCheckTree(const Map &m, int calledFromLine);
public slots:
void init();
private slots:
@ -119,15 +119,15 @@ QDebug operator << (QDebug d, const MyClass &c) {
return d;
}
template <class KEY, class VALUE>
void tst_QMap::sanityCheckTree(const QMap<KEY, VALUE> &m, int calledFromLine)
template <class Map>
void tst_QMap::sanityCheckTree(const Map &m, int calledFromLine)
{
QString possibleFrom;
possibleFrom.setNum(calledFromLine);
possibleFrom = "Called from line: " + possibleFrom;
int count = 0;
typename QMap<KEY, VALUE>::const_iterator oldite = m.constBegin();
for (typename QMap<KEY, VALUE>::const_iterator i = m.constBegin(); i != m.constEnd(); ++i) {
typename Map::const_iterator oldite = m.constBegin();
for (typename Map::const_iterator i = m.constBegin(); i != m.constEnd(); ++i) {
count++;
bool oldIteratorIsLarger = i.key() < oldite.key();
QVERIFY2(!oldIteratorIsLarger, possibleFrom.toUtf8());
@ -594,7 +594,7 @@ void tst_QMap::contains()
void tst_QMap::find()
{
QMap<int, QString> map1;
QMultiMap<int, QString> map1;
QString testString="Teststring %0";
QString compareString;
int i,count=0;
@ -614,7 +614,7 @@ void tst_QMap::find()
QCOMPARE(map1.count(4), i - 2);
}
QMap<int, QString>::const_iterator it=map1.constFind(4);
QMultiMap<int, QString>::const_iterator it=map1.constFind(4);
for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
compareString = testString.arg(i);
@ -627,7 +627,7 @@ void tst_QMap::find()
void tst_QMap::constFind()
{
QMap<int, QString> map1;
QMultiMap<int, QString> map1;
QString testString="Teststring %0";
QString compareString;
int i,count=0;
@ -648,7 +648,7 @@ void tst_QMap::constFind()
map1.insertMulti(4, compareString);
}
QMap<int, QString>::const_iterator it=map1.constFind(4);
QMultiMap<int, QString>::const_iterator it=map1.constFind(4);
for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
compareString = testString.arg(i);
@ -661,7 +661,7 @@ void tst_QMap::constFind()
void tst_QMap::lowerUpperBound()
{
QMap<int, QString> map1;
QMultiMap<int, QString> map1;
map1.insert(1, "one");
map1.insert(5, "five");
@ -712,7 +712,7 @@ void tst_QMap::lowerUpperBound()
void tst_QMap::mergeCompare()
{
QMap<int, QString> map1, map2, map3, map1b, map2b;
QMultiMap<int, QString> map1, map2, map3, map1b, map2b;
map1.insert(1,"ett");
map1.insert(3,"tre");
@ -770,13 +770,13 @@ void tst_QMap::iterators()
QMap<int, QString>::iterator stlIt = map.begin();
QCOMPARE(stlIt.value(), QLatin1String("Teststring 1"));
stlIt+=5;
std::advance(stlIt, 5);
QCOMPARE(stlIt.value(), QLatin1String("Teststring 6"));
stlIt++;
QCOMPARE(stlIt.value(), QLatin1String("Teststring 7"));
stlIt-=3;
std::advance(stlIt, -3);
QCOMPARE(stlIt.value(), QLatin1String("Teststring 4"));
stlIt--;
@ -791,13 +791,13 @@ void tst_QMap::iterators()
QMap<int, QString>::const_iterator cstlIt = map.constBegin();
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 1"));
cstlIt+=5;
std::advance(cstlIt, 5);
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 6"));
cstlIt++;
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 7"));
cstlIt-=3;
std::advance(cstlIt, -3);
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 4"));
cstlIt--;
@ -926,28 +926,23 @@ void tst_QMap::keyValueIterator()
void tst_QMap::keys_values_uniqueKeys()
{
QMap<QString, int> map;
QVERIFY(map.uniqueKeys().isEmpty());
QMultiMap<QString, int> map;
QVERIFY(map.keys().isEmpty());
QVERIFY(map.values().isEmpty());
map.insertMulti("alpha", 1);
QVERIFY(map.keys() == (QList<QString>() << "alpha"));
QVERIFY(map.uniqueKeys() == map.keys());
QVERIFY(map.values() == (QList<int>() << 1));
map.insertMulti("beta", -2);
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "beta"));
QVERIFY(map.keys() == map.uniqueKeys());
QVERIFY(map.values() == (QList<int>() << 1 << -2));
map.insertMulti("alpha", 2);
QVERIFY(map.uniqueKeys() == (QList<QString>() << "alpha" << "beta"));
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "alpha" << "beta"));
QVERIFY(map.values() == (QList<int>() << 2 << 1 << -2));
map.insertMulti("beta", 4);
QVERIFY(map.uniqueKeys() == (QList<QString>() << "alpha" << "beta"));
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "alpha" << "beta" << "beta"));
QVERIFY(map.values() == (QList<int>() << 2 << 1 << 4 << -2));
}
@ -1077,14 +1072,14 @@ void tst_QMap::const_shared_null()
void tst_QMap::equal_range()
{
QMap<int, QString> map;
const QMap<int, QString> &cmap = map;
QMultiMap<int, QString> map;
const QMultiMap<int, QString> &cmap = map;
QPair<QMap<int, QString>::iterator, QMap<int, QString>::iterator> result = map.equal_range(0);
QPair<QMultiMap<int, QString>::iterator, QMultiMap<int, QString>::iterator> result = map.equal_range(0);
QCOMPARE(result.first, map.end());
QCOMPARE(result.second, map.end());
QPair<QMap<int, QString>::const_iterator, QMap<int, QString>::const_iterator> cresult = cmap.equal_range(0);
QPair<QMultiMap<int, QString>::const_iterator, QMultiMap<int, QString>::const_iterator> cresult = cmap.equal_range(0);
QCOMPARE(cresult.first, cmap.cend());
QCOMPARE(cresult.second, cmap.cend());
@ -1294,10 +1289,10 @@ void tst_QMap::insertMap()
// make sure this isn't adding multiple entries with the
// same key to the QMap.
QMap<int, int> map;
QMultiMap<int, int> map2;
map2.insert(0, 0);
map.insert(0, 0);
QMap<int, int> map2;
map2.insert(0, 1);
map2.insert(0, 2);
map.insert(map2);
@ -1452,11 +1447,11 @@ void tst_QMap::testInsertWithHint()
void tst_QMap::testInsertMultiWithHint()
{
QMap<int, int> map;
QMultiMap<int, int> map;
map.insertMulti(map.end(), 64, 65);
map[128] = 129;
map[256] = 257;
map.insert(128, 129);
map.insert(256, 257);
sanityCheckTree(map, __LINE__);
map.insertMulti(map.end(), 512, 513);
@ -1467,11 +1462,11 @@ void tst_QMap::testInsertMultiWithHint()
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 6);
QMap<int, int>::iterator i = map.insertMulti(map.constBegin(), 256, 259); // wrong hint
QMultiMap<int, int>::iterator i = map.insertMulti(map.constBegin(), 256, 259); // wrong hint
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 7);
QMap<int, int>::iterator j = map.insertMulti(map.constBegin(), 69, 66);
QMultiMap<int, int>::iterator j = map.insertMulti(map.constBegin(), 69, 66);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 8);
@ -1502,14 +1497,14 @@ void tst_QMap::testInsertMultiWithHint()
void tst_QMap::eraseValidIteratorOnSharedMap()
{
QMap<int, int> a, b;
QMultiMap<int, int> a, b;
a.insert(10, 10);
a.insertMulti(10, 40);
a.insertMulti(10, 25);
a.insertMulti(10, 30);
a.insert(20, 20);
QMap<int, int>::iterator i = a.begin();
QMultiMap<int, int>::iterator i = a.begin();
while (i.value() != 25)
++i;
@ -1529,12 +1524,12 @@ void tst_QMap::eraseValidIteratorOnSharedMap()
QCOMPARE(itemsWith10, 4);
// Border cases
QMap <QString, QString> ms1, ms2, ms3;
QMultiMap <QString, QString> ms1, ms2, ms3;
ms1.insert("foo", "bar");
ms1.insertMulti("foo", "quux");
ms1.insertMulti("foo", "bar");
QMap <QString, QString>::iterator si = ms1.begin();
QMultiMap <QString, QString>::iterator si = ms1.begin();
ms2 = ms1;
ms1.erase(si);
si = ms1.begin();

View File

@ -203,7 +203,11 @@ inline QDBusIntrospection::Argument arg(const char* type, const char *name = 0)
template<typename T>
inline QMap<QString, T>& operator<<(QMap<QString, T>& map, const T& m)
{ map.insertMulti(m.name, m); return map; }
{ map.insert(m.name, m); return map; }
template<typename T>
inline QMultiMap<QString, T>& operator<<(QMultiMap<QString, T>& map, const T& m)
{ map.insert(m.name, m); return map; }
inline const char* mapName(const MethodMap&)
{ return "MethodMap"; }
@ -263,11 +267,11 @@ QString printable(const QDBusIntrospection::Property& p)
return result;
}
template<typename T>
char* printableMap(const QMap<QString, T>& map)
template<typename Map>
char* printableMap(const Map& map)
{
QString contents = "\n";
typename QMap<QString, T>::const_iterator it = map.begin();
auto it = map.begin();
for ( ; it != map.end(); ++it) {
if (it.key() != it.value().name)
contents += it.value().name + ":";