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.cpp257
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