diff options
-rw-r--r-- | src/corelib/tools/qstring.cpp | 35 | ||||
-rw-r--r-- | src/corelib/tools/qstring.h | 5 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qstringref/tst_qstringref.cpp | 75 |
3 files changed, 113 insertions, 2 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index d3cb62429f..8b23f33735 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6625,8 +6625,8 @@ QString QString::number(double n, char f, int prec) } namespace { -template<class ResultList, typename MidMethod, typename Separator> -static ResultList splitString(const QString &source, MidMethod mid, const Separator &sep, +template<class ResultList, class StringSource, typename MidMethod, typename Separtor> +static ResultList splitString(const StringSource &source, MidMethod mid, const Separtor &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs, const int separatorSize) { ResultList list; @@ -6707,6 +6707,37 @@ QVector<QStringRef> QString::splitRef(QChar sep, SplitBehavior behavior, Qt::Cas return splitString<QVector<QStringRef> >(*this, &QString::midRef, sep, behavior, cs, 1); } +/*! + Splits the string into substrings references wherever \a sep occurs, and + returns the list of those strings. If \a sep does not match + anywhere in the string, split() 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 +*/ +QVector<QStringRef> QStringRef::split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const +{ + return splitString<QVector<QStringRef> >(*this, &QStringRef::mid, sep, behavior, cs, sep.size()); +} + +/*! + \overload + \since 5.4 +*/ +QVector<QStringRef> QStringRef::split(QChar sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const +{ + return splitString<QVector<QStringRef> >(*this, &QStringRef::mid, sep, behavior, cs, 1); +} + #ifndef QT_NO_REGEXP namespace { template<class ResultList, typename MidMethod> diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 21b64f5006..349588911b 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1305,6 +1305,11 @@ public: int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; + QVector<QStringRef> split(const QString &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, + Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT; + QVector<QStringRef> split(QChar sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, + Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT; + QStringRef left(int n) const Q_REQUIRED_RESULT; QStringRef right(int n) const Q_REQUIRED_RESULT; QStringRef mid(int pos, int n = -1) const Q_REQUIRED_RESULT; diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp index 342abb7ea8..fe5fe92872 100644 --- a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp +++ b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp @@ -93,6 +93,8 @@ private slots: void left(); void right(); void mid(); + void split_data(); + void split(); }; static QStringRef emptyRef() @@ -1984,6 +1986,79 @@ void tst_QStringRef::mid() QVERIFY(emptyRef.mid(-10, 3).isEmpty()); } +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; } + +void tst_QStringRef::split_data() +{ + QTest::addColumn<QString>("str"); + QTest::addColumn<QString>("sep"); + QTest::addColumn<QStringList>("result"); + + QTest::newRow("a,b,c") << "a,b,c" << "," << (QStringList() << "a" << "b" << "c"); + QTest::newRow("a,b,c,a,b,c") << "a,b,c,a,b,c" << "," << (QStringList() << "a" << "b" << "c" << "a" << "b" << "c"); + QTest::newRow("a,b,c,,a,b,c") << "a,b,c,,a,b,c" << "," << (QStringList() << "a" << "b" << "c" << "" << "a" << "b" << "c"); + QTest::newRow("2") << QString("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile") + << " " + << (QStringList() << "-rw-r--r--" << "" << "1" << "0" << "" << "0" << "" + << "519240" << "Jul" << "" << "9" << "" << "2002" << "bigfile"); + QTest::newRow("one-empty") << "" << " " << (QStringList() << ""); + QTest::newRow("two-empty") << " " << " " << (QStringList() << "" << ""); + QTest::newRow("three-empty") << " " << " " << (QStringList() << "" << "" << ""); + + QTest::newRow("all-empty") << "" << "" << (QStringList() << "" << ""); + QTest::newRow("all-null") << QString() << QString() << (QStringList() << QString() << QString()); + QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << ""); +} + +void tst_QStringRef::split() +{ + QFETCH(QString, str); + QFETCH(QString, sep); + QFETCH(QStringList, result); + + QVector<QStringRef> list; + // we construct a bigger valid string to check + // if ref.split is using the right size + QString source = str + str + str; + QStringRef ref = source.midRef(str.size(), str.size()); + QCOMPARE(ref.size(), str.size()); + + list = ref.split(sep); + QVERIFY(list == result); + if (sep.size() == 1) { + list = ref.split(sep.at(0)); + QVERIFY(list == result); + } + + list = ref.split(sep, QString::KeepEmptyParts); + QVERIFY(list == result); + if (sep.size() == 1) { + list = ref.split(sep.at(0), QString::KeepEmptyParts); + QVERIFY(list == result); + } + + result.removeAll(""); + list = ref.split(sep, QString::SkipEmptyParts); + QVERIFY(list == result); + if (sep.size() == 1) { + list = ref.split(sep.at(0), QString::SkipEmptyParts); + QVERIFY(list == result); + } +} + QTEST_APPLESS_MAIN(tst_QStringRef) #include "tst_qstringref.moc" |