Rework QByteArrayView comparison helpers

Commit fb50ab7006 replaced relational
operators in QByteArrayView with comparison helper macros.

That commit had to implement the helper methods as static members
instead of hidden friends, because otherwise it broke the
construction of QByteArrayView from QLatin1StringView.

The reason for that is the conditional noexcept on the relational
operators. The noexcept(noexcept(comparesEqual)) check inside the
class declaration expands before the class is complete, and as a
result discards the QByteArrayView constructor, which is restricted
by the QtPrivate::IsContainerCompatibleWithQByteArrayView trait.

Back then I could not find a proper solution, so just decided to
declare the helper functions for QByteArrayView as private static
members.

Such approach has two drawbacks:
- all new helper functions for QBAV vs other type T relational
  operators should also be static member functions, because
  the compiler always prefers member functions over friend
  functions, even if the argument types do not match.
- QBAV helper functions cannot be used in generic code. Also,
  qCompareThreeWay() would not work for QBAV.

To fix the issue this patch explicitly adds a
QByteArrayView(QLatin1StringView) constructor which is not
restricted by any trait. To keep the constructor constexpr, we
have to move the actual definition into qlatin1stringview.h
header file.

Integrity compiler also complains about
QByteArrayView(QUtf8StringView) constructors, so the same approach
is used to enable them.

This allows to convert all the private static member helpers in
QByteArrayView to hidden friends.

The extended tests will be added in a follow-up commit, because
they require some more changes.

Amends fb50ab7006 and
a08bafc920.

This patch removes some exported methods and adds new ones, but
it is not BiC, because the aforementioned patches are only merged
into dev branch at this point.

Task-number: QTBUG-108805
Change-Id: Iee6526a71d859c4fcb2e95bf20fe84ddead6dfb0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Ivan Solovev 2024-03-04 18:45:54 +01:00
parent 769f68b19b
commit fff6562f8c
4 changed files with 25 additions and 14 deletions

View File

@ -168,6 +168,9 @@ public:
constexpr QByteArrayView(const char (&data)[Size]) noexcept
: QByteArrayView(data, lengthHelperCharArray(data, Size)) {}
constexpr QByteArrayView(QLatin1StringView v) noexcept; // defined in qlatin1stringview.h
constexpr QByteArrayView(QUtf8StringView v) noexcept; // defined in qutf8stringview.h
#ifdef Q_QDOC
template <typename Byte, size_t Size>
#else
@ -326,13 +329,13 @@ private:
Q_ASSERT(n <= size() - pos);
}
static inline bool
friend bool
comparesEqual(const QByteArrayView &lhs, const QByteArrayView &rhs) noexcept
{
return lhs.size() == rhs.size()
&& (!lhs.size() || memcmp(lhs.data(), rhs.data(), lhs.size()) == 0);
}
static inline Qt::strong_ordering
friend Qt::strong_ordering
compareThreeWay(const QByteArrayView &lhs, const QByteArrayView &rhs) noexcept
{
const int res = QtPrivate::compareMemory(lhs, rhs);
@ -340,20 +343,22 @@ private:
}
Q_DECLARE_STRONGLY_ORDERED(QByteArrayView)
static inline bool comparesEqual(const QByteArrayView &lhs, const char *rhs) noexcept
friend bool comparesEqual(const QByteArrayView &lhs, const char *rhs) noexcept
{ return comparesEqual(lhs, QByteArrayView(rhs)); }
static inline Qt::strong_ordering
friend Qt::strong_ordering
compareThreeWay(const QByteArrayView &lhs, const char *rhs) noexcept
{ return compareThreeWay(lhs, QByteArrayView(rhs)); }
Q_DECLARE_STRONGLY_ORDERED(QByteArrayView, const char *)
// defined in qstring.cpp
static bool
friend Q_CORE_EXPORT bool
comparesEqual(const QByteArrayView &lhs, const QChar &rhs) noexcept;
static Qt::strong_ordering
friend Q_CORE_EXPORT Qt::strong_ordering
compareThreeWay(const QByteArrayView &lhs, const QChar &rhs) noexcept;
static bool comparesEqual(const QByteArrayView &lhs, char16_t rhs) noexcept;
static Qt::strong_ordering compareThreeWay(const QByteArrayView &lhs, char16_t rhs) noexcept;
friend Q_CORE_EXPORT bool
comparesEqual(const QByteArrayView &lhs, char16_t rhs) noexcept;
friend Q_CORE_EXPORT Qt::strong_ordering
compareThreeWay(const QByteArrayView &lhs, char16_t rhs) noexcept;
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
Q_DECLARE_STRONGLY_ORDERED(QByteArrayView, QChar, QT_ASCII_CAST_WARN)
Q_DECLARE_STRONGLY_ORDERED(QByteArrayView, char16_t, QT_ASCII_CAST_WARN)

View File

@ -330,6 +330,10 @@ Q_DECLARE_TYPEINFO(QLatin1StringView, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(QLatin1String, Q_RELOCATABLE_TYPE);
#endif
constexpr QByteArrayView::QByteArrayView(QLatin1StringView v) noexcept
: QByteArrayView(v.data(), v.size())
{}
namespace Qt {
inline namespace Literals {
inline namespace StringLiterals {

View File

@ -6718,25 +6718,23 @@ int QString::compare_helper(const QChar *data1, qsizetype length1, const char *d
\overload compare()
*/
bool QByteArrayView::comparesEqual(const QByteArrayView &lhs, const QChar &rhs) noexcept
bool comparesEqual(const QByteArrayView &lhs, const QChar &rhs) noexcept
{
return QtPrivate::equalStrings(QUtf8StringView(lhs), QStringView(&rhs, 1));
}
Qt::strong_ordering QByteArrayView::compareThreeWay(const QByteArrayView &lhs,
const QChar &rhs) noexcept
Qt::strong_ordering compareThreeWay(const QByteArrayView &lhs, const QChar &rhs) noexcept
{
const int res = QtPrivate::compareStrings(QUtf8StringView(lhs), QStringView(&rhs, 1));
return Qt::compareThreeWay(res, 0);
}
bool QByteArrayView::comparesEqual(const QByteArrayView &lhs, char16_t rhs) noexcept
bool comparesEqual(const QByteArrayView &lhs, char16_t rhs) noexcept
{
return QtPrivate::equalStrings(QUtf8StringView(lhs), QStringView(&rhs, 1));
}
Qt::strong_ordering QByteArrayView::compareThreeWay(const QByteArrayView &lhs,
char16_t rhs) noexcept
Qt::strong_ordering compareThreeWay(const QByteArrayView &lhs, char16_t rhs) noexcept
{
const int res = QtPrivate::compareStrings(QUtf8StringView(lhs), QStringView(&rhs, 1));
return Qt::compareThreeWay(res, 0);

View File

@ -414,6 +414,10 @@ private:
qsizetype m_size;
};
constexpr QByteArrayView::QByteArrayView(QUtf8StringView v) noexcept
: QByteArrayView(v.data(), v.size())
{}
#ifdef Q_QDOC
#undef QBasicUtf8StringView
#else