diff options
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 3 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 93 |
2 files changed, 94 insertions, 2 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 29734f902e..5f17b234f2 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2462,9 +2462,8 @@ inline T qNumVariantToHelper(const QVariant::Private &d, T ret = 0; if ((d.type >= QMetaType::User || t >= QMetaType::User) - && QMetaType::convert(&val, d.type, &ret, t)) { + && QMetaType::convert(constData(d), d.type, &ret, t)) return ret; - } if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok) *ok = false; diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index f78f993645..c7d862c20e 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -224,6 +224,7 @@ private slots: void moreCustomTypes(); void movabilityTest(); void variantInVariant(); + void userConversion(); void forwardDeclare(); void debugStream_data(); @@ -3312,6 +3313,98 @@ void tst_QVariant::variantInVariant() QCOMPARE(qvariant_cast<QVariant>(var9), var1); } +struct Convertible { + double d; + operator int() const { return (int)d; } + operator double() const { return d; } + operator QString() const { return QString::number(d); } +}; + +Q_DECLARE_METATYPE(Convertible); + +struct BigConvertible { + double d; + double dummy; + double dummy2; + operator int() const { return (int)d; } + operator double() const { return d; } + operator QString() const { return QString::number(d); } +}; + +Q_DECLARE_METATYPE(BigConvertible); +Q_STATIC_ASSERT(sizeof(BigConvertible) > sizeof(QVariant)); + +void tst_QVariant::userConversion() +{ + { + QVERIFY(!(QMetaType::hasRegisteredConverterFunction<int, Convertible>())); + QVERIFY(!(QMetaType::hasRegisteredConverterFunction<double, Convertible>())); + QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, Convertible>())); + + Convertible c = { 123 }; + QVariant v = qVariantFromValue(c); + + bool ok; + v.toInt(&ok); + QVERIFY(!ok); + + v.toDouble(&ok); + QVERIFY(!ok); + + QString s = v.toString(); + QVERIFY(s.isEmpty()); + + QMetaType::registerConverter<Convertible, int>(); + QMetaType::registerConverter<Convertible, double>(); + QMetaType::registerConverter<Convertible, QString>(); + + int i = v.toInt(&ok); + QVERIFY(ok); + QCOMPARE(i, 123); + + double d = v.toDouble(&ok); + QVERIFY(ok); + QCOMPARE(d, 123.); + + s = v.toString(); + QCOMPARE(s, QString::fromLatin1("123")); + } + + { + QVERIFY(!(QMetaType::hasRegisteredConverterFunction<int, BigConvertible>())); + QVERIFY(!(QMetaType::hasRegisteredConverterFunction<double, BigConvertible>())); + QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, BigConvertible>())); + + BigConvertible c = { 123, 0, 0 }; + QVariant v = qVariantFromValue(c); + + bool ok; + v.toInt(&ok); + QVERIFY(!ok); + + v.toDouble(&ok); + QVERIFY(!ok); + + QString s = v.toString(); + QVERIFY(s.isEmpty()); + + QMetaType::registerConverter<BigConvertible, int>(); + QMetaType::registerConverter<BigConvertible, double>(); + QMetaType::registerConverter<BigConvertible, QString>(); + + int i = v.toInt(&ok); + QVERIFY(ok); + QCOMPARE(i, 123); + + double d = v.toDouble(&ok); + QVERIFY(ok); + QCOMPARE(d, 123.); + + s = v.toString(); + QCOMPARE(s, QString::fromLatin1("123")); + } +} + class Forward; Q_DECLARE_OPAQUE_POINTER(Forward*) Q_DECLARE_METATYPE(Forward*) |