diff options
Diffstat (limited to 'src/corelib/text/qstringlist.cpp')
-rw-r--r-- | src/corelib/text/qstringlist.cpp | 257 |
1 files changed, 201 insertions, 56 deletions
diff --git a/src/corelib/text/qstringlist.cpp b/src/corelib/text/qstringlist.cpp index 8eb730ee02..61923e0b3f 100644 --- a/src/corelib/text/qstringlist.cpp +++ b/src/corelib/text/qstringlist.cpp @@ -84,25 +84,7 @@ QT_BEGIN_NAMESPACE \section1 Iterating Over the Strings - To iterate over a list, you can either use index positions or - QList's Java-style and STL-style iterator types: - - Indexing: - - \snippet qstringlist/main.cpp 1 - - Java-style iterator: - - \snippet qstringlist/main.cpp 2 - - STL-style iterator: - - \snippet qstringlist/main.cpp 3 - - The QStringListIterator class is simply a type definition for - QListIterator<QString>. QStringList also provide the - QMutableStringListIterator class which is a type definition for - QMutableListIterator<QString>. + See \l {Iterating over Containers}. \section1 Manipulating the Strings @@ -207,8 +189,11 @@ QT_BEGIN_NAMESPACE \fn void QStringList::sort(Qt::CaseSensitivity cs) Sorts the list of strings in ascending order. + +//! [comparison-case-sensitivity] If \a cs is \l Qt::CaseSensitive (the default), the string comparison is case sensitive; otherwise the comparison is case insensitive. +//! [comparison-case-sensitivity] Sorting is performed using the STL's std::sort() algorithm, which averages \l{linear-logarithmic time}, i.e. O(\e{n} log \e{n}). @@ -221,22 +206,16 @@ QT_BEGIN_NAMESPACE integer index. */ -namespace { -struct CaseInsensitiveLessThan { - typedef bool result_type; - result_type operator()(const QString &s1, const QString &s2) const - { - return s1.compare(s2, Qt::CaseInsensitive) < 0; - } -}; -} - void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs) { - if (cs == Qt::CaseSensitive) + if (cs == Qt::CaseSensitive) { std::sort(that->begin(), that->end()); - else - std::sort(that->begin(), that->end(), CaseInsensitiveLessThan()); + } else { + auto CISCompare = [](const auto &s1, const auto &s2) { + return s1.compare(s2, Qt::CaseInsensitive) < 0; + }; + std::sort(that->begin(), that->end(), CISCompare); + } } @@ -245,9 +224,7 @@ void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs) Returns a list of all the strings containing the substring \a str. - If \a cs is \l Qt::CaseSensitive (the default), the string - comparison is case sensitive; otherwise the comparison is case - insensitive. + \include qstringlist.cpp comparison-case-sensitivity \snippet qstringlist/main.cpp 5 \snippet qstringlist/main.cpp 10 @@ -260,6 +237,17 @@ void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs) \sa contains() */ +template <typename String> +static QStringList filter_helper(const QStringList &that, const String &needle, Qt::CaseSensitivity cs) +{ + QStringList res; + for (const auto &s : that) { + if (s.contains(needle, cs)) + res.append(s); + } + return res; +} + /*! \fn QStringList QStringList::filter(QStringView str, Qt::CaseSensitivity cs) const \overload @@ -268,14 +256,48 @@ void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs) QStringList QtPrivate::QStringList_filter(const QStringList *that, QStringView str, Qt::CaseSensitivity cs) { - QStringMatcher matcher(str, cs); + return filter_helper(*that, str, cs); +} + +/*! + \fn QStringList QStringList::filter(const QStringMatcher &matcher) const + \since 6.7 + \overload + + Returns a list of all the strings matched by \a matcher (i.e. for which + \c matcher.indexIn() returns an index >= 0). + + Using a QStringMatcher may be faster when searching in large lists and/or + in lists with long strings (the best way to find out is benchmarking). + + For example: + \snippet qstringlist/main.cpp 18 + + \sa contains() +*/ + +QStringList QtPrivate::QStringList_filter(const QStringList &that, const QStringMatcher &matcher) +{ QStringList res; - for (qsizetype i = 0; i < that->size(); ++i) - if (matcher.indexIn(that->at(i)) != -1) - res << that->at(i); + for (const auto &s : that) { + if (matcher.indexIn(s) != -1) + res.append(s); + } return res; } +/*! + \fn QStringList QStringList::filter(QLatin1StringView str, Qt::CaseSensitivity cs) const + \since 6.7 + \overload +*/ + +QStringList QtPrivate::QStringList_filter(const QStringList &that, QLatin1StringView needle, + Qt::CaseSensitivity cs) +{ + return filter_helper(that, needle, cs); +} + template<typename T> static bool stringList_contains(const QStringList &stringList, const T &str, Qt::CaseSensitivity cs) { @@ -291,8 +313,9 @@ static bool stringList_contains(const QStringList &stringList, const T &str, Qt: \fn bool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const Returns \c true if the list contains the string \a str; otherwise - returns \c false. The search is case insensitive if \a cs is - Qt::CaseInsensitive; the search is case sensitive by default. + returns \c false. + + \include qstringlist.cpp comparison-case-sensitivity \sa indexOf(), lastIndexOf(), QString::contains() */ @@ -303,8 +326,9 @@ static bool stringList_contains(const QStringList &stringList, const T &str, Qt: \since 5.12 Returns \c true if the list contains the string \a str; otherwise - returns \c false. The search is case insensitive if \a cs is - Qt::CaseInsensitive; the search is case sensitive by default. + returns \c false. + + \include qstringlist.cpp comparison-case-sensitivity */ bool QtPrivate::QStringList_contains(const QStringList *that, QStringView str, Qt::CaseSensitivity cs) @@ -317,9 +341,10 @@ bool QtPrivate::QStringList_contains(const QStringList *that, QStringView str, \overload \since 5.10 - Returns \c true if the list contains the string \a str; otherwise - returns \c false. The search is case insensitive if \a cs is - Qt::CaseInsensitive; the search is case sensitive by default. + Returns \c true if the list contains the Latin-1 string viewed by \a str; otherwise + returns \c false. + + \include qstringlist.cpp comparison-case-sensitivity \sa indexOf(), lastIndexOf(), QString::contains() */ @@ -342,9 +367,9 @@ bool QtPrivate::QStringList_contains(const QStringList *that, QLatin1StringView QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegularExpression &re) { QStringList res; - for (qsizetype i = 0; i < that->size(); ++i) { - if (that->at(i).contains(re)) - res << that->at(i); + for (const auto &str : *that) { + if (str.contains(re)) + res.append(str); } return res; } @@ -355,8 +380,9 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegula Returns a string list where every string has had the \a before text replaced with the \a after text wherever the \a before text - is found. The \a before text is matched case-sensitively or not - depending on the \a cs flag. + is found. + + \include qstringlist.cpp comparison-case-sensitivity For example: @@ -386,8 +412,19 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegula void QtPrivate::QStringList_replaceInStrings(QStringList *that, QStringView before, QStringView after, Qt::CaseSensitivity cs) { - for (qsizetype i = 0; i < that->size(); ++i) - (*that)[i].replace(before.data(), before.length(), after.data(), after.length(), cs); + // Before potentially detaching "that" list, check if any string contains "before" + qsizetype i = -1; + for (qsizetype j = 0; j < that->size(); ++j) { + if (that->at(j).contains(before, cs)) { + i = j; + break; + } + } + if (i == -1) + return; + + for (; i < that->size(); ++i) + (*that)[i].replace(before.data(), before.size(), after.data(), after.size(), cs); } #if QT_CONFIG(regularexpression) @@ -414,9 +451,21 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, QStringView befo \snippet qstringlist/main.cpp 5 \snippet qstringlist/main.cpp 17 */ -void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularExpression &re, const QString &after) +void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularExpression &re, + const QString &after) { - for (qsizetype i = 0; i < that->size(); ++i) + // Before potentially detaching "that" list, check if any string contains "before" + qsizetype i = -1; + for (qsizetype j = 0; j < that->size(); ++j) { + if (that->at(j).contains(re)) { + i = j; + break; + } + } + if (i == -1) + return; + + for (; i < that->size(); ++i) (*that)[i].replace(re, after); } #endif // QT_CONFIG(regularexpression) @@ -492,7 +541,7 @@ QString QtPrivate::QStringList_join(const QStringList &list, QLatin1StringView s */ QString QtPrivate::QStringList_join(const QStringList *that, QStringView sep) { - return QStringList_join(that, sep.data(), sep.length()); + return QStringList_join(that, sep.data(), sep.size()); } /*! @@ -532,6 +581,102 @@ QString QtPrivate::QStringList_join(const QStringList *that, QStringView sep) the latter string list. */ +/*! + \fn qsizetype QStringList::indexOf(const QString &str, qsizetype from, Qt::CaseSensitivity cs) const + \fn qsizetype QStringList::indexOf(QStringView str, qsizetype from, Qt::CaseSensitivity cs) const + \fn qsizetype QStringList::indexOf(QLatin1StringView str, qsizetype from, Qt::CaseSensitivity cs) const + + Returns the index position of the first match of \a str in the list, + searching forward from index position \a from. Returns -1 if no item + matched. + + \include qstringlist.cpp comparison-case-sensitivity + +//! [overloading-base-class-methods] + \note The \a cs parameter was added in Qt 6.7, i.e. these methods now overload + the methods inherited from the base class. Prior to that these methods only + had two parameters. This change is source compatible and existing code should + continue to work. +//! [overloading-base-class-methods] + + \sa lastIndexOf() +*/ + +template <typename String> +qsizetype indexOf_helper(const QStringList &that, String needle, qsizetype from, + Qt::CaseSensitivity cs) +{ + if (from < 0) // Historical behavior + from = qMax(from + that.size(), 0); + + if (from >= that.size()) + return -1; + + for (qsizetype i = from; i < that.size(); ++i) { + if (needle.compare(that.at(i), cs) == 0) + return i; + } + return -1; +} + +qsizetype QtPrivate::QStringList_indexOf(const QStringList &that, QStringView needle, + qsizetype from, Qt::CaseSensitivity cs) +{ + return indexOf_helper(that, needle, from, cs); +} + +qsizetype QtPrivate::QStringList_indexOf(const QStringList &that, QLatin1StringView needle, + qsizetype from, Qt::CaseSensitivity cs) +{ + return indexOf_helper(that, needle, from, cs); +} + +/*! + \fn qsizetype QStringList::lastIndexOf(const QString &str, qsizetype from, Qt::CaseSensitivity cs) const + \fn qsizetype QStringList::lastIndexOf(QStringView str, qsizetype from, Qt::CaseSensitivity cs) const + \fn qsizetype QStringList::lastIndexOf(QLatin1StringView str, qsizetype from, Qt::CaseSensitivity cs) const + + Returns the index position of the last match of \a str in the list, + searching backward from index position \a from. If \a from is -1 (the + default), the search starts at the last item. Returns -1 if no item + matched. + + \include qstringlist.cpp comparison-case-sensitivity + + \include qstringlist.cpp overloading-base-class-methods + + \sa indexOf() +*/ + +template <typename String> +qsizetype lastIndexof_helper(const QStringList &that, String needle, qsizetype from, + Qt::CaseSensitivity cs) +{ + if (from < 0) + from += that.size(); + else if (from >= that.size()) + from = that.size() - 1; + + for (qsizetype i = from; i >= 0; --i) { + if (needle.compare(that.at(i), cs) == 0) + return i; + } + + return -1; +} + +qsizetype QtPrivate::QStringList_lastIndexOf(const QStringList &that, QLatin1StringView needle, + qsizetype from, Qt::CaseSensitivity cs) +{ + return lastIndexof_helper(that, needle, from, cs); +} + +qsizetype QtPrivate::QStringList_lastIndexOf(const QStringList &that, QStringView needle, + qsizetype from, Qt::CaseSensitivity cs) +{ + return lastIndexof_helper(that, needle, from, cs); +} + #if QT_CONFIG(regularexpression) /*! \fn qsizetype QStringList::indexOf(const QRegularExpression &re, qsizetype from) const |