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());
|
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
|
\overload
|
||||||
*/
|
*/
|
||||||
@ -6676,6 +6698,15 @@ QStringList QString::split(QChar sep, SplitBehavior behavior, Qt::CaseSensitivit
|
|||||||
return splitString<QStringList>(*this, &QString::mid, sep, behavior, cs, 1);
|
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
|
#ifndef QT_NO_REGEXP
|
||||||
namespace {
|
namespace {
|
||||||
template<class ResultList, typename MidMethod>
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
#ifndef QT_NO_REGULAREXPRESSION
|
#ifndef QT_NO_REGULAREXPRESSION
|
||||||
@ -6793,6 +6843,25 @@ QStringList QString::split(const QRegularExpression &re, SplitBehavior behavior)
|
|||||||
{
|
{
|
||||||
return splitString<QStringList>(*this, &QString::mid, re, 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_BOOTSTRAPPED
|
||||||
#endif // QT_NO_REGULAREXPRESSION
|
#endif // QT_NO_REGULAREXPRESSION
|
||||||
|
|
||||||
|
@ -441,13 +441,19 @@ public:
|
|||||||
|
|
||||||
QStringList split(const QString &sep, SplitBehavior behavior = KeepEmptyParts,
|
QStringList split(const QString &sep, SplitBehavior behavior = KeepEmptyParts,
|
||||||
Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
|
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,
|
QStringList split(QChar sep, SplitBehavior behavior = KeepEmptyParts,
|
||||||
Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
|
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
|
#ifndef QT_NO_REGEXP
|
||||||
QStringList split(const QRegExp &sep, SplitBehavior behavior = KeepEmptyParts) const Q_REQUIRED_RESULT;
|
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
|
#endif
|
||||||
#ifndef QT_NO_REGULAREXPRESSION
|
#ifndef QT_NO_REGULAREXPRESSION
|
||||||
QStringList split(const QRegularExpression &sep, SplitBehavior behavior = KeepEmptyParts) const Q_REQUIRED_RESULT;
|
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
|
#endif
|
||||||
enum NormalizationForm {
|
enum NormalizationForm {
|
||||||
NormalizationForm_D,
|
NormalizationForm_D,
|
||||||
|
@ -76,6 +76,10 @@ class tst_QString : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
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:
|
public:
|
||||||
tst_QString();
|
tst_QString();
|
||||||
public slots:
|
public slots:
|
||||||
@ -221,6 +225,14 @@ private slots:
|
|||||||
void split();
|
void split();
|
||||||
void split_regexp_data();
|
void split_regexp_data();
|
||||||
void split_regexp();
|
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_data();
|
||||||
void fromUtf16();
|
void fromUtf16();
|
||||||
void fromUtf16_char16_data();
|
void fromUtf16_char16_data();
|
||||||
@ -4989,16 +5001,49 @@ void tst_QString::split_data()
|
|||||||
QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
|
QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QString::split()
|
template<class> struct StringSplitWrapper;
|
||||||
|
template<> struct StringSplitWrapper<QString>
|
||||||
{
|
{
|
||||||
QFETCH(QString, str);
|
const QString &string;
|
||||||
QFETCH(QString, sep);
|
|
||||||
QFETCH(QStringList, result);
|
|
||||||
|
|
||||||
|
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));
|
QRegExp rx = QRegExp(QRegExp::escape(sep));
|
||||||
QRegularExpression re(QRegularExpression::escape(sep));
|
QRegularExpression re(QRegularExpression::escape(sep));
|
||||||
|
|
||||||
QStringList list;
|
List list;
|
||||||
|
StringSplitWrapper<typename List::value_type> str = {string};
|
||||||
|
|
||||||
list = str.split(sep);
|
list = str.split(sep);
|
||||||
QVERIFY(list == result);
|
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()
|
void tst_QString::split_regexp_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<QString>("string");
|
QTest::addColumn<QString>("string");
|
||||||
@ -5054,24 +5120,66 @@ void tst_QString::split_regexp_data()
|
|||||||
<< (QStringList() << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << ".");
|
<< (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()
|
void tst_QString::split_regexp()
|
||||||
{
|
{
|
||||||
QFETCH(QString, string);
|
QFETCH(QString, string);
|
||||||
QFETCH(QString, pattern);
|
QFETCH(QString, pattern);
|
||||||
QFETCH(QStringList, result);
|
QFETCH(QStringList, result);
|
||||||
|
split_regexp<QStringList, QRegExp>(string, pattern, result);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList list;
|
void tst_QString::split_regularexpression_data()
|
||||||
list = string.split(QRegExp(pattern));
|
{
|
||||||
QCOMPARE(list, result);
|
split_regexp_data();
|
||||||
list = string.split(QRegularExpression(pattern));
|
}
|
||||||
QCOMPARE(list, result);
|
|
||||||
|
|
||||||
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);
|
void tst_QString::splitRef_regularexpression_data()
|
||||||
QCOMPARE(list, result);
|
{
|
||||||
list = string.split(QRegularExpression(pattern), QString::SkipEmptyParts);
|
split_regexp_data();
|
||||||
QCOMPARE(list, result);
|
}
|
||||||
|
|
||||||
|
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()
|
void tst_QString::fromUtf16_data()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user