From b1377ed02dce9a173e345aab22af504de2b77d54 Mon Sep 17 00:00:00 2001 From: Andrei Golubev Date: Thu, 4 Mar 2021 17:19:33 +0100 Subject: [PATCH 1/2] Add literal operators for QString and QByteArray [ChangeLog][QtCore][QString] Added literal operator u"..."_qs that converts a char16_t string literal to QString [ChangeLog][QtCore][QByteArray] Added literal operator "..."_qba that converts char string literal to QByteArray Change-Id: I4aa59b28cc17bff346b378eb70008fb8185d21ac Reviewed-by: Edward Welbourne Reviewed-by: Fabian Kosmale --- src/corelib/text/qbytearray.cpp | 21 ++++++++++++++++ src/corelib/text/qbytearray.h | 7 ++++++ src/corelib/text/qstring.cpp | 21 ++++++++++++++++ src/corelib/text/qstring.h | 7 ++++++ .../text/qbytearray/tst_qbytearray.cpp | 24 +++++++++++++++++++ .../auto/corelib/text/qstring/tst_qstring.cpp | 24 +++++++++++++++++++ 6 files changed, 104 insertions(+) diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index bead997ab84..677fc6d6ace 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -4766,6 +4766,27 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA \sa QStringLiteral */ +/*! + \function QtLiterals::operator""_qba(const char *str, size_t size) + + \relates QByteArray + \since 6.2 + + Literal operator that creates a QByteArray out of a char string literal \a + str. Creating a QByteArray from it is free in this case, and the generated + string data is stored in the read-only segment of the compiled object file. + Duplicate literals may share the same read-only memory. This functionality is + interchangeable with QByteArrayLiteral, but saves typing when many string + literals are present in the code. + + The following code creates a QByteArray: + \code + auto str = "hello"_qba; + \endcode + + \sa QByteArrayLiteral, QtLiterals::operator""_qs(const char16_t *str, size_t size) +*/ + /*! \class QByteArray::FromBase64Result \inmodule QtCore diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h index 0aad272f942..91c34747d84 100644 --- a/src/corelib/text/qbytearray.h +++ b/src/corelib/text/qbytearray.h @@ -756,6 +756,13 @@ QByteArray QByteArrayView::toByteArray() const return QByteArray(data(), size()); } +inline namespace QtLiterals { +inline QByteArray operator"" _qba(const char *str, size_t size) noexcept +{ + return QByteArray(QByteArrayData(nullptr, const_cast(str), qsizetype(size))); +} +} // QtLiterals + QT_END_NAMESPACE #endif // QBYTEARRAY_H diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 49e56d26d63..3455daa3ca0 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -10505,6 +10505,27 @@ QString QString::toHtmlEscaped() const \sa QByteArrayLiteral */ +/*! + \function QtLiterals::operator""_qs(const char16_t *str, size_t size) + + \relates QString + \since 6.2 + + Literal operator that creates a QString out of a char16_t string literal \a + str. Creating a QString from it is free in this case, and the generated string + data is stored in the read-only segment of the compiled object file. Duplicate + literals may share the same read-only memory. This functionality is + interchangeable with QStringLiteral, but saves typing when many string + literals are present in the code. + + The following code creates a QString: + \code + auto str = u"hello"_qs; + \endcode + + \sa QStringLiteral, QtLiterals::operator""_qba(const char *str, size_t size) +*/ + /*! \internal */ diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index abf8957be9b..c6d97c9d513 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -1541,6 +1541,13 @@ qsizetype erase_if(QString &s, Predicate pred) return QtPrivate::sequential_erase_if(s, pred); } +inline namespace QtLiterals { +inline QString operator"" _qs(const char16_t *str, size_t size) noexcept +{ + return QString(QStringPrivate(nullptr, const_cast(str), qsizetype(size))); +} +} // QtLiterals + QT_END_NAMESPACE #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER) diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 70180bbf3b8..1ce92becee4 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -126,6 +126,7 @@ private slots: void movablity_data(); void movablity(); void literals(); + void userDefinedLiterals(); void toUpperLower_data(); void toUpperLower(); void isUpper(); @@ -1991,6 +1992,29 @@ void tst_QByteArray::literals() QVERIFY(str2.capacity() >= str2.length()); } +void tst_QByteArray::userDefinedLiterals() +{ + QByteArray str = "abcd"_qba; + + QVERIFY(str.length() == 4); + QCOMPARE(str.capacity(), 0); + QVERIFY(str == "abcd"); + QVERIFY(!str.data_ptr()->isMutable()); + + const char *s = str.constData(); + QByteArray str2 = str; + QVERIFY(str2.constData() == s); + QCOMPARE(str2.capacity(), 0); + + // detach on non const access + QVERIFY(str.data() != s); + QVERIFY(str.capacity() >= str.length()); + + QVERIFY(str2.constData() == s); + QVERIFY(str2.data() != s); + QVERIFY(str2.capacity() >= str2.length()); +} + void tst_QByteArray::toUpperLower_data() { QTest::addColumn("input"); diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index 79c4fa4ab02..f36da049f95 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -569,6 +569,7 @@ private slots: #if !defined(QT_NO_UNICODE_LITERAL) void literals(); #endif + void userDefinedLiterals(); void eightBitLiterals_data(); void eightBitLiterals(); void reserve(); @@ -6445,6 +6446,29 @@ void tst_QString::literals() } #endif +void tst_QString::userDefinedLiterals() +{ + QString str = u"abcd"_qs; + + QVERIFY(str.length() == 4); + QCOMPARE(str.capacity(), 0); + QVERIFY(str == QLatin1String("abcd")); + QVERIFY(!str.data_ptr()->isMutable()); + + const QChar *s = str.constData(); + QString str2 = str; + QVERIFY(str2.constData() == s); + QCOMPARE(str2.capacity(), 0); + + // detach on non const access + QVERIFY(str.data() != s); + QVERIFY(str.capacity() >= str.length()); + + QVERIFY(str2.constData() == s); + QVERIFY(str2.data() != s); + QVERIFY(str2.capacity() >= str2.length()); +} + void tst_QString::eightBitLiterals_data() { QTest::addColumn("data"); From c34f51d58c1e3333a663b09b974bbd7b145a2d1b Mon Sep 17 00:00:00 2001 From: Andrei Golubev Date: Thu, 4 Mar 2021 17:20:52 +0100 Subject: [PATCH 2/2] Remove meaningless QT_NO_UNICODE_LITERAL check in QString literal tests This check doesn't really do anything useful anymore: QStringLiteral is used in Qt without any extra QT_NO_UNICODE_LITERAL #if-ery Additionally, clean the related (and outdated) comment in {QString, QByteArray}::literals() Change-Id: I65b1eac33c5470508997be24f9ba6cf56d8578ea Reviewed-by: Lars Knoll --- tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp | 1 - tests/auto/corelib/text/qstring/tst_qstring.cpp | 5 ----- 2 files changed, 6 deletions(-) diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 1ce92becee4..382190567b2 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -1968,7 +1968,6 @@ void tst_QByteArray::movablity() QVERIFY(true); } -// Only tested on c++0x compliant compiler or gcc void tst_QByteArray::literals() { QByteArray str(QByteArrayLiteral("abcd")); diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index f36da049f95..57885f596df 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -566,9 +566,7 @@ private slots: #if QT_CONFIG(icu) void toUpperLower_icu(); #endif -#if !defined(QT_NO_UNICODE_LITERAL) void literals(); -#endif void userDefinedLiterals(); void eightBitLiterals_data(); void eightBitLiterals(); @@ -6420,8 +6418,6 @@ void tst_QString::toUpperLower_icu() } #endif // icu -#if !defined(QT_NO_UNICODE_LITERAL) -// Only tested on c++0x compliant compiler or gcc void tst_QString::literals() { QString str(QStringLiteral("abcd")); @@ -6444,7 +6440,6 @@ void tst_QString::literals() QVERIFY(str2.data() != s); QVERIFY(str2.capacity() >= str2.length()); } -#endif void tst_QString::userDefinedLiterals() {