QVariant: do allow non-default-constructible types

So long as you only ask us to copy it. Copying is mandatory, though.

I'll firm up the warning in a later commit, which may not get cherry-
picked as far back.

Pick-to: 6.2 6.3 6.4
Fixes: QTBUG-105140
Change-Id: I3859764fed084846bcb0fffd170432abf65dc197
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Thiago Macieira 2022-07-22 09:11:16 -07:00
parent 392566cf61
commit df0085d3a2
2 changed files with 30 additions and 3 deletions

View File

@ -220,7 +220,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
*d = QVariant::Private();
return;
}
if (!(iface->copyCtr && iface->defaultCtr)) {
if (!iface->copyCtr || (!copy && !iface->defaultCtr)) {
// QVariant requires type to be copy and default constructible
*d = QVariant::Private();
qWarning("QVariant: Provided metatype does not support "

View File

@ -289,6 +289,7 @@ private slots:
void constructFromIncompatibleMetaType_data();
void constructFromIncompatibleMetaType();
void copyNonDefaultConstructible();
private:
void dataStream_data(QDataStream::Version version);
@ -5110,11 +5111,19 @@ void tst_QVariant::equalsWithoutMetaObject()
QVERIFY(qobjectVariant != noMetaObjectVariant);
}
class NonDefaultConstructible
struct NonDefaultConstructible
{
NonDefaultConstructible(int ) {}
NonDefaultConstructible(int i) :i(i) {}
int i;
friend bool operator==(NonDefaultConstructible l, NonDefaultConstructible r)
{ return l.i == r.i; }
};
template <> char *QTest::toString<NonDefaultConstructible>(const NonDefaultConstructible &ndc)
{
return qstrdup('{' + QByteArray::number(ndc.i) + '}');
}
struct Indestructible
{
Indestructible() {}
@ -5154,5 +5163,23 @@ void tst_QVariant::constructFromIncompatibleMetaType()
QVERIFY(!QVariant(regular).convert(type));
}
void tst_QVariant::copyNonDefaultConstructible()
{
NonDefaultConstructible ndc(42);
QVariant var(QMetaType::fromType<NonDefaultConstructible>(), &ndc);
QVERIFY(var.isDetached());
QCOMPARE(var.metaType(), QMetaType::fromType<NonDefaultConstructible>());
QVERIFY(var.constData() != &ndc);
// qvariant_cast<T> and QVariant::value<T> don't compile
QCOMPARE(*static_cast<const NonDefaultConstructible *>(var.constData()), ndc);
QVariant var2 = var;
var2.detach(); // force another copy
QVERIFY(var2.isDetached());
QVERIFY(var2.constData() != var.constData());
QCOMPARE(var2, var);
}
QTEST_MAIN(tst_QVariant)
#include "tst_qvariant.moc"