summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qstringlist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qstringlist.cpp')
-rw-r--r--src/corelib/text/qstringlist.cpp333
1 files changed, 210 insertions, 123 deletions
diff --git a/src/corelib/text/qstringlist.cpp b/src/corelib/text/qstringlist.cpp
index c395750376..61923e0b3f 100644
--- a/src/corelib/text/qstringlist.cpp
+++ b/src/corelib/text/qstringlist.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qstringlist.h>
#include <qset.h>
@@ -108,7 +72,7 @@ QT_BEGIN_NAMESPACE
\section1 Adding Strings
Strings can be added to a list using the \l
- {QList::insert()}{insert()} \l
+ {QList::insert()}{insert()}, \l
{QList::append()}{append()}, \l
{QList::operator+=()}{operator+=()} and \l
{operator<<()} functions.
@@ -120,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
@@ -243,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}).
@@ -257,34 +206,25 @@ 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);
+ }
}
-#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn QStringList QStringList::filter(const QString &str, Qt::CaseSensitivity cs) const
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
@@ -296,7 +236,17 @@ void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs)
\sa contains()
*/
-#endif
+
+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
@@ -306,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)
{
@@ -325,17 +309,16 @@ static bool stringList_contains(const QStringList &stringList, const T &str, Qt:
}
-#if QT_STRINGVIEW_LEVEL < 2
/*!
\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()
*/
-#endif
/*!
\fn bool QStringList::contains(QStringView str, Qt::CaseSensitivity cs) const
@@ -343,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)
@@ -353,17 +337,18 @@ bool QtPrivate::QStringList_contains(const QStringList *that, QStringView str,
}
/*!
- \fn bool QStringList::contains(QLatin1String str, Qt::CaseSensitivity cs) const
+ \fn bool QStringList::contains(QLatin1StringView str, Qt::CaseSensitivity cs) const
\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()
*/
-bool QtPrivate::QStringList_contains(const QStringList *that, QLatin1String str,
+bool QtPrivate::QStringList_contains(const QStringList *that, QLatin1StringView str,
Qt::CaseSensitivity cs)
{
return stringList_contains(*that, str, cs);
@@ -382,22 +367,22 @@ bool QtPrivate::QStringList_contains(const QStringList *that, QLatin1String str,
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;
}
#endif // QT_CONFIG(regularexpression)
-#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
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:
@@ -418,7 +403,6 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegula
\overload
\since 5.14
*/
-#endif
/*!
\fn QStringList &QStringList::replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs)
@@ -428,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)
@@ -456,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)
@@ -474,7 +481,6 @@ static qsizetype accumulatedSize(const QStringList &list, qsizetype seplen)
return result;
}
-#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn QString QStringList::join(const QString &separator) const
@@ -484,7 +490,6 @@ static qsizetype accumulatedSize(const QStringList &list, qsizetype seplen)
\sa QString::split()
*/
-#endif
/*!
\fn QString QStringList::join(QChar separator) const
@@ -509,11 +514,11 @@ QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, q
}
/*!
- \fn QString QStringList::join(QLatin1String separator) const
+ \fn QString QStringList::join(QLatin1StringView separator) const
\since 5.8
\overload join()
*/
-QString QtPrivate::QStringList_join(const QStringList &list, QLatin1String sep)
+QString QtPrivate::QStringList_join(const QStringList &list, QLatin1StringView sep)
{
QString result;
if (!list.isEmpty()) {
@@ -536,7 +541,7 @@ QString QtPrivate::QStringList_join(const QStringList &list, QLatin1String sep)
*/
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());
}
/*!
@@ -576,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
@@ -648,22 +749,8 @@ qsizetype QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QReg
*/
qsizetype QtPrivate::QStringList_removeDuplicates(QStringList *that)
{
- qsizetype n = that->size();
- qsizetype j = 0;
-
- QDuplicateTracker<QString> seen;
- seen.reserve(n);
- for (qsizetype i = 0; i < n; ++i) {
- const QString &s = that->at(i);
- if (seen.hasSeen(s))
- continue;
- if (j != i)
- that->swapItemsAt(i, j);
- ++j;
- }
- if (n != j)
- that->erase(that->begin() + j, that->end());
- return n - j;
+ QDuplicateTracker<QString> seen(that->size());
+ return that->removeIf([&](const QString &s) { return seen.hasSeen(s); });
}
QT_END_NAMESPACE