Skip to content

Commit

Permalink
Q{Any,Utf8}StringView: fix construction from arrays of unknown size
Browse files Browse the repository at this point in the history
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.5
Fixes: QTBUG-112746
Change-Id: I7acdcae3c5bdf80a0bed673e621d53ef34a92a1e
Reviewed-by: Thiago Macieira <[email protected]>
(cherry picked from commit 734bd05)
(cherry picked from commit 51bfc9d)
Reviewed-by: Ivan Solovev <[email protected]>
  • Loading branch information
marcmutz committed Dec 16, 2024
1 parent 85f335d commit fb91b0d
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/corelib/text/qanystringview.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,13 @@ class QAnyStringView
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
Expand Down
4 changes: 4 additions & 0 deletions src/corelib/text/qutf8stringview.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ class QBasicUtf8StringView
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
Expand Down
2 changes: 2 additions & 0 deletions tests/auto/corelib/text/qanystringview/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 38 additions & 0 deletions tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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 >);
Expand All @@ -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*>);
Expand All @@ -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*>);
Expand Down Expand Up @@ -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*>);
Expand Down Expand Up @@ -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*>);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
25 changes: 25 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 @@ -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()
{
Expand Down

0 comments on commit fb91b0d

Please sign in to comment.