Q{Any,Utf8}StringView: fix construction from arrays of unknown size

Like QStringView's, these classes' documentation promised
is_constructible<View,Char[]>, but failed to deliver, because neither
the (const Pointer&) nor the (const Container &) compile for arrays of
unkonwn bounds, and the (const Char*) one is just a QDoc fake.

Apply the same fix as for QStringView: Add a ctor specifically for
arrays of unknown bound, delegating to the (ptr) overload.

The GHS compiler doesn't like the CanConvert static_asserts, so
comment them out for it. The functionality itself is tested by
the from*ArrayWithUnknownSize tests.

[ChangeLog][QtCore][QUtf8StringView/QAnyStringView] Made construction
from arrays of unknown size compile. Such arrays will use the const
Char* constructor, determining the size of the array at runtime.

Pick-to: 6.8 6.5
Fixes: QTBUG-112746
Change-Id: I7acdcae3c5bdf80a0bed673e621d53ef34a92a1e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 734bd05d0a6d37d6488cf8d1b2b9f79b9329d966)
This commit is contained in:
Marc Mutz 2024-12-10 13:24:55 +01:00
parent 1f0dc7635e
commit 51bfc9da41
6 changed files with 82 additions and 1 deletions

View File

@ -185,10 +185,13 @@ public:
template <typename Char>
constexpr QAnyStringView(const Char *str) noexcept;
#else
template <typename Pointer, if_compatible_pointer<Pointer> = true>
constexpr QAnyStringView(const Pointer &str) noexcept
: QAnyStringView{str, str ? lengthHelperPointer(str) : 0} {}
template <typename Char, if_compatible_char<Char> = true>
constexpr QAnyStringView(const Char (&str)[]) noexcept
: QAnyStringView{&*str} {} // decay to pointer
#endif
// defined in qstring.h

View File

@ -174,6 +174,10 @@ public:
template <typename Pointer, if_compatible_pointer<Pointer> = true>
constexpr QBasicUtf8StringView(const Pointer &str) noexcept
: QBasicUtf8StringView(str, QtPrivate::lengthHelperPointer(str)) {}
template <typename Char, if_compatible_char<Char> = true>
constexpr QBasicUtf8StringView(const Char (&str)[]) noexcept
: QBasicUtf8StringView(&*str) {} // decay to pointer
#endif
#ifdef Q_QDOC

View File

@ -14,6 +14,8 @@ endif()
qt_internal_add_test(tst_qanystringview
SOURCES
tst_qanystringview.cpp
../qstringview/arrays_of_unknown_bounds.cpp
../qstringview/arrays_of_unknown_bounds.h
NO_BATCH # QTBUG-121815
DEFINES
QTEST_THROW_ON_FAIL

View File

@ -1,6 +1,8 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "../qstringview/arrays_of_unknown_bounds.h"
#include <QAnyStringView>
#include <QChar>
#include <QDebug>
@ -84,6 +86,10 @@ static_assert(CanConvert<QChar>);
static_assert(CanConvert<QChar[123]>);
static_assert(CanConvert<const QChar[123]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert< QChar[]>);
static_assert(CanConvert<const QChar[]>);
#endif
static_assert(CanConvert< QString >);
static_assert(CanConvert<const QString >);
@ -98,6 +104,10 @@ static_assert(CanConvert<ushort>);
static_assert(CanConvert<ushort[123]>);
static_assert(CanConvert<const ushort[123]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert< ushort[]>);
static_assert(CanConvert<const ushort[]>);
#endif
static_assert(CanConvert< ushort*>);
static_assert(CanConvert<const ushort*>);
@ -119,6 +129,10 @@ static_assert(CanConvert<char8_t>);
static_assert(CanConvert< char8_t[123]>);
static_assert(CanConvert<const char8_t[123]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert< char8_t[]>);
static_assert(CanConvert<const char8_t[]>);
#endif
static_assert(CanConvert< char8_t*>);
static_assert(CanConvert<const char8_t*>);
@ -154,6 +168,10 @@ static_assert(CanConvert<char16_t>);
static_assert(CanConvert< char16_t[123]>);
static_assert(CanConvert<const char16_t[123]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert< char16_t[]>);
static_assert(CanConvert<const char16_t[]>);
#endif
static_assert(CanConvert< char16_t*>);
static_assert(CanConvert<const char16_t*>);
@ -187,6 +205,10 @@ static_assert(CanConvert<char32_t>); // ... except here
static_assert(!CanConvert< char32_t[123]>);
static_assert(!CanConvert<const char32_t[123]>);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(!CanConvert< char32_t[]>);
static_assert(!CanConvert<const char32_t[]>);
#endif
static_assert(!CanConvert< char32_t*>);
static_assert(!CanConvert<const char32_t*>);
@ -224,6 +246,10 @@ static_assert(CanConvert<wchar_t> == CanConvertFromWCharT); // ### FIXME: should
static_assert(CanConvert< wchar_t[123]> == CanConvertFromWCharT);
static_assert(CanConvert<const wchar_t[123]> == CanConvertFromWCharT);
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
static_assert(CanConvert< wchar_t[]> == CanConvertFromWCharT);
static_assert(CanConvert<const wchar_t[]> == CanConvertFromWCharT);
#endif
static_assert(CanConvert< wchar_t*> == CanConvertFromWCharT);
static_assert(CanConvert<const wchar_t*> == CanConvertFromWCharT);
@ -344,10 +370,22 @@ private Q_SLOTS:
void fromQLatin1StringView() const { fromQStringOrByteArray<QLatin1StringView>(); }
void fromCharArray() const { fromArray<char>(); }
void fromCharArrayOfUnknownSize() const
{
from_array_of_unknown_size<QAnyStringView>();
from_array_of_unknown_size<QUtf8StringView>();
}
void fromChar8Array() const { ONLY_IF_CHAR_8_T(fromArray<char8_t>()); }
void fromChar8ArrayOfUnknownSize() const
{
ONLY_IF_CHAR_8_T(from_u8array_of_unknown_size<QAnyStringView>());
ONLY_IF_CHAR_8_T(from_u8array_of_unknown_size<QUtf8StringView>());
}
void fromChar16Array() const { fromArray<char16_t>(); }
void fromChar16ArrayOfUnknownSize() const { from_u16array_of_unknown_size<QAnyStringView>(); }
void fromQCharArray() const { fromArray<QChar>(); }
void fromWCharTArray() const { ONLY_WIN(fromArray<wchar_t>()); }
void fromWCharTArrayOfUnknownSize() const { ONLY_WIN(from_warray_of_unknown_size<QAnyStringView>()); }
void fromQCharStar() const
{

View File

@ -3,7 +3,16 @@
#include "arrays_of_unknown_bounds.h"
const char string_array[] = "abc\0def";
const int string_array_size = 3;
#ifdef __cpp_char8_t
const char8_t u8string_array[] = u8"abc\0def";
const int u8string_array_size = 3;
#endif
const char16_t u16string_array[] = u"abc\0def";
const int u16string_array_size = 3;
const wchar_t wstring_array[] = L"abc\0def";
const int wstring_array_size = 3;

View File

@ -5,11 +5,36 @@
#include <QtTest/qtest.h>
extern const char string_array[];
extern const int string_array_size;
#ifdef __cpp_char8_t
extern const char8_t u8string_array[];
extern const int u8string_array_size;
#endif
extern const char16_t u16string_array[];
extern const int u16string_array_size;
extern const wchar_t wstring_array[];
extern const int wstring_array_size;
template <typename StringView>
void from_array_of_unknown_size()
{
StringView bv = string_array;
QCOMPARE(bv.size(), string_array_size);
}
#ifdef __cpp_char8_t
template <typename StringView>
void from_u8array_of_unknown_size()
{
StringView sv = u8string_array;
QCOMPARE(sv.size(), u8string_array_size);
}
#endif
template <typename StringView>
void from_u16array_of_unknown_size()
{