/src/qt/qtbase/src/corelib/kernel/qvariant.cpp
C++ | 1762 lines | 1071 code | 130 blank | 561 comment | 108 complexity | b48aeef7ef209246510f83273404c1f6 MD5 | raw file
- /****************************************************************************
- **
- ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
- ** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
- ** Contact: http://www.qt-project.org/legal
- **
- ** This file is part of the QtCore module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
- ** Commercial License Usage
- ** Licensees holding valid commercial Qt licenses may use this file in
- ** accordance with the commercial license agreement provided with the
- ** Software or, alternatively, in accordance with the terms contained in
- ** a written agreement between you and Digia. For licensing terms and
- ** conditions see http://qt.digia.com/licensing. For further information
- ** use the contact form at http://qt.digia.com/contact-us.
- **
- ** GNU Lesser General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU Lesser
- ** General Public License version 2.1 as published by the Free Software
- ** Foundation and appearing in the file LICENSE.LGPL included in the
- ** packaging of this file. Please review the following information to
- ** ensure the GNU Lesser General Public License version 2.1 requirements
- ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- **
- ** In addition, as a special exception, Digia gives you certain additional
- ** rights. These rights are described in the Digia Qt LGPL Exception
- ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- **
- ** GNU General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU
- ** General Public License version 3.0 as published by the Free Software
- ** Foundation and appearing in the file LICENSE.GPL included in the
- ** packaging of this file. Please review the following information to
- ** ensure the GNU General Public License version 3.0 requirements will be
- ** met: http://www.gnu.org/copyleft/gpl.html.
- **
- **
- ** $QT_END_LICENSE$
- **
- ****************************************************************************/
- #include "qvariant.h"
- #include "qbitarray.h"
- #include "qbytearray.h"
- #include "qdatastream.h"
- #include "qdebug.h"
- #include "qmap.h"
- #include "qdatetime.h"
- #include "qeasingcurve.h"
- #include "qlist.h"
- #include "qregularexpression.h"
- #include "qstring.h"
- #include "qstringlist.h"
- #include "qurl.h"
- #include "qlocale.h"
- #include "quuid.h"
- #ifndef QT_BOOTSTRAPPED
- #include "qabstractitemmodel.h"
- #include "qjsonvalue.h"
- #include "qjsonobject.h"
- #include "qjsonarray.h"
- #include "qjsondocument.h"
- #endif
- #include "private/qvariant_p.h"
- #include "qmetatype_p.h"
- #ifndef QT_NO_GEOM_VARIANT
- #include "qsize.h"
- #include "qpoint.h"
- #include "qrect.h"
- #include "qline.h"
- #endif
- #include <float.h>
- QT_BEGIN_NAMESPACE
- #ifndef DBL_DIG
- # define DBL_DIG 10
- #endif
- #ifndef FLT_DIG
- # define FLT_DIG 6
- #endif
- namespace {
- class HandlersManager
- {
- static const QVariant::Handler *Handlers[QModulesPrivate::ModulesCount];
- public:
- const QVariant::Handler *operator[] (const uint typeId) const
- {
- return Handlers[QModulesPrivate::moduleForType(typeId)];
- }
- void registerHandler(const QModulesPrivate::Names name, const QVariant::Handler *handler)
- {
- Handlers[name] = handler;
- }
- };
- } // namespace
- namespace {
- struct CoreTypesFilter {
- template<typename T>
- struct Acceptor {
- static const bool IsAccepted = QModulesPrivate::QTypeModuleInfo<T>::IsCore && QtMetaTypePrivate::TypeDefinition<T>::IsAvailable;
- };
- };
- } // annonymous
- namespace { // annonymous used to hide QVariant handlers
- static void construct(QVariant::Private *x, const void *copy)
- {
- QVariantConstructor<CoreTypesFilter> constructor(x, copy);
- QMetaTypeSwitcher::switcher<void>(constructor, x->type, 0);
- }
- static void clear(QVariant::Private *d)
- {
- QVariantDestructor<CoreTypesFilter> cleaner(d);
- QMetaTypeSwitcher::switcher<void>(cleaner, d->type, 0);
- }
- static bool isNull(const QVariant::Private *d)
- {
- QVariantIsNull<CoreTypesFilter> isNull(d);
- return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
- }
- /*!
- \internal
- Compares \a a to \a b. The caller guarantees that \a a and \a b
- are of the same type.
- */
- static bool compare(const QVariant::Private *a, const QVariant::Private *b)
- {
- QVariantComparator<CoreTypesFilter> comparator(a, b);
- return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
- }
- /*!
- \internal
- */
- static qlonglong qMetaTypeNumber(const QVariant::Private *d)
- {
- switch (d->type) {
- case QMetaType::Int:
- return d->data.i;
- case QMetaType::LongLong:
- return d->data.ll;
- case QMetaType::Char:
- return qlonglong(d->data.c);
- case QMetaType::SChar:
- return qlonglong(d->data.sc);
- case QMetaType::Short:
- return qlonglong(d->data.s);
- case QMetaType::Long:
- return qlonglong(d->data.l);
- case QMetaType::Float:
- return qRound64(d->data.f);
- case QVariant::Double:
- return qRound64(d->data.d);
- #ifndef QT_BOOTSTRAPPED
- case QMetaType::QJsonValue:
- return v_cast<QJsonValue>(d)->toDouble();
- #endif
- }
- Q_ASSERT(false);
- return 0;
- }
- static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
- {
- switch (d->type) {
- case QVariant::UInt:
- return d->data.u;
- case QVariant::ULongLong:
- return d->data.ull;
- case QMetaType::UChar:
- return d->data.uc;
- case QMetaType::UShort:
- return d->data.us;
- case QMetaType::ULong:
- return d->data.ul;
- }
- Q_ASSERT(false);
- return 0;
- }
- static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
- {
- *ok = true;
- switch (uint(d->type)) {
- case QVariant::String:
- return v_cast<QString>(d)->toLongLong(ok);
- case QVariant::Char:
- return v_cast<QChar>(d)->unicode();
- case QVariant::ByteArray:
- return v_cast<QByteArray>(d)->toLongLong(ok);
- case QVariant::Bool:
- return qlonglong(d->data.b);
- case QVariant::Double:
- case QVariant::Int:
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::Short:
- case QMetaType::Long:
- case QMetaType::Float:
- case QMetaType::LongLong:
- case QMetaType::QJsonValue:
- return qMetaTypeNumber(d);
- case QVariant::ULongLong:
- case QVariant::UInt:
- case QMetaType::UChar:
- case QMetaType::UShort:
- case QMetaType::ULong:
- return qlonglong(qMetaTypeUNumber(d));
- }
- if (QMetaType::typeFlags(d->type) & QMetaType::IsEnumeration) {
- switch (QMetaType::sizeOf(d->type)) {
- case 1:
- return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->ptr) : d->data.sc;
- case 2:
- return d->is_shared ? *reinterpret_cast<qint16 *>(d->data.shared->ptr) : d->data.s;
- case 4:
- return d->is_shared ? *reinterpret_cast<qint32 *>(d->data.shared->ptr) : d->data.i;
- case 8:
- return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ll;
- }
- }
- *ok = false;
- return Q_INT64_C(0);
- }
- static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
- {
- *ok = true;
- switch (uint(d->type)) {
- case QVariant::String:
- return v_cast<QString>(d)->toULongLong(ok);
- case QVariant::Char:
- return v_cast<QChar>(d)->unicode();
- case QVariant::ByteArray:
- return v_cast<QByteArray>(d)->toULongLong(ok);
- case QVariant::Bool:
- return qulonglong(d->data.b);
- case QVariant::Double:
- case QVariant::Int:
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::Short:
- case QMetaType::Long:
- case QMetaType::Float:
- case QMetaType::LongLong:
- case QMetaType::QJsonValue:
- return qulonglong(qMetaTypeNumber(d));
- case QVariant::ULongLong:
- case QVariant::UInt:
- case QMetaType::UChar:
- case QMetaType::UShort:
- case QMetaType::ULong:
- return qMetaTypeUNumber(d);
- }
- if (QMetaType::typeFlags(d->type) & QMetaType::IsEnumeration) {
- switch (QMetaType::sizeOf(d->type)) {
- case 1:
- return d->is_shared ? *reinterpret_cast<uchar *>(d->data.shared->ptr) : d->data.uc;
- case 2:
- return d->is_shared ? *reinterpret_cast<quint16 *>(d->data.shared->ptr) : d->data.us;
- case 4:
- return d->is_shared ? *reinterpret_cast<quint32 *>(d->data.shared->ptr) : d->data.u;
- case 8:
- return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ull;
- }
- }
- *ok = false;
- return Q_UINT64_C(0);
- }
- template<typename TInput, typename LiteralWrapper>
- inline bool qt_convertToBool(const QVariant::Private *const d)
- {
- TInput str = v_cast<TInput>(d)->toLower();
- return !(str == LiteralWrapper("0") || str == LiteralWrapper("false") || str.isEmpty());
- }
- /*!
- \internal
- Returns the internal data pointer from \a d.
- */
- static const void *constData(const QVariant::Private &d)
- {
- return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.c);
- }
- /*!
- \internal
- Converts \a d to type \a t, which is placed in \a result.
- */
- static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
- {
- Q_ASSERT(d->type != uint(t));
- Q_ASSERT(result);
- if (d->type >= QMetaType::User || t >= QMetaType::User) {
- const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
- if (ok)
- *ok = isOk;
- if (isOk)
- return true;
- }
- bool dummy;
- if (!ok)
- ok = &dummy;
- switch (uint(t)) {
- #ifndef QT_BOOTSTRAPPED
- case QVariant::Url:
- switch (d->type) {
- case QVariant::String:
- *static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
- break;
- default:
- return false;
- }
- break;
- #endif
- case QVariant::String: {
- QString *str = static_cast<QString *>(result);
- switch (d->type) {
- case QVariant::Char:
- *str = QString(*v_cast<QChar>(d));
- break;
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::UChar:
- *str = QChar::fromLatin1(d->data.c);
- break;
- case QMetaType::Short:
- case QMetaType::Long:
- case QVariant::Int:
- case QVariant::LongLong:
- *str = QString::number(qMetaTypeNumber(d));
- break;
- case QVariant::UInt:
- case QVariant::ULongLong:
- case QMetaType::UShort:
- case QMetaType::ULong:
- *str = QString::number(qMetaTypeUNumber(d));
- break;
- case QMetaType::Float:
- *str = QString::number(d->data.f, 'g', FLT_DIG);
- break;
- case QVariant::Double:
- *str = QString::number(d->data.d, 'g', DBL_DIG);
- break;
- #if !defined(QT_NO_DATESTRING)
- case QVariant::Date:
- *str = v_cast<QDate>(d)->toString(Qt::ISODate);
- break;
- case QVariant::Time:
- *str = v_cast<QTime>(d)->toString(Qt::ISODate);
- break;
- case QVariant::DateTime:
- *str = v_cast<QDateTime>(d)->toString(Qt::ISODate);
- break;
- #endif
- case QVariant::Bool:
- *str = QLatin1String(d->data.b ? "true" : "false");
- break;
- case QVariant::ByteArray:
- *str = QString::fromUtf8(v_cast<QByteArray>(d)->constData());
- break;
- case QVariant::StringList:
- if (v_cast<QStringList>(d)->count() == 1)
- *str = v_cast<QStringList>(d)->at(0);
- break;
- #ifndef QT_BOOTSTRAPPED
- case QVariant::Url:
- *str = v_cast<QUrl>(d)->toString();
- break;
- case QMetaType::QJsonValue:
- *str = v_cast<QJsonValue>(d)->toString();
- break;
- #endif
- case QVariant::Uuid:
- *str = v_cast<QUuid>(d)->toString();
- break;
- default:
- return false;
- }
- break;
- }
- case QVariant::Char: {
- QChar *c = static_cast<QChar *>(result);
- switch (d->type) {
- case QVariant::Int:
- case QVariant::LongLong:
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::Short:
- case QMetaType::Long:
- case QMetaType::Float:
- *c = QChar(ushort(qMetaTypeNumber(d)));
- break;
- case QVariant::UInt:
- case QVariant::ULongLong:
- case QMetaType::UChar:
- case QMetaType::UShort:
- case QMetaType::ULong:
- *c = QChar(ushort(qMetaTypeUNumber(d)));
- break;
- default:
- return false;
- }
- break;
- }
- #ifndef QT_NO_GEOM_VARIANT
- case QVariant::Size: {
- QSize *s = static_cast<QSize *>(result);
- switch (d->type) {
- case QVariant::SizeF:
- *s = v_cast<QSizeF>(d)->toSize();
- break;
- default:
- return false;
- }
- break;
- }
- case QVariant::SizeF: {
- QSizeF *s = static_cast<QSizeF *>(result);
- switch (d->type) {
- case QVariant::Size:
- *s = QSizeF(*(v_cast<QSize>(d)));
- break;
- default:
- return false;
- }
- break;
- }
- case QVariant::Line: {
- QLine *s = static_cast<QLine *>(result);
- switch (d->type) {
- case QVariant::LineF:
- *s = v_cast<QLineF>(d)->toLine();
- break;
- default:
- return false;
- }
- break;
- }
- case QVariant::LineF: {
- QLineF *s = static_cast<QLineF *>(result);
- switch (d->type) {
- case QVariant::Line:
- *s = QLineF(*(v_cast<QLine>(d)));
- break;
- default:
- return false;
- }
- break;
- }
- #endif
- case QVariant::StringList:
- if (d->type == QVariant::List) {
- QStringList *slst = static_cast<QStringList *>(result);
- const QVariantList *list = v_cast<QVariantList >(d);
- for (int i = 0; i < list->size(); ++i)
- slst->append(list->at(i).toString());
- } else if (d->type == QVariant::String) {
- QStringList *slst = static_cast<QStringList *>(result);
- *slst = QStringList(*v_cast<QString>(d));
- } else {
- return false;
- }
- break;
- case QVariant::Date: {
- QDate *dt = static_cast<QDate *>(result);
- if (d->type == QVariant::DateTime)
- *dt = v_cast<QDateTime>(d)->date();
- #ifndef QT_NO_DATESTRING
- else if (d->type == QVariant::String)
- *dt = QDate::fromString(*v_cast<QString>(d), Qt::ISODate);
- #endif
- else
- return false;
- return dt->isValid();
- }
- case QVariant::Time: {
- QTime *t = static_cast<QTime *>(result);
- switch (d->type) {
- case QVariant::DateTime:
- *t = v_cast<QDateTime>(d)->time();
- break;
- #ifndef QT_NO_DATESTRING
- case QVariant::String:
- *t = QTime::fromString(*v_cast<QString>(d), Qt::ISODate);
- break;
- #endif
- default:
- return false;
- }
- return t->isValid();
- }
- case QVariant::DateTime: {
- QDateTime *dt = static_cast<QDateTime *>(result);
- switch (d->type) {
- #ifndef QT_NO_DATESTRING
- case QVariant::String:
- *dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
- break;
- #endif
- case QVariant::Date:
- *dt = QDateTime(*v_cast<QDate>(d));
- break;
- default:
- return false;
- }
- return dt->isValid();
- }
- case QVariant::ByteArray: {
- QByteArray *ba = static_cast<QByteArray *>(result);
- switch (d->type) {
- case QVariant::String:
- *ba = v_cast<QString>(d)->toUtf8();
- break;
- case QVariant::Double:
- *ba = QByteArray::number(d->data.d, 'g', DBL_DIG);
- break;
- case QMetaType::Float:
- *ba = QByteArray::number(d->data.f, 'g', FLT_DIG);
- break;
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::UChar:
- *ba = QByteArray(1, d->data.c);
- break;
- case QVariant::Int:
- case QVariant::LongLong:
- case QMetaType::Short:
- case QMetaType::Long:
- *ba = QByteArray::number(qMetaTypeNumber(d));
- break;
- case QVariant::UInt:
- case QVariant::ULongLong:
- case QMetaType::UShort:
- case QMetaType::ULong:
- *ba = QByteArray::number(qMetaTypeUNumber(d));
- break;
- case QVariant::Bool:
- *ba = QByteArray(d->data.b ? "true" : "false");
- break;
- default:
- return false;
- }
- }
- break;
- case QMetaType::Short:
- *static_cast<short *>(result) = short(qConvertToNumber(d, ok));
- return *ok;
- case QMetaType::Long:
- *static_cast<long *>(result) = long(qConvertToNumber(d, ok));
- return *ok;
- case QMetaType::UShort:
- *static_cast<ushort *>(result) = ushort(qConvertToUnsignedNumber(d, ok));
- return *ok;
- case QMetaType::ULong:
- *static_cast<ulong *>(result) = ulong(qConvertToUnsignedNumber(d, ok));
- return *ok;
- case QVariant::Int:
- *static_cast<int *>(result) = int(qConvertToNumber(d, ok));
- return *ok;
- case QVariant::UInt:
- *static_cast<uint *>(result) = uint(qConvertToUnsignedNumber(d, ok));
- return *ok;
- case QVariant::LongLong:
- *static_cast<qlonglong *>(result) = qConvertToNumber(d, ok);
- return *ok;
- case QVariant::ULongLong: {
- *static_cast<qulonglong *>(result) = qConvertToUnsignedNumber(d, ok);
- return *ok;
- }
- case QMetaType::SChar: {
- signed char s = qConvertToNumber(d, ok);
- *static_cast<signed char*>(result) = s;
- return *ok;
- }
- case QMetaType::UChar: {
- *static_cast<uchar *>(result) = qConvertToUnsignedNumber(d, ok);
- return *ok;
- }
- case QVariant::Bool: {
- bool *b = static_cast<bool *>(result);
- switch(d->type) {
- case QVariant::ByteArray:
- *b = qt_convertToBool<QByteArray, QByteArray>(d);
- break;
- case QVariant::String:
- *b = qt_convertToBool<QString, QLatin1String>(d);
- break;
- case QVariant::Char:
- *b = !v_cast<QChar>(d)->isNull();
- break;
- case QVariant::Double:
- case QVariant::Int:
- case QVariant::LongLong:
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::Short:
- case QMetaType::Long:
- case QMetaType::Float:
- *b = qMetaTypeNumber(d) != Q_INT64_C(0);
- break;
- case QVariant::UInt:
- case QVariant::ULongLong:
- case QMetaType::UChar:
- case QMetaType::UShort:
- case QMetaType::ULong:
- *b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
- break;
- #ifndef QT_BOOTSTRAPPED
- case QMetaType::QJsonValue:
- *b = v_cast<QJsonValue>(d)->toBool();
- break;
- #endif
- default:
- *b = false;
- return false;
- }
- break;
- }
- case QVariant::Double: {
- double *f = static_cast<double *>(result);
- switch (d->type) {
- case QVariant::String:
- *f = v_cast<QString>(d)->toDouble(ok);
- break;
- case QVariant::ByteArray:
- *f = v_cast<QByteArray>(d)->toDouble(ok);
- break;
- case QVariant::Bool:
- *f = double(d->data.b);
- break;
- case QMetaType::Float:
- *f = double(d->data.f);
- break;
- case QVariant::LongLong:
- case QVariant::Int:
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::Short:
- case QMetaType::Long:
- *f = double(qMetaTypeNumber(d));
- break;
- case QVariant::UInt:
- case QVariant::ULongLong:
- case QMetaType::UChar:
- case QMetaType::UShort:
- case QMetaType::ULong:
- *f = double(qMetaTypeUNumber(d));
- break;
- #ifndef QT_BOOTSTRAPPED
- case QMetaType::QJsonValue:
- *f = v_cast<QJsonValue>(d)->toDouble();
- break;
- #endif
- default:
- *f = 0.0;
- return false;
- }
- break;
- }
- case QMetaType::Float: {
- float *f = static_cast<float *>(result);
- switch (d->type) {
- case QVariant::String:
- *f = v_cast<QString>(d)->toFloat(ok);
- break;
- case QVariant::ByteArray:
- *f = v_cast<QByteArray>(d)->toFloat(ok);
- break;
- case QVariant::Bool:
- *f = float(d->data.b);
- break;
- case QVariant::Double:
- *f = float(d->data.d);
- break;
- case QVariant::LongLong:
- case QVariant::Int:
- case QMetaType::Char:
- case QMetaType::SChar:
- case QMetaType::Short:
- case QMetaType::Long:
- *f = float(qMetaTypeNumber(d));
- break;
- case QVariant::UInt:
- case QVariant::ULongLong:
- case QMetaType::UChar:
- case QMetaType::UShort:
- case QMetaType::ULong:
- *f = float(qMetaTypeUNumber(d));
- break;
- #ifndef QT_BOOTSTRAPPED
- case QMetaType::QJsonValue:
- *f = v_cast<QJsonValue>(d)->toDouble();
- break;
- #endif
- default:
- *f = 0.0f;
- return false;
- }
- break;
- }
- case QVariant::List:
- if (d->type == QVariant::StringList) {
- QVariantList *lst = static_cast<QVariantList *>(result);
- const QStringList *slist = v_cast<QStringList>(d);
- for (int i = 0; i < slist->size(); ++i)
- lst->append(QVariant(slist->at(i)));
- } else if (qstrcmp(QMetaType::typeName(d->type), "QList<QVariant>") == 0) {
- *static_cast<QVariantList *>(result) =
- *static_cast<QList<QVariant> *>(d->data.shared->ptr);
- } else {
- return false;
- }
- break;
- case QVariant::Map:
- if (qstrcmp(QMetaType::typeName(d->type), "QMap<QString, QVariant>") == 0) {
- *static_cast<QVariantMap *>(result) =
- *static_cast<QMap<QString, QVariant> *>(d->data.shared->ptr);
- } else {
- return false;
- }
- break;
- case QVariant::Hash:
- if (qstrcmp(QMetaType::typeName(d->type), "QHash<QString, QVariant>") == 0) {
- *static_cast<QVariantHash *>(result) =
- *static_cast<QHash<QString, QVariant> *>(d->data.shared->ptr);
- } else {
- return false;
- }
- break;
- #ifndef QT_NO_GEOM_VARIANT
- case QVariant::Rect:
- if (d->type == QVariant::RectF)
- *static_cast<QRect *>(result) = (v_cast<QRectF>(d))->toRect();
- else
- return false;
- break;
- case QVariant::RectF:
- if (d->type == QVariant::Rect)
- *static_cast<QRectF *>(result) = *v_cast<QRect>(d);
- else
- return false;
- break;
- case QVariant::PointF:
- if (d->type == QVariant::Point)
- *static_cast<QPointF *>(result) = *v_cast<QPoint>(d);
- else
- return false;
- break;
- case QVariant::Point:
- if (d->type == QVariant::PointF)
- *static_cast<QPoint *>(result) = (v_cast<QPointF>(d))->toPoint();
- else
- return false;
- break;
- case QMetaType::Char:
- {
- *static_cast<qint8 *>(result) = qint8(qConvertToNumber(d, ok));
- return *ok;
- }
- #endif
- case QVariant::Uuid:
- switch (d->type) {
- case QVariant::String:
- *static_cast<QUuid *>(result) = QUuid(*v_cast<QString>(d));
- break;
- default:
- return false;
- }
- break;
- default:
- return false;
- }
- return true;
- }
- #if !defined(QT_NO_DEBUG_STREAM)
- static void streamDebug(QDebug dbg, const QVariant &v)
- {
- QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
- QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
- QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
- }
- #endif
- const QVariant::Handler qt_kernel_variant_handler = {
- construct,
- clear,
- isNull,
- #ifndef QT_NO_DATASTREAM
- 0,
- 0,
- #endif
- compare,
- convert,
- 0,
- #if !defined(QT_NO_DEBUG_STREAM)
- streamDebug
- #else
- 0
- #endif
- };
- static void dummyConstruct(QVariant::Private *, const void *) { Q_ASSERT_X(false, "QVariant", "Trying to construct an unknown type"); }
- static void dummyClear(QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to clear an unknown type"); }
- static bool dummyIsNull(const QVariant::Private *d) { Q_ASSERT_X(false, "QVariant::isNull", "Trying to call isNull on an unknown type"); return d->is_null; }
- static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
- static bool dummyConvert(const QVariant::Private *, int, void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
- #if !defined(QT_NO_DEBUG_STREAM)
- static void dummyStreamDebug(QDebug, const QVariant &) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); }
- #endif
- const QVariant::Handler qt_dummy_variant_handler = {
- dummyConstruct,
- dummyClear,
- dummyIsNull,
- #ifndef QT_NO_DATASTREAM
- 0,
- 0,
- #endif
- dummyCompare,
- dummyConvert,
- 0,
- #if !defined(QT_NO_DEBUG_STREAM)
- dummyStreamDebug
- #else
- 0
- #endif
- };
- static void customConstruct(QVariant::Private *d, const void *copy)
- {
- const QMetaType type(d->type);
- const uint size = type.sizeOf();
- if (!size) {
- qWarning("Trying to construct an instance of an invalid type, type id: %i", d->type);
- d->type = QVariant::Invalid;
- return;
- }
- // this logic should match with QVariantIntegrator::CanUseInternalSpace
- if (size <= sizeof(QVariant::Private::Data)
- && (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
- type.construct(&d->data.ptr, copy);
- d->is_shared = false;
- } else {
- void *ptr = type.create(copy);
- d->is_shared = true;
- d->data.shared = new QVariant::PrivateShared(ptr);
- }
- }
- 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;
- }
- }
- static bool customIsNull(const QVariant::Private *d)
- {
- return d->is_null;
- }
- static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
- {
- const char *const typeName = QMetaType::typeName(a->type);
- if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
- qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
- const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
- const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
- uint typeNameLen = qstrlen(typeName);
- if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
- return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
- if (a->is_null && b->is_null)
- return true;
- return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
- }
- static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
- {
- if (d->type >= QMetaType::User || t >= QMetaType::User) {
- if (QMetaType::convert(constData(*d), d->type, result, t)) {
- if (ok)
- *ok = true;
- return true;
- }
- }
- return convert(d, t, result, ok);
- }
- #if !defined(QT_NO_DEBUG_STREAM)
- static void customStreamDebug(QDebug dbg, const QVariant &variant) {
- #ifndef QT_BOOTSTRAPPED
- QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType());
- if (flags & QMetaType::PointerToQObject)
- dbg.nospace() << variant.value<QObject*>();
- #else
- Q_UNUSED(dbg);
- Q_UNUSED(variant);
- #endif
- }
- #endif
- const QVariant::Handler qt_custom_variant_handler = {
- customConstruct,
- customClear,
- customIsNull,
- #ifndef QT_NO_DATASTREAM
- 0,
- 0,
- #endif
- customCompare,
- customConvert,
- 0,
- #if !defined(QT_NO_DEBUG_STREAM)
- customStreamDebug
- #else
- 0
- #endif
- };
- } // annonymous used to hide QVariant handlers
- static HandlersManager handlerManager;
- Q_STATIC_ASSERT_X(!QModulesPrivate::Core, "Initialization assumes that ModulesNames::Core is 0");
- const QVariant::Handler *HandlersManager::Handlers[QModulesPrivate::ModulesCount]
- = { &qt_kernel_variant_handler, &qt_dummy_variant_handler,
- &qt_dummy_variant_handler, &qt_custom_variant_handler };
- Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
- {
- return &qt_kernel_variant_handler;
- }
- Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
- {
- handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
- }
- /*!
- \class QVariant
- \inmodule QtCore
- \brief The QVariant class acts like a union for the most common Qt data types.
- \ingroup objectmodel
- \ingroup shared
- Because C++ forbids unions from including types that have
- non-default constructors or destructors, most interesting Qt
- classes cannot be used in unions. Without QVariant, this would be
- a problem for QObject::property() and for database work, etc.
- A QVariant object holds a single value of a single type() at a
- time. (Some type()s are multi-valued, for example a string list.)
- You can find out what type, T, the variant holds, convert it to a
- different type using convert(), get its value using one of the
- toT() functions (e.g., toSize()) and check whether the type can
- be converted to a particular type using canConvert().
- The methods named toT() (e.g., toInt(), toString()) are const. If
- you ask for the stored type, they return a copy of the stored
- object. If you ask for a type that can be generated from the
- stored type, toT() copies and converts and leaves the object
- itself unchanged. If you ask for a type that cannot be generated
- from the stored type, the result depends on the type; see the
- function documentation for details.
- Here is some example code to demonstrate the use of QVariant:
- \snippet code/src_corelib_kernel_qvariant.cpp 0
- You can even store QList<QVariant> and QMap<QString, QVariant>
- values in a variant, so you can easily construct arbitrarily
- complex data structures of arbitrary types. This is very powerful
- and versatile, but may prove less memory and speed efficient than
- storing specific types in standard data structures.
- QVariant also supports the notion of null values, where you can
- have a defined type with no value set. However, note that QVariant
- types can only be cast when they have had a value set.
- \snippet code/src_corelib_kernel_qvariant.cpp 1
- QVariant can be extended to support other types than those
- mentioned in the \l Type enum. See the \l QMetaType documentation
- for details.
- \section1 A Note on GUI Types
- Because QVariant is part of the Qt Core module, it cannot provide
- conversion functions to data types defined in Qt GUI, such as
- QColor, QImage, and QPixmap. In other words, there is no \c
- toColor() function. Instead, you can use the QVariant::value() or
- the qvariant_cast() template function. For example:
- \snippet code/src_corelib_kernel_qvariant.cpp 2
- The inverse conversion (e.g., from QColor to QVariant) is
- automatic for all data types supported by QVariant, including
- GUI-related types:
- \snippet code/src_corelib_kernel_qvariant.cpp 3
- \section1 Using canConvert() and convert() Consecutively
- When using canConvert() and convert() consecutively, it is possible for
- canConvert() to return true, but convert() to return false. This
- is typically because canConvert() only reports the general ability of
- QVariant to convert between types given suitable data; it is still
- possible to supply data which cannot actually be converted.
- For example, canConvert(Int) would return true when called on a variant
- containing a string because, in principle, QVariant is able to convert
- strings of numbers to integers.
- However, if the string contains non-numeric characters, it cannot be
- converted to an integer, and any attempt to convert it will fail.
- Hence, it is important to have both functions return true for a
- successful conversion.
- \sa QMetaType
- */
- /*!
- \obsolete Use QMetaType::Type instead
- \enum QVariant::Type
- This enum type defines the types of variable that a QVariant can
- contain.
- \value Invalid no type
- \value BitArray a QBitArray
- \value Bitmap a QBitmap
- \value Bool a bool
- \value Brush a QBrush
- \value ByteArray a QByteArray
- \value Char a QChar
- \value Color a QColor
- \value Cursor a QCursor
- \value Date a QDate
- \value DateTime a QDateTime
- \value Double a double
- \value EasingCurve a QEasingCurve
- \value Uuid a QUuid
- \value ModelIndex a QModelIndex
- \value Font a QFont
- \value Hash a QVariantHash
- \value Icon a QIcon
- \value Image a QImage
- \value Int an int
- \value KeySequence a QKeySequence
- \value Line a QLine
- \value LineF a QLineF
- \value List a QVariantList
- \value Locale a QLocale
- \value LongLong a \l qlonglong
- \value Map a QVariantMap
- \value Matrix a QMatrix
- \value Transform a QTransform
- \value Matrix4x4 a QMatrix4x4
- \value Palette a QPalette
- \value Pen a QPen
- \value Pixmap a QPixmap
- \value Point a QPoint
- \value PointF a QPointF
- \value Polygon a QPolygon
- \value PolygonF a QPolygonF
- \value Quaternion a QQuaternion
- \value Rect a QRect
- \value RectF a QRectF
- \value RegExp a QRegExp
- \value RegularExpression a QRegularExpression
- \value Region a QRegion
- \value Size a QSize
- \value SizeF a QSizeF
- \value SizePolicy a QSizePolicy
- \value String a QString
- \value StringList a QStringList
- \value TextFormat a QTextFormat
- \value TextLength a QTextLength
- \value Time a QTime
- \value UInt a \l uint
- \value ULongLong a \l qulonglong
- \value Url a QUrl
- \value Vector2D a QVector2D
- \value Vector3D a QVector3D
- \value Vector4D a QVector4D
- \value UserType Base value for user-defined types.
- \omitvalue LastGuiType
- \omitvalue LastCoreType
- \omitvalue LastType
- */
- /*!
- \fn QVariant::QVariant(QVariant &&other)
- Move-constructs a QVariant instance, making it point at the same
- object that \a other was pointing to.
- \since 5.2
- */
- /*!
- \fn QVariant &QVariant::operator=(QVariant &&other)
- Move-assigns \a other to this QVariant instance.
- \since 5.2
- */
- /*!
- \fn QVariant::QVariant()
- Constructs an invalid variant.
- */
- /*!
- \fn QVariant::QVariant(int typeId, const void *copy)
- Constructs variant of type \a typeId, and initializes with
- \a copy if \a copy is not 0.
- Note that you have to pass the address of the variable you want stored.
- Usually, you never have to use this constructor, use QVariant::fromValue()
- instead to construct variants from the pointer types represented by
- \c QMetaType::VoidStar, and \c QMetaType::QObjectStar.
- \sa QVariant::fromValue(), QMetaType::Type
- */
- /*!
- \fn QVariant::QVariant(Type type)
- Constructs a null variant of type \a type.
- */
- /*!
- \fn QVariant::create(int type, const void *copy)
- \internal
- Constructs a variant private of type \a type, and initializes with \a copy if
- \a copy is not 0.
- */
- void QVariant::create(int type, const void *copy)
- {
- d.type = type;
- handlerManager[type]->construct(&d, copy);
- }
- /*!
- \fn QVariant::~QVariant()
- Destroys the QVariant and the contained object.
- Note that subclasses that reimplement clear() should reimplement
- the destructor to call clear(). This destructor calls clear(), but
- because it is the destructor, QVariant::clear() is called rather
- than a subclass's clear().
- */
- QVariant::~QVariant()
- {
- if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
- handlerManager[d.type]->clear(&d);
- }
- /*!
- \fn QVariant::QVariant(const QVariant &p)
- Constructs a copy of the variant, \a p, passed as the argument to
- this constructor.
- */
- QVariant::QVariant(const QVariant &p)
- : d(p.d)
- {
- if (d.is_shared) {
- d.data.shared->ref.ref();
- } else if (p.d.type > Char) {
- handlerManager[d.type]->construct(&d, p.constData());
- d.is_null = p.d.is_null;
- }
- }
- #ifndef QT_NO_DATASTREAM
- /*!
- Reads the variant from the data stream, \a s.
- */
- QVariant::QVariant(QDataStream &s)
- {
- d.is_null = true;
- s >> *this;
- }
- #endif //QT_NO_DATASTREAM
- /*!
- \fn QVariant::QVariant(const QString &val)
- Constructs a new variant with a string value, \a val.
- */
- /*!
- \fn QVariant::QVariant(QLatin1String val)
- Constructs a new variant with a string value, \a val.
- */
- /*!
- \fn QVariant::QVariant(const char *val)
- Constructs a new variant with a string value of \a val.
- The variant creates a deep copy of \a val into a QString assuming
- UTF-8 encoding on the input \a val.
- Note that \a val is converted to a QString for storing in the
- variant and QVariant::userType() will return QMetaType::QString for
- the variant.
- You can disable this operator by defining \c
- QT_NO_CAST_FROM_ASCII when you compile your applications.
- */
- #ifndef QT_NO_CAST_FROM_ASCII
- QVariant::QVariant(const char *val)
- {
- QString s = QString::fromUtf8(val);
- create(String, &s);
- }
- #endif
- /*!
- \fn QVariant::QVariant(const QStringList &val)
- Constructs a new variant with a string list value, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
- Constructs a new variant with a map of QVariants, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
- Constructs a new variant with a hash of QVariants, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QDate &val)
- Constructs a new variant with a date value, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QTime &val)
- Constructs a new variant with a time value, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QDateTime &val)
- Constructs a new variant with a date/time value, \a val.
- */
- /*!
- \since 4.7
- \fn QVariant::QVariant(const QEasingCurve &val)
- Constructs a new variant with an easing curve value, \a val.
- */
- /*!
- \since 5.0
- \fn QVariant::QVariant(const QUuid &val)
- Constructs a new variant with an uuid value, \a val.
- */
- /*!
- \since 5.0
- \fn QVariant::QVariant(const QModelIndex &val)
- Constructs a new variant with an modelIndex value, \a val.
- */
- /*!
- \since 5.0
- \fn QVariant::QVariant(const QJsonValue &val)
- Constructs a new variant with a json value, \a val.
- */
- /*!
- \since 5.0
- \fn QVariant::QVariant(const QJsonObject &val)
- Constructs a new variant with a json object value, \a val.
- */
- /*!
- \since 5.0
- \fn QVariant::QVariant(const QJsonArray &val)
- Constructs a new variant with a json array value, \a val.
- */
- /*!
- \since 5.0
- \fn QVariant::QVariant(const QJsonDocument &val)
- Constructs a new variant with a json document value, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QByteArray &val)
- Constructs a new variant with a bytearray value, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QBitArray &val)
- Constructs a new variant with a bitarray value, \a val.
- */
- /*!
- \fn QVariant::QVariant(const QPoint &val)
- Constructs a new variant with a point value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QPointF &val)
- Constructs a new variant with a point value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QRectF &val)
- Constructs a new variant with a rect value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QLineF &val)
- Constructs a new variant with a line value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QLine &val)
- Constructs a new variant with a line value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QRect &val)
- Constructs a new variant with a rect value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QSize &val)
- Constructs a new variant with a size value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QSizeF &val)
- Constructs a new variant with a size value of \a val.
- */
- /*!
- \fn QVariant::QVariant(const QUrl &val)
- Constructs a new variant with a url value of \a val.
- */
- /*!
- \fn QVariant::QVariant(int val)
- Constructs a new variant with an integer value, \a val.
- */
- /*!
- \fn QVariant::QVariant(uint val)
- Constructs a new variant with an unsigned integer value, \a val.
- */
- /*!
- \fn QVariant::QVariant(qlonglong val)
- Constructs a new variant with a long long integer value, \a val.
- */
- /*!
- \fn QVariant::QVariant(qulonglong val)
- Constructs a new variant with an unsigned long long integer value, \a val.
- */
- /*!
- \fn QVariant::QVariant(bool val)
- Constructs a new variant with a boolean value, \a val.
- */
- /*!
- \fn QVariant::QVariant(double val)
- Constructs a new variant with a floating point value, \a val.
- */
- /*!
- \fn QVariant::QVariant(float val)
- Constructs a new variant with a floating point value, \a val.
- \since 4.6
- */
- /*!
- \fn QVariant::QVariant(const QList<QVariant> &val)
- Constructs a new variant with a list value, \a val.
- */
- /*!
- \fn QVariant::QVariant(QChar c)
- Constructs a new variant with a char value, \a c.
- */
- /*!
- \fn QVariant::QVariant(const QLocale &l)
- Constructs a new variant with a locale value, \a l.
- */
- /*!
- \fn QVariant::QVariant(const QRegExp ®Exp)
- Constructs a new variant with the regexp value \a regExp.
- */
- /*!
- \fn QVariant::QVariant(const QRegularExpression &re)
- \since 5.0
- Constructs a new variant with the regular expression value \a re.
- */
- QVariant::QVariant(Type type)
- { create(type, 0); }
- QVariant::QVariant(int typeId, const void *copy)
- { create(typeId, copy); d.is_null = false; }
- /*!
- \internal
- flags is true if it is a pointer type
- */
- QVariant::QVariant(int typeId, const void *copy, uint flags)
- {
- if (flags) { //type is a pointer type
- d.type = typeId;
- d.data.ptr = *reinterpret_cast<void *const*>(copy);
- } else {
- create(typeId, copy);
- }
- d.is_null = false;
- }
- QVariant::QVariant(int val)
- : d(Int)
- { d.data.i = val; }
- QVariant::QVariant(uint val)
- : d(UInt)
- { d.data.u = val; }
- QVariant::QVariant(qlonglong val)
- : d(LongLong)
- { d.data.ll = val; }
- QVariant::QVariant(qulonglong val)
- : d(ULongLong)
- { d.data.ull = val; }
- QVariant::QVariant(bool val)
- : d(Bool)
- { d.data.b = val; }
- QVariant::QVariant(double val)
- : d(Double)
- { d.data.d = val; }
- QVariant::QVariant(float val)
- : d(QMetaType::Float)
- { d.data.f = val; }
- QVariant::QVariant(const QByteArray &val)
- : d(ByteArray)
- { v_construct<QByteArray>(&d, val); }
- QVariant::QVariant(const QBitArray &val)
- : d(BitArray)
- { v_construct<QBitArray>(&d, val); }
- QVariant::QVariant(const QString &val)
- : d(String)
- { v_construct<QString>(&d, val); }
- QVariant::QVariant(QChar val)
- : d(Char)
- { v_construct<QChar>(&d, val); }
- QVariant::QVariant(QLatin1String val)
- : d(String)
- { v_construct<QString>(&d, val); }
- QVariant::QVariant(const QStringList &val)
- : d(StringList)
- { v_construct<QStringList>(&d, val); }
- QVariant::QVariant(const QDate &val)
- : d(Date)
- { v_construct<QDate>(&d, val); }
- QVariant::QVariant(const QTime &val)
- : d(Time)
- { v_construct<QTime>(&d, val); }
- QVariant::QVariant(const QDateTime &val)
- : d(DateTime)
- { v_construct<QDateTime>(&d, val); }
- #ifndef QT_BOOTSTRAPPED
- QVariant::QVariant(const QEasingCurve &val)
- : d(EasingCurve)
- { v_construct<QEasingCurve>(&d, val); }
- #endif
- QVariant::QVariant(const QList<QVariant> &list)
- : d(List)
- { v_construct<QVariantList>(&d, list); }
- QVariant::QVariant(const QMap<QString, QVariant> &map)
- : d(Map)
- { v_construct<QVariantMap>(&d, map); }
- QVariant::QVariant(const QHash<QString, QVariant> &hash)
- : d(Hash)
- { v_construct<QVariantHash>(&d, hash); }
- #ifndef QT_NO_GEOM_VARIANT
- QVariant::QVariant(const QPoint &pt)
- : d(Point)
- { v_construct<QPoint>(&d, pt); }
- QVariant::QVariant(const QPointF &pt)
- : d(PointF)
- { v_construct<QPointF>(&d, pt); }
- QVariant::QVariant(const QRectF &r)
- : d(RectF)
- { v_construct<QRectF>(&d, r); }
- QVariant::QVariant(const QLineF &l)
- : d(LineF)
- { v_construct<QLineF>(&d, l); }
- QVariant::QVariant(const QLine &l)
- : d(Line)
- { v_construct<QLine>(&d, l); }
- QVariant::QVariant(const QRect &r)
- : d(Rect)
- { v_construct<QRect>(&d, r); }
- QVariant::QVariant(const QSize &s)
- : d(Size)
- { v_construct<QSize>(&d, s); }
- QVariant::QVariant(const QSizeF &s)
- : d(SizeF)
- { v_construct<QSizeF>(&d, s); }
- #endif
- #ifndef QT_BOOTSTRAPPED
- QVariant::QVariant(const QUrl &u)
- : d(Url)
- { v_construct<QUrl>(&d, u); }
- #endif
- QVariant::QVariant(const QLocale &l)
- : d(Locale)
- { v_construct<QLocale>(&d, l); }
- #ifndef QT_NO_REGEXP
- QVariant::QVariant(const QRegExp ®Exp)
- : d(RegExp)
- { v_construct<QRegExp>(&d, regExp); }
- #endif // QT_NO_REGEXP
- #ifndef QT_BOOTSTRAPPED
- #ifndef QT_NO_REGULAREXPRESSION
- QVariant::QVariant(const QRegularExpression &re)
- : d(RegularExpression)
- { v_construct<QRegularExpression>(&d, re); }
- #endif
- QVariant::QVariant(const QUuid &uuid)
- : d(Uuid)
- { v_construct<QUuid>(&d, uuid); }
- QVariant::QVariant(const QModelIndex &modelIndex)
- : d(ModelIndex)
- { v_construct<QModelIndex>(&d, modelIndex); }
- QVariant::QVariant(const QJsonValue &jsonValue)
- : d(QMetaType::QJsonValue)
- { v_construct<QJsonValue>(&d, jsonValue); }
- QVariant::QVariant(const QJsonObject &jsonObject)
- : d(QMetaType::QJsonObject)
- { v_construct<QJsonObject>(&d, jsonObject); }
- QVariant::QVariant(const QJsonArray &jsonArray)
- : d(QMetaType::QJsonArray)
- { v_construct<QJsonArray>(&d, jsonArray); }
- QVariant::QVariant(const QJsonDocument &jsonDocument)
- : d(QMetaType::QJsonDocument)
- { v_construct<QJsonDocument>(&d, jsonDocument); }
- #endif // QT_BOOTSTRAPPED
- /*!
- Returns the storage type of the value stored in the variant.
- Although this function is declared as returning QVariant::Type,
- the return value should be interpreted as QMetaType::Type. In
- particular, QVariant::UserType is returned here only if the value
- is equal or greater than QMetaType::User.
- Note that return values in the ranges QVariant::Char through
- QVariant::RegExp and QVariant::Font through QVariant::Transform
- correspond to the values in the ranges QMetaType::QChar through
- QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
- Pay particular attention when working with char and QChar
- variants. Note that there is no QVariant constructor specifically
- for type char, but there is one for QChar. For a variant of type
- QChar, this function returns QVariant::Char, which is the same as
- QMetaType::QChar, but for a variant of type \c char, this function
- returns QMetaType::Char, which is \e not the same as
- QVariant::Char.
- Also note that the types \c void*, \c long, \c short, \c unsigned
- \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
- QObject*, and \c QWidget* are represented in QMetaType::Type but
- not in QVariant::Type, and they can be returned by this function.
- However, they are considered to be user defined types when tested
- against QVariant::Type.
- To test whether an instance of QVariant contains a data type that
- is compatible with the data type you are interested in, use
- canConvert().
- */
- QVariant::Type QVariant::type() const
- {
- return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
- }
- /*!
- Returns the storage type of the value stored in the variant. For
- non-user types, this is the same as type().
- \sa type()
- */
- int QVariant::userType() const
- {
- return d.type;
- }
- /*!
- Assigns the value of the variant \a variant to this variant.
- */
- QVariant& QVariant::operator=(const QVariant &variant)
- {
- if (this == &variant)
- return *this;
- clear();
- if (variant.d.is_shared) {
- variant.d.data.shared->ref.ref();
- d = variant.d;
- } else if (variant.d.type > Char) {
- d.type = variant.d.type;
- handlerManager[d.type]->construct(&d, variant.constData());
- d.is_null = variant.d.is_null;
- } else {
- d = variant.d;
- }
- return *this;
- }
- /*!
- \fn void QVariant::swap(QVariant &other)
- \since 4.8
- Swaps variant \a other with this variant. This operation is very
- fast and never fails.
- */
- /*!
- \fn void QVariant::detach()
- \internal
- */
- void QVariant::detach()
- {
- if (!d.is_shared || d.data.shared->ref.load() == 1)
- return;
- Private dd;
- dd.type = d.type;
- handlerManager[d.type]->construct(&dd, constData());
- if (!d.data.shared->ref.deref())
- handlerManager[d.type]->clear(&d);
- d.data.shared = dd.data.shared;
- }
- /*!
- \fn bool QVariant::isDetached() const
- \internal
- */
- /*!
- Returns the name of the type stored in the variant. The returned
- strings describe the C++ datatype used to store the data: for
- example, "QFont", "QString", or "QVariantList". An Invalid
- variant returns 0.
- */
- const char