From 6f833eff92fe703a13214a0c1a593d94e51847d1 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 9 Aug 2021 15:19:02 +0200 Subject: [PATCH] Add QByteArrayView::trimmed() Unlike simplified(), it just moves the end-points, without needing to modify contents, so it makes sense (as for QStringView and QLatin1String) to provide it. Moved QByteArray's trimmed() tests to tst_QByteArrayApiSymmetry so that QBAV can now share them. [ChangeLog][QtCore][QByteArrayView] Added trimmed(). Change-Id: Ifd7a752adb5f3d3e2ad0aa8220efa7e7d2d39baa Reviewed-by: Sona Kurazyan --- src/corelib/text/qbytearray.cpp | 7 ++++ src/corelib/text/qbytearrayalgorithms.h | 4 +- src/corelib/text/qbytearrayview.h | 5 ++- src/corelib/text/qbytearrayview.qdoc | 17 ++++++++- .../text/qbytearray/tst_qbytearray.cpp | 29 +------------- .../tst_qbytearrayapisymmetry.cpp | 38 ++++++++++++++++++- .../qbytearrayview/tst_qbytearrayview.cpp | 1 + 7 files changed, 69 insertions(+), 32 deletions(-) diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index d97375897d5..23db7db3e26 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -3390,6 +3390,13 @@ QByteArray QByteArray::trimmed_helper(QByteArray &a) return QStringAlgorithms::trimmed_helper(a); } +QByteArrayView QtPrivate::trimmed(QByteArrayView view) noexcept +{ + auto start = view.begin(); + auto stop = view.end(); + QStringAlgorithms::trimmed_helper_positions(start, stop); + return QByteArrayView(start, stop); +} /*! Returns a byte array of size \a width that contains this byte array padded diff --git a/src/corelib/text/qbytearrayalgorithms.h b/src/corelib/text/qbytearrayalgorithms.h index be1e6cc953c..638af2948b4 100644 --- a/src/corelib/text/qbytearrayalgorithms.h +++ b/src/corelib/text/qbytearrayalgorithms.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -72,6 +72,8 @@ qsizetype count(QByteArrayView haystack, QByteArrayView needle) noexcept; [[nodiscard]] Q_CORE_EXPORT int compareMemory(QByteArrayView lhs, QByteArrayView rhs); +[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QByteArrayView trimmed(QByteArrayView s) noexcept; + } // namespace QtPrivate /***************************************************************************** diff --git a/src/corelib/text/qbytearrayview.h b/src/corelib/text/qbytearrayview.h index 9d35e214151..1dfc65b4c4c 100644 --- a/src/corelib/text/qbytearrayview.h +++ b/src/corelib/text/qbytearrayview.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -240,6 +240,9 @@ public: constexpr void chop(qsizetype n) { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size -= n; } + [[nodiscard]] QByteArrayView trimmed() const noexcept + { return QtPrivate::trimmed(*this); } + [[nodiscard]] bool startsWith(QByteArrayView other) const noexcept { return QtPrivate::startsWith(*this, other); } [[nodiscard]] bool startsWith(char c) const noexcept diff --git a/src/corelib/text/qbytearrayview.qdoc b/src/corelib/text/qbytearrayview.qdoc index 30d8d476856..740734ebbd6 100644 --- a/src/corelib/text/qbytearrayview.qdoc +++ b/src/corelib/text/qbytearrayview.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -619,6 +619,21 @@ \sa sliced(), first(), last(), chopped(), truncate() */ +/*! + \fn QByteArrayView QByteArrayView::trimmed() const noexcept + \since 6.3 + + Returns a copy of this byte array view with spacing characters + removed from the start and end. + + The spacing characters are those for which the standard C++ \c isspace() + function returns \c true in the C locale; these are the ASCII characters + tabulation '\\t', line feed '\\n', carriage return '\\r', vertical + tabulation '\\v', form feed '\\f', and space ' '. + + \sa QChar::SpecialCharacter, {QByteArray#Spacing Characters}{Spacing Characters} +*/ + /*! \fn bool QByteArrayView::startsWith(QByteArrayView bv) const \fn bool QByteArrayView::startsWith(char ch) const diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index b0d55f7542c..9f4949f5b38 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -44,6 +44,7 @@ class tst_QByteArray : public QObject public: tst_QByteArray(); private slots: + // Note: much of the shared API is tested in ../qbytearrayapisymmetry/ void swap(); void qChecksum_data(); void qChecksum(); @@ -157,8 +158,6 @@ private slots: void fill(); void dataPointers(); void truncate(); - void trimmed(); - void trimmed_data(); void simplified(); void simplified_data(); void left(); @@ -2797,32 +2796,6 @@ void tst_QByteArray::truncate() QVERIFY(a.isEmpty()); } -void tst_QByteArray::trimmed() -{ - QFETCH(QByteArray, source); - QFETCH(QByteArray, expected); - - QCOMPARE(source.trimmed(), expected); - QByteArray copy = source; - QCOMPARE(std::move(copy).trimmed(), expected); - - if (source.isEmpty()) - QVERIFY(!source.isDetached()); -} - -void tst_QByteArray::trimmed_data() -{ - QTest::addColumn("source"); - QTest::addColumn("expected"); - - QTest::newRow("null") << QByteArray() << QByteArray(); - QTest::newRow("empty") << QByteArray("") << QByteArray(""); - QTest::newRow("no spaces") << QByteArray("a b\nc\td") << QByteArray("a b\nc\td"); - QTest::newRow("with spaces") << QByteArray("\t \v a b\r\nc \td\ve f \r\n\f") - << QByteArray("a b\r\nc \td\ve f"); - QTest::newRow("all spaces") << QByteArray("\t \r \n \v \f") << QByteArray(""); -} - void tst_QByteArray::simplified() { QFETCH(QByteArray, source); diff --git a/tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp b/tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp index fe0c3efbee5..5f181647af5 100644 --- a/tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp +++ b/tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -121,6 +121,11 @@ private slots: void chop_QByteArrayView_data() { chop_data(); } void chop_QByteArrayView() { chop_impl(); } + void trimmed_QByteArray_data() { trimmed_data(); } + void trimmed_QByteArray() { trimmed_impl(); } + void trimmed_QByteArrayView_data() { trimmed_data(); } + void trimmed_QByteArrayView() { trimmed_impl(); } + private: void startsWith_data(); template void startsWith_impl(); @@ -156,6 +161,9 @@ private: void chop_data(); template void chop_impl(); + + void trimmed_data(); + template void trimmed_impl(); }; static const auto empty = QByteArray(""); @@ -877,5 +885,33 @@ void tst_QByteArrayApiSymmetry::chop_impl() } } +void tst_QByteArrayApiSymmetry::trimmed_data() +{ + QTest::addColumn("source"); + QTest::addColumn("expected"); + + QTest::newRow("null") << QByteArray() << QByteArray(); + QTest::newRow("empty") << QByteArray("") << QByteArray(""); + QTest::newRow("no end-spaces") << QByteArray("a b\nc\td") << QByteArray("a b\nc\td"); + QTest::newRow("with end-spaces") + << QByteArray("\t \v a b\r\nc \td\ve f \r\n\f") << QByteArray("a b\r\nc \td\ve f"); + QTest::newRow("all spaces") << QByteArray("\t \r \n \v \f") << QByteArray(""); +} + +template void tst_QByteArrayApiSymmetry::trimmed_impl() +{ + QFETCH(QByteArray, source); + QFETCH(QByteArray, expected); + + QCOMPARE(ByteArray(source).trimmed(), ByteArray(expected)); + ByteArray copy{source}; + QCOMPARE(std::move(copy).trimmed(), ByteArray(expected)); + + if constexpr (std::is_same_v) { + if (source.isEmpty()) + QVERIFY(!source.isDetached()); + } +} + QTEST_APPLESS_MAIN(tst_QByteArrayApiSymmetry) #include "tst_qbytearrayapisymmetry.moc" diff --git a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp index d65731fdbdf..2953fc5c044 100644 --- a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp +++ b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp @@ -107,6 +107,7 @@ class tst_QByteArrayView : public QObject { Q_OBJECT private slots: + // Note: much of the shared API is tested in ../qbytearrayapisymmetry/ void constExpr() const; void basics() const; void literals() const;