/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
namespace {
template<typename T>
-struct TypeDefiniton {
+struct TypeDefinition {
static const bool IsAvailable = true;
};
// Ignore these types, as incomplete
#ifdef QT_BOOTSTRAPPED
-template<> struct TypeDefiniton<QEasingCurve> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QModelIndex> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QEasingCurve> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QModelIndex> { static const bool IsAvailable = false; };
#endif
#ifdef QT_NO_GEOM_VARIANT
-template<> struct TypeDefiniton<QRect> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QRectF> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QSize> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QSizeF> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QLine> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QLineF> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QPoint> { static const bool IsAvailable = false; };
-template<> struct TypeDefiniton<QPointF> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QRect> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QRectF> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QSize> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QSizeF> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QLine> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QLineF> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QPoint> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QPointF> { static const bool IsAvailable = false; };
#endif
struct CoreTypesFilter {
template<typename T>
struct Acceptor {
- static const bool IsAccepted = QTypeModuleInfo<T>::IsCore && TypeDefiniton<T>::IsAvailable;
+ static const bool IsAccepted = QTypeModuleInfo<T>::IsCore && TypeDefinition<T>::IsAvailable;
};
};
-} // annonymous used to hide TypeDefiniton
+} // annonymous used to hide TypeDefinition
namespace { // annonymous used to hide QVariant handlers
Converts \a d to type \a t, which is placed in \a result.
*/
-static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, bool *ok)
+static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
{
Q_ASSERT(d->type != uint(t));
Q_ASSERT(result);
return true;
}
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG_STREAM)
static void streamDebug(QDebug dbg, const QVariant &v)
{
QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
compare,
convert,
0,
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG_STREAM)
streamDebug
#else
0
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 *, QVariant::Type , void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
+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 = {
dummyCompare,
dummyConvert,
0,
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG_STREAM)
dummyStreamDebug
#else
0
static void customConstruct(QVariant::Private *d, const void *copy)
{
- const uint size = QMetaType::sizeOf(d->type);
+ const QMetaType type(d->type);
+ const uint size = type.sizeOf();
if (!size) {
d->type = QVariant::Invalid;
return;
// this logic should match with QVariantIntegrator::CanUseInternalSpace
if (size <= sizeof(QVariant::Private::Data)
- && (QMetaType::typeFlags(d->type) & QMetaType::MovableType)) {
- QMetaType::construct(d->type, &d->data.ptr, copy);
+ && (type.flags() & QMetaType::MovableType)) {
+ type.construct(&d->data.ptr, copy);
d->is_shared = false;
} else {
- void *ptr = QMetaType::create(d->type, copy);
+ void *ptr = type.create(copy);
d->is_shared = true;
d->data.shared = new QVariant::PrivateShared(ptr);
}
return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
}
-static bool customConvert(const QVariant::Private *, QVariant::Type, void *, bool *ok)
+static bool customConvert(const QVariant::Private *, int, void *, bool *ok)
{
if (ok)
*ok = false;
return false;
}
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG_STREAM)
static void customStreamDebug(QDebug, const QVariant &) {}
#endif
customCompare,
customConvert,
0,
-#if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG_STREAM)
customStreamDebug
#else
0
/*!
- \fn QVariant::QVariant(int typeOrUserType, const void *copy)
+ \fn QVariant::QVariant(int typeId, const void *copy)
- Constructs variant of type \a typeOrUserType, and initializes with
+ 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.
\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, using the encoding
- set by QTextCodec::setCodecForCStrings().
+ 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::type() will return QMetaType::QString for
+ 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.
-
- \sa QTextCodec::setCodecForCStrings()
*/
#ifndef QT_NO_CAST_FROM_ASCII
*/
/*!
- \fn QVariant::QVariant(const QChar &c)
+ \fn QVariant::QVariant(QChar c)
Constructs a new variant with a char value, \a c.
*/
QVariant::QVariant(Type type)
{ create(type, 0); }
-QVariant::QVariant(int typeOrUserType, const void *copy)
-{ create(typeOrUserType, copy); d.is_null = false; }
+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 typeOrUserType, const void *copy, uint flags)
+QVariant::QVariant(int typeId, const void *copy, uint flags)
{
if (flags) { //type is a pointer type
- d.type = typeOrUserType;
+ d.type = typeId;
d.data.ptr = *reinterpret_cast<void *const*>(copy);
} else {
- create(typeOrUserType, copy);
+ create(typeId, copy);
}
d.is_null = false;
}
{ d.is_null = false; d.type = BitArray; v_construct<QBitArray>(&d, val); }
QVariant::QVariant(const QString &val)
{ d.is_null = false; d.type = String; v_construct<QString>(&d, val); }
-QVariant::QVariant(const QChar &val)
+QVariant::QVariant(QChar val)
{ d.is_null = false; d.type = Char; v_construct<QChar>(&d, val); }
QVariant::QVariant(const QLatin1String &val)
{ QString str(val); d.is_null = false; d.type = String; v_construct<QString>(&d, str); }
*/
const char *QVariant::typeName() const
{
- return typeToName(Type(d.type));
+ return typeToName(d.type);
}
/*!
}
/*!
- Converts the enum representation of the storage type, \a typ, to
+ Converts the int representation of the storage type, \a typeId, to
its string representation.
Returns a null pointer if the type is QVariant::Invalid or doesn't exist.
*/
-const char *QVariant::typeToName(Type typ)
+const char *QVariant::typeToName(int typeId)
{
- if (typ == Invalid)
+ if (typeId == Invalid)
return 0;
- if (typ == UserType)
- return "UserType";
- return QMetaType::typeName(typ);
+ return QMetaType::typeName(typeId);
}
{
if (!name || !*name)
return Invalid;
- if (strcmp(name, "Q3CString") == 0)
- return ByteArray;
- if (strcmp(name, "Q_LLONG") == 0)
- return LongLong;
- if (strcmp(name, "Q_ULLONG") == 0)
- return ULongLong;
- if (strcmp(name, "QIconSet") == 0)
- return Icon;
- if (strcmp(name, "UserType") == 0)
- return UserType;
int metaType = QMetaType::type(name);
- return metaType <= int(LastGuiType) ? QVariant::Type(metaType) : UserType;
+ return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
}
#ifndef QT_NO_DATASTREAM
enum { MapFromThreeCount = 36 };
-static const ushort map_from_three[MapFromThreeCount] =
+static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
{
QVariant::Invalid,
QVariant::Map,
QVariant::Size,
QVariant::Color,
QVariant::Palette,
- 63, // ColorGroup
+ 0, // ColorGroup
QVariant::Icon,
QVariant::Point,
QVariant::Image,
{
clear();
- quint32 u;
- s >> u;
+ quint32 typeId;
+ s >> typeId;
if (s.version() < QDataStream::Qt_4_0) {
- if (u >= MapFromThreeCount)
+ if (typeId >= MapFromThreeCount)
return;
- u = map_from_three[u];
+ typeId = mapIdFromQt3ToCurrent[typeId];
+ } else if (s.version() < QDataStream::Qt_5_0) {
+ if (typeId == 127 /* QVariant::UserType */) {
+ typeId = QMetaType::User;
+ } else if (typeId >= 128 && typeId != QVariant::UserType) {
+ // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
+ // by moving all ids down by 97.
+ typeId -= 97;
+ } else if (typeId == 69 /* QIcon */) {
+ // In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
+ typeId = QMetaType::QIcon;
+ } else if (typeId == 75 /* QSizePolicy */) {
+ typeId = QMetaType::QSizePolicy;
+ } else if (typeId >= 70) {
+ // and as a result this types recieved lower ids too
+ if (typeId <= 74) { // QImage QPolygon QRegion QBitmap QCursor
+ typeId -=1;
+ } else if (typeId <= 86) { // QKeySequence QPen QTextLength QTextFormat QMatrix QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
+ typeId -=2;
+ }
+ }
}
+
qint8 is_null = false;
if (s.version() >= QDataStream::Qt_4_2)
s >> is_null;
- if (u == QVariant::UserType) {
+ if (typeId == QVariant::UserType) {
QByteArray name;
s >> name;
- u = QMetaType::type(name);
- if (!u) {
+ typeId = QMetaType::type(name);
+ if (typeId == QMetaType::UnknownType) {
s.setStatus(QDataStream::ReadCorruptData);
return;
}
}
- create(static_cast<int>(u), 0);
+ create(static_cast<int>(typeId), 0);
d.is_null = is_null;
if (!isValid()) {
*/
void QVariant::save(QDataStream &s) const
{
- quint32 tp = type();
+ quint32 typeId = type();
if (s.version() < QDataStream::Qt_4_0) {
int i;
for (i = MapFromThreeCount - 1; i >= 0; i--) {
- if (map_from_three[i] == tp) {
- tp = i;
+ if (mapIdFromQt3ToCurrent[i] == typeId) {
+ typeId = i;
break;
}
}
s << QVariant();
return;
}
+ } else if (s.version() < QDataStream::Qt_5_0) {
+ if (typeId == QMetaType::User) {
+ typeId = 127; // QVariant::UserType had this value in Qt4
+ } else if (typeId >= 128 - 97 && typeId <= LastCoreType) {
+ // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
+ // by moving all ids down by 97.
+ typeId += 97;
+ } else if (typeId == QMetaType::QIcon) {
+ // In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
+ typeId = 69;
+ } else if (typeId == QMetaType::QSizePolicy) {
+ typeId = 75;
+ } else if (typeId >= QMetaType::QImage) {
+ // and as a result this types recieved lower ids too
+ if (typeId <= QMetaType::QCursor) {
+ typeId +=1;
+ } else if (typeId <= QMetaType::QQuaternion) {
+ typeId +=2;
+ }
+ }
}
- s << tp;
+ s << typeId;
if (s.version() >= QDataStream::Qt_4_2)
s << qint8(d.is_null);
- if (tp == QVariant::UserType) {
+ if (d.type >= QVariant::UserType) {
s << QMetaType::typeName(userType());
}
}
if (!QMetaType::save(s, d.type, constData())) {
+ qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n", QMetaType::typeName(d.type), d.type);
Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
- qWarning("QVariant::save: unable to save type %d.", d.type);
}
}
template <typename T>
inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
{
- const QVariant::Type targetType = static_cast<const QVariant::Type>(qMetaTypeId<T>());
+ const uint targetType = qMetaTypeId<T>();
if (d.type == targetType)
return *v_cast<T>(&d);
return val;
T ret = 0;
- if (!handlerManager[d.type]->convert(&d, QVariant::Type(t), &ret, ok) && ok)
+ if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
*ok = false;
return ret;
}
/*!
Returns true if the variant's type can be cast to the requested
- type, \a t. Such casting is done automatically when calling the
+ type, \a targetTypeId. Such casting is done automatically when calling the
toInt(), toBool(), ... methods.
The following casts are done automatically:
\sa convert()
*/
-bool QVariant::canConvert(Type t) const
+bool QVariant::canConvert(int targetTypeId) const
{
- //we can treat floats as double
- //the reason for not doing it the "proper" way is that QMetaType::Float's value is 135,
- //which can't be handled by qCanConvertMatrix
- //In addition QVariant::Type doesn't have a Float value, so we're using QMetaType::Float
+ // TODO Reimplement this function, currently it works but it is a historical mess.
const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
- if (uint(t) == uint(QMetaType::Float)) t = QVariant::Double;
+ if (uint(targetTypeId) == uint(QMetaType::Float)) targetTypeId = QVariant::Double;
- if (currentType == uint(t))
+ if (currentType == uint(targetTypeId))
return true;
- if (currentType > QVariant::LastCoreType || t > QVariant::LastCoreType) {
- switch (uint(t)) {
+ // FIXME It should be LastCoreType intead of Uuid
+ if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) {
+ switch (uint(targetTypeId)) {
case QVariant::Int:
return currentType == QVariant::KeySequence
|| currentType == QMetaType::ULong
}
}
- if(t == String && currentType == StringList)
+ if (targetTypeId == String && currentType == StringList)
return v_cast<QStringList>(&d)->count() == 1;
else
- return qCanConvertMatrix[t] & (1 << currentType);
+ return qCanConvertMatrix[targetTypeId] & (1 << currentType);
}
/*!
- Casts the variant to the requested type, \a t. If the cast cannot be
+ Casts the variant to the requested type, \a targetTypeId. If the cast cannot be
done, the variant is cleared. Returns true if the current type of
the variant was successfully cast; otherwise returns false.
\sa canConvert(), clear()
*/
-bool QVariant::convert(Type t)
+bool QVariant::convert(int targetTypeId)
{
- if (d.type == uint(t))
+ if (d.type == uint(targetTypeId))
return true;
QVariant oldValue = *this;
clear();
- if (!oldValue.canConvert(t))
+ if (!oldValue.canConvert(targetTypeId))
return false;
- create(t, 0);
+ create(targetTypeId, 0);
if (oldValue.isNull())
return false;
bool isOk = true;
- if (!handlerManager[d.type]->convert(&oldValue.d, t, data(), &isOk))
+ if (!handlerManager[d.type]->convert(&oldValue.d, targetTypeId, data(), &isOk))
isOk = false;
d.is_null = !isOk;
return isOk;
bool QVariant::convert(const int type, void *ptr) const
{
Q_ASSERT(type < int(QMetaType::User));
- return handlerManager[type]->convert(&d, QVariant::Type(type), ptr, 0);
+ return handlerManager[type]->convert(&d, type, ptr, 0);
}
else
return toLongLong() == v.toLongLong();
}
- if (!v2.canConvert(Type(d.type)) || !v2.convert(Type(d.type)))
+ if (!v2.canConvert(d.type) || !v2.convert(d.type))
return false;
}
return handlerManager[d.type]->compare(&d, &v2.d);
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QVariant &v)
{
-#ifndef Q_BROKEN_DEBUG_STREAM
dbg.nospace() << "QVariant(" << QMetaType::typeName(v.userType()) << ", ";
handlerManager[v.d.type]->debugStream(dbg, v);
dbg.nospace() << ')';
return dbg.space();
-#else
- qWarning("This compiler doesn't support streaming QVariant to QDebug");
- return dbg;
- Q_UNUSED(v);
-#endif
}
QDebug operator<<(QDebug dbg, const QVariant::Type p)
{
-#ifndef Q_BROKEN_DEBUG_STREAM
dbg.nospace() << "QVariant::" << QMetaType::typeName(p);
return dbg.space();
-#else
- qWarning("This compiler doesn't support streaming QVariant::Type to QDebug");
- return dbg;
- Q_UNUSED(p);
-#endif
}
#endif