Add QStringView::split() methods
Since QString::split() is not going away in Qt 6, we should aim to provide API symmetry here, and ease porting existing code from QString(Ref) to use QStringView. This is easier than having to port everything to use tokenize() at the same time. tokenize() will however lead to better performance and thus should be preferred. Change-Id: I1eb43300a90167c6e9389ab56f416f2bf7edf506 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>bb10
parent
4f1ebf666e
commit
aac39167b7
|
|
@ -7197,7 +7197,7 @@ static ResultList splitString(const StringSource &source, QStringView sep,
|
|||
extra = (sep.size() == 0 ? 1 : 0);
|
||||
}
|
||||
if (start != source.size() || behavior == Qt::KeepEmptyParts)
|
||||
list.append(source.mid(start, -1));
|
||||
list.append(source.mid(start));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -7381,10 +7381,37 @@ QVector<QStringRef> QStringRef::split(QChar sep, QString::SplitBehavior behavior
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\fn QList<QStringView> QStringView::split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const
|
||||
\fn QList<QStringView> QStringView::split(QStringView sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const
|
||||
|
||||
|
||||
Splits the string into substring references wherever \a sep occurs, and
|
||||
returns the list of those strings.
|
||||
|
||||
See QString::split() for how \a sep, \a behavior and \a cs interact to form
|
||||
the result.
|
||||
|
||||
\note All references are valid as long this string is alive. Destroying this
|
||||
string will cause all references to be dangling pointers.
|
||||
|
||||
\since 6.0
|
||||
*/
|
||||
QList<QStringView> QStringView::split(QStringView sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const
|
||||
{
|
||||
return splitString<QVector<QStringView>>(QStringView(*this), sep, behavior, cs);
|
||||
}
|
||||
|
||||
QList<QStringView> QStringView::split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const
|
||||
{
|
||||
return split(QStringView(&sep, 1), behavior, cs);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(regularexpression)
|
||||
namespace {
|
||||
template<class ResultList, typename MidMethod>
|
||||
static ResultList splitString(const QString &source, MidMethod mid, const QRegularExpression &re,
|
||||
template<class ResultList, typename String>
|
||||
static ResultList splitString(const String &source, const QRegularExpression &re,
|
||||
Qt::SplitBehavior behavior)
|
||||
{
|
||||
ResultList list;
|
||||
|
|
@ -7400,12 +7427,12 @@ static ResultList splitString(const QString &source, MidMethod mid, const QRegul
|
|||
QRegularExpressionMatch match = iterator.next();
|
||||
end = match.capturedStart();
|
||||
if (start != end || behavior == Qt::KeepEmptyParts)
|
||||
list.append((source.*mid)(start, end - start));
|
||||
list.append(source.mid(start, end - start));
|
||||
start = match.capturedEnd();
|
||||
}
|
||||
|
||||
if (start != source.size() || behavior == Qt::KeepEmptyParts)
|
||||
list.append((source.*mid)(start, -1));
|
||||
list.append(source.mid(start));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
@ -7440,7 +7467,7 @@ static ResultList splitString(const QString &source, MidMethod mid, const QRegul
|
|||
*/
|
||||
QStringList QString::split(const QRegularExpression &re, Qt::SplitBehavior behavior) const
|
||||
{
|
||||
return splitString<QStringList>(*this, &QString::mid, re, behavior);
|
||||
return splitString<QStringList>(*this, re, behavior);
|
||||
}
|
||||
|
||||
# if QT_DEPRECATED_SINCE(5, 15)
|
||||
|
|
@ -7471,7 +7498,25 @@ QStringList QString::split(const QRegularExpression &re, SplitBehavior behavior)
|
|||
*/
|
||||
QVector<QStringRef> QString::splitRef(const QRegularExpression &re, Qt::SplitBehavior behavior) const
|
||||
{
|
||||
return splitString<QVector<QStringRef> >(*this, &QString::midRef, re, behavior);
|
||||
return splitString<QVector<QStringRef> >(QStringRef(this), re, behavior);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.0
|
||||
|
||||
Splits the string into substring views 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 to be dangling pointers.
|
||||
|
||||
\sa split() QStringRef
|
||||
*/
|
||||
QList<QStringView> QStringView::split(const QRegularExpression &re, Qt::SplitBehavior behavior) const
|
||||
{
|
||||
return splitString<QList<QStringView>>(*this, re, behavior);
|
||||
}
|
||||
|
||||
# if QT_DEPRECATED_SINCE(5, 15)
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ QT_BEGIN_NAMESPACE
|
|||
class QString;
|
||||
class QStringRef;
|
||||
class QStringView;
|
||||
class QRegularExpression;
|
||||
|
||||
namespace QtPrivate {
|
||||
template <typename Char>
|
||||
|
|
@ -339,6 +340,21 @@ public:
|
|||
|
||||
Q_REQUIRED_RESULT inline int toWCharArray(wchar_t *array) const; // defined in qstring.h
|
||||
|
||||
|
||||
Q_REQUIRED_RESULT Q_CORE_EXPORT
|
||||
QList<QStringView> split(QStringView sep,
|
||||
Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
|
||||
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
||||
Q_REQUIRED_RESULT Q_CORE_EXPORT
|
||||
QList<QStringView> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
|
||||
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
||||
|
||||
#if QT_CONFIG(regularexpression)
|
||||
Q_REQUIRED_RESULT Q_CORE_EXPORT
|
||||
QList<QStringView> split(const QRegularExpression &sep,
|
||||
Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
|
||||
#endif
|
||||
|
||||
//
|
||||
// STL compatibility API:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -5685,19 +5685,41 @@ template<> struct StringSplitWrapper<QString>
|
|||
{
|
||||
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 QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.split(sep, behavior); }
|
||||
QStringList split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
|
||||
QStringList split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
|
||||
QStringList split(const QRegularExpression &sep, Qt::SplitBehavior behavior = Qt::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 QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
|
||||
QVector<QStringRef> split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
|
||||
QVector<QStringRef> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
|
||||
QVector<QStringRef> split(const QRegularExpression &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
|
||||
};
|
||||
|
||||
template<> struct StringSplitWrapper<QStringView>
|
||||
{
|
||||
const QString &string;
|
||||
QList<QStringView> split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
|
||||
{ return QStringView{string}.split(sep, behavior, cs); }
|
||||
QList<QStringView> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
|
||||
{ return QStringView{string}.split(sep, behavior, cs); }
|
||||
QList<QStringView> split(const QRegularExpression &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const
|
||||
{ return QStringView{string}.split(sep, behavior); }
|
||||
};
|
||||
|
||||
static bool operator==(const QList<QStringView> &result, const QStringList &expected)
|
||||
{
|
||||
if (expected.size() != result.size())
|
||||
return false;
|
||||
for (int i = 0; i < expected.size(); ++i)
|
||||
if (expected.at(i) != result.at(i))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool operator ==(const QStringList &left, const QVector<QStringRef> &right)
|
||||
{
|
||||
if (left.size() != right.size())
|
||||
|
|
@ -5732,22 +5754,22 @@ void tst_QString::split(const QString &string, const QString &sep, QStringList r
|
|||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
list = str.split(sep, QString::KeepEmptyParts);
|
||||
list = str.split(sep, Qt::KeepEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
list = str.split(re, QString::KeepEmptyParts);
|
||||
list = str.split(re, Qt::KeepEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
if (sep.size() == 1) {
|
||||
list = str.split(sep.at(0), QString::KeepEmptyParts);
|
||||
list = str.split(sep.at(0), Qt::KeepEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
}
|
||||
|
||||
result.removeAll("");
|
||||
list = str.split(sep, QString::SkipEmptyParts);
|
||||
list = str.split(sep, Qt::SkipEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
list = str.split(re, QString::SkipEmptyParts);
|
||||
list = str.split(re, Qt::SkipEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
if (sep.size() == 1) {
|
||||
list = str.split(sep.at(0), QString::SkipEmptyParts);
|
||||
list = str.split(sep.at(0), Qt::SkipEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
}
|
||||
QT_WARNING_POP
|
||||
|
|
@ -5759,6 +5781,7 @@ void tst_QString::split()
|
|||
QFETCH(QString, sep);
|
||||
QFETCH(QStringList, result);
|
||||
split<QStringList>(str, sep, result);
|
||||
split<QVector<QStringView>>(str, sep, result);
|
||||
}
|
||||
|
||||
void tst_QString::splitRef_data()
|
||||
|
|
@ -5804,7 +5827,7 @@ void tst_QString::split_regexp(const QString &_string, const QString &pattern, Q
|
|||
|
||||
result.removeAll(QString());
|
||||
|
||||
list = string.split(RegExp(pattern), QString::SkipEmptyParts);
|
||||
list = string.split(RegExp(pattern), Qt::SkipEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
}
|
||||
|
||||
|
|
@ -5814,6 +5837,7 @@ void tst_QString::split_regularexpression()
|
|||
QFETCH(QString, pattern);
|
||||
QFETCH(QStringList, result);
|
||||
split_regexp<QStringList, QRegularExpression>(string, pattern, result);
|
||||
split_regexp<QList<QStringView>, QRegularExpression>(string, pattern, result);
|
||||
}
|
||||
|
||||
void tst_QString::splitRef_regularexpression_data()
|
||||
|
|
|
|||
Loading…
Reference in New Issue