From 96d67da420697cee10bdc537a1a592f6f22e2b8f Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 21 May 2023 13:38:09 +0200 Subject: String-like containers: add implicit conversions towards std:: string views In C++20 std::basic_string_view has gained a range constructor (like QStringView always had), but that range constructor has been made explicit. This means we can't just pass a QString(View) to a function taking a u16string_view. The consensus seems to be that that types that should implictly convert towards stdlib's string views should do that via implicit conversion operators. This patch adds them for * QByteArrayView => std::string_view * QString(View) => std::u16string_view * QUtf8StringView => std::string_view or std::u8string_view, depending on the storage_type QLatin1StringView doesn't have a matching std:: view so I'm not enabling its conversion. QByteArray poses a challenge, in that it already defines a conversion towards const char *. (One can disable that conversion with a macro.) That conversion makes it impossible to support: QByteArray ba; std::string_view sv1(ba); // 1 std::string_view sv2 = ba; // 2 because: * if only operator const char *() is defined, then (2) doesn't work (situation right now); * if both conversions to const char * and string_view are defined, then (1) is ambiguous on certain compilers (MSVC, QCC). Interestingly enough, not on GCC/Clang, but only in C++17 and later modes. I can't kill the conversion towards const char * (API break, and we use it *everywhere* in Qt), hence, QByteArray does not get the implicit conversion, at least not in this patch. [ChangeLog][QtCore][QByteArrayView] Added an implicit conversion operator towards std::string_view. [ChangeLog][QtCore][QString] Added an implicit conversion operator towards std::u16string_view. [ChangeLog][QtCore][QStringView] Added an implicit conversion operator towards std::u16string_view. [ChangeLog][QtCore][QUtf8StringView] Added an implicit conversion operator towards std::string_view (QUtf8StringView is using char as its storage type in Qt 6). Note that QUtf8StringView is planned to use char8_t in Qt 7, therefore it is expected that the conversion will change towards std::u8string_view in Qt 7. Change-Id: I6d3b64d211a386241ae157765cd1b03f531f909a Reviewed-by: Thiago Macieira --- tests/auto/corelib/text/qstring/tst_qstring.cpp | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tests/auto/corelib/text/qstring/tst_qstring.cpp') diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index eaf35c969e..010216e787 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -696,6 +696,8 @@ private slots: void sliced(); void chopped(); void removeIf(); + + void std_stringview_conversion(); }; Q_DECLARE_OPERATORS_FOR_FLAGS(tst_QString::DataOptions) @@ -8762,6 +8764,31 @@ void tst_QString::removeIf() QCOMPARE(a.removeIf(removeA), u"BcbC"); } +void tst_QString::std_stringview_conversion() +{ + static_assert(std::is_convertible_v); + + QString s; + std::u16string_view sv(s); + QCOMPARE(sv, std::u16string_view()); + + s = u""_s; + sv = s; + QCOMPARE(s.size(), 0); + QCOMPARE(sv.size(), size_t(0)); + QCOMPARE(sv, std::u16string_view()); + + s = u"Hello"_s; + sv = s; + QCOMPARE(sv, std::u16string_view(u"Hello")); + + s = u"Hello\0world"_s; + sv = s; + QCOMPARE(s.size(), 11); + QCOMPARE(sv.size(), size_t(11)); + QCOMPARE(sv, std::u16string_view(u"Hello\0world", 11)); +} + // QString's collation order is only supported during the lifetime as QCoreApplication QTEST_GUILESS_MAIN(tst_QString) -- cgit v1.2.3