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 Pick-to: 6.9 Change-Id: I201033656f123b09644e5de447cd5d7b038e5154 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
9a6036dea2
commit
54d47f8390
@ -176,6 +176,10 @@ public:
|
|||||||
constexpr QByteArrayView(const char (&data)[Size]) noexcept
|
constexpr QByteArrayView(const char (&data)[Size]) noexcept
|
||||||
: QByteArrayView(data, lengthHelperCharArray(data, Size)) {}
|
: 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
|
#ifdef Q_QDOC
|
||||||
template <typename Byte, size_t Size>
|
template <typename Byte, size_t Size>
|
||||||
#else
|
#else
|
||||||
|
@ -246,6 +246,21 @@
|
|||||||
\sa {Compatible Byte Types}
|
\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])
|
\fn template <size_t Size> QByteArrayView::QByteArrayView(const char (&data)[Size])
|
||||||
|
|
||||||
@ -264,6 +279,9 @@
|
|||||||
implicit constructor overload, we need to stop at the first
|
implicit constructor overload, we need to stop at the first
|
||||||
\c{char(0)}. This is logical for a char array, but not
|
\c{char(0)}. This is logical for a char array, but not
|
||||||
for a \c{std::byte} array.
|
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
|
\sa fromArray
|
||||||
*/
|
*/
|
||||||
|
@ -14,6 +14,8 @@ endif()
|
|||||||
qt_internal_add_test(tst_qbytearrayview
|
qt_internal_add_test(tst_qbytearrayview
|
||||||
SOURCES
|
SOURCES
|
||||||
tst_qbytearrayview.cpp
|
tst_qbytearrayview.cpp
|
||||||
|
../qstringview/arrays_of_unknown_bounds.cpp
|
||||||
|
../qstringview/arrays_of_unknown_bounds.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(QT_FEATURE_sanitize_undefined)
|
if(QT_FEATURE_sanitize_undefined)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (C) 2020 The Qt Company Ltd.
|
// Copyright (C) 2020 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
|
#include "../qstringview/arrays_of_unknown_bounds.h"
|
||||||
|
|
||||||
#include <QByteArrayView>
|
#include <QByteArrayView>
|
||||||
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
@ -20,24 +22,43 @@ static_assert(!CanConvert<const char16_t*>);
|
|||||||
static_assert(!CanConvert<char>);
|
static_assert(!CanConvert<char>);
|
||||||
static_assert(CanConvert<char[1]>);
|
static_assert(CanConvert<char[1]>);
|
||||||
static_assert(CanConvert<const 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<char*>);
|
||||||
static_assert(CanConvert<const char*>);
|
static_assert(CanConvert<const char*>);
|
||||||
|
|
||||||
static_assert(!CanConvert<uchar>);
|
static_assert(!CanConvert<uchar>);
|
||||||
|
// sic! policy decision:
|
||||||
static_assert(!CanConvert<uchar[1]>);
|
static_assert(!CanConvert<uchar[1]>);
|
||||||
static_assert(!CanConvert<const 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<uchar*>);
|
||||||
static_assert(CanConvert<const uchar*>);
|
static_assert(CanConvert<const uchar*>);
|
||||||
|
|
||||||
static_assert(!CanConvert<signed char>);
|
static_assert(!CanConvert<signed char>);
|
||||||
|
// sic! policy decision:
|
||||||
static_assert(!CanConvert<signed char[1]>);
|
static_assert(!CanConvert<signed char[1]>);
|
||||||
static_assert(!CanConvert<const 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<signed char*>);
|
||||||
static_assert(CanConvert<const signed char*>);
|
static_assert(CanConvert<const signed char*>);
|
||||||
|
|
||||||
static_assert(!CanConvert<std::byte>);
|
static_assert(!CanConvert<std::byte>);
|
||||||
|
// sic! policy decision:
|
||||||
static_assert(!CanConvert<std::byte[1]>);
|
static_assert(!CanConvert<std::byte[1]>);
|
||||||
static_assert(!CanConvert<const 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<std::byte*>);
|
||||||
static_assert(CanConvert<const std::byte*>);
|
static_assert(CanConvert<const std::byte*>);
|
||||||
|
|
||||||
@ -108,6 +129,13 @@ private slots:
|
|||||||
void basics() const;
|
void basics() const;
|
||||||
void literals() const;
|
void literals() const;
|
||||||
void fromArray() 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 literalsWithInternalNulls() const;
|
||||||
void at() const;
|
void at() const;
|
||||||
|
|
||||||
|
@ -11,6 +11,18 @@ const char8_t u8string_array[] = u8"abc\0def";
|
|||||||
const int u8string_array_size = 3;
|
const int u8string_array_size = 3;
|
||||||
#endif
|
#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 char16_t u16string_array[] = u"abc\0def";
|
||||||
const int u16string_array_size = 3;
|
const int u16string_array_size = 3;
|
||||||
|
|
||||||
|
@ -13,6 +13,15 @@ extern const char8_t u8string_array[];
|
|||||||
extern const int u8string_array_size;
|
extern const int u8string_array_size;
|
||||||
#endif
|
#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 char16_t u16string_array[];
|
||||||
extern const int u16string_array_size;
|
extern const int u16string_array_size;
|
||||||
|
|
||||||
@ -35,6 +44,27 @@ void from_u8array_of_unknown_size()
|
|||||||
}
|
}
|
||||||
#endif
|
#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>
|
template <typename StringView>
|
||||||
void from_u16array_of_unknown_size()
|
void from_u16array_of_unknown_size()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user