Skip to content

Commit

Permalink
QByteArrayView: add a ctor for arrays of unknown bounds
Browse files Browse the repository at this point in the history
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
Pick-to: 6.9
Change-Id: I201033656f123b09644e5de447cd5d7b038e5154
Reviewed-by: Ivan Solovev <[email protected]>
  • Loading branch information
marcmutz committed Dec 16, 2024
1 parent 9a6036d commit 54d47f8
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/corelib/text/qbytearrayview.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ class Q_CORE_EXPORT QByteArrayView
constexpr QByteArrayView(const char (&data)[Size]) noexcept
: QByteArrayView(data, lengthHelperCharArray(data, Size)) {}

template <typename Byte, if_compatible_byte<Byte> = true>
constexpr QByteArrayView(const Byte (&data)[]) noexcept
: QByteArrayView(&*data) {} // decay to pointer

#ifdef Q_QDOC
template <typename Byte, size_t Size>
#else
Expand Down
18 changes: 18 additions & 0 deletions src/corelib/text/qbytearrayview.qdoc
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,21 @@
\sa {Compatible Byte Types}
*/

/*!
\fn template <typename Byte, QByteArrayView::if_compatible_byte<Byte>> 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 <size_t Size> QByteArrayView::QByteArrayView(const char (&data)[Size])

Expand All @@ -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
*/
Expand Down
2 changes: 2 additions & 0 deletions tests/auto/corelib/text/qbytearrayview/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 28 additions & 0 deletions tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp
Original file line number Diff line number Diff line change
@@ -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 <QByteArrayView>

#include <QTest>
Expand All @@ -20,24 +22,43 @@ static_assert(!CanConvert<const char16_t*>);
static_assert(!CanConvert<char>);
static_assert(CanConvert<char[1]>);
static_assert(CanConvert<const char[1]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert<char[]>);
static_assert(CanConvert<const char[]>);
#endif
static_assert(CanConvert<char*>);
static_assert(CanConvert<const char*>);

static_assert(!CanConvert<uchar>);
// sic! policy decision:
static_assert(!CanConvert<uchar[1]>);
static_assert(!CanConvert<const uchar[1]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert<uchar[]>);
static_assert(CanConvert<const uchar[]>);
#endif
static_assert(CanConvert<uchar*>);
static_assert(CanConvert<const uchar*>);

static_assert(!CanConvert<signed char>);
// sic! policy decision:
static_assert(!CanConvert<signed char[1]>);
static_assert(!CanConvert<const signed char[1]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert<signed char[]>);
static_assert(CanConvert<const signed char[]>);
#endif
static_assert(CanConvert<signed char*>);
static_assert(CanConvert<const signed char*>);

static_assert(!CanConvert<std::byte>);
// sic! policy decision:
static_assert(!CanConvert<std::byte[1]>);
static_assert(!CanConvert<const std::byte[1]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert<std::byte[]>);
static_assert(CanConvert<const std::byte[]>);
#endif
static_assert(CanConvert<std::byte*>);
static_assert(CanConvert<const std::byte*>);

Expand Down Expand Up @@ -108,6 +129,13 @@ private slots:
void basics() const;
void literals() const;
void fromArray() const;
void fromArrayWithUnknownSize() const
{
from_array_of_unknown_size<QByteArrayView>();
from_uarray_of_unknown_size<QByteArrayView>();
from_sarray_of_unknown_size<QByteArrayView>();
from_byte_array_of_unknown_size<QByteArrayView>();
}
void literalsWithInternalNulls() const;
void at() const;

Expand Down
12 changes: 12 additions & 0 deletions tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
30 changes: 30 additions & 0 deletions tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -35,6 +44,27 @@ void from_u8array_of_unknown_size()
}
#endif

template <typename StringView>
void from_uarray_of_unknown_size()
{
StringView bv = ustring_array;
QCOMPARE(bv.size(), ustring_array_size);
}

template <typename StringView>
void from_sarray_of_unknown_size()
{
StringView bv = sstring_array;
QCOMPARE(bv.size(), sstring_array_size);
}

template <typename StringView>
void from_byte_array_of_unknown_size()
{
StringView bv = byte_array;
QCOMPARE(bv.size(), byte_array_size);
}

template <typename StringView>
void from_u16array_of_unknown_size()
{
Expand Down

0 comments on commit 54d47f8

Please sign in to comment.