Clean up QVariant::Private::Data
Remove all the internal members of the union. Instead replace it with raw storage (uchar[]) aligned to max_align_t. Place all accesses to the internal members with get<> methods for consistency. Change-Id: Icebf46b90c9375aa6ea0b5913b2132608e8c223d Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
This commit is contained in:
parent
bfbac6be75
commit
524edc7363
@ -107,21 +107,21 @@ static qlonglong qMetaTypeNumber(const QVariant::Private *d)
|
||||
{
|
||||
switch (d->type().id()) {
|
||||
case QMetaType::Int:
|
||||
return d->data.i;
|
||||
return d->get<int>();
|
||||
case QMetaType::LongLong:
|
||||
return d->data.ll;
|
||||
return d->get<qlonglong>();
|
||||
case QMetaType::Char:
|
||||
return qlonglong(d->data.c);
|
||||
return qlonglong(d->get<char>());
|
||||
case QMetaType::SChar:
|
||||
return qlonglong(d->data.sc);
|
||||
return qlonglong(d->get<signed char>());
|
||||
case QMetaType::Short:
|
||||
return qlonglong(d->data.s);
|
||||
return qlonglong(d->get<short>());
|
||||
case QMetaType::Long:
|
||||
return qlonglong(d->data.l);
|
||||
return qlonglong(d->get<long>());
|
||||
case QMetaType::Float:
|
||||
return qRound64(d->data.f);
|
||||
return qRound64(d->get<float>());
|
||||
case QMetaType::Double:
|
||||
return qRound64(d->data.d);
|
||||
return qRound64(d->get<double>());
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
case QMetaType::QJsonValue:
|
||||
return d->get<QJsonValue>().toDouble();
|
||||
@ -137,15 +137,15 @@ static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
|
||||
{
|
||||
switch (d->type().id()) {
|
||||
case QMetaType::UInt:
|
||||
return d->data.u;
|
||||
return d->get<unsigned int>();
|
||||
case QMetaType::ULongLong:
|
||||
return d->data.ull;
|
||||
return d->get<qulonglong>();
|
||||
case QMetaType::UChar:
|
||||
return d->data.uc;
|
||||
return d->get<unsigned char>();
|
||||
case QMetaType::UShort:
|
||||
return d->data.us;
|
||||
return d->get<unsigned short>();
|
||||
case QMetaType::ULong:
|
||||
return d->data.ul;
|
||||
return d->get<unsigned long>();
|
||||
}
|
||||
Q_ASSERT(false);
|
||||
return 0;
|
||||
@ -178,7 +178,7 @@ static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok, bool all
|
||||
case QMetaType::QByteArray:
|
||||
return d->get<QByteArray>().toLongLong(ok);
|
||||
case QMetaType::Bool:
|
||||
return qlonglong(d->data.b);
|
||||
return qlonglong(d->get<bool>());
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
case QMetaType::QCborValue:
|
||||
if (!d->get<QCborValue>().isInteger() && !d->get<QCborValue>().isDouble())
|
||||
@ -212,13 +212,13 @@ static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok, bool all
|
||||
|| d->type().id() == QMetaType::QCborSimpleType) {
|
||||
switch (typeInfo.sizeOf()) {
|
||||
case 1:
|
||||
return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->data()) : d->data.sc;
|
||||
return d->get<signed char>();
|
||||
case 2:
|
||||
return d->is_shared ? *reinterpret_cast<qint16 *>(d->data.shared->data()) : d->data.s;
|
||||
return d->get<short>();
|
||||
case 4:
|
||||
return d->is_shared ? *reinterpret_cast<qint32 *>(d->data.shared->data()) : d->data.i;
|
||||
return d->get<int>();
|
||||
case 8:
|
||||
return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->data()) : d->data.ll;
|
||||
return d->get<qlonglong>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,9 +233,9 @@ static qreal qConvertToRealNumber(const QVariant::Private *d, bool *ok)
|
||||
case QMetaType::QString:
|
||||
return d->get<QString>().toDouble(ok);
|
||||
case QMetaType::Double:
|
||||
return qreal(d->data.d);
|
||||
return qreal(d->get<double>());
|
||||
case QMetaType::Float:
|
||||
return qreal(d->data.f);
|
||||
return qreal(d->get<float>());
|
||||
case QMetaType::ULongLong:
|
||||
case QMetaType::UInt:
|
||||
case QMetaType::UChar:
|
||||
@ -266,7 +266,7 @@ static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
|
||||
case QMetaType::QByteArray:
|
||||
return d->get<QByteArray>().toULongLong(ok);
|
||||
case QMetaType::Bool:
|
||||
return qulonglong(d->data.b);
|
||||
return qulonglong(d->get<bool>());
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
case QMetaType::QCborValue:
|
||||
if (d->get<QCborValue>().isDouble())
|
||||
@ -300,13 +300,13 @@ static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
|
||||
if (typeInfo.flags() & QMetaType::IsEnumeration) {
|
||||
switch (typeInfo.sizeOf()) {
|
||||
case 1:
|
||||
return d->is_shared ? *reinterpret_cast<uchar *>(d->data.shared->data()) : d->data.uc;
|
||||
return d->get<unsigned char>();
|
||||
case 2:
|
||||
return d->is_shared ? *reinterpret_cast<quint16 *>(d->data.shared->data()) : d->data.us;
|
||||
return d->get<unsigned short>();
|
||||
case 4:
|
||||
return d->is_shared ? *reinterpret_cast<quint32 *>(d->data.shared->data()) : d->data.u;
|
||||
return d->get<unsigned int>();
|
||||
case 8:
|
||||
return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->data()) : d->data.ull;
|
||||
return d->get<qulonglong>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,16 +321,6 @@ inline bool qt_convertToBool(const QVariant::Private *const d)
|
||||
return !(str.isEmpty() || str == LiteralWrapper("0") || str == LiteralWrapper("false"));
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Returns the internal data pointer from \a d.
|
||||
*/
|
||||
|
||||
static const void *constData(const QVariant::Private &d)
|
||||
{
|
||||
return d.is_shared ? d.data.shared->data() : reinterpret_cast<const void *>(&d.data.c);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_QOBJECT
|
||||
/*!
|
||||
\internal
|
||||
@ -361,7 +351,7 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
Q_ASSERT(result);
|
||||
|
||||
if (d->type().id() >= QMetaType::LastCoreType || t >= QMetaType::LastCoreType) {
|
||||
if (QMetaType::convert(constData(*d), d->type().id(), result, t))
|
||||
if (QMetaType::convert(d->storage(), d->type().id(), result, t))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -414,7 +404,7 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
case QMetaType::Char:
|
||||
case QMetaType::SChar:
|
||||
case QMetaType::UChar:
|
||||
*str = QChar::fromLatin1(d->data.c);
|
||||
*str = QChar::fromLatin1(d->get<char>());
|
||||
break;
|
||||
case QMetaType::Short:
|
||||
case QMetaType::Long:
|
||||
@ -429,10 +419,10 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
*str = QString::number(qMetaTypeUNumber(d));
|
||||
break;
|
||||
case QMetaType::Float:
|
||||
*str = QString::number(d->data.f, 'g', QLocale::FloatingPointShortest);
|
||||
*str = QString::number(d->get<float>(), 'g', QLocale::FloatingPointShortest);
|
||||
break;
|
||||
case QMetaType::Double:
|
||||
*str = QString::number(d->data.d, 'g', QLocale::FloatingPointShortest);
|
||||
*str = QString::number(d->get<double>(), 'g', QLocale::FloatingPointShortest);
|
||||
break;
|
||||
#if QT_CONFIG(datestring)
|
||||
case QMetaType::QDate:
|
||||
@ -446,7 +436,7 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
break;
|
||||
#endif
|
||||
case QMetaType::Bool:
|
||||
*str = d->data.b ? QStringLiteral("true") : QStringLiteral("false");
|
||||
*str = d->get<bool>() ? QStringLiteral("true") : QStringLiteral("false");
|
||||
break;
|
||||
case QMetaType::QByteArray:
|
||||
*str = QString::fromUtf8(d->get<QByteArray>().constData());
|
||||
@ -639,15 +629,15 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
*ba = d->get<QString>().toUtf8();
|
||||
break;
|
||||
case QMetaType::Double:
|
||||
*ba = QByteArray::number(d->data.d, 'g', QLocale::FloatingPointShortest);
|
||||
*ba = QByteArray::number(d->get<double>(), 'g', QLocale::FloatingPointShortest);
|
||||
break;
|
||||
case QMetaType::Float:
|
||||
*ba = QByteArray::number(d->data.f, 'g', QLocale::FloatingPointShortest);
|
||||
*ba = QByteArray::number(d->get<float>(), 'g', QLocale::FloatingPointShortest);
|
||||
break;
|
||||
case QMetaType::Char:
|
||||
case QMetaType::SChar:
|
||||
case QMetaType::UChar:
|
||||
*ba = QByteArray(1, d->data.c);
|
||||
*ba = QByteArray(1, d->get<char>());
|
||||
break;
|
||||
case QMetaType::Int:
|
||||
case QMetaType::LongLong:
|
||||
@ -662,7 +652,7 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
*ba = QByteArray::number(qMetaTypeUNumber(d));
|
||||
break;
|
||||
case QMetaType::Bool:
|
||||
*ba = QByteArray(d->data.b ? "true" : "false");
|
||||
*ba = QByteArray(d->get<bool>() ? "true" : "false");
|
||||
break;
|
||||
case QMetaType::QUuid:
|
||||
*ba = d->get<QUuid>().toByteArray();
|
||||
@ -783,10 +773,10 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
*f = d->get<QByteArray>().toDouble(&ok);
|
||||
return ok;
|
||||
case QMetaType::Bool:
|
||||
*f = double(d->data.b);
|
||||
*f = double(d->get<bool>());
|
||||
break;
|
||||
case QMetaType::Float:
|
||||
*f = double(d->data.f);
|
||||
*f = double(d->get<float>());
|
||||
break;
|
||||
case QMetaType::LongLong:
|
||||
case QMetaType::Int:
|
||||
@ -831,10 +821,10 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
*f = d->get<QByteArray>().toFloat(&ok);
|
||||
return ok;
|
||||
case QMetaType::Bool:
|
||||
*f = float(d->data.b);
|
||||
*f = float(d->get<bool>());
|
||||
break;
|
||||
case QMetaType::Double:
|
||||
*f = float(d->data.d);
|
||||
*f = float(d->get<double>());
|
||||
break;
|
||||
case QMetaType::LongLong:
|
||||
case QMetaType::Int:
|
||||
@ -1023,7 +1013,7 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
*static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Null);
|
||||
break;
|
||||
case QMetaType::Bool:
|
||||
*static_cast<QJsonValue *>(result) = QJsonValue(d->data.b);
|
||||
*static_cast<QJsonValue *>(result) = QJsonValue(d->get<bool>());
|
||||
break;
|
||||
case QMetaType::Int:
|
||||
case QMetaType::UInt:
|
||||
@ -1153,7 +1143,7 @@ static bool convert(const QVariant::Private *d, int t, void *result)
|
||||
*static_cast<QCborValue *>(result) = QCborValue(QCborValue::Null);
|
||||
break;
|
||||
case QMetaType::Bool:
|
||||
*static_cast<QCborValue *>(result) = QCborValue(d->data.b);
|
||||
*static_cast<QCborValue *>(result) = QCborValue(d->get<bool>());
|
||||
break;
|
||||
case QMetaType::Int:
|
||||
case QMetaType::UInt:
|
||||
@ -1366,8 +1356,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
|
||||
return;
|
||||
}
|
||||
|
||||
// this logic should match with QVariantIntegrator::CanUseInternalSpace
|
||||
if (size <= sizeof(QVariant::Private::Data)) {
|
||||
if (QVariant::Private::canUseInternalSpace(size)) {
|
||||
type.construct(&d->data, copy);
|
||||
d->is_shared = false;
|
||||
} else {
|
||||
@ -1929,25 +1918,25 @@ QVariant::QVariant(QMetaType type, const void *copy) : d(type)
|
||||
|
||||
QVariant::QVariant(int val)
|
||||
: d(Int)
|
||||
{ d.data.i = val; }
|
||||
{ d.set(val); }
|
||||
QVariant::QVariant(uint val)
|
||||
: d(UInt)
|
||||
{ d.data.u = val; }
|
||||
{ d.set(val); }
|
||||
QVariant::QVariant(qlonglong val)
|
||||
: d(LongLong)
|
||||
{ d.data.ll = val; }
|
||||
{ d.set(val); }
|
||||
QVariant::QVariant(qulonglong val)
|
||||
: d(ULongLong)
|
||||
{ d.data.ull = val; }
|
||||
{ d.set(val); }
|
||||
QVariant::QVariant(bool val)
|
||||
: d(Bool)
|
||||
{ d.data.b = val; }
|
||||
{ d.set(val); }
|
||||
QVariant::QVariant(double val)
|
||||
: d(Double)
|
||||
{ d.data.d = val; }
|
||||
{ d.set(val); }
|
||||
QVariant::QVariant(float val)
|
||||
: d(QMetaType::Float)
|
||||
{ d.data.f = val; }
|
||||
{ d.set(val); }
|
||||
|
||||
QVariant::QVariant(const QByteArray &val)
|
||||
: d(ByteArray)
|
||||
@ -2474,7 +2463,7 @@ inline T qVariantToHelper(const QVariant::Private &d)
|
||||
|
||||
T ret;
|
||||
if (d.type().id() >= QMetaType::LastCoreType || targetType.id() >= QMetaType::LastCoreType) {
|
||||
const void * const from = constData(d);
|
||||
const void * const from = d.storage();
|
||||
if (QMetaType::convert(from, d.type().id(), &ret, targetType.id()))
|
||||
return ret;
|
||||
}
|
||||
@ -2908,7 +2897,7 @@ inline T qNumVariantToHelper(const QVariant::Private &d, bool *ok, const T& val)
|
||||
|
||||
T ret = 0;
|
||||
if ((d.type().id() >= QMetaType::LastCoreType || t >= QMetaType::LastCoreType)
|
||||
&& QMetaType::convert(constData(d), d.type().id(), &ret, t))
|
||||
&& QMetaType::convert(d.storage(), d.type().id(), &ret, t))
|
||||
return ret;
|
||||
|
||||
bool success = convert(&d, t, &ret);
|
||||
@ -2936,7 +2925,7 @@ inline T qNumVariantToHelper(const QVariant::Private &d, bool *ok, const T& val)
|
||||
*/
|
||||
int QVariant::toInt(bool *ok) const
|
||||
{
|
||||
return qNumVariantToHelper<int>(d, ok, d.data.i);
|
||||
return qNumVariantToHelper<int>(d, ok, d.get<int>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2958,7 +2947,7 @@ int QVariant::toInt(bool *ok) const
|
||||
*/
|
||||
uint QVariant::toUInt(bool *ok) const
|
||||
{
|
||||
return qNumVariantToHelper<uint>(d, ok, d.data.u);
|
||||
return qNumVariantToHelper<uint>(d, ok, d.get<unsigned int>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2975,7 +2964,7 @@ uint QVariant::toUInt(bool *ok) const
|
||||
*/
|
||||
qlonglong QVariant::toLongLong(bool *ok) const
|
||||
{
|
||||
return qNumVariantToHelper<qlonglong>(d, ok, d.data.ll);
|
||||
return qNumVariantToHelper<qlonglong>(d, ok, d.get<qlonglong>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2992,7 +2981,7 @@ qlonglong QVariant::toLongLong(bool *ok) const
|
||||
*/
|
||||
qulonglong QVariant::toULongLong(bool *ok) const
|
||||
{
|
||||
return qNumVariantToHelper<qulonglong>(d, ok, d.data.ull);
|
||||
return qNumVariantToHelper<qulonglong>(d, ok, d.get<qulonglong>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3010,7 +2999,7 @@ qulonglong QVariant::toULongLong(bool *ok) const
|
||||
bool QVariant::toBool() const
|
||||
{
|
||||
if (d.type() == QMetaType::fromType<bool>())
|
||||
return d.data.b;
|
||||
return d.get<bool>();
|
||||
|
||||
bool res = false;
|
||||
|
||||
@ -3039,7 +3028,7 @@ bool QVariant::toBool() const
|
||||
*/
|
||||
double QVariant::toDouble(bool *ok) const
|
||||
{
|
||||
return qNumVariantToHelper<double>(d, ok, d.data.d);
|
||||
return qNumVariantToHelper<double>(d, ok, d.get<double>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3058,7 +3047,7 @@ double QVariant::toDouble(bool *ok) const
|
||||
*/
|
||||
float QVariant::toFloat(bool *ok) const
|
||||
{
|
||||
return qNumVariantToHelper<float>(d, ok, d.data.f);
|
||||
return qNumVariantToHelper<float>(d, ok, d.get<float>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3077,7 +3066,7 @@ float QVariant::toFloat(bool *ok) const
|
||||
*/
|
||||
qreal QVariant::toReal(bool *ok) const
|
||||
{
|
||||
return qNumVariantToHelper<qreal>(d, ok, d.data.real);
|
||||
return qNumVariantToHelper<qreal>(d, ok, d.get<qreal>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3356,7 +3345,7 @@ bool QVariant::canConvert(int targetTypeId) const
|
||||
if (QMetaType::typeFlags(targetTypeId) & QMetaType::IsEnumeration) {
|
||||
targetTypeId = QMetaType::Int;
|
||||
} else {
|
||||
return canConvertMetaObject(currentType, targetTypeId, d.data.o);
|
||||
return canConvertMetaObject(currentType, targetTypeId, d.get<QObject *>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3504,7 +3493,7 @@ bool QVariant::canConvert(int targetTypeId) const
|
||||
&& qCanConvertMatrix[QVariant::Int] & (1U << currentType))
|
||||
|| QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
|
||||
case QMetaType::QObjectStar:
|
||||
return canConvertMetaObject(currentType, targetTypeId, d.data.o);
|
||||
return canConvertMetaObject(currentType, targetTypeId, d.get<QObject *>());
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -3553,7 +3542,7 @@ bool QVariant::convert(int targetTypeId)
|
||||
return false;
|
||||
|
||||
if ((QMetaType::typeFlags(oldValue.userType()) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {
|
||||
create(targetTypeId, &oldValue.d.data.o);
|
||||
create(targetTypeId, &oldValue.d.get<QObject *>());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3821,7 +3810,7 @@ bool QVariant::equals(const QVariant &v) const
|
||||
if (!metatype.isValid())
|
||||
return true;
|
||||
|
||||
return metatype.equals(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v.d)));
|
||||
return metatype.equals(d.storage(), v.d.storage());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3859,10 +3848,8 @@ bool QVariant::isNull() const
|
||||
{
|
||||
if (d.is_null || !metaType().isValid())
|
||||
return true;
|
||||
if (metaType().flags() & QMetaType::IsPointer) {
|
||||
const void *d_ptr = d.is_shared ? d.data.shared->data() : &(d.data);
|
||||
return *static_cast<void *const *>(d_ptr) == nullptr;
|
||||
}
|
||||
if (metaType().flags() & QMetaType::IsPointer)
|
||||
return d.get<void *>() == nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3874,7 +3861,7 @@ QDebug operator<<(QDebug dbg, const QVariant &v)
|
||||
dbg.nospace() << "QVariant(";
|
||||
if (typeId != QMetaType::UnknownType) {
|
||||
dbg << QMetaType::typeName(typeId) << ", ";
|
||||
bool streamed = v.d.type().debugStream(dbg, constData(v.d));
|
||||
bool streamed = v.d.type().debugStream(dbg, v.d.storage());
|
||||
if (!streamed && v.canConvert<QString>())
|
||||
dbg << v.toString();
|
||||
} else {
|
||||
|
@ -352,7 +352,7 @@ class Q_CORE_EXPORT QVariant
|
||||
|
||||
void *data();
|
||||
const void *constData() const
|
||||
{ return d.is_shared ? d.data.shared->data() : &d.data.ptr; }
|
||||
{ return d.storage(); }
|
||||
inline const void *data() const { return constData(); }
|
||||
|
||||
template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
|
||||
@ -442,7 +442,21 @@ class Q_CORE_EXPORT QVariant
|
||||
};
|
||||
struct Private
|
||||
{
|
||||
Private() noexcept : packedType(0), is_shared(false), is_null(true) {}
|
||||
static constexpr size_t MaxInternalSize = 3*sizeof(void *);
|
||||
template<typename T>
|
||||
static constexpr bool CanUseInternalSpace = (sizeof(T) <= MaxInternalSize);
|
||||
static constexpr bool canUseInternalSpace(size_t s) { return s <= MaxInternalSize; }
|
||||
|
||||
alignas(std::max_align_t) union
|
||||
{
|
||||
uchar data[MaxInternalSize] = {};
|
||||
PrivateShared *shared;
|
||||
} data;
|
||||
quintptr is_shared : 1;
|
||||
quintptr is_null : 1;
|
||||
quintptr packedType : sizeof(QMetaType) * 8 - 2;
|
||||
|
||||
Private() noexcept : is_shared(false), is_null(true), packedType(0) {}
|
||||
explicit Private(const QMetaType &type) noexcept : is_shared(false), is_null(false)
|
||||
{
|
||||
if (type.d_ptr)
|
||||
@ -468,45 +482,19 @@ class Q_CORE_EXPORT QVariant
|
||||
}
|
||||
Q_CORE_EXPORT ~Private();
|
||||
|
||||
union Data
|
||||
{
|
||||
void *threeptr[3] = { nullptr, nullptr, nullptr };
|
||||
char c;
|
||||
uchar uc;
|
||||
short s;
|
||||
signed char sc;
|
||||
ushort us;
|
||||
int i;
|
||||
uint u;
|
||||
long l;
|
||||
ulong ul;
|
||||
bool b;
|
||||
double d;
|
||||
float f;
|
||||
qreal real;
|
||||
qlonglong ll;
|
||||
qulonglong ull;
|
||||
QObject *o;
|
||||
void *ptr;
|
||||
PrivateShared *shared;
|
||||
} data;
|
||||
quintptr packedType : sizeof(QMetaType) * 8 - 2;
|
||||
quintptr is_shared : 1;
|
||||
quintptr is_null : 1;
|
||||
|
||||
template<typename T>
|
||||
static constexpr bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data);
|
||||
|
||||
const void *storage() const
|
||||
{ return is_shared ? data.shared->data() : &data; }
|
||||
{ return is_shared ? data.shared->data() : &data.data; }
|
||||
|
||||
const void *internalStorage() const
|
||||
{ Q_ASSERT(is_shared); return &data; }
|
||||
{ Q_ASSERT(is_shared); return &data.data; }
|
||||
|
||||
// determine internal storage at compile time
|
||||
template<typename T>
|
||||
const T &get() const
|
||||
{ return *static_cast<const T *>(CanUseInternalSpace<T> ? &data : data.shared->data()); }
|
||||
{ return *static_cast<const T *>(storage()); }
|
||||
template<typename T>
|
||||
void set(const T &t)
|
||||
{ *static_cast<T *>(CanUseInternalSpace<T> ? &data.data : data.shared->data()) = t; }
|
||||
|
||||
inline QMetaType type() const
|
||||
{
|
||||
@ -750,7 +738,7 @@ namespace QtPrivate {
|
||||
static T object(const QVariant &v)
|
||||
{
|
||||
return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject
|
||||
? v.d.data.o
|
||||
? v.d.get<QObject *>()
|
||||
: QVariantValueHelper::metaType(v));
|
||||
}
|
||||
#endif
|
||||
|
@ -91,7 +91,7 @@ struct BigClass
|
||||
{
|
||||
double n,i,e,r,o,b;
|
||||
};
|
||||
static_assert(sizeof(BigClass) > sizeof(QVariant::Private::Data));
|
||||
static_assert(sizeof(BigClass) > sizeof(QVariant::Private::MaxInternalSize));
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(BigClass, Q_MOVABLE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
@ -101,7 +101,7 @@ struct SmallClass
|
||||
{
|
||||
char s;
|
||||
};
|
||||
static_assert(sizeof(SmallClass) <= sizeof(QVariant::Private::Data));
|
||||
static_assert(sizeof(SmallClass) <= sizeof(QVariant::Private::MaxInternalSize));
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(SmallClass, Q_MOVABLE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user