diff options
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 99 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.h | 17 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant_p.h | 43 |
3 files changed, 76 insertions, 83 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index ea66658..b4427c0 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -71,6 +71,27 @@ QT_BEGIN_NAMESPACE # define FLT_DIG 6 #endif + +static const void *constDataHelper(const QVariant::Private &d) +{ + switch (d.type) { + case QVariant::Int: + return &d.data.i; + case QVariant::UInt: + return &d.data.u; + case QVariant::Bool: + return &d.data.b; + case QVariant::LongLong: + return &d.data.ll; + case QVariant::ULongLong: + return &d.data.ull; + case QVariant::Double: + return &d.data.d; + default: + return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr); + } +} + static void construct(QVariant::Private *x, const void *copy) { x->is_shared = false; @@ -158,9 +179,6 @@ static void construct(QVariant::Private *x, const void *copy) case QVariant::Double: x->data.d = copy ? *static_cast<const double*>(copy) : 0.0; break; - case QMetaType::Float: - x->data.f = copy ? *static_cast<const float*>(copy) : 0.0f; - break; case QVariant::LongLong: x->data.ll = copy ? *static_cast<const qlonglong *>(copy) : Q_INT64_C(0); break; @@ -256,7 +274,6 @@ static void clear(QVariant::Private *d) case QVariant::LongLong: case QVariant::ULongLong: case QVariant::Double: - case QMetaType::Float: break; case QVariant::Invalid: case QVariant::UserType: @@ -474,7 +491,7 @@ static qlonglong qMetaTypeNumber(const QVariant::Private *d) case QMetaType::Long: return qlonglong(*static_cast<long *>(d->data.shared->ptr)); case QMetaType::Float: - return qRound64(d->data.f); + return qRound64(*static_cast<float *>(d->data.shared->ptr)); case QVariant::Double: return qRound64(d->data.d); } @@ -611,7 +628,7 @@ static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, *str = QString::number(qMetaTypeUNumber(d)); break; case QMetaType::Float: - *str = QString::number(d->data.f, 'g', FLT_DIG); + *str = QString::number(*static_cast<float *>(d->data.shared->ptr), 'g', FLT_DIG); break; case QVariant::Double: *str = QString::number(d->data.d, 'g', DBL_DIG); @@ -782,7 +799,7 @@ static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, *ba = QByteArray::number(d->data.d, 'g', DBL_DIG); break; case QMetaType::Float: - *ba = QByteArray::number(d->data.f, 'g', FLT_DIG); + *ba = QByteArray::number(*static_cast<float *>(d->data.shared->ptr), 'g', FLT_DIG); break; case QMetaType::Char: case QMetaType::UChar: @@ -884,7 +901,7 @@ static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, *f = double(d->data.b); break; case QMetaType::Float: - *f = double(d->data.f); + *f = *static_cast<float *>(d->data.shared->ptr); break; case QVariant::LongLong: case QVariant::Int: @@ -1338,7 +1355,7 @@ void QVariant::create(int type, const void *copy) QVariant::~QVariant() { - if (d.type > Char && d.type != QMetaType::Float && (!d.is_shared || !d.data.shared->ref.deref())) + if (d.type > Char && (!d.is_shared || !d.data.shared->ref.deref())) handler->clear(&d); } @@ -1354,7 +1371,7 @@ QVariant::QVariant(const QVariant &p) { if (d.is_shared) { d.data.shared->ref.ref(); - } else if (p.d.type > Char && p.d.type != QMetaType::Float) { + } else if (p.d.type > Char) { handler->construct(&d, p.constData()); d.is_null = p.d.is_null; } @@ -1548,12 +1565,6 @@ QVariant::QVariant(const char *val) */ /*! - \fn QVariant::QVariant(float val) - - Constructs a new variant with a floating point value, \a val. -*/ - -/*! \fn QVariant::QVariant(const QList<QVariant> &val) Constructs a new variant with a list value, \a val. @@ -1608,44 +1619,44 @@ QVariant::QVariant(double val) { d.is_null = false; d.type = Double; d.data.d = val; } QVariant::QVariant(const QByteArray &val) -{ d.is_null = false; d.type = ByteArray; v_construct<QByteArray>(&d, val); } +{ create(ByteArray, &val); } QVariant::QVariant(const QBitArray &val) -{ d.is_null = false; d.type = BitArray; v_construct<QBitArray>(&d, val); } +{ create(BitArray, &val); } QVariant::QVariant(const QString &val) -{ d.is_null = false; d.type = String; v_construct<QString>(&d, val); } +{ create(String, &val); } QVariant::QVariant(const QChar &val) -{ d.is_null = false; d.type = Char; v_construct<QChar>(&d, val); } +{ create (Char, &val); } QVariant::QVariant(const QLatin1String &val) -{ QString str(val); d.is_null = false; d.type = String; v_construct<QString>(&d, str); } +{ QString str(val); create(String, &str); } QVariant::QVariant(const QStringList &val) -{ d.is_null = false; d.type = StringList; v_construct<QStringList>(&d, val); } +{ create(StringList, &val); } QVariant::QVariant(const QDate &val) -{ d.is_null = false; d.type = Date; v_construct<QDate>(&d, val); } +{ create(Date, &val); } QVariant::QVariant(const QTime &val) -{ d.is_null = false; d.type = Time; v_construct<QTime>(&d, val); } +{ create(Time, &val); } QVariant::QVariant(const QDateTime &val) -{ d.is_null = false; d.type = DateTime; v_construct<QDateTime>(&d, val); } +{ create(DateTime, &val); } QVariant::QVariant(const QList<QVariant> &list) -{ d.is_null = false; d.type = List; v_construct<QVariantList>(&d, list); } +{ create(List, &list); } QVariant::QVariant(const QMap<QString, QVariant> &map) -{ d.is_null = false; d.type = Map; v_construct<QVariantMap>(&d, map); } +{ create(Map, &map); } QVariant::QVariant(const QHash<QString, QVariant> &hash) -{ d.is_null = false; d.type = Hash; v_construct<QVariantHash>(&d, hash); } +{ create(Hash, &hash); } #ifndef QT_NO_GEOM_VARIANT -QVariant::QVariant(const QPoint &pt) { d.is_null = false; d.type = Point; v_construct<QPoint>(&d, pt); } -QVariant::QVariant(const QPointF &pt) { d.is_null = false; d.type = PointF; v_construct<QPointF>(&d, pt); } -QVariant::QVariant(const QRectF &r) { d.is_null = false; d.type = RectF; v_construct<QRectF>(&d, r); } -QVariant::QVariant(const QLineF &l) { d.is_null = false; d.type = LineF; v_construct<QLineF>(&d, l); } -QVariant::QVariant(const QLine &l) { d.is_null = false; d.type = Line; v_construct<QLine>(&d, l); } -QVariant::QVariant(const QRect &r) { d.is_null = false; d.type = Rect; v_construct<QRect>(&d, r); } -QVariant::QVariant(const QSize &s) { d.is_null = false; d.type = Size; v_construct<QSize>(&d, s); } -QVariant::QVariant(const QSizeF &s) { d.is_null = false; d.type = SizeF; v_construct<QSizeF>(&d, s); } +QVariant::QVariant(const QPoint &pt) { create(Point, &pt); } +QVariant::QVariant(const QPointF &pt) { create (PointF, &pt); } +QVariant::QVariant(const QRectF &r) { create (RectF, &r); } +QVariant::QVariant(const QLineF &l) { create (LineF, &l); } +QVariant::QVariant(const QLine &l) { create (Line, &l); } +QVariant::QVariant(const QRect &r) { create(Rect, &r); } +QVariant::QVariant(const QSize &s) { create(Size, &s); } +QVariant::QVariant(const QSizeF &s) { create(SizeF, &s); } #endif -QVariant::QVariant(const QUrl &u) { d.is_null = false; d.type = Url; v_construct<QUrl>(&d, u); } -QVariant::QVariant(const QLocale &l) { d.is_null = false; d.type = Locale; v_construct<QLocale>(&d, l); } +QVariant::QVariant(const QUrl &u) { create(Url, &u); } +QVariant::QVariant(const QLocale &l) { create(Locale, &l); } #ifndef QT_NO_REGEXP -QVariant::QVariant(const QRegExp ®Exp) { d.is_null = false; d.type = RegExp; v_construct<QRegExp>(&d, regExp); } +QVariant::QVariant(const QRegExp ®Exp) { create(RegExp, ®Exp); } #endif QVariant::QVariant(Qt::GlobalColor color) { create(62, &color); } @@ -1710,7 +1721,7 @@ QVariant& QVariant::operator=(const QVariant &variant) if (variant.d.is_shared) { variant.d.data.shared->ref.ref(); d = variant.d; - } else if (variant.d.type > Char && variant.d.type != QMetaType::Float) { + } else if (variant.d.type > Char) { d.type = variant.d.type; handler->construct(&d, variant.constData()); d.is_null = variant.d.is_null; @@ -1896,7 +1907,7 @@ void QVariant::load(QDataStream &s) } // const cast is safe since we operate on a newly constructed variant - if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) { + if (!QMetaType::load(s, d.type, const_cast<void *>(constDataHelper(d)))) { s.setStatus(QDataStream::ReadCorruptData); qWarning("QVariant::load: unable to load type %d.", d.type); } @@ -1936,7 +1947,7 @@ void QVariant::save(QDataStream &s) const return; } - if (!QMetaType::save(s, d.type, constData())) { + if (!QMetaType::save(s, d.type, constDataHelper(d))) { Q_ASSERT_X(false, "QVariant::save", "Invalid type to save"); qWarning("QVariant::save: unable to save type %d.", d.type); } @@ -2715,7 +2726,7 @@ bool QVariant::cmp(const QVariant &v) const const void *QVariant::constData() const { - return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr); + return constDataHelper(d); } /*! @@ -2728,7 +2739,7 @@ const void *QVariant::constData() const void* QVariant::data() { detach(); - return const_cast<void *>(constData()); + return const_cast<void *>(constDataHelper(d)); } diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index d73fcbc..580b101 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -128,7 +128,7 @@ class Q_CORE_EXPORT QVariant LineF = 24, Point = 25, PointF = 26, - RegExp = 27, + RegExp = 27, Hash = 28, LastCoreType = Hash, @@ -181,7 +181,6 @@ class Q_CORE_EXPORT QVariant QVariant(qulonglong ull); QVariant(bool b); QVariant(double d); - QVariant(float f) { d.is_null = false; d.type = QMetaType::Float; d.data.f = f; } #ifndef QT_NO_CAST_FROM_ASCII QT_ASCII_CAST_WARN_CONSTRUCTOR QVariant(const char *str); #endif @@ -350,7 +349,6 @@ class Q_CORE_EXPORT QVariant uint u; bool b; double d; - float f; qlonglong ll; qulonglong ull; void *ptr; @@ -445,18 +443,7 @@ inline QVariant qVariantFromValue(const QVariant &t) { return t; } template <typename T> inline void qVariantSetValue(QVariant &v, const T &t) { - //if possible we reuse the current QVariant private - const int type = qMetaTypeId<T>(reinterpret_cast<T *>(0)); - QVariant::Private &d = v.data_ptr(); - if (type <= int(QVariant::Char) || (type == d.type && v.isDetached())) { - d.type = type; - T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr); - if (QTypeInfo<T>::isComplex) - old->~T(); - new (old) T(t); //call the copy constructor - } else { - v = QVariant(type, &t); - } + v = QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t); } inline QVariant::QVariant() {} diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index 074575b..0764fe3 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE +extern Q_CORE_EXPORT const QVariant::Handler *qExtendedVariantHandler; + #ifdef Q_CC_SUN // Sun CC picks the wrong overload, so introduce awful hack template <typename T> @@ -68,7 +70,7 @@ inline T *v_cast(const QVariant::Private *nd, T * = 0) QVariant::Private *d = const_cast<QVariant::Private *>(nd); return ((sizeof(T) > sizeof(QVariant::Private::Data)) ? static_cast<T *>(d->data.shared->ptr) - : static_cast<T *>(static_cast<void *>(&d->data.c))); + : reinterpret_cast<T*>(&d->data.c)); } #else // every other compiler in this world @@ -78,7 +80,7 @@ inline const T *v_cast(const QVariant::Private *d, T * = 0) { return ((sizeof(T) > sizeof(QVariant::Private::Data)) ? static_cast<const T *>(d->data.shared->ptr) - : static_cast<const T *>(static_cast<const void *>(&d->data.c))); + : reinterpret_cast<const T *>(&d->data.c)); } template <typename T> @@ -86,17 +88,15 @@ inline T *v_cast(QVariant::Private *d, T * = 0) { return ((sizeof(T) > sizeof(QVariant::Private::Data)) ? static_cast<T *>(d->data.shared->ptr) - : static_cast<T *>(static_cast<void *>(&d->data.c))); + : reinterpret_cast<T *>(&d->data.c)); } #endif - -//a simple template that avoids to allocate 2 memory chunks when creating a QVariant +//a simple template that avoids to allocate 2 buffers when creating a QVariant template <class T> class QVariantPrivateSharedEx : public QVariant::PrivateShared { public: - QVariantPrivateSharedEx() : QVariant::PrivateShared(&m_t) { } QVariantPrivateSharedEx(const T&t) : QVariant::PrivateShared(&m_t), m_t(t) { } private: @@ -105,12 +105,14 @@ private: // constructs a new variant if copy is 0, otherwise copy-constructs template <class T> -inline void v_construct(QVariant::Private *x, const T &t) +inline void v_construct(QVariant::Private *x, const T& t) { + x->type = qMetaTypeId<T>(reinterpret_cast<T *>(0)); if (sizeof(T) > sizeof(QVariant::Private::Data)) { x->data.shared = new QVariantPrivateSharedEx<T>(t); x->is_shared = true; } else { + x->is_shared = false; new (&x->data.ptr) T(t); } } @@ -118,31 +120,24 @@ inline void v_construct(QVariant::Private *x, const T &t) template <class T> inline void v_construct(QVariant::Private *x, const void *copy, T * = 0) { - if (sizeof(T) > sizeof(QVariant::Private::Data)) { - x->data.shared = copy ? new QVariantPrivateSharedEx<T>(*static_cast<const T *>(copy)) - : new QVariantPrivateSharedEx<T>; - x->is_shared = true; + if (copy) { + v_construct<T>(x, *reinterpret_cast<const T*>(copy)); } else { - if (copy) - new (&x->data.ptr) T(*static_cast<const T *>(copy)); - else - new (&x->data.ptr) T; + T t; + v_construct<T>(x, t); } } + // deletes the internal structures template <class T> inline void v_clear(QVariant::Private *d, T* = 0) { - - if (sizeof(T) > sizeof(QVariant::Private::Data)) { - //now we need to cast - //because QVariant::PrivateShared doesn't have a virtual destructor - delete static_cast<QVariantPrivateSharedEx<T>*>(d->data.shared); - } else { - v_cast<T>(d)->~T(); - } - + //now we need to call the destructor in any case + //because QVariant::PrivateShared doesn't have a virtual destructor + v_cast<T>(d)->~T(); + if (sizeof(T) > sizeof(QVariant::Private::Data)) + delete d->data.shared; } QT_END_NAMESPACE |