summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qvariant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qvariant.cpp')
-rw-r--r--src/corelib/kernel/qvariant.cpp364
1 files changed, 354 insertions, 10 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 6192b66487..4d1aa911f7 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
@@ -60,6 +60,9 @@
#include "qabstractitemmodel.h"
#endif
#ifndef QT_BOOTSTRAPPED
+#include "qcborarray.h"
+#include "qcborcommon.h"
+#include "qcbormap.h"
#include "qjsonvalue.h"
#include "qjsonobject.h"
#include "qjsonarray.h"
@@ -167,6 +170,8 @@ static qlonglong qMetaTypeNumber(const QVariant::Private *d)
#ifndef QT_BOOTSTRAPPED
case QMetaType::QJsonValue:
return v_cast<QJsonValue>(d)->toDouble();
+ case QMetaType::QCborValue:
+ return v_cast<QCborValue>(d)->toInteger();
#endif
}
Q_ASSERT(false);
@@ -205,6 +210,10 @@ static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
case QVariant::Bool:
return qlonglong(d->data.b);
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isInteger() && !v_cast<QCborValue>(d)->isDouble())
+ break;
+ return qMetaTypeNumber(d);
case QMetaType::QJsonValue:
if (!v_cast<QJsonValue>(d)->isDouble())
break;
@@ -229,7 +238,7 @@ static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
}
QMetaType typeInfo(d->type);
- if (typeInfo.flags() & QMetaType::IsEnumeration) {
+ if (typeInfo.flags() & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
switch (typeInfo.sizeOf()) {
case 1:
return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->ptr) : d->data.sc;
@@ -261,6 +270,8 @@ static qreal qConvertToRealNumber(const QVariant::Private *d, bool *ok)
case QMetaType::ULong:
return qreal(qMetaTypeUNumber(d));
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ return v_cast<QCborValue>(d)->toDouble();
case QMetaType::QJsonValue:
return v_cast<QJsonValue>(d)->toDouble();
#endif
@@ -284,6 +295,12 @@ static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
case QVariant::Bool:
return qulonglong(d->data.b);
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isDouble())
+ return qulonglong(qConvertToRealNumber(d, ok));
+ if (!v_cast<QCborValue>(d)->isInteger())
+ return false;
+ return qulonglong(qMetaTypeNumber(d));
case QMetaType::QJsonValue:
if (!v_cast<QJsonValue>(d)->isDouble())
break;
@@ -391,6 +408,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QVariant::String:
*static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
break;
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isUrl()) {
+ *static_cast<QUrl *>(result) = v_cast<QCborValue>(d)->toUrl();
+ break;
+ }
+ return false;
default:
return false;
}
@@ -476,6 +499,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
else if (!v_cast<QJsonValue>(d)->isNull())
return false;
break;
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isContainer() || v_cast<QCborValue>(d)->isTag())
+ return false;
+ *str = v_cast<QCborValue>(d)->toVariant().toString();
+ break;
#endif
case QVariant::Uuid:
*str = v_cast<QUuid>(d)->toString();
@@ -621,6 +649,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QVariant::String:
*dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
break;
+# ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isDateTime())
+ *dt = v_cast<QCborValue>(d)->toDateTime();
+ else
+ return false;
+ break;
+# endif
#endif
case QVariant::Date:
*dt = QDateTime(*v_cast<QDate>(d));
@@ -668,6 +704,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QMetaType::Nullptr:
*ba = QByteArray();
break;
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isByteArray())
+ *ba = v_cast<QCborValue>(d)->toByteArray();
+ else
+ return false;
+ break;
+#endif
default:
#ifndef QT_NO_QOBJECT
{
@@ -746,6 +790,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
break;
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ *b = v_cast<QCborValue>(d)->toBool();
+ if (!v_cast<QCborValue>(d)->isBool())
+ return false;
+ break;
case QMetaType::QJsonValue:
*b = v_cast<QJsonValue>(d)->toBool(false);
if (!v_cast<QJsonValue>(d)->isBool())
@@ -789,6 +838,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*f = double(qMetaTypeUNumber(d));
break;
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ *f = v_cast<QCborValue>(d)->toDouble();
+ if (!v_cast<QCborValue>(d)->isDouble())
+ return false;
+ break;
case QMetaType::QJsonValue:
*f = v_cast<QJsonValue>(d)->toDouble(0.0);
if (!v_cast<QJsonValue>(d)->isDouble())
@@ -832,6 +886,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*f = float(qMetaTypeUNumber(d));
break;
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ *f = v_cast<QCborValue>(d)->toDouble();
+ if (!v_cast<QCborValue>(d)->isDouble())
+ return false;
+ break;
case QMetaType::QJsonValue:
*f = v_cast<QJsonValue>(d)->toDouble(0.0);
if (!v_cast<QJsonValue>(d)->isDouble())
@@ -856,6 +915,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*static_cast<QVariantList *>(result) =
*static_cast<QList<QVariant> *>(d->data.shared->ptr);
#ifndef QT_BOOTSTRAPPED
+ } else if (d->type == QMetaType::QCborValue) {
+ if (!v_cast<QCborValue>(d)->isArray())
+ return false;
+ *static_cast<QVariantList *>(result) = v_cast<QCborValue>(d)->toArray().toVariantList();
+ } else if (d->type == QMetaType::QCborArray) {
+ *static_cast<QVariantList *>(result) = v_cast<QCborArray>(d)->toVariantList();
} else if (d->type == QMetaType::QJsonValue) {
if (!v_cast<QJsonValue>(d)->isArray())
return false;
@@ -878,6 +943,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
for (auto it = hash->begin(); it != end; ++it)
map->insertMulti(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
+ } else if (d->type == QMetaType::QCborValue) {
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QVariantMap *>(result) = v_cast<QCborValue>(d)->toMap().toVariantMap();
+ } else if (d->type == QMetaType::QCborMap) {
+ *static_cast<QVariantMap *>(result) = v_cast<QCborMap>(d)->toVariantMap();
} else if (d->type == QMetaType::QJsonValue) {
if (!v_cast<QJsonValue>(d)->isObject())
return false;
@@ -900,6 +971,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
for (auto it = map->begin(); it != end; ++it)
hash->insertMulti(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
+ } else if (d->type == QMetaType::QCborValue) {
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QVariantHash *>(result) = v_cast<QCborValue>(d)->toMap().toVariantHash();
+ } else if (d->type == QMetaType::QCborMap) {
+ *static_cast<QVariantHash *>(result) = v_cast<QCborMap>(d)->toVariantHash();
} else if (d->type == QMetaType::QJsonValue) {
if (!v_cast<QJsonValue>(d)->isObject())
return false;
@@ -950,11 +1027,36 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QVariant::ByteArray:
*static_cast<QUuid *>(result) = QUuid(*v_cast<QByteArray>(d));
break;
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isUuid())
+ return false;
+ *static_cast<QUuid *>(result) = v_cast<QCborValue>(d)->toUuid();
+ break;
+#endif
default:
return false;
}
break;
+ case QMetaType::Nullptr:
+ *static_cast<std::nullptr_t *>(result) = nullptr;
+ if (QMetaType::typeFlags(t) & (QMetaType::PointerToGadget | QMetaType::PointerToQObject)
+ || d->type == QMetaType::VoidStar) {
+ if (v_cast<const void *>(d) == nullptr)
+ break;
+ }
#ifndef QT_BOOTSTRAPPED
+ if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isNull())
+ break;
+#endif
+ return false;
+
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QRegularExpression:
+ if (d->type != QMetaType::QCborValue || !v_cast<QCborValue>(d)->isRegularExpression())
+ return false;
+ *static_cast<QRegularExpression *>(result) = v_cast<QCborValue>(d)->toRegularExpression();
+ break;
case QMetaType::QJsonValue:
switch (d->type) {
case QMetaType::Nullptr:
@@ -1005,6 +1107,15 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*static_cast<QJsonValue *>(result) = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
break;
}
+ case QMetaType::QCborValue:
+ *static_cast<QJsonValue *>(result) = v_cast<QCborValue>(d)->toJsonValue();
+ break;
+ case QMetaType::QCborMap:
+ *static_cast<QJsonValue *>(result) = v_cast<QCborMap>(d)->toJsonObject();
+ break;
+ case QMetaType::QCborArray:
+ *static_cast<QJsonValue *>(result) = v_cast<QCborArray>(d)->toJsonArray();
+ break;
default:
*static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Undefined);
return false;
@@ -1028,6 +1139,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
return false;
*static_cast<QJsonArray *>(result) = v_cast<QJsonDocument>(d)->array();
break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isArray())
+ return false;
+ *static_cast<QJsonArray *>(result) = v_cast<QCborValue>(d)->toArray().toJsonArray();
+ break;
+ case QMetaType::QCborArray:
+ *static_cast<QJsonArray *>(result) = v_cast<QCborArray>(d)->toJsonArray();
+ break;
default:
return false;
}
@@ -1050,11 +1169,177 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
return false;
*static_cast<QJsonObject *>(result) = v_cast<QJsonDocument>(d)->object();
break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QJsonObject *>(result) = v_cast<QCborValue>(d)->toMap().toJsonObject();
+ break;
+ case QMetaType::QCborMap:
+ *static_cast<QJsonObject *>(result) = v_cast<QCborMap>(d)->toJsonObject();
+ break;
+ default:
+ return false;
+ }
+ break;
+ case QMetaType::QCborSimpleType:
+ if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isSimpleType()) {
+ *static_cast<QCborSimpleType *>(result) = v_cast<QCborValue>(d)->toSimpleType();
+ break;
+ }
+ return false;
+ case QMetaType::QCborValue:
+ switch (d->type) {
+ case QMetaType::Nullptr:
+ *static_cast<QCborValue *>(result) = QCborValue(QCborValue::Null);
+ break;
+ case QVariant::Bool:
+ *static_cast<QCborValue *>(result) = QCborValue(d->data.b);
+ break;
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ case QMetaType::ULong:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong:
+ case QMetaType::UShort:
+ case QMetaType::UChar:
+ case QMetaType::Char:
+ case QMetaType::SChar:
+ case QMetaType::Short:
+ *static_cast<QCborValue *>(result) = QCborValue(qConvertToNumber(d, ok));
+ Q_ASSERT(ok);
+ break;
+ case QMetaType::Double:
+ case QMetaType::Float:
+ *static_cast<QCborValue *>(result) = QCborValue(qConvertToRealNumber(d, ok));
+ Q_ASSERT(ok);
+ break;
+ case QVariant::String:
+ *static_cast<QCborValue *>(result) = *v_cast<QString>(d);
+ break;
+ case QVariant::StringList:
+ *static_cast<QCborValue *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
+ break;
+ case QVariant::ByteArray:
+ *static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
+ break;
+ case QVariant::Date:
+ *static_cast<QCborValue *>(result) = QCborValue(QDateTime(*v_cast<QDate>(d)));
+ break;
+ case QVariant::DateTime:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));
+ break;
+ case QVariant::Url:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUrl>(d));
+ break;
+ case QVariant::RegularExpression:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QRegularExpression>(d));
+ break;
+ case QVariant::Uuid:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUuid>(d));
+ break;
+ case QVariant::List:
+ *static_cast<QCborValue *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
+ break;
+ case QVariant::Map:
+ *static_cast<QCborValue *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
+ break;
+ case QVariant::Hash:
+ *static_cast<QCborValue *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
+ break;
+ case QMetaType::QJsonValue:
+ *static_cast<QCborValue *>(result) = QCborValue::fromJsonValue(*v_cast<QJsonValue>(d));
+ break;
+ case QMetaType::QJsonObject:
+ *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
+ break;
+ case QMetaType::QJsonArray:
+ *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
+ break;
+ case QMetaType::QJsonDocument: {
+ QJsonDocument doc = *v_cast<QJsonDocument>(d);
+ if (doc.isArray())
+ *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(doc.array());
+ else
+ *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(doc.object());
+ break;
+ }
+ case QMetaType::QCborSimpleType:
+ *static_cast<QCborValue *>(result) = *v_cast<QCborSimpleType>(d);
+ break;
+ case QMetaType::QCborMap:
+ *static_cast<QCborValue *>(result) = *v_cast<QCborMap>(d);
+ break;
+ case QMetaType::QCborArray:
+ *static_cast<QCborValue *>(result) = *v_cast<QCborArray>(d);
+ break;
+ default:
+ *static_cast<QCborValue *>(result) = {};
+ return false;
+ }
+ break;
+ case QMetaType::QCborArray:
+ switch (d->type) {
+ case QVariant::StringList:
+ *static_cast<QCborArray *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
+ break;
+ case QVariant::List:
+ *static_cast<QCborArray *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
+ break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isArray())
+ return false;
+ *static_cast<QCborArray *>(result) = v_cast<QCborValue>(d)->toArray();
+ break;
+ case QMetaType::QJsonDocument:
+ if (!v_cast<QJsonDocument>(d)->isArray())
+ return false;
+ *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonDocument>(d)->array());
+ break;
+ case QMetaType::QJsonValue:
+ if (!v_cast<QJsonValue>(d)->isArray())
+ return false;
+ *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonValue>(d)->toArray());
+ break;
+ case QMetaType::QJsonArray:
+ *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
+ break;
+ default:
+ return false;
+ }
+ break;
+ case QMetaType::QCborMap:
+ switch (d->type) {
+ case QVariant::Map:
+ *static_cast<QCborMap *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
+ break;
+ case QVariant::Hash:
+ *static_cast<QCborMap *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
+ break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QCborMap *>(result) = v_cast<QCborValue>(d)->toMap();
+ break;
+ case QMetaType::QJsonDocument:
+ if (v_cast<QJsonDocument>(d)->isArray())
+ return false;
+ *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonDocument>(d)->object());
+ break;
+ case QMetaType::QJsonValue:
+ if (!v_cast<QJsonValue>(d)->isObject())
+ return false;
+ *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonValue>(d)->toObject());
+ break;
+ case QMetaType::QJsonObject:
+ *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
+ break;
default:
return false;
}
break;
#endif
+
default:
#ifndef QT_NO_QOBJECT
if (d->type == QVariant::String || d->type == QVariant::ByteArray) {
@@ -1081,7 +1366,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
}
}
#endif
- if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration) {
+ if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
qlonglong value = qConvertToNumber(d, ok);
if (*ok) {
switch (QMetaType::sizeOf(t)) {
@@ -1175,9 +1460,16 @@ static void customConstruct(QVariant::Private *d, const void *copy)
type.construct(&d->data.ptr, copy);
d->is_shared = false;
} else {
- void *ptr = type.create(copy);
+ // Private::Data contains long long, and long double is the biggest standard type.
+ const size_t maxAlignment =
+ qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double));
+ const size_t s = sizeof(QVariant::PrivateShared);
+ const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
+ void *data = operator new(offset + size);
+ void *ptr = static_cast<char *>(data) + offset;
+ type.construct(ptr, copy);
d->is_shared = true;
- d->data.shared = new QVariant::PrivateShared(ptr);
+ d->data.shared = new (data) QVariant::PrivateShared(ptr);
}
}
@@ -1186,8 +1478,9 @@ static void customClear(QVariant::Private *d)
if (!d->is_shared) {
QMetaType::destruct(d->type, &d->data.ptr);
} else {
- QMetaType::destroy(d->type, d->data.shared->ptr);
- delete d->data.shared;
+ QMetaType::destruct(d->type, d->data.shared->ptr);
+ d->data.shared->~PrivateShared();
+ operator delete(d->data.shared);
}
}
@@ -3272,15 +3565,66 @@ bool QVariant::canConvert(int targetTypeId) const
case QMetaType::QVariantList:
case QMetaType::QVariantMap:
case QMetaType::QVariantHash:
+ case QMetaType::QCborValue:
+ case QMetaType::QCborArray:
+ case QMetaType::QCborMap:
return true;
default:
return false;
}
}
if (currentType == QMetaType::QJsonArray)
- return targetTypeId == QMetaType::QVariantList;
+ return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
+ || targetTypeId == QMetaType::QCborArray;
if (currentType == QMetaType::QJsonObject)
- return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash;
+ return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
+ || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QCborMap;
+
+ if (currentType == QMetaType::QCborValue || targetTypeId == QMetaType::QCborValue) {
+ switch (currentType == QMetaType::QCborValue ? targetTypeId : currentType) {
+ case QMetaType::UnknownType:
+ case QMetaType::Nullptr:
+ case QMetaType::Bool:
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ case QMetaType::Double:
+ case QMetaType::Float:
+ case QMetaType::ULong:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong:
+ case QMetaType::UShort:
+ case QMetaType::UChar:
+ case QMetaType::Char:
+ case QMetaType::SChar:
+ case QMetaType::Short:
+ case QMetaType::QString:
+ case QMetaType::QByteArray:
+ case QMetaType::QDateTime:
+ case QMetaType::QUrl:
+ case QMetaType::QRegularExpression:
+ case QMetaType::QUuid:
+ case QMetaType::QVariantList:
+ case QMetaType::QVariantMap:
+ case QMetaType::QVariantHash:
+ case QMetaType::QJsonValue:
+ case QMetaType::QJsonArray:
+ case QMetaType::QJsonObject:
+ case QMetaType::QJsonDocument:
+ case QMetaType::QCborArray:
+ case QMetaType::QCborMap:
+ case QMetaType::QCborSimpleType:
+ return true;
+ default:
+ return false;
+ }
+ }
+ if (currentType == QMetaType::QCborArray)
+ return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
+ || targetTypeId == QMetaType::QJsonArray;
+ if (currentType == QMetaType::QCborMap)
+ return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
+ || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QJsonObject;
// FIXME It should be LastCoreType intead of Uuid
if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) {
@@ -3380,7 +3724,7 @@ bool QVariant::convert(int targetTypeId)
create(targetTypeId, 0);
// Fail if the value is not initialized or was forced null by a previous failed convert.
- if (oldValue.d.is_null)
+ if (oldValue.d.is_null && oldValue.d.type != QMetaType::Nullptr)
return false;
if ((QMetaType::typeFlags(oldValue.userType()) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {