QStringView: fix construction from arrays of unknown size
The original idea (8b5aa7b6c40d70a7ec15b3ea485f28a142fb247c) of the separation of array and pointer ctors was to determine string literal sizes at compile-time in C++11's limited constexpr semantics. But when the scanning for NUL characters was added to the array ctor in 107ff4c1d6b5da2cb11c65b2bd9106817f7fdb02, the distinction between the two ctors became meaningless, because we were able to assume post-C++11 constexpr to make the Char(0) scan a compile-time action. Finally, 9e1dc1e8a9fda1a7576cc6377c8a36decff631eb removed the array ctor in favor of the generic Container ctor. I didn't check whether the old code handled arrays of unknown size, as in extern const char16_t str[]; QStringView sv = str; ~~~ const char16_t str[] = "str"; but std::size() (and therefore if_compatible_container) surely bails on such arrays, and if_compatible_pointer also SFINAEs out. As a consequence, such arrays cannot be used to construct QStringViews atm. Fix by adding a new constructor for arrays of unknown size, delegating to the existing pointer 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][QStringView] 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.9 6.8 6.5 Task-number: QTBUG-112746 Change-Id: Ifdb217350d93d38f081c99f14661975491d32076 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
7ecb12b2c7
commit
56faffd92b
@ -150,10 +150,13 @@ public:
|
||||
template <typename Char>
|
||||
constexpr QStringView(const Char *str) noexcept;
|
||||
#else
|
||||
|
||||
template <typename Pointer, if_compatible_pointer<Pointer> = true>
|
||||
constexpr QStringView(const Pointer &str) noexcept
|
||||
: QStringView(str, str ? lengthHelperPointer(str) : 0) {}
|
||||
|
||||
template <typename Char, if_compatible_char<Char> = true>
|
||||
constexpr QStringView(const Char (&str)[]) noexcept // array of unknown bounds
|
||||
: QStringView{&*str} {} // decay to pointer
|
||||
#endif
|
||||
|
||||
#ifdef Q_QDOC
|
||||
|
@ -14,6 +14,7 @@ endif()
|
||||
qt_internal_add_test(tst_qstringview
|
||||
SOURCES
|
||||
tst_qstringview.cpp
|
||||
arrays_of_unknown_bounds.cpp arrays_of_unknown_bounds.h
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
)
|
||||
|
@ -0,0 +1,9 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include "arrays_of_unknown_bounds.h"
|
||||
|
||||
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;
|
@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtTest/qtest.h>
|
||||
|
||||
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_u16array_of_unknown_size()
|
||||
{
|
||||
StringView sv = u16string_array;
|
||||
QCOMPARE(sv.size(), u16string_array_size);
|
||||
}
|
||||
|
||||
template <typename StringView>
|
||||
void from_warray_of_unknown_size()
|
||||
{
|
||||
StringView sv = wstring_array;
|
||||
QCOMPARE(sv.size(), wstring_array_size);
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include "arrays_of_unknown_bounds.h"
|
||||
|
||||
#include <QStringView>
|
||||
#include <QStringTokenizer>
|
||||
#include <QString>
|
||||
@ -45,6 +47,9 @@ static_assert(!CanConvert<QByteArray>::value);
|
||||
static_assert(!CanConvert<QChar>::value);
|
||||
|
||||
static_assert(CanConvert<QChar[123]>::value);
|
||||
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
|
||||
static_assert(CanConvert<QChar[]>::value);
|
||||
#endif
|
||||
|
||||
static_assert(CanConvert< QString >::value);
|
||||
static_assert(CanConvert<const QString >::value);
|
||||
@ -58,6 +63,9 @@ static_assert(CanConvert<const QString&>::value);
|
||||
static_assert(!CanConvert<ushort>::value);
|
||||
|
||||
static_assert(CanConvert<ushort[123]>::value);
|
||||
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
|
||||
static_assert(CanConvert<ushort[]>::value);
|
||||
#endif
|
||||
|
||||
static_assert(CanConvert< ushort*>::value);
|
||||
static_assert(CanConvert<const ushort*>::value);
|
||||
@ -76,6 +84,9 @@ static_assert(!CanConvert<std::list<ushort>>::value);
|
||||
static_assert(!CanConvert<char16_t>::value);
|
||||
|
||||
static_assert(CanConvert<char16_t[123]>::value);
|
||||
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
|
||||
static_assert(CanConvert<char16_t[]>::value);
|
||||
#endif
|
||||
|
||||
static_assert(CanConvert< char16_t*>::value);
|
||||
static_assert(CanConvert<const char16_t*>::value);
|
||||
@ -114,6 +125,9 @@ constexpr bool CanConvertFromWCharT =
|
||||
static_assert(!CanConvert<wchar_t>::value);
|
||||
|
||||
static_assert(CanConvert<wchar_t[123]>::value == CanConvertFromWCharT);
|
||||
#ifndef Q_OS_INTEGRITY // ¯\_(ツ)_/¯
|
||||
static_assert(CanConvert<wchar_t[]>::value == CanConvertFromWCharT);
|
||||
#endif
|
||||
|
||||
static_assert(CanConvert< wchar_t*>::value == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<const wchar_t*>::value == CanConvertFromWCharT);
|
||||
@ -189,6 +203,16 @@ private Q_SLOTS:
|
||||
#endif
|
||||
}
|
||||
|
||||
void fromChar16TArrayWithUnknownSize() { from_u16array_of_unknown_size<QStringView>(); }
|
||||
void fromWCharTArrayWithUnknownSize()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
from_warray_of_unknown_size<QStringView>();
|
||||
#else
|
||||
QSKIP("This is a Windows-only test");
|
||||
#endif
|
||||
}
|
||||
|
||||
void fromQCharRange() const
|
||||
{
|
||||
const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
|
||||
|
Loading…
x
Reference in New Issue
Block a user