From 94928669c128088c107f20aadd1fa74c69f06e89 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 9 Dec 2024 17:08:35 +0100 Subject: [PATCH] QByteArrayView: add a ctor for arrays of unknown bounds This appears to not have worked, ever, so add it as a new feature, for view API symmetry, not as a bug-fix. The new constructor is available for all compatible byte types, because it is more like the (ptr) constructor (which is available for all compatible byte types) than the known-size-array constructor (which is only available for char). This does not affect QB/QBV overload sets, since they could exist ambiguity-free only if one of them is a Q_WEAK_OVERLOAD. The GHS compiler doesn't like the CanConvert static_asserts, so comment them out for it. The functionality itself is tested by the fromArrayWithUnknownSize test. [ChangeLog][QtCore][QByteArrayView] Made construction from arrays of unknown size compile. Such arrays will use the const Byte* constructor, determining the size of the array at runtime. Task-number: QTBUG-112746 Change-Id: I201033656f123b09644e5de447cd5d7b038e5154 Reviewed-by: Ivan Solovev (cherry picked from commit 54d47f8390cb85c5b0f0ac050b5aa5a934d798b0) Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/corelib/text/qbytearrayview.h | 4 +++ src/corelib/text/qbytearrayview.qdoc | 18 +++++++++++ .../text/qbytearrayview/CMakeLists.txt | 2 ++ .../qbytearrayview/tst_qbytearrayview.cpp | 28 +++++++++++++++++ .../qstringview/arrays_of_unknown_bounds.cpp | 12 ++++++++ .../qstringview/arrays_of_unknown_bounds.h | 30 +++++++++++++++++++ 6 files changed, 94 insertions(+) diff --git a/src/corelib/text/qbytearrayview.h b/src/corelib/text/qbytearrayview.h index 4934777fb21..568b69dbb3f 100644 --- a/src/corelib/text/qbytearrayview.h +++ b/src/corelib/text/qbytearrayview.h @@ -176,6 +176,10 @@ public: constexpr QByteArrayView(const char (&data)[Size]) noexcept : QByteArrayView(data, lengthHelperCharArray(data, Size)) {} + template = true> + constexpr QByteArrayView(const Byte (&data)[]) noexcept + : QByteArrayView(&*data) {} // decay to pointer + #ifdef Q_QDOC template #else diff --git a/src/corelib/text/qbytearrayview.qdoc b/src/corelib/text/qbytearrayview.qdoc index bc9df292769..7d9a455b9fd 100644 --- a/src/corelib/text/qbytearrayview.qdoc +++ b/src/corelib/text/qbytearrayview.qdoc @@ -246,6 +246,21 @@ \sa {Compatible Byte Types} */ +/*! + \fn template > QByteArrayView::QByteArrayView(const Byte (&data)[]) + \since 6.9 + + Constructs a byte array view on \a data, an array of unknown size. The + length is determined by scanning for the first \c{Byte(0)}. + + \a data must remain valid for the lifetime of this byte array view object. + + This constructor only participates in overload resolution if \c Byte is a + compatible byte type. + + \sa {Compatible Byte Types} +*/ + /*! \fn template QByteArrayView::QByteArrayView(const char (&data)[Size]) @@ -264,6 +279,9 @@ implicit constructor overload, we need to stop at the first \c{char(0)}. This is logical for a char array, but not for a \c{std::byte} array. + It is, however, inconsistent with the corresponding pointer (\c{Byte*}) and + unknown-length-array (\c{Byte[]}) constructors, and so might change in a + future version of Qt. \sa fromArray */ diff --git a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt index 8922ae22677..3a57f87ea87 100644 --- a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt +++ b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt @@ -14,6 +14,8 @@ endif() qt_internal_add_test(tst_qbytearrayview SOURCES tst_qbytearrayview.cpp + ../qstringview/arrays_of_unknown_bounds.cpp + ../qstringview/arrays_of_unknown_bounds.h ) if(QT_FEATURE_sanitize_undefined) diff --git a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp index a65f3ffc307..0155a1aeb9e 100644 --- a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp +++ b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp @@ -1,6 +1,8 @@ // Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +#include "../qstringview/arrays_of_unknown_bounds.h" + #include #include @@ -20,24 +22,43 @@ static_assert(!CanConvert); static_assert(!CanConvert); static_assert(CanConvert); static_assert(CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert); +static_assert(CanConvert); +#endif static_assert(CanConvert); static_assert(CanConvert); static_assert(!CanConvert); +// sic! policy decision: static_assert(!CanConvert); static_assert(!CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert); +static_assert(CanConvert); +#endif static_assert(CanConvert); static_assert(CanConvert); static_assert(!CanConvert); +// sic! policy decision: static_assert(!CanConvert); static_assert(!CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert); +static_assert(CanConvert); +#endif static_assert(CanConvert); static_assert(CanConvert); static_assert(!CanConvert); +// sic! policy decision: static_assert(!CanConvert); static_assert(!CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert); +static_assert(CanConvert); +#endif static_assert(CanConvert); static_assert(CanConvert); @@ -108,6 +129,13 @@ private slots: void basics() const; void literals() const; void fromArray() const; + void fromArrayWithUnknownSize() const + { + from_array_of_unknown_size(); + from_uarray_of_unknown_size(); + from_sarray_of_unknown_size(); + from_byte_array_of_unknown_size(); + } void literalsWithInternalNulls() const; void at() const; diff --git a/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.cpp b/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.cpp index a8697464fb1..172015958f5 100644 --- a/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.cpp +++ b/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.cpp @@ -11,6 +11,18 @@ const char8_t u8string_array[] = u8"abc\0def"; const int u8string_array_size = 3; #endif +const uchar ustring_array[] = "abc\0def"; +const int ustring_array_size = 3; + +const signed char sstring_array[] = "abc\0def"; +const int sstring_array_size = 3; + +const std::byte byte_array[] = { + std::byte{'a'}, std::byte{'b'}, std::byte{'c'}, std::byte{}, + std::byte{'d'}, std::byte{'e'}, std::byte{'f'} +}; +const int byte_array_size = 3; + const char16_t u16string_array[] = u"abc\0def"; const int u16string_array_size = 3; diff --git a/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.h b/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.h index 863b58a1faf..d47c2437c6b 100644 --- a/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.h +++ b/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.h @@ -13,6 +13,15 @@ extern const char8_t u8string_array[]; extern const int u8string_array_size; #endif +extern const uchar ustring_array[]; +extern const int ustring_array_size; + +extern const signed char sstring_array[]; +extern const int sstring_array_size; + +extern const std::byte byte_array[]; +extern const int byte_array_size; + extern const char16_t u16string_array[]; extern const int u16string_array_size; @@ -35,6 +44,27 @@ void from_u8array_of_unknown_size() } #endif +template +void from_uarray_of_unknown_size() +{ + StringView bv = ustring_array; + QCOMPARE(bv.size(), ustring_array_size); +} + +template +void from_sarray_of_unknown_size() +{ + StringView bv = sstring_array; + QCOMPARE(bv.size(), sstring_array_size); +} + +template +void from_byte_array_of_unknown_size() +{ + StringView bv = byte_array; + QCOMPARE(bv.size(), byte_array_size); +} + template void from_u16array_of_unknown_size() {