summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@qt.io>2023-06-05 12:17:02 +0000
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2023-06-06 06:12:53 +0200
commit4d261c1b544330c5481b2ac2e42fbab764255ab5 (patch)
tree70c53c6c0a9c0fefe9b02d26e9d78370e32461fe
parent88de6960747aa567c6947913f9e5715cfb972d46 (diff)
Revert "QStringBuilder: remove unneeded specializations"
This reverts commit 3c6c3eccd1f91bd1ae0a518318ef264f8eff63f5. Reason for revert: They do appear to be needed, and removing them changes behavior: QTBUG-114206 Pick-to: 6.6 Fixes: QTBUG-114206 Task-number: QTBUG-114238 Change-Id: Iac75bbc1ef14fe89f4282bd58fe996f9a09b8506 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/text/qstringbuilder.h39
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp26
2 files changed, 65 insertions, 0 deletions
diff --git a/src/corelib/text/qstringbuilder.h b/src/corelib/text/qstringbuilder.h
index f7900f4f58..79b854cdb4 100644
--- a/src/corelib/text/qstringbuilder.h
+++ b/src/corelib/text/qstringbuilder.h
@@ -100,6 +100,45 @@ public:
const B &b;
};
+// This specialization is here for backwards compatibility: appending
+// two null strings must give back a null string, so we're special
+// casing this one out.
+template <>
+class QStringBuilder <QString, QString> : public QStringBuilderBase<QStringBuilder<QString, QString>, QString>
+{
+ public:
+ QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
+ QStringBuilder(const QStringBuilder &other) : a(other.a), b(other.b) {}
+
+ operator QString() const
+ { QString r(a); r += b; return r; }
+
+ const QString &a;
+ const QString &b;
+
+ private:
+ QStringBuilder &operator=(const QStringBuilder &) = delete;
+};
+
+// Ditto, but see QTBUG-114238
+template <>
+class QStringBuilder <QByteArray, QByteArray> : public QStringBuilderBase<QStringBuilder<QByteArray, QByteArray>, QByteArray>
+{
+ public:
+ QStringBuilder(const QByteArray &a_, const QByteArray &b_) : a(a_), b(b_) {}
+ QStringBuilder(const QStringBuilder &other) : a(other.a), b(other.b) {}
+
+ operator QByteArray() const
+ { QByteArray r(a); r += b; return r; }
+
+ const QByteArray &a;
+ const QByteArray &b;
+
+ private:
+ QStringBuilder &operator=(const QStringBuilder &) = delete;
+};
+
+
template <> struct QConcatenable<char> : private QAbstractConcatenable
{
typedef char type;
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp
index ed9460b92b..dc2aa9eb39 100644
--- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp
@@ -77,6 +77,28 @@ void checkItWorksWithFreeSpaceAtBegin(const String &chunk, const Separator &sepa
QCOMPARE(str, expected);
}
+template <typename String>
+void checkNullVsEmpty(const String &empty, const char *failureReason = nullptr)
+{
+ String a;
+ String b;
+ QVERIFY(a.isNull());
+ QVERIFY(b.isNull());
+ String result = a P b;
+ QVERIFY(result.isNull());
+
+ String d = empty;
+ QVERIFY(d.isEmpty());
+ QVERIFY(!d.isNull());
+ result = a P d;
+ QVERIFY(result.isEmpty());
+ if (failureReason)
+ QEXPECT_FAIL("", failureReason, Continue);
+ QVERIFY(!result.isNull());
+
+ result = a P a P a;
+ QVERIFY(!result.isNull());
+}
void runScenario()
{
@@ -357,6 +379,10 @@ void runScenario()
QCOMPARE(ba2, QByteArray(withZero + withZero + withZero));
}
+ // null vs. empty
+ checkNullVsEmpty(QStringLiteral(""));
+ checkNullVsEmpty(QByteArrayLiteral(""), "QTBUG-114238: inconsistent isEmpty/isNull between QString and QByteArray concatenation");
+
checkItWorksWithFreeSpaceAtBegin(QByteArray(UTF8_LITERAL), "1234");
if (QTest::currentTestFailed())
return;