summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qvariant.cpp3
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp93
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*)