summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qstring.cpp69
-rw-r--r--src/corelib/tools/qstring.h6
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp138
3 files changed, 198 insertions, 15 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index e8eb04b598..fdde0955dd 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -6669,6 +6669,28 @@ QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseS
}
/*!
+ Splits the string into substring references wherever \a sep occurs, and
+ returns the list of those strings. If \a sep does not match
+ anywhere in the string, splitRef() returns a single-element vector
+ containing this string reference.
+
+ \a cs specifies whether \a sep should be matched case
+ sensitively or case insensitively.
+
+ If \a behavior is QString::SkipEmptyParts, empty entries don't
+ appear in the result. By default, empty entries are kept.
+
+ \note All references are valid as long this string is alive. Destroying this
+ string will cause all references be dangling pointers.
+
+ \since 5.4
+ \sa QStringRef split()
+*/
+QVector<QStringRef> QString::splitRef(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
+{
+ return splitString<QVector<QStringRef> >(*this, &QString::midRef, sep, behavior, cs, sep.size());
+}
+/*!
\overload
*/
QStringList QString::split(QChar sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
@@ -6676,6 +6698,15 @@ QStringList QString::split(QChar sep, SplitBehavior behavior, Qt::CaseSensitivit
return splitString<QStringList>(*this, &QString::mid, sep, behavior, cs, 1);
}
+/*!
+ \overload
+ \since 5.4
+*/
+QVector<QStringRef> QString::splitRef(QChar sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
+{
+ return splitString<QVector<QStringRef> >(*this, &QString::midRef, sep, behavior, cs, 1);
+}
+
#ifndef QT_NO_REGEXP
namespace {
template<class ResultList, typename MidMethod>
@@ -6729,6 +6760,25 @@ QStringList QString::split(const QRegExp &rx, SplitBehavior behavior) const
{
return splitString<QStringList>(*this, &QString::mid, rx, behavior);
}
+
+/*!
+ \overload
+ \since 5.4
+
+ Splits the string into substring references wherever the regular expression
+ \a rx matches, and returns the list of those strings. If \a rx
+ does not match anywhere in the string, splitRef() returns a
+ single-element vector containing this string reference.
+
+ \note All references are valid as long this string is alive. Destroying this
+ string will cause all references be dangling pointers.
+
+ \sa QStringRef split()
+*/
+QVector<QStringRef> QString::splitRef(const QRegExp &rx, SplitBehavior behavior) const
+{
+ return splitString<QVector<QStringRef> >(*this, &QString::midRef, rx, behavior);
+}
#endif
#ifndef QT_NO_REGULAREXPRESSION
@@ -6793,6 +6843,25 @@ QStringList QString::split(const QRegularExpression &re, SplitBehavior behavior)
{
return splitString<QStringList>(*this, &QString::mid, re, behavior);
}
+
+/*!
+ \overload
+ \since 5.4
+
+ Splits the string into substring references wherever the regular expression
+ \a re matches, and returns the list of those strings. If \a re
+ does not match anywhere in the string, splitRef() returns a
+ single-element vector containing this string reference.
+
+ \note All references are valid as long this string is alive. Destroying this
+ string will cause all references be dangling pointers.
+
+ \sa split() QStringRef
+*/
+QVector<QStringRef> QString::splitRef(const QRegularExpression &re, SplitBehavior behavior) const
+{
+ return splitString<QVector<QStringRef> >(*this, &QString::midRef, re, behavior);
+}
#endif // QT_BOOTSTRAPPED
#endif // QT_NO_REGULAREXPRESSION
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 3afd68af1f..21b64f5006 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -441,13 +441,19 @@ public:
QStringList split(const QString &sep, SplitBehavior behavior = KeepEmptyParts,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
+ QVector<QStringRef> splitRef(const QString &sep, SplitBehavior behavior = KeepEmptyParts,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
QStringList split(QChar sep, SplitBehavior behavior = KeepEmptyParts,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
+ QVector<QStringRef> splitRef(QChar sep, SplitBehavior behavior = KeepEmptyParts,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
#ifndef QT_NO_REGEXP
QStringList split(const QRegExp &sep, SplitBehavior behavior = KeepEmptyParts) const Q_REQUIRED_RESULT;
+ QVector<QStringRef> splitRef(const QRegExp &sep, SplitBehavior behavior = KeepEmptyParts) const Q_REQUIRED_RESULT;
#endif
#ifndef QT_NO_REGULAREXPRESSION
QStringList split(const QRegularExpression &sep, SplitBehavior behavior = KeepEmptyParts) const Q_REQUIRED_RESULT;
+ QVector<QStringRef> splitRef(const QRegularExpression &sep, SplitBehavior behavior = KeepEmptyParts) const Q_REQUIRED_RESULT;
#endif
enum NormalizationForm {
NormalizationForm_D,
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 37cb3754d3..2b2b436015 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -76,6 +76,10 @@ class tst_QString : public QObject
{
Q_OBJECT
+ template<typename List, class RegExp>
+ void split_regexp(const QString &string, const QString &pattern, QStringList result);
+ template<typename List>
+ void split(const QString &string, const QString &separator, QStringList result);
public:
tst_QString();
public slots:
@@ -221,6 +225,14 @@ private slots:
void split();
void split_regexp_data();
void split_regexp();
+ void split_regularexpression_data();
+ void split_regularexpression();
+ void splitRef_data();
+ void splitRef();
+ void splitRef_regexp_data();
+ void splitRef_regexp();
+ void splitRef_regularexpression_data();
+ void splitRef_regularexpression();
void fromUtf16_data();
void fromUtf16();
void fromUtf16_char16_data();
@@ -4989,16 +5001,49 @@ void tst_QString::split_data()
QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
}
-void tst_QString::split()
+template<class> struct StringSplitWrapper;
+template<> struct StringSplitWrapper<QString>
{
- QFETCH(QString, str);
- QFETCH(QString, sep);
- QFETCH(QStringList, result);
+ const QString &string;
+
+ QStringList split(const QString &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
+ QStringList split(QChar sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
+ QStringList split(const QRegExp &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.split(sep, behavior); }
+ QStringList split(const QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.split(sep, behavior); }
+};
+
+template<> struct StringSplitWrapper<QStringRef>
+{
+ const QString &string;
+ QVector<QStringRef> split(const QString &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
+ QVector<QStringRef> split(QChar sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
+ QVector<QStringRef> split(const QRegExp &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
+ QVector<QStringRef> split(const QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
+};
+static bool operator ==(const QStringList &left, const QVector<QStringRef> &right)
+{
+ if (left.size() != right.size())
+ return false;
+
+ QStringList::const_iterator iLeft = left.constBegin();
+ QVector<QStringRef>::const_iterator iRight = right.constBegin();
+ for (; iLeft != left.end(); ++iLeft, ++iRight) {
+ if (*iLeft != *iRight)
+ return false;
+ }
+ return true;
+}
+static inline bool operator ==(const QVector<QStringRef> &left, const QStringList &right) { return right == left; }
+
+template<class List>
+void tst_QString::split(const QString &string, const QString &sep, QStringList result)
+{
QRegExp rx = QRegExp(QRegExp::escape(sep));
QRegularExpression re(QRegularExpression::escape(sep));
- QStringList list;
+ List list;
+ StringSplitWrapper<typename List::value_type> str = {string};
list = str.split(sep);
QVERIFY(list == result);
@@ -5035,6 +5080,27 @@ void tst_QString::split()
}
}
+void tst_QString::split()
+{
+ QFETCH(QString, str);
+ QFETCH(QString, sep);
+ QFETCH(QStringList, result);
+ split<QStringList>(str, sep, result);
+}
+
+void tst_QString::splitRef_data()
+{
+ split_data();
+}
+
+void tst_QString::splitRef()
+{
+ QFETCH(QString, str);
+ QFETCH(QString, sep);
+ QFETCH(QStringList, result);
+ split<QVector<QStringRef> >(str, sep, result);
+}
+
void tst_QString::split_regexp_data()
{
QTest::addColumn<QString>("string");
@@ -5054,24 +5120,66 @@ void tst_QString::split_regexp_data()
<< (QStringList() << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << ".");
}
+template<class List, class RegExp>
+void tst_QString::split_regexp(const QString &_string, const QString &pattern, QStringList result)
+{
+ List list;
+ StringSplitWrapper<typename List::value_type> string = {_string};
+
+ list = string.split(RegExp(pattern));
+ QVERIFY(list == result);
+
+ result.removeAll(QString());
+
+ list = string.split(RegExp(pattern), QString::SkipEmptyParts);
+ QVERIFY(list == result);
+}
+
void tst_QString::split_regexp()
{
QFETCH(QString, string);
QFETCH(QString, pattern);
QFETCH(QStringList, result);
+ split_regexp<QStringList, QRegExp>(string, pattern, result);
+}
- QStringList list;
- list = string.split(QRegExp(pattern));
- QCOMPARE(list, result);
- list = string.split(QRegularExpression(pattern));
- QCOMPARE(list, result);
+void tst_QString::split_regularexpression_data()
+{
+ split_regexp_data();
+}
- result.removeAll(QString());
+void tst_QString::split_regularexpression()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, result);
+ split_regexp<QStringList, QRegularExpression>(string, pattern, result);
+}
- list = string.split(QRegExp(pattern), QString::SkipEmptyParts);
- QCOMPARE(list, result);
- list = string.split(QRegularExpression(pattern), QString::SkipEmptyParts);
- QCOMPARE(list, result);
+void tst_QString::splitRef_regularexpression_data()
+{
+ split_regexp_data();
+}
+
+void tst_QString::splitRef_regularexpression()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, result);
+ split_regexp<QVector<QStringRef>, QRegularExpression>(string, pattern, result);
+}
+
+void tst_QString::splitRef_regexp_data()
+{
+ split_regexp_data();
+}
+
+void tst_QString::splitRef_regexp()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, result);
+ split_regexp<QVector<QStringRef>, QRegExp>(string, pattern, result);
}
void tst_QString::fromUtf16_data()