From 9f1948f59b916966ea0ecdf9c7d3473f7685e08e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 15 Jan 2020 21:04:17 +0100 Subject: QRegularExpression: fixup docs of wildcardToRegularExpression Fix a couple of typos, and add a paragraph explaining that there is no need of anchor the pattern again; a wildcard is always anchored. Fixes: QTBUG-81396 Change-Id: Ia67dc7477a05a450bdcc3def1ebbacce2006da4d Reviewed-by: Thiago Macieira --- src/corelib/text/qregularexpression.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index 67be67c243..59d21e0a23 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -1892,6 +1892,10 @@ QString QRegularExpression::escape(const QString &str) \snippet code/src_corelib_tools_qregularexpression.cpp 31 + The returned regular expression is already fully anchored. In other + words, there is no need of calling anchoredPattern() again on the + result. + \warning Unlike QRegExp, this implementation follows closely the definition of wildcard for glob patterns: \table @@ -1918,12 +1922,12 @@ QString QRegularExpression::escape(const QString &str) \note The backslash (\\) character is \e not an escape char in this context. In order to match one of the special characters, place it in square brackets - (for example, "[?]"). + (for example, \c{[?]}). More information about the implementation can be found in: \list \li \l {https://en.wikipedia.org/wiki/Glob_(programming)} {The Wikipedia Glob article} - \li \c man 7 glob + \li \c {man 7 glob} \endlist \sa escape() -- cgit v1.2.3 From c0ea88a6776b6281d5774d03572b1aecc2ef3c25 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 6 Jan 2020 17:47:41 +0100 Subject: Fix MS-Win system locale code to return QString for numeric tokens QSystemLocale::query() is specified to return a QString (wrapped in a QVariant) for the various tokens used in formatting numbers (zero digit, signs, separators) but the MS-Win back-end was returning QChar (wrapped as QVariant) instead, using the first UCS-2 code-point of the string (even if this was the first of a surrogate pair). The same error shall be perpetrated by its caller, but we can at least DTRT in the back-end, ready for the coming fix (in Qt 6) to its caller. In the process, eliminate some local variables that shadowed a member variable and adapt number-conversion to cope with surrogate-pair digits. Optimised the latter for the case where zero is "0". Change-Id: Idfb416c301add4c961dde613b3dc28b2e31fd0af Reviewed-by: Thiago Macieira --- src/corelib/text/qlocale_win.cpp | 97 +++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 35 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index 79ea67f966..4b4152c519 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -106,11 +106,11 @@ struct QSystemLocalePrivate { QSystemLocalePrivate(); - QChar zeroDigit(); - QChar decimalPoint(); - QChar groupSeparator(); - QChar negativeSign(); - QChar positiveSign(); + QString zeroDigit(); + QString decimalPoint(); + QString groupSeparator(); + QString negativeSign(); + QString positiveSign(); QVariant dateFormat(QLocale::FormatType); QVariant timeFormat(QLocale::FormatType); QVariant dateTimeFormat(QLocale::FormatType); @@ -147,12 +147,11 @@ private: WCHAR lcName[LOCALE_NAME_MAX_LENGTH]; #endif SubstitutionType substitutionType; - QChar zero; + QString zero; // cached value for zeroDigit() int getLocaleInfo(LCTYPE type, LPWSTR data, int size); QString getLocaleInfo(LCTYPE type, int maxlen = 0); int getLocaleInfo_int(LCTYPE type, int maxlen = 0); - QChar getLocaleInfo_qchar(LCTYPE type); int getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size); int getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size); @@ -236,12 +235,6 @@ int QSystemLocalePrivate::getLocaleInfo_int(LCTYPE type, int maxlen) return ok ? v : 0; } -QChar QSystemLocalePrivate::getLocaleInfo_qchar(LCTYPE type) -{ - QString str = getLocaleInfo(type); - return str.isEmpty() ? QChar() : str.at(0); -} - QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution() { if (substitutionType == SUnknown) { @@ -257,13 +250,12 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution() else if (buf[0] == '2') substitutionType = QSystemLocalePrivate::SAlways; else { - wchar_t digits[11]; + wchar_t digits[11]; // See zeroDigit() for why 11. if (!getLocaleInfo(LOCALE_SNATIVEDIGITS, digits, 11)) { substitutionType = QSystemLocalePrivate::SNever; return substitutionType; } - const wchar_t zero = digits[0]; - if (buf[0] == zero + 2) + if (buf[0] == digits[0] + 2) substitutionType = QSystemLocalePrivate::SAlways; else substitutionType = QSystemLocalePrivate::SNever; @@ -274,40 +266,75 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution() QString &QSystemLocalePrivate::substituteDigits(QString &string) { - ushort zero = zeroDigit().unicode(); - ushort *qch = reinterpret_cast(string.data()); - for (ushort *end = qch + string.size(); qch != end; ++qch) { - if (*qch >= '0' && *qch <= '9') - *qch = zero + (*qch - '0'); + zeroDigit(); // Ensure zero is set. + switch (zero.size()) { + case 1: { + const ushort offset = zero.at(0).unicode() - '0'; + if (!offset) // Nothing to do + break; + Q_ASSERT(offset > 9); + ushort *const qch = reinterpret_cast(string.data()); + for (int i = 0, stop = string.size(); i < stop; ++i) { + ushort &ch = qch[i]; + if (ch >= '0' && ch <= '9') + ch += offset; + } + break; + } + case 2: { + // Surrogate pair (high, low): + uint digit = QChar::surrogateToUcs4(zero.at(0), zero.at(1)); + for (int i = 0; i < 10; i++) { + const QChar s[2] = { QChar::highSurrogate(digit + i), QChar::lowSurrogate(digit + i) }; + string.replace(QString(QLatin1Char('0' + i)), QString(s, 2)); + } + break; + } + default: + Q_ASSERT(!"Expected zero digit to be a single UCS2 code-point or a surrogate pair"); + case 0: // Apparently this locale info was not available. + break; } return string; } -QChar QSystemLocalePrivate::zeroDigit() +QString QSystemLocalePrivate::zeroDigit() { - if (zero.isNull()) - zero = getLocaleInfo_qchar(LOCALE_SNATIVEDIGITS); + if (zero.isEmpty()) { + /* Ten digits plus a terminator. + + https://docs.microsoft.com/en-us/windows/win32/intl/locale-snative-constants + "Native equivalents of ASCII 0 through 9. The maximum number of + characters allowed for this string is eleven, including a terminating + null character." + */ + wchar_t digits[11]; + if (getLocaleInfo(LOCALE_SNATIVEDIGITS, digits, 11)) { + // assert all(digits[i] == i + digits[0] for i in range(1, 10)), assumed above + zero = QString::fromWCharArray(digits, 1); + } + } return zero; } -QChar QSystemLocalePrivate::decimalPoint() +QString QSystemLocalePrivate::decimalPoint() { - return getLocaleInfo_qchar(LOCALE_SDECIMAL); + return getLocaleInfo(LOCALE_SDECIMAL); } -QChar QSystemLocalePrivate::groupSeparator() +QString QSystemLocalePrivate::groupSeparator() { - return getLocaleInfo_qchar(LOCALE_STHOUSAND); + return getLocaleInfo(LOCALE_STHOUSAND); } -QChar QSystemLocalePrivate::negativeSign() +QString QSystemLocalePrivate::negativeSign() { - return getLocaleInfo_qchar(LOCALE_SNEGATIVESIGN); + return getLocaleInfo(LOCALE_SNEGATIVESIGN); } -QChar QSystemLocalePrivate::positiveSign() +QString QSystemLocalePrivate::positiveSign() { - return getLocaleInfo_qchar(LOCALE_SPOSITIVESIGN); + return getLocaleInfo(LOCALE_SPOSITIVESIGN); } QVariant QSystemLocalePrivate::dateFormat(QLocale::FormatType type) @@ -677,7 +704,7 @@ void QSystemLocalePrivate::update() GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); #endif substitutionType = SUnknown; - zero = QChar(); + zero.resize(0); } QString QSystemLocalePrivate::winToQtFormat(QStringView sys_fmt) @@ -749,7 +776,7 @@ QLocale QSystemLocale::fallbackUiLocale() const return QLocale(QString::fromLatin1(getWinLocaleName())); } -QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const +QVariant QSystemLocale::query(QueryType type, QVariant in) const { QSystemLocalePrivate *d = systemLocalePrivate(); switch(type) { -- cgit v1.2.3 From 800dda19a611339863aa5cfe6da13bc235d68e68 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 15 Jan 2020 23:00:58 +0100 Subject: Do not anchor an already-anchored regexp wildcardToRegularExpression() returns an anchored regexp, so it is pointless to anchor it again. Change-Id: If470179d63ae7ca2e7f137c0f403ec5bb5be8aaf Task-number: QTBUG-81396 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qdiriterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index ce436b06e3..1cf6b1be08 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -181,7 +181,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QFileSystemEntry &entry, const QS #elif QT_CONFIG(regularexpression) nameRegExps.reserve(nameFilters.size()); for (const auto &filter : nameFilters) { - QString re = QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(filter)); + QString re = QRegularExpression::wildcardToRegularExpression(filter); nameRegExps.append( QRegularExpression(re, (filters & QDir::CaseSensitive) ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption)); } -- cgit v1.2.3 From 28f95d4688c28f8c06aa103012c6a00e197db12c Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 15 Jan 2020 14:38:14 +0100 Subject: Doc: Fix qdoc compilation errors qtbase Task-number: QTBUG-79824 Change-Id: I5a39525e3e735415ba96e2d585c5de754deb15de Reviewed-by: Venugopal Shivashankar --- src/corelib/doc/qtcore.qdocconf | 2 +- src/corelib/doc/src/qtcore-index.qdoc | 2 +- src/corelib/global/qendian.cpp | 1 - src/corelib/time/qcalendar.cpp | 2 +- src/corelib/time/qtimezone.cpp | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index 15b1925e51..2b9adabc3a 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -26,7 +26,7 @@ qhp.QtCore.subprojects.classes.sortPages = true tagfile = ../../../doc/qtcore/qtcore.tags -depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake qtwinextras qtqml +depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake qtwinextras qtqml qtcmake headerdirs += .. diff --git a/src/corelib/doc/src/qtcore-index.qdoc b/src/corelib/doc/src/qtcore-index.qdoc index 29fc25f69d..5838d13914 100644 --- a/src/corelib/doc/src/qtcore-index.qdoc +++ b/src/corelib/doc/src/qtcore-index.qdoc @@ -56,7 +56,7 @@ \include module-use.qdocinc using qt module \quotefile overview/using-qt-core.cmake - See also the \l[QtDoc]{Build with CMake} overview. + See also the \l{Build with CMake} overview. \section2 Building with qmake diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp index 98dc6a9a4b..eb08b2f848 100644 --- a/src/corelib/global/qendian.cpp +++ b/src/corelib/global/qendian.cpp @@ -192,7 +192,6 @@ QT_BEGIN_NAMESPACE an in-place swap (if necessary). If they are not the same, the memory regions must not overlap. - \sa qFromLittleEndian() \sa qToBigEndian() \sa qToLittleEndian() */ diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp index 6a4623ce92..9d485f181e 100644 --- a/src/corelib/time/qcalendar.cpp +++ b/src/corelib/time/qcalendar.cpp @@ -723,7 +723,7 @@ QCalendar::QCalendar(QLatin1String name) QCalendar::QCalendar(QStringView name) : d(QCalendarBackend::fromName(name)) {} -/* +/*! \fn bool QCalendar::isValid() const Returns true if this is a valid calendar object. diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp index ef323de14a..0bba2afc61 100644 --- a/src/corelib/time/qtimezone.cpp +++ b/src/corelib/time/qtimezone.cpp @@ -217,7 +217,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz); This class includes data obtained from the CLDR data files under the terms of the Unicode Data Files and Software License. See - \l{Unicode Common Locale Data Repository (CLDR)} for details. + \l{unicode-cldr}{Unicode Common Locale Data Repository (CLDR)} for details. \sa QDateTime */ -- cgit v1.2.3 From 4ec6748c6a30f74e6d8fbb90fc118b306d1fa690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 26 Nov 2019 16:08:38 +0100 Subject: 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 Reviewed-by: Lars Knoll --- src/corelib/tools/qmap.cpp | 95 +++++++----- src/corelib/tools/qmap.h | 351 ++++++++++++++++++++++++++------------------- 2 files changed, 262 insertions(+), 184 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 970373101f..d747a8cda4 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -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: + 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: \snippet code/src_corelib_tools_qmap.cpp 10 @@ -676,9 +675,8 @@ void QMapDataBase::freeData(QMapDataBase *d) /*! \fn template int QMap::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 QList QMap::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 QList QMap::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 QList QMap::keys(const T &value) const @@ -806,6 +802,7 @@ void QMapDataBase::freeData(QMapDataBase *d) */ /*! \fn template QList QMap::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 int QMap::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 int QMap::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 QMap::iterator QMap::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 void QMap::insert(const QMap &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 QMap::iterator QMap::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 QMap::iterator QMap::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 QMap &QMap::unite(const QMap &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\ 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 QList QMultiMap::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 int QMultiMap::count(const Key &key) const + + Returns the number of items associated with key \a key. +*/ + +/*! \fn template QList QMultiMap::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 diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index fa736e8413..281812b5e6 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -380,12 +380,15 @@ public: T &operator[](const Key &key); const T operator[](const Key &key) const; - QList uniqueKeys() const; QList keys() const; QList keys(const T &value) const; QList values() const; - QList 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 uniqueKeys() const; + QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QList 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; + friend class QMultiMap; }; friend class iterator; @@ -514,6 +518,7 @@ public: inline bool operator!=(const iterator &o) const { return operator!=(const_iterator(o)); } #endif friend class QMap; + friend class QMultiMap; }; 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 &map); - iterator insertMulti(const Key &key, const T &value); - iterator insertMulti(const_iterator pos, const Key &akey, const T &avalue); - QMap &unite(const QMap &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 &unite(const QMap &other); +#endif // STL compatibility typedef Key key_type; @@ -610,6 +617,8 @@ private: return true; #endif } + + friend class QMultiMap; }; template @@ -671,23 +680,6 @@ Q_INLINE_TEMPLATE T &QMap::operator[](const Key &akey) return n->value; } -template -Q_INLINE_TEMPLATE int QMap::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 Q_INLINE_TEMPLATE bool QMap::contains(const Key &akey) const { @@ -832,75 +824,6 @@ Q_INLINE_TEMPLATE void QMap::insert(const QMap &map) } } -template -Q_INLINE_TEMPLATE typename QMap::iterator QMap::insertMulti(const Key &akey, - const T &avalue) -{ - detach(); - Node* y = d->end(); - Node* x = static_cast(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 -typename QMap::iterator QMap::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(pos.i->left); - if (n) { - while (n->right) - n = static_cast(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(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(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 Q_INLINE_TEMPLATE typename QMap::const_iterator QMap::constFind(const Key &akey) const @@ -923,19 +846,6 @@ Q_INLINE_TEMPLATE typename QMap::iterator QMap::find(const Key & return iterator(n ? n : d->end()); } -template -Q_INLINE_TEMPLATE QMap &QMap::unite(const QMap &other) -{ - QMap 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 QPair::iterator, typename QMap::iterator> QMap::equal_range(const Key &akey) { @@ -1051,26 +961,6 @@ Q_OUTOFLINE_TEMPLATE void QMap::detach_helper() d->recalcMostLeftNode(); } -template -Q_OUTOFLINE_TEMPLATE QList QMap::uniqueKeys() const -{ - QList 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 Q_OUTOFLINE_TEMPLATE QList QMap::keys() const { @@ -1123,21 +1013,6 @@ Q_OUTOFLINE_TEMPLATE QList QMap::values() const return res; } -template -Q_OUTOFLINE_TEMPLATE QList QMap::values(const Key &akey) const -{ - QList res; - Node *n = d->findNode(akey); - if (n) { - const_iterator it(n); - do { - res.append(*it); - ++it; - } while (it != constEnd() && !qMapLessThanKey(akey, it.key())); - } - return res; -} - template Q_INLINE_TEMPLATE typename QMap::const_iterator QMap::lowerBound(const Key &akey) const { @@ -1234,15 +1109,20 @@ public: QMultiMap(QMap &&other) noexcept : QMap(std::move(other)) {} void swap(QMultiMap &other) noexcept { QMap::swap(other); } + QList uniqueKeys() const; + QList values(const Key &key) const; + + using typename QMap::iterator; + using typename QMap::const_iterator; + inline typename QMap::iterator replace(const Key &key, const T &value) { return QMap::insert(key, value); } - inline typename QMap::iterator insert(const Key &key, const T &value) - { return QMap::insertMulti(key, value); } - inline typename QMap::iterator insert(typename QMap::const_iterator pos, const Key &key, const T &value) - { return QMap::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::count; using QMap::find; using QMap::constFind; + using QMap::values; + using QMap::size; + using QMap::detach; + using QMap::erase; + using QMap::isValidIterator; + using typename QMap::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::iterator find(const Key &key, const T &value) { @@ -1285,6 +1172,123 @@ private: const T operator[](const Key &key) const; }; +template +Q_OUTOFLINE_TEMPLATE QList QMultiMap::uniqueKeys() const +{ + QList 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 +Q_OUTOFLINE_TEMPLATE QList QMultiMap::values(const Key &akey) const +{ + QList res; + Node *n = this->d->findNode(akey); + if (n) { + const_iterator it(n); + do { + res.append(*it); + ++it; + } while (it != this->constEnd() && !qMapLessThanKey(akey, it.key())); + } + return res; +} + +template +Q_INLINE_TEMPLATE typename QMultiMap::iterator QMultiMap::insert(const Key &akey, + const T &avalue) +{ + detach(); + Node* y = this->d->end(); + Node* x = static_cast(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 +typename QMultiMap::iterator QMultiMap::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(pos.i->left); + if (n) { + while (n->right) + n = static_cast(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(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(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 +Q_INLINE_TEMPLATE QMultiMap &QMultiMap::unite(const QMultiMap &other) +{ + QMultiMap 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 Q_INLINE_TEMPLATE bool QMultiMap::contains(const Key &key, const T &value) const { @@ -1299,7 +1303,7 @@ Q_INLINE_TEMPLATE int QMultiMap::remove(const Key &key, const T &value) typename QMap::iterator end(QMap::end()); while (i != end && !qMapLessThanKey(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::remove(const Key &key, const T &value) return n; } +template +Q_INLINE_TEMPLATE int QMultiMap::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 Q_INLINE_TEMPLATE int QMultiMap::count(const Key &key, const T &value) const { @@ -1322,6 +1343,44 @@ Q_INLINE_TEMPLATE int QMultiMap::count(const Key &key, const T &value) c return n; } +#if QT_DEPRECATED_SINCE(5, 15) +template +QList QMap::uniqueKeys() const +{ + return static_cast *>(this)->uniqueKeys(); +} + +template +QList QMap::values(const Key &key) const +{ + return static_cast *>(this)->values(key); +} + +template +int QMap::count(const Key &key) const +{ + return static_cast *>(this)->count(key); +} + +template +typename QMap::iterator QMap::insertMulti(const Key &key, const T &value) +{ + return static_cast *>(this)->insert(key, value); +} + +template +typename QMap::iterator QMap::insertMulti(const_iterator pos, const Key &akey, const T &avalue) +{ + return static_cast *>(this)->insert(pos, akey, avalue); +} + +template +QMap &QMap::unite(const QMap &other) +{ + return static_cast *>(this)->unite(other); +} +#endif + Q_DECLARE_ASSOCIATIVE_ITERATOR(Map) Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Map) -- cgit v1.2.3