QByteArray: add conversion to std::string_view

96d67da420697cee10bdc537a1a592f6f22e2b8f didn't originally add this
conversion because on certain compilers (QNX) it's ambiguous. The
problem seems to be that QByteArray by default is convertible to const
char *; by adding a conversion to std::string_view, then the explicit
conversion

  std::string_view v(ba);

somehow becomes ambiguous.

Still, we've decided that we want the implicit conversion on non-broken
compilers, so this commits add it there.

[ChangeLog][QtCore][QByteArray] Added an implicit conversion operator
towards std::string_view.

[ChangeLog][QtCore][Important Behavior Changes] Converting a QByteArray
to a std::string_view will now create a view span over the entirety of
the byte array. Before, the view would have stopped at the first NUL in
the byte array (if there was one), unless the QT_NO_CAST_FROM_BYTEARRAY
macro was defined.

Change-Id: I70bbddac97636fbedb4d449eaa65cad4ecbdf0bf
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Giuseppe D'Angelo 2024-06-14 16:06:23 +02:00
parent 1a8c8ffb0c
commit 34f993b7f5
3 changed files with 55 additions and 0 deletions

View File

@ -4837,6 +4837,15 @@ std::string QByteArray::toStdString() const
return std::string(data(), size_t(size()));
}
/*!
\fn QByteArray::operator std::string_view() const noexcept
\since 6.10
Converts this QByteArray object to a \c{std::string_view} object.
The returned string view will span over the entirety of the byte
array.
*/
/*!
\since 4.4

View File

@ -118,6 +118,18 @@ public:
inline operator const char *() const;
inline operator const void *() const;
#endif
// Some compilers consider this conversion ambiguous, so
// we're not offering it there:
// * QCC 8.3 on QNX
// * GHS 2022.1.4 on INTEGRITY
#if (!defined(Q_OS_QNX) || !defined(Q_CC_GNU_ONLY) || Q_CC_GNU_ONLY > 803) && \
(!defined(Q_CC_GHS) || !defined(__GHS_VERSION_NUMBER) || __GHS_VERSION_NUMBER > 202214)
# define QT_BYTEARRAY_CONVERTS_TO_STD_STRING_VIEW
Q_IMPLICIT operator std::string_view() const noexcept
{ return std::string_view(data(), std::size_t(size())); }
#endif
inline char *data();
inline const char *data() const noexcept;
const char *constData() const noexcept { return data(); }

View File

@ -148,6 +148,7 @@ private slots:
void length();
void length_data();
void slice() const;
void std_stringview_conversion();
};
static const QByteArray::DataPointer staticStandard = {
@ -3202,5 +3203,38 @@ void tst_QByteArray::slice() const
QVERIFY(a.isEmpty());
}
void tst_QByteArray::std_stringview_conversion()
{
#ifdef QT_BYTEARRAY_CONVERTS_TO_STD_STRING_VIEW
static_assert(std::is_convertible_v<QByteArray, std::string_view>);
QByteArray ba;
std::string_view sv = ba;
QCOMPARE(sv, std::string_view());
sv = std::string_view(ba);
QCOMPARE(sv, std::string_view());
ba = ""_ba;
sv = ba;
QCOMPARE(ba.size(), 0);
QCOMPARE(sv.size(), size_t(0));
QCOMPARE(sv, std::string_view());
ba = "Hello"_ba;
sv = ba;
QCOMPARE(ba.size(), 5);
QCOMPARE(sv.size(), size_t(5));
QCOMPARE(sv, std::string_view("Hello"));
ba = "Hello\0world"_ba;
sv = ba;
QCOMPARE(ba.size(), 11);
QCOMPARE(sv.size(), size_t(11));
QCOMPARE(sv, std::string_view("Hello\0world", 11));
#else
QSKIP("This compiler does not support QByteArray -> std::string_view implicit conversions");
#endif
}
QTEST_MAIN(tst_QByteArray)
#include "tst_qbytearray.moc"