From 34f993b7f54d8cdf5a5820248970abf38c83157d Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 14 Jun 2024 16:06:23 +0200 Subject: [PATCH] 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 Reviewed-by: Thiago Macieira --- src/corelib/text/qbytearray.cpp | 9 +++++ src/corelib/text/qbytearray.h | 12 +++++++ .../text/qbytearray/tst_qbytearray.cpp | 34 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index 3088396eb82..eee179ffa14 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -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 diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h index 969f1252199..a8b456a73ef 100644 --- a/src/corelib/text/qbytearray.h +++ b/src/corelib/text/qbytearray.h @@ -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(); } diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 3318593166d..bd8a0dc2248 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -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 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"