Add QString::splitRef functions.
The functions can be used to optimize code that do not need to use the split results as QString directly. [ChangeLog][QtCore] QString can now split a string to a list of QStringRef. Change-Id: Ic2dc929e1fba82f9a060e37c51068a301cb5b866 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
parent
b80c449c2d
commit
f5c3126201
@ -6668,6 +6668,28 @@ QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseS
|
||||
return splitString<QStringList>(*this, &QString::mid, sep, behavior, cs, sep.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
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
|
||||
*/
|
||||
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user