diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-09-18 15:27:38 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2023-06-02 22:31:36 +0200 |
commit | 79ae79d05c65019233cf9ae9e77ef59d90e75ac2 (patch) | |
tree | 417e8dcfed1af2c78a9de0daaa8e059afce2590c /tests/auto/corelib/kernel/qvariant | |
parent | 581c4bcb62a9d3cbb4c33df3f0f7a0a965225e74 (diff) |
QVariant::fromValue: Add rvalue optimization
When passing an rvalue-reference to QVariant, there is no reason to make
a copy if the type is moveable. Moreover, we know that the pointer which
we construct from the object passed to fromValue non-null. We make use
of both facts by parametrizing custom_construct on
non-nullness and availability of a move-ctor, and then dispatching to
the suitable template.
We need to keep the const T& overload, as otherwise code which
explicitly specializes fromValue and passes a const lvalue to it would
stop to compile.
[ChangeLog][QtCore][QVariant] Added fromValue() overload taking rvalues.
Change-Id: I44fb757d516ef364fe7967bc103b3f98278b4919
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/corelib/kernel/qvariant')
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index feb03a029f..addf7ceec9 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -5573,6 +5573,16 @@ void tst_QVariant::mutableView() QCOMPARE(extracted.text, nullptr); } +struct MoveTester +{ + bool wasMoved = false; + MoveTester() = default; + MoveTester(const MoveTester &) {}; // non-trivial on purpose + MoveTester(MoveTester &&other) { other.wasMoved = true; } + MoveTester& operator=(const MoveTester &) = default; + MoveTester& operator=(MoveTester &&other) {other.wasMoved = true; return *this;} +}; + void tst_QVariant::moveOperations() { { @@ -5594,6 +5604,19 @@ void tst_QVariant::moveOperations() v = QVariant::fromValue(list); v2 = std::move(v); QVERIFY(v2.value<std::list<int>>() == list); + + { + MoveTester tester; + QVariant::fromValue(tester); + QVERIFY(!tester.wasMoved); + QVariant::fromValue(std::move(tester)); + QVERIFY(tester.wasMoved); + } + { + const MoveTester tester; + QVariant::fromValue(std::move(tester)); + QVERIFY(!tester.wasMoved); // we don't want to move from const variables + } } class NoMetaObject : public QObject {}; |