From 51bfc9da41faa41a3161d30879b394a0dac94dcf Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 10 Dec 2024 13:24:55 +0100 Subject: [PATCH] Q{Any,Utf8}StringView: fix construction from arrays of unknown size Like QStringView's, these classes' documentation promised is_constructible, 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 (cherry picked from commit 734bd05d0a6d37d6488cf8d1b2b9f79b9329d966) --- src/corelib/text/qanystringview.h | 5 ++- src/corelib/text/qutf8stringview.h | 4 ++ .../text/qanystringview/CMakeLists.txt | 2 + .../qanystringview/tst_qanystringview.cpp | 38 +++++++++++++++++++ .../qstringview/arrays_of_unknown_bounds.cpp | 9 +++++ .../qstringview/arrays_of_unknown_bounds.h | 25 ++++++++++++ 6 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/corelib/text/qanystringview.h b/src/corelib/text/qanystringview.h index a0b6845524f..34cf3e66a86 100644 --- a/src/corelib/text/qanystringview.h +++ b/src/corelib/text/qanystringview.h @@ -185,10 +185,13 @@ class QAnyStringView template constexpr QAnyStringView(const Char *str) noexcept; #else - template = true> constexpr QAnyStringView(const Pointer &str) noexcept : QAnyStringView{str, str ? lengthHelperPointer(str) : 0} {} + + template = true> + constexpr QAnyStringView(const Char (&str)[]) noexcept + : QAnyStringView{&*str} {} // decay to pointer #endif // defined in qstring.h diff --git a/src/corelib/text/qutf8stringview.h b/src/corelib/text/qutf8stringview.h index 185cf335425..f205a48acd3 100644 --- a/src/corelib/text/qutf8stringview.h +++ b/src/corelib/text/qutf8stringview.h @@ -174,6 +174,10 @@ class QBasicUtf8StringView template = true> constexpr QBasicUtf8StringView(const Pointer &str) noexcept : QBasicUtf8StringView(str, QtPrivate::lengthHelperPointer(str)) {} + + template = true> + constexpr QBasicUtf8StringView(const Char (&str)[]) noexcept + : QBasicUtf8StringView(&*str) {} // decay to pointer #endif #ifdef Q_QDOC diff --git a/tests/auto/corelib/text/qanystringview/CMakeLists.txt b/tests/auto/corelib/text/qanystringview/CMakeLists.txt index 894115d1c28..9b1e0798312 100644 --- a/tests/auto/corelib/text/qanystringview/CMakeLists.txt +++ b/tests/auto/corelib/text/qanystringview/CMakeLists.txt @@ -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 diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index cd9ce8caec9..d8706b8a873 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -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 #include #include @@ -84,6 +86,10 @@ static_assert(CanConvert); static_assert(CanConvert); static_assert(CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert< QChar[]>); +static_assert(CanConvert); +#endif static_assert(CanConvert< QString >); static_assert(CanConvert); @@ -98,6 +104,10 @@ static_assert(CanConvert); static_assert(CanConvert); static_assert(CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert< ushort[]>); +static_assert(CanConvert); +#endif static_assert(CanConvert< ushort*>); static_assert(CanConvert); @@ -119,6 +129,10 @@ static_assert(CanConvert); static_assert(CanConvert< char8_t[123]>); static_assert(CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert< char8_t[]>); +static_assert(CanConvert); +#endif static_assert(CanConvert< char8_t*>); static_assert(CanConvert); @@ -154,6 +168,10 @@ static_assert(CanConvert); static_assert(CanConvert< char16_t[123]>); static_assert(CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert< char16_t[]>); +static_assert(CanConvert); +#endif static_assert(CanConvert< char16_t*>); static_assert(CanConvert); @@ -187,6 +205,10 @@ static_assert(CanConvert); // ... except here static_assert(!CanConvert< char32_t[123]>); static_assert(!CanConvert); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(!CanConvert< char32_t[]>); +static_assert(!CanConvert); +#endif static_assert(!CanConvert< char32_t*>); static_assert(!CanConvert); @@ -224,6 +246,10 @@ static_assert(CanConvert == CanConvertFromWCharT); // ### FIXME: should static_assert(CanConvert< wchar_t[123]> == CanConvertFromWCharT); static_assert(CanConvert == CanConvertFromWCharT); +#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯ +static_assert(CanConvert< wchar_t[]> == CanConvertFromWCharT); +static_assert(CanConvert == CanConvertFromWCharT); +#endif static_assert(CanConvert< wchar_t*> == CanConvertFromWCharT); static_assert(CanConvert == CanConvertFromWCharT); @@ -344,10 +370,22 @@ private Q_SLOTS: void fromQLatin1StringView() const { fromQStringOrByteArray(); } void fromCharArray() const { fromArray(); } + void fromCharArrayOfUnknownSize() const + { + from_array_of_unknown_size(); + from_array_of_unknown_size(); + } void fromChar8Array() const { ONLY_IF_CHAR_8_T(fromArray()); } + void fromChar8ArrayOfUnknownSize() const + { + ONLY_IF_CHAR_8_T(from_u8array_of_unknown_size()); + ONLY_IF_CHAR_8_T(from_u8array_of_unknown_size()); + } void fromChar16Array() const { fromArray(); } + void fromChar16ArrayOfUnknownSize() const { from_u16array_of_unknown_size(); } void fromQCharArray() const { fromArray(); } void fromWCharTArray() const { ONLY_WIN(fromArray()); } + void fromWCharTArrayOfUnknownSize() const { ONLY_WIN(from_warray_of_unknown_size()); } void fromQCharStar() 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 3f53504a4aa..a8697464fb1 100644 --- a/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.cpp +++ b/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.cpp @@ -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; 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 1198b1048fb..863b58a1faf 100644 --- a/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.h +++ b/tests/auto/corelib/text/qstringview/arrays_of_unknown_bounds.h @@ -5,11 +5,36 @@ #include +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 +void from_array_of_unknown_size() +{ + StringView bv = string_array; + QCOMPARE(bv.size(), string_array_size); +} + +#ifdef __cpp_char8_t +template +void from_u8array_of_unknown_size() +{ + StringView sv = u8string_array; + QCOMPARE(sv.size(), u8string_array_size); +} +#endif + template void from_u16array_of_unknown_size() {