summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-06-06 00:27:44 +0200
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-07-13 01:32:53 +0200
commit43fa292ff621550d0977908b499fb54096251825 (patch)
tree7f4f06e5dc4f70dc01080ac2b78a4c617172c1b5
parent23444d4b26a13677a2029a2b5a53bfae76647b71 (diff)
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>
-rw-r--r--src/corelib/kernel/qvariant.cpp14
-rw-r--r--src/corelib/kernel/qvariant.h42
-rw-r--r--src/gui/text/qtextformat.cpp2
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp8
5 files changed, 41 insertions, 27 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index f4d4dafe6b..8a34806c60 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -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}.
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index b5e9deedf0..87fb16485f 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -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);
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 58c318bcbf..d12f7e152d 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -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;
}
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 9920c8812d..344b020956 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -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());
}
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
index 1c311a27ea..aa08f1c44d 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -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);