From e5a6e9bb80fb2427228f70488b8839b4aa0b4261 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 7 Mar 2018 08:43:51 +0100 Subject: [PATCH 1/7] Doc: improve QScopedPointer::reset() documentation - Fix grammar - Mention take() Change-Id: I3bde229755549230ad3d0962da6eeb164a060fb1 Reviewed-by: Andy Shaw --- src/corelib/tools/qscopedpointer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 6c24e19bfaa..769a18f9e01 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -250,9 +250,12 @@ QT_BEGIN_NAMESPACE /*! \fn template void QScopedPointer::reset(T *other = 0) - Deletes the existing object it is pointing to if any, and sets its pointer to + Deletes the existing object it is pointing to (if any), and sets its pointer to \a other. QScopedPointer now owns \a other and will delete it in its destructor. + + To clear the pointer held without deleting the object it points to (and hence take ownership + of the object), use \l take() instead. */ /*! From c082d84d5d7fdbfb64de18f06a8ddbc77f2e6de4 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Fri, 2 Mar 2018 18:36:20 +0000 Subject: [PATCH 2/7] Fix QLabel crash if buddy's lifetime is too short If buddy is deleted then QLabel will still try to deliver the shortcut event to it, in QLabel::event(), and cras. Besides connecting to destroyed() which alone fixes the crash, also hardened it and guarded against dereferencing null buddy, in the unlikely event of someone adding features to QLabel. The second part is suitable for backporting to the LTS branches. Task-Id: QTBUG-66841 Change-Id: Ib6a36a9f99cee31afe1f88eb77f5b6cafb8b1086 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qlabel.cpp | 19 ++++++++++++++++++- src/widgets/widgets/qlabel.h | 3 +++ src/widgets/widgets/qlabel_p.h | 1 + .../widgets/widgets/qlabel/tst_qlabel.cpp | 12 ++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index ee4825d3e51..046acfeea94 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -963,7 +963,9 @@ bool QLabel::event(QEvent *e) if (type == QEvent::Shortcut) { QShortcutEvent *se = static_cast(e); if (se->shortcutId() == d->shortcutId) { - QWidget * w = d->buddy; + QWidget *w = d->buddy; + if (!w) + return QFrame::event(e); if (w->focusPolicy() != Qt::NoFocus) w->setFocus(Qt::ShortcutFocusReason); #if QT_CONFIG(abstractbutton) @@ -1163,7 +1165,15 @@ void QLabelPrivate::updateLabel() void QLabel::setBuddy(QWidget *buddy) { Q_D(QLabel); + + if (d->buddy) + disconnect(d->buddy, SIGNAL(destroyed()), this, SLOT(_q_buddyDeleted())); + d->buddy = buddy; + + if (buddy) + connect(buddy, SIGNAL(destroyed()), this, SLOT(_q_buddyDeleted())); + if (d->isTextLabel) { if (d->shortcutId) releaseShortcut(d->shortcutId); @@ -1204,6 +1214,13 @@ void QLabelPrivate::updateShortcut() shortcutId = q->grabShortcut(QKeySequence::mnemonic(text)); } + +void QLabelPrivate::_q_buddyDeleted() +{ + Q_Q(QLabel); + q->setBuddy(nullptr); +} + #endif // QT_NO_SHORTCUT #if QT_CONFIG(movie) diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h index e1cc333a1c8..2f5db5a7d3e 100644 --- a/src/widgets/widgets/qlabel.h +++ b/src/widgets/widgets/qlabel.h @@ -158,6 +158,9 @@ private: #endif Q_PRIVATE_SLOT(d_func(), void _q_linkHovered(const QString &)) +#ifndef QT_NO_SHORTCUT + Q_PRIVATE_SLOT(d_func(), void _q_buddyDeleted()) +#endif friend class QTipLabel; friend class QMessageBoxPrivate; friend class QBalloonTip; diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index e05a5b5c359..59188563a95 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -89,6 +89,7 @@ public: #endif #ifndef QT_NO_SHORTCUT void updateShortcut(); + void _q_buddyDeleted(); #endif inline bool needTextControl() const { return isTextLabel diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp index 500ec2e1fa8..84071962bca 100644 --- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp +++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp @@ -178,9 +178,11 @@ void tst_QLabel::setBuddy() test_label= new QLabel( test_box ); test_label->setText( "&Test with a buddy" ); QWidget *test_edit = new QLineEdit( test_box ); + QWidget *test_edit2 = new QLineEdit( test_box ); QVBoxLayout *layout = new QVBoxLayout(test_box); layout->addWidget(test_label); layout->addWidget(test_edit); + layout->addWidget(test_edit2); test_box->show(); qApp->setActiveWindow(test_box); QVERIFY(test_box->isActiveWindow()); @@ -190,6 +192,16 @@ void tst_QLabel::setBuddy() QVERIFY( !test_edit->hasFocus() ); QTest::keyClick( test_box, 't', Qt::AltModifier ); QVERIFY( test_edit->hasFocus() ); + + // Setting a new buddy should disconnect the old one's destroyed() signal + test_label->setBuddy(test_edit2); + delete test_edit; + QCOMPARE(test_label->buddy(), test_edit2); + + // And deleting our own buddy should disconnect and not crash + delete test_edit2; + QTest::keyClick(test_box, 't', Qt::AltModifier ); + delete test_box; } #endif From 4d204854745f6682d9937b8c13a429890e5bc738 Mon Sep 17 00:00:00 2001 From: Alexander Shevchenko Date: Thu, 8 Mar 2018 22:15:13 +0200 Subject: [PATCH 3/7] set attribute specifier before namespace name That is correct C++. GCC (and apparently Clang) accept it after the name for compatibility with the old __attribute__ syntax. Change-Id: Ie7f3adaaed83198ca1c61bc0efdf51634e457b07 Reviewed-by: Thiago Macieira --- tests/auto/other/compiler/tst_compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index 0410856790e..b2b45bb2377 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -693,7 +693,7 @@ QT_WARNING_DISABLE_GCC("-Wunused-local-typedefs") [[noreturn]] void attribute_f1(); void attribute_f2 [[noreturn]] (); # if (defined(__cpp_namespace_attributes) && __cpp_namespace_attributes >= 201411) && __has_cpp_attribute(deprecated) -namespace NS [[deprecated]] { } +namespace [[deprecated]] NS { } # endif #endif From 9b7809a43ee0add8c11d3387b73a01bfdedd0043 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 6 Mar 2018 18:05:02 +0300 Subject: [PATCH 4/7] xcb: Fix FP1616 to int conversion Divide the whole FP1616 value by 0x10000 instead of dividing the integer part by 0x10000 and the fractional part by 0xFFFF. It also makes fixed1616ToInt() consistent with fixed1616ToReal(), see 7d3f353a5bd573dc0e72f7f55c70212a6b3837fa. Change-Id: Id76025028c926872b002ef0a1ca8a8bdc2de3e1e Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e9a6e536a75..fed096f3114 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2333,7 +2333,7 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) #if QT_CONFIG(xinput2) static inline int fixed1616ToInt(FP1616 val) { - return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); + return int(qreal(val) / 0x10000); } void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source) From b767c7363f7ceda88553fb8abb6d4cb70b70bd2f Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 8 Mar 2018 13:23:52 +0100 Subject: [PATCH 5/7] qxcbconnection_xi2.cpp: fix debug check to avoid confusing debug output The check on line 972 says lcQpaXInputEvents().isDebugEnabled() so that debug output was always showing "from 0,0" due to lastScrollPosition not being set. Change-Id: I345732e36db05108f70474261c47e78333b57d30 Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 39d2857212a..0302d585b5e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -956,7 +956,7 @@ void QXcbConnection::xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice) return; } QPointF lastScrollPosition; - if (lcQpaXInput().isDebugEnabled()) + if (lcQpaXInputEvents().isDebugEnabled()) lastScrollPosition = scrollingDevice.lastScrollPosition; for (int c = 0; c < deviceInfo->num_classes; ++c) { XIAnyClassInfo *classInfo = deviceInfo->classes[c]; From fee8944cbe2a976e1b4a71c5df048e84a0bc6db0 Mon Sep 17 00:00:00 2001 From: Nils Jeisecke Date: Fri, 2 Mar 2018 16:57:11 +0100 Subject: [PATCH 6/7] Allow use of template class instances inheriting from a Q_GADGET in Qml The Q_GADGET macro cannot be used in templates. It can however be useful to derive a template class from a Q_GADGET enabled base class to benefit from type safety features in C++ (e.g. the class could represent an id or handle for some C++ type). For proper wrapping of a QVariant with a gadget value in a QJSValue, the QMetaType::IsGadget flag must be set for the registered template instance type - which does not happen prior to the fix because IsGadgetHelper requires qt_check_for_QGADGET_macro to be defined in the registered class but not in an ancestor class - in other words: The class must declare Q_GADGET. To overcome this, IsGadgetHelper/IsPointerToGadgetHelper can now differentiate between a Q_GADGET flagged class (allowing automatic registration) and a derived class, e.g. a template class (forcing Q_DECLARE_METATYPE to be used explicitly). [ChangeLog][QtCore][QMetaObject] It is now possible to use template class instances inheriting from a Q_GADGET in Qml Task-number: QTBUG-66744 Change-Id: I7632ad45cff79fa422b3f852ca0b963f35fab155 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qmetatype.h | 26 ++++++++++++------- .../kernel/qmetatype/tst_qmetatype.cpp | 19 ++++++++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 455d0350e01..4674efe5680 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1381,7 +1381,7 @@ namespace QtPrivate }; template - struct IsGadgetHelper { enum { Value = false }; }; + struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; template struct IsGadgetHelper @@ -1389,11 +1389,14 @@ namespace QtPrivate template static char checkType(void (X::*)()); static void *checkType(void (T::*)()); - enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + enum { + IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), + IsGadgetOrDerivedFrom = true + }; }; template - struct IsPointerToGadgetHelper { enum { Value = false }; }; + struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; template struct IsPointerToGadgetHelper @@ -1402,7 +1405,10 @@ namespace QtPrivate template static char checkType(void (X::*)()); static void *checkType(void (T::*)()); - enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + enum { + IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), + IsGadgetOrDerivedFrom = true + }; }; @@ -1435,12 +1441,12 @@ namespace QtPrivate static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template - struct MetaObjectForType::Value>::type> + struct MetaObjectForType::IsGadgetOrDerivedFrom>::type> { static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template - struct MetaObjectForType::Value>::Type> + struct MetaObjectForType::IsGadgetOrDerivedFrom>::type> { static inline const QMetaObject *value() { return &IsPointerToGadgetHelper::BaseType::staticMetaObject; } }; @@ -1599,8 +1605,8 @@ namespace QtPrivate template ::Value ? QMetaType::PointerToQObject : - QtPrivate::IsGadgetHelper::Value ? QMetaType::IsGadget : - QtPrivate::IsPointerToGadgetHelper::Value ? QMetaType::PointerToGadget : + QtPrivate::IsGadgetHelper::IsRealGadget ? QMetaType::IsGadget : + QtPrivate::IsPointerToGadgetHelper::IsRealGadget ? QMetaType::PointerToGadget : QtPrivate::IsQEnumHelper::Value ? QMetaType::IsEnumeration : 0> struct QMetaTypeIdQObject { @@ -1653,8 +1659,8 @@ namespace QtPrivate { | (IsWeakPointerToTypeDerivedFromQObject::Value ? QMetaType::WeakPointerToQObject : 0) | (IsTrackingPointerToTypeDerivedFromQObject::Value ? QMetaType::TrackingPointerToQObject : 0) | (std::is_enum::value ? QMetaType::IsEnumeration : 0) - | (IsGadgetHelper::Value ? QMetaType::IsGadget : 0) - | (IsPointerToGadgetHelper::Value ? QMetaType::PointerToGadget : 0) + | (IsGadgetHelper::IsGadgetOrDerivedFrom ? QMetaType::IsGadget : 0) + | (IsPointerToGadgetHelper::IsGadgetOrDerivedFrom ? QMetaType::PointerToGadget : 0) }; }; diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index cc628ee26e3..c6fd5d17c2d 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -141,6 +141,14 @@ public: class CustomNonQObject {}; class GadgetDerived : public CustomGadget {}; +// cannot use Q_GADGET due to moc limitations but wants to behave like +// a Q_GADGET in Qml land +template +class GadgetDerivedAndTyped : public CustomGadget {}; + +Q_DECLARE_METATYPE(GadgetDerivedAndTyped) +Q_DECLARE_METATYPE(GadgetDerivedAndTyped*) + void tst_QMetaType::defined() { QCOMPARE(int(QMetaTypeId2::Defined), 1); @@ -157,6 +165,10 @@ void tst_QMetaType::defined() QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); + + // registered with Q_DECLARE_METATYPE + QVERIFY(QMetaTypeId2>::Defined); + QVERIFY(QMetaTypeId2*>::Defined); } struct Bar @@ -396,6 +408,10 @@ void tst_QMetaType::typeName_data() QTest::newRow("CustomGadget*") << ::qMetaTypeId() << QString::fromLatin1("CustomGadget*"); QTest::newRow("CustomQObject::CustomQEnum") << ::qMetaTypeId() << QString::fromLatin1("CustomQObject::CustomQEnum"); QTest::newRow("Qt::ArrowType") << ::qMetaTypeId() << QString::fromLatin1("Qt::ArrowType"); + + // template instance class derived from Q_GADGET enabled class + QTest::newRow("GadgetDerivedAndTyped") << ::qMetaTypeId>() << QString::fromLatin1("GadgetDerivedAndTyped"); + QTest::newRow("GadgetDerivedAndTyped*") << ::qMetaTypeId*>() << QString::fromLatin1("GadgetDerivedAndTyped*"); } void tst_QMetaType::typeName() @@ -1703,6 +1719,9 @@ void tst_QMetaType::metaObject_data() QTest::newRow("MyGadget*") << ::qMetaTypeId() << &MyGadget::staticMetaObject << false << true << false; QTest::newRow("MyEnum") << ::qMetaTypeId() << &MyGadget::staticMetaObject << false << false << false; QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId() << &QObject::staticQtMetaObject << false << false << false; + + QTest::newRow("GadgetDerivedAndTyped") << ::qMetaTypeId>() << &GadgetDerivedAndTyped::staticMetaObject << true << false << false; + QTest::newRow("GadgetDerivedAndTyped*") << ::qMetaTypeId*>() << &GadgetDerivedAndTyped::staticMetaObject << false << true << false; } From 1e27219968f760501c99f9f744f172d475a57162 Mon Sep 17 00:00:00 2001 From: Eric Lemanissier Date: Fri, 9 Mar 2018 12:09:09 +0100 Subject: [PATCH 7/7] add missing tests of rvalue overloads for QVarLengthArray and QVector they were missing in dd58ddd5d97f0663d5fafb7e81bff4fc7db13ba7 Change-Id: I52a2f855ead7716f8fe887524b27d4bd258f43d3 Reviewed-by: Allan Sandfeld Jensen --- .../qvarlengtharray/tst_qvarlengtharray.cpp | 9 +++++++++ tests/auto/corelib/tools/qvector/tst_qvector.cpp | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp index ced1d08d65f..ac4c8c8d4e7 100644 --- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp +++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp @@ -966,12 +966,14 @@ void tst_QVarLengthArray::insertMove() QCOMPARE(MyBase::liveCount, 4); vec.append(std::move(m3)); + QVERIFY(m3.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); QCOMPARE(MyBase::errorCount, 0); QCOMPARE(MyBase::liveCount, 4); QCOMPARE(MyBase::movedCount, 1); vec.push_back(std::move(m4)); + QVERIFY(m4.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); QVERIFY(vec.at(1).wasConstructedAt(&m4)); QCOMPARE(MyBase::errorCount, 0); @@ -979,6 +981,7 @@ void tst_QVarLengthArray::insertMove() QCOMPARE(MyBase::movedCount, 2); vec.prepend(std::move(m1)); + QVERIFY(m1.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m3)); QVERIFY(vec.at(2).wasConstructedAt(&m4)); @@ -987,9 +990,11 @@ void tst_QVarLengthArray::insertMove() QCOMPARE(MyBase::movedCount, 3); vec.insert(1, std::move(m2)); + QVERIFY(m2.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m2)); QVERIFY(vec.at(2).wasConstructedAt(&m3)); + QVERIFY(vec.at(3).wasConstructedAt(&m4)); QCOMPARE(MyBase::copyCount, 0); QCOMPARE(MyBase::liveCount, 4); @@ -1014,15 +1019,19 @@ void tst_QVarLengthArray::nonCopyable() int *const ptr4 = val4.get(); vec.append(std::move(val3)); + QVERIFY(!val3); QVERIFY(ptr3 == vec.at(0).get()); vec.append(std::move(val4)); + QVERIFY(!val4); QVERIFY(ptr3 == vec.at(0).get()); QVERIFY(ptr4 == vec.at(1).get()); vec.prepend(std::move(val1)); + QVERIFY(!val1); QVERIFY(ptr1 == vec.at(0).get()); QVERIFY(ptr3 == vec.at(1).get()); QVERIFY(ptr4 == vec.at(2).get()); vec.insert(1, std::move(val2)); + QVERIFY(!val2); QVERIFY(ptr1 == vec.at(0).get()); QVERIFY(ptr2 == vec.at(1).get()); QVERIFY(ptr3 == vec.at(2).get()); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index ef10357b6db..600291715a3 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -2895,26 +2895,40 @@ void tst_QVector::insertMove() const const int instancesCount = Movable::counter.loadAcquire(); { QVector vec; + vec.reserve(5); + Movable m0; Movable m1; Movable m2; Movable m3; Movable m4; vec.append(std::move(m3)); + QVERIFY(m3.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); vec.push_back(std::move(m4)); + QVERIFY(m4.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); QVERIFY(vec.at(1).wasConstructedAt(&m4)); vec.prepend(std::move(m1)); + QVERIFY(m1.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m3)); QVERIFY(vec.at(2).wasConstructedAt(&m4)); vec.insert(1, std::move(m2)); + QVERIFY(m2.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m2)); QVERIFY(vec.at(2).wasConstructedAt(&m3)); + QVERIFY(vec.at(3).wasConstructedAt(&m4)); + vec.push_front(std::move(m0)); + QVERIFY(m0.wasConstructedAt(nullptr)); + QVERIFY(vec.at(0).wasConstructedAt(&m0)); + QVERIFY(vec.at(1).wasConstructedAt(&m1)); + QVERIFY(vec.at(2).wasConstructedAt(&m2)); + QVERIFY(vec.at(3).wasConstructedAt(&m3)); + QVERIFY(vec.at(4).wasConstructedAt(&m4)); - QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 8); + QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 10); } QCOMPARE(Movable::counter.loadAcquire(), instancesCount); }