QVariant::setValue(): enable move semantics
Given we optimize for the case where the new value is of the same type of the one already stored in the variant, enable move assignment for that case. As a drive-by, avoid a path to detach() for data() if we know we're detached. Change-Id: I9abbdc10637ce77ebb747b49d83e1ef914d997bb Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
23444d4b26
commit
43fa292ff6
|
|
@ -4019,7 +4019,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
|
|||
#endif
|
||||
|
||||
|
||||
/*! \fn template<typename T> void QVariant::setValue(const T &value)
|
||||
/*! \fn template<typename T> void QVariant::setValue(T &&value)
|
||||
|
||||
Stores a copy of \a value. If \c{T} is a type that QVariant
|
||||
doesn't support, QMetaType is used to store the value. A compile
|
||||
|
|
@ -4032,6 +4032,18 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
|
|||
\sa value(), fromValue(), canConvert()
|
||||
*/
|
||||
|
||||
/*! \fn template<typename T> void QVariant::setValue(const QVariant &value)
|
||||
|
||||
Copies \a value over this QVariant. It is equivalent to simply
|
||||
assigning \a value to this QVariant.
|
||||
*/
|
||||
|
||||
/*! \fn template<typename T> void QVariant::setValue(QVariant &&value)
|
||||
|
||||
Moves \a value over this QVariant. It is equivalent to simply
|
||||
move assigning \a value to this QVariant.
|
||||
*/
|
||||
|
||||
/*! \fn template<typename T> T QVariant::value() const
|
||||
|
||||
Returns the stored value converted to the template type \c{T}.
|
||||
|
|
|
|||
|
|
@ -356,8 +356,28 @@ class Q_CORE_EXPORT QVariant
|
|||
const void *constData() const;
|
||||
inline const void *data() const { return constData(); }
|
||||
|
||||
template<typename T>
|
||||
inline void setValue(const T &value);
|
||||
template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
|
||||
void setValue(T &&avalue)
|
||||
{
|
||||
using VT = std::decay_t<T>;
|
||||
QMetaType metaType = QMetaType::fromType<VT>();
|
||||
// If possible we reuse the current QVariant private.
|
||||
if (isDetached() && d.type() == metaType) {
|
||||
*reinterpret_cast<VT *>(const_cast<void *>(constData())) = std::forward<T>(avalue);
|
||||
} else {
|
||||
*this = QVariant::fromValue<VT>(std::forward<T>(avalue));
|
||||
}
|
||||
}
|
||||
|
||||
void setValue(const QVariant &avalue)
|
||||
{
|
||||
*this = avalue;
|
||||
}
|
||||
|
||||
void setValue(QVariant &&avalue)
|
||||
{
|
||||
*this = std::move(avalue);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T value() const
|
||||
|
|
@ -533,24 +553,6 @@ inline bool QVariant::isValid() const
|
|||
return d.type().isValid();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void QVariant::setValue(const T &avalue)
|
||||
{
|
||||
QMetaType metaType = QMetaType::fromType<T>();
|
||||
// If possible we reuse the current QVariant private.
|
||||
if (isDetached() && d.type() == metaType) {
|
||||
*reinterpret_cast<T *>(data()) = avalue;
|
||||
} else {
|
||||
*this = QVariant::fromValue<T>(avalue);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void QVariant::setValue(const QVariant &avalue)
|
||||
{
|
||||
*this = avalue;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
|
||||
Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p);
|
||||
|
|
|
|||
|
|
@ -2122,7 +2122,7 @@ void QTextBlockFormat::setTabPositions(const QList<QTextOption::Tab> &tabs)
|
|||
QList<QTextOption::Tab>::ConstIterator iter = tabs.constBegin();
|
||||
while (iter != tabs.constEnd()) {
|
||||
QVariant v;
|
||||
v.setValue<QTextOption::Tab>(*iter);
|
||||
v.setValue(*iter);
|
||||
list.append(v);
|
||||
++iter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ void tst_QVariant::constructor()
|
|||
QVERIFY(var7.isValid());
|
||||
QVERIFY(!var7.isNull());
|
||||
QVariant var8;
|
||||
var8.setValue<int>(5);
|
||||
var8.setValue(5);
|
||||
QVERIFY(var8.isValid());
|
||||
QVERIFY(!var8.isNull());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4499,7 +4499,7 @@ protected:
|
|||
break;
|
||||
case QGraphicsItem::ItemTransformChange: {
|
||||
QVariant variant;
|
||||
variant.setValue<QTransform>(transform());
|
||||
variant.setValue(transform());
|
||||
oldValues << variant;
|
||||
}
|
||||
break;
|
||||
|
|
@ -4616,7 +4616,7 @@ void tst_QGraphicsItem::itemChange()
|
|||
}
|
||||
{
|
||||
// ItemTransformChange / ItemTransformHasChanged
|
||||
tester.itemChangeReturnValue.setValue<QTransform>(QTransform().rotate(90));
|
||||
tester.itemChangeReturnValue.setValue(QTransform().rotate(90));
|
||||
tester.setTransform(QTransform::fromTranslate(50, 0), true);
|
||||
++changeCount; // notification sent too
|
||||
++changeCount;
|
||||
|
|
@ -4628,7 +4628,7 @@ void tst_QGraphicsItem::itemChange()
|
|||
QCOMPARE(qvariant_cast<QTransform>(tester.values.at(tester.values.size() - 1)),
|
||||
QTransform().rotate(90));
|
||||
QVariant variant;
|
||||
variant.setValue<QTransform>(QTransform());
|
||||
variant.setValue(QTransform());
|
||||
QCOMPARE(tester.oldValues.constLast(), variant);
|
||||
QCOMPARE(tester.transform(), QTransform().rotate(90));
|
||||
}
|
||||
|
|
@ -4763,7 +4763,7 @@ void tst_QGraphicsItem::itemChange()
|
|||
}
|
||||
{
|
||||
// ItemParentChange
|
||||
tester.itemChangeReturnValue.setValue<QGraphicsItem *>(nullptr);
|
||||
tester.itemChangeReturnValue.setValue(static_cast<QGraphicsItem *>(nullptr));
|
||||
tester.setParentItem(&testerHelper);
|
||||
QCOMPARE(tester.changes.size(), ++changeCount);
|
||||
QCOMPARE(tester.changes.constLast(), QGraphicsItem::ItemParentChange);
|
||||
|
|
|
|||
Loading…
Reference in New Issue