From f7eff7251786186ca895c8fc537b304bc89977b3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 24 Feb 2012 18:44:17 +0100 Subject: Add a new Q_GLOBAL_STATIC implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlike the previous implementation, this implementation is locked: only one initialisation is ever run at the same time. It is exception-safe, meaning that a throwing constructor will restart the process. Also, start using the thread-safe behaviour that GCC has offered for a long time and C++11 requires. Change-Id: I20db44f57d258923df64c0051358fd0d9a5ccd51 Reviewed-by: Olivier Goffart Reviewed-by: David Faure (KDE) Reviewed-by: Jędrzej Nowacki --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 581644b19f..d7add383e1 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -144,6 +144,16 @@ private slots: void disconnectDoesNotLeakFunctor(); }; +struct QObjectCreatedOnShutdown +{ + QObjectCreatedOnShutdown() {} + ~QObjectCreatedOnShutdown() + { + QObject(); + } +}; +static QObjectCreatedOnShutdown s_qobjectCreatedOnShutdown; + class SenderObject : public QObject { Q_OBJECT -- cgit v1.2.3 From 03b25125986f083a260b421abeed1f1d088d27b3 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 5 Feb 2013 14:35:10 +0100 Subject: Fix QMetaType of const references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes QMetaType detection of const reference arguments in signals while connecting using the new syntax and Qt::QueuedConnection const references should have the same QMetaType as non references. That means we need to remove the const reference while getting the QMetaType. Change-Id: I9b2688da7fb9ae985aec0d8fa62a1165357ffe71 Reviewed-by: Thiago Macieira Reviewed-by: Stephen Kelly Reviewed-by: Jędrzej Nowacki --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index a6d1d9f14d..c3ecf419e0 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Olivier Goffart ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -1446,9 +1447,11 @@ public: public slots: void slot1(CustomType ct); + void slot2(const QList &ct); signals: void signal1(CustomType ct); + void signal2(const QList &ct); public: CustomType received; @@ -1457,6 +1460,8 @@ public: void QCustomTypeChecker::slot1(CustomType ct) { received = ct; } +void QCustomTypeChecker::slot2(const QList< CustomType >& ct) +{ received = ct[0]; } void tst_QObject::customTypes() { @@ -4667,6 +4672,21 @@ void tst_QObject::customTypesPointer() QCOMPARE(qRegisterMetaType("CustomType"), idx); QCOMPARE(QMetaType::type("CustomType"), idx); QVERIFY(QMetaType::isRegistered(idx)); + + // Test auto registered type (QList) + QList list; + QCOMPARE(instanceCount, 4); + list.append(t1); + QCOMPARE(instanceCount, 5); + QVERIFY(connect(&checker, &QCustomTypeChecker::signal2, + &checker, &QCustomTypeChecker::slot2, Qt::QueuedConnection)); + emit checker.signal2(list); + QCOMPARE(instanceCount, 5); //because the list is implicitly shared. + list.clear(); + QCOMPARE(instanceCount, 5); + QCoreApplication::processEvents(); + QCOMPARE(checker.received.value(), t1.value()); + QCOMPARE(instanceCount, 4); } QCOMPARE(instanceCount, 3); } -- cgit v1.2.3 From ab59a7ef09d56e59f9496ac59d88ba05db61e298 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 12 Oct 2012 12:20:40 +0200 Subject: Add private API to connect to slots in QObjectPrivate Change-Id: I16ffbf91ff4c6e9fca6fe7984800d2c24e70701b Reviewed-by: Thiago Macieira --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index c3ecf419e0..0521c2277c 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -141,6 +141,7 @@ private slots: void returnValue2_data(); void returnValue2(); void connectVirtualSlots(); + void connectPrivateSlots(); void connectFunctorArgDifference(); void disconnectDoesNotLeakFunctor(); }; @@ -5565,6 +5566,72 @@ void tst_QObject::connectVirtualSlots() */ } +#ifndef QT_BUILD_INTERNAL +void tst_QObject::connectPrivateSlots() +{QSKIP("Needs QT_BUILD_INTERNAL");} +#else +class ConnectToPrivateSlotPrivate; + +class ConnectToPrivateSlot :public QObject { + Q_OBJECT +public: + ConnectToPrivateSlot(); + void test(SenderObject *obj1) ; + Q_DECLARE_PRIVATE(ConnectToPrivateSlot) +}; + +class ConnectToPrivateSlotPrivate : public QObjectPrivate { +public: + Q_DECLARE_PUBLIC(ConnectToPrivateSlot) + int receivedCount; + QVariant receivedValue; + + void thisIsAPrivateSlot() { + receivedCount++; + }; + + void thisIsAPrivateSlotWithArg(const QVariant &v) { + receivedCount++; + receivedValue = v; + }; +}; + +ConnectToPrivateSlot::ConnectToPrivateSlot(): QObject(*new ConnectToPrivateSlotPrivate) {} + +void ConnectToPrivateSlot::test(SenderObject* obj1) { + Q_D(ConnectToPrivateSlot); + d->receivedCount = 0; + QVERIFY(QObjectPrivate::connect(obj1, &SenderObject::signal1, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot)); + QVERIFY(QObjectPrivate::connect(obj1, &SenderObject::signal7, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlotWithArg)); + QCOMPARE(d->receivedCount, 0); + obj1->signal1(); + QCOMPARE(d->receivedCount, 1); + QCOMPARE(d->receivedValue, QVariant()); + obj1->signal7(666, QLatin1Literal("_")); + QCOMPARE(d->receivedCount, 2); + QCOMPARE(d->receivedValue, QVariant(666)); + QVERIFY(QObjectPrivate::connect(obj1, &SenderObject::signal2, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot, Qt::UniqueConnection)); + QVERIFY(!QObjectPrivate::connect(obj1, &SenderObject::signal2, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot, Qt::UniqueConnection)); + obj1->signal2(); + QCOMPARE(d->receivedCount, 3); + QVERIFY(QObjectPrivate::disconnect(obj1, &SenderObject::signal2, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot)); + obj1->signal2(); + QCOMPARE(d->receivedCount, 3); + QVERIFY(!QObjectPrivate::disconnect(obj1, &SenderObject::signal2, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot)); +} + +void tst_QObject::connectPrivateSlots() +{ + SenderObject sender; + { + ConnectToPrivateSlot o; + o.test(&sender); + } + sender.signal7(777, QLatin1String("check that deleting the object properly disconnected")); + sender.signal1(); +} +#endif + struct SlotFunctor { void operator()() {} -- cgit v1.2.3 From 6d0a685fc63355d355b576d5f47b3b93d777fedf Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 6 Mar 2013 16:09:56 +0100 Subject: Simplify further extension of tst_QObject::connectSlotsByName I changed the existing test-case code to make it more scalable in terms of adding more connectSlotsByName related tests. The old "manual list of ints"-method was really not developer friendly. This is a preparation for a subsequent modification of connectSlotsByName behavior. Change-Id: Ib760e52631ce4b5ae2a3ebdb4854849ff6c93bfe Reviewed-by: Olivier Goffart Reviewed-by: Friedemann Kleint --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 150 +++++----------------- 1 file changed, 31 insertions(+), 119 deletions(-) (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 0521c2277c..17752c405c 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -69,7 +69,7 @@ class tst_QObject : public QObject private slots: void initTestCase(); void disconnect(); - void connectByName(); + void connectSlotsByName(); void connectSignalsToSignalsWithDefaultArguments(); void receivers(); void normalize(); @@ -380,6 +380,7 @@ public: void emitSignalWithParams(int i) { emit signalWithParams(i); } void emitSignalWithParams(int i, QString string) { emit signalWithParams(i, string); } void emitSignalManyParams(int i1, int i2, int i3, QString string, bool onoff) { emit signalManyParams(i1, i2, i3, string, onoff); } + void emitSignalManyParams(int i1, int i2, int i3, QString string, bool onoff, bool dummy) { emit signalManyParams(i1, i2, i3, string, onoff, dummy); } void emitSignalManyParams2(int i1, int i2, int i3, QString string, bool onoff) { emit signalManyParams2(i1, i2, i3, string, onoff); } void emitSignalLoopBack() { emit signalLoopBack(); } @@ -398,74 +399,36 @@ class AutoConnectReceiver : public QObject Q_OBJECT public: + QList called_slots; + AutoConnectReceiver() { - reset(); - connect(this, SIGNAL(on_Sender_signalLoopBack()), this, SLOT(slotLoopBack())); } - void reset() { - called_slot10 = 0; - called_slot9 = 0; - called_slot8 = 0; - called_slot7 = 0; - called_slot6 = 0; - called_slot5 = 0; - called_slot4 = 0; - called_slot3 = 0; - called_slot2 = 0; - called_slot1 = 0; - } - - int called_slot1; - int called_slot2; - int called_slot3; - int called_slot4; - int called_slot5; - int called_slot6; - int called_slot7; - int called_slot8; - int called_slot9; - int called_slot10; - - bool called(int slot) { - switch (slot) { - case 1: return called_slot1; - case 2: return called_slot2; - case 3: return called_slot3; - case 4: return called_slot4; - case 5: return called_slot5; - case 6: return called_slot6; - case 7: return called_slot7; - case 8: return called_slot8; - case 9: return called_slot9; - case 10: return called_slot10; - default: return false; - } - } public slots: - void on_Sender_signalNoParams() { ++called_slot1; } - void on_Sender_signalWithParams(int i = 0) { ++called_slot2; Q_UNUSED(i); } - void on_Sender_signalWithParams(int i, QString string) { ++called_slot3; Q_UNUSED(i);Q_UNUSED(string); } - void on_Sender_signalManyParams() { ++called_slot4; } - void on_Sender_signalManyParams(int i1, int i2, int i3, QString string, bool onoff) { ++called_slot5; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); } + void on_Sender_signalNoParams() { called_slots << 1; } + void on_Sender_signalWithParams(int i = 0) { called_slots << 2; Q_UNUSED(i); } + void on_Sender_signalWithParams(int i, QString string) { called_slots << 3; Q_UNUSED(i);Q_UNUSED(string); } + void on_Sender_signalManyParams() { called_slots << 4; } + void on_Sender_signalManyParams(int i1, int i2, int i3, QString string, bool onoff) + { called_slots << 5; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); } void on_Sender_signalManyParams(int i1, int i2, int i3, QString string, bool onoff, bool dummy) - { ++called_slot6; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); Q_UNUSED(dummy);} + { called_slots << 6; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); Q_UNUSED(dummy);} void on_Sender_signalManyParams2(int i1, int i2, int i3, QString string, bool onoff) - { ++called_slot7; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); } - void slotLoopBack() { ++called_slot8; } + { called_slots << 7; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); } + void slotLoopBack() { called_slots << 8; } protected slots: - void o() { ++called_slot9; } - void on() { ++called_slot10; } + void o() { called_slots << -1; } + void on() { called_slots << -1; } signals: void on_Sender_signalLoopBack(); }; -void tst_QObject::connectByName() +void tst_QObject::connectSlotsByName() { AutoConnectReceiver receiver; AutoConnectSender sender(&receiver); @@ -473,83 +436,32 @@ void tst_QObject::connectByName() QMetaObject::connectSlotsByName(&receiver); + receiver.called_slots.clear(); sender.emitSignalNoParams(); - QCOMPARE(receiver.called(1), true); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); + QCOMPARE(receiver.called_slots, QList() << 1); + receiver.called_slots.clear(); sender.emitSignalWithParams(0); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), true); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); + QCOMPARE(receiver.called_slots, QList() << 2); + receiver.called_slots.clear(); sender.emitSignalWithParams(0, "string"); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), true); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); + QCOMPARE(receiver.called_slots, QList() << 3); + receiver.called_slots.clear(); sender.emitSignalManyParams(1, 2, 3, "string", true); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), true); - QCOMPARE(receiver.called(5), true); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); + sender.emitSignalManyParams(1, 2, 3, "string", true, false); + // the slot '4' (signalManyParams()) will get connected + // to either of the two signalManyParams(...) overloads + QCOMPARE(receiver.called_slots, QList() << 4 << 5 << 6); + receiver.called_slots.clear(); sender.emitSignalManyParams2(1, 2, 3, "string", true); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), true); - QCOMPARE(receiver.called(8), false); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); + QCOMPARE(receiver.called_slots, QList() << 7); + receiver.called_slots.clear(); sender.emitSignalLoopBack(); - QCOMPARE(receiver.called(1), false); - QCOMPARE(receiver.called(2), false); - QCOMPARE(receiver.called(3), false); - QCOMPARE(receiver.called(4), false); - QCOMPARE(receiver.called(5), false); - QCOMPARE(receiver.called(6), false); - QCOMPARE(receiver.called(7), false); - QCOMPARE(receiver.called(8), true); - QCOMPARE(receiver.called(9), false); - QCOMPARE(receiver.called(10), false); - receiver.reset(); + QCOMPARE(receiver.called_slots, QList() << 8); } void tst_QObject::qobject_castTemplate() -- cgit v1.2.3 From 6b68be9587c6d6946faff34f88d80de53f11ed86 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 6 Mar 2013 17:18:48 +0100 Subject: Let QMetaObject::connectSlotsByName(o) also check for signals of o QMetaObject::connectSlotsByName(QObject* o) creates a list of all children to look for signals that match slots of o. This changeset simply adds the object o itself to that list. The motivation is to finally fix the long standing QtCreator bug QTCREATORBUG-6494. Where executing 'Go to slot...' and choosing 'accepted()' for a simple QDialog named 'MyDialog' will add a on_MyDialog_accepted() slot to MyDialog. That slot never gets connected. More details may be found in the linked QTBUG-7595. Task-number: QTBUG-7595 Task-number: QTCREATORBUG-6494 Change-Id: I35f52761791af697eabb569adb5faee6fae50638 Reviewed-by: Olivier Goffart Reviewed-by: Friedemann Kleint --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 17752c405c..db21ab4fe4 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -406,6 +406,8 @@ public: connect(this, SIGNAL(on_Sender_signalLoopBack()), this, SLOT(slotLoopBack())); } + void emitSignalNoParams() { emit signalNoParams(); } + void emit_signal_with_underscore() { emit signal_with_underscore(); } public slots: void on_Sender_signalNoParams() { called_slots << 1; } @@ -419,6 +421,8 @@ public slots: void on_Sender_signalManyParams2(int i1, int i2, int i3, QString string, bool onoff) { called_slots << 7; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); } void slotLoopBack() { called_slots << 8; } + void on_Receiver_signalNoParams() { called_slots << 9; } + void on_Receiver_signal_with_underscore() { called_slots << 10; } protected slots: void o() { called_slots << -1; } @@ -426,11 +430,14 @@ protected slots: signals: void on_Sender_signalLoopBack(); + void signalNoParams(); + void signal_with_underscore(); }; void tst_QObject::connectSlotsByName() { AutoConnectReceiver receiver; + receiver.setObjectName("Receiver"); AutoConnectSender sender(&receiver); sender.setObjectName("Sender"); @@ -462,6 +469,14 @@ void tst_QObject::connectSlotsByName() receiver.called_slots.clear(); sender.emitSignalLoopBack(); QCOMPARE(receiver.called_slots, QList() << 8); + + receiver.called_slots.clear(); + receiver.emitSignalNoParams(); + QCOMPARE(receiver.called_slots, QList() << 9); + + receiver.called_slots.clear(); + receiver.emit_signal_with_underscore(); + QCOMPARE(receiver.called_slots, QList() << 10); } void tst_QObject::qobject_castTemplate() -- cgit v1.2.3 From 3c2748afd58ef84d14b028fa43d193addb1add4c Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 6 Mar 2013 17:44:15 +0100 Subject: Improve warning messages (and readability) of connectSlotsByName() While adding a test case for the new behavior, two issues with the connectSlotsByName implementation came up: 1. for auto-connected slots that don't exactly match a signal, a 'compatible' one is searched. There might be more than one of those. The implementation randomly picks any. 2. The "No matching signal for %s" warning gets printed even for slots that can never be connected via connectSlotsMyName anyway (e.g. "on_something"). This is inconsistent. This fixed both: an explicit warning is printed if more than one 'compatible' signal is found and the "No matching signal for %s" warning is only printed if the slot adheres to the full "on_child_signal()" naming convention. In the process I added comments and changed the code slightly to make it more readable and explicitly hint at non-obvious behavior. Change-Id: Icc8e3b9936188d2da8dfff9f0373c8e5c776eb14 Reviewed-by: Olivier Goffart Reviewed-by: Friedemann Kleint --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index db21ab4fe4..dd88d863c9 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -427,6 +427,9 @@ public slots: protected slots: void o() { called_slots << -1; } void on() { called_slots << -1; } + void on_() { called_slots << -1; } + void on_something() { called_slots << -1; } + void on_child_signal() { called_slots << -1; } signals: void on_Sender_signalLoopBack(); @@ -441,6 +444,8 @@ void tst_QObject::connectSlotsByName() AutoConnectSender sender(&receiver); sender.setObjectName("Sender"); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: No matching signal for on_child_signal()"); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: Connecting slot on_Sender_signalManyParams() with the first of the following compatible signals: (\"signalManyParams(int,int,int,QString,bool)\", \"signalManyParams(int,int,int,QString,bool,bool)\") "); QMetaObject::connectSlotsByName(&receiver); receiver.called_slots.clear(); -- cgit v1.2.3 From bc98bba2f302922761209c0e91485e809354abc1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 1 Mar 2013 10:18:36 +0100 Subject: Support connection to functor with multiple operator() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When variadic templates and decltype are supported, detect the best overload of operator() to call. Currently, the code takes the type of the operator(), which requires that the functor only has one, and that it has no template parameter. This feature is required if we want to connect to c++1y generic lambda (N3418) Change-Id: Ifa957da6955ea39ab804b58f320da9f98ff47d63 Reviewed-by: Jędrzej Nowacki --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 126 ++++++++++++++++++++++ 1 file changed, 126 insertions(+) (limited to 'tests/auto/corelib/kernel/qobject/tst_qobject.cpp') diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index dd88d863c9..06fc89f657 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -143,6 +143,7 @@ private slots: void connectVirtualSlots(); void connectPrivateSlots(); void connectFunctorArgDifference(); + void connectFunctorOverloads(); void disconnectDoesNotLeakFunctor(); }; @@ -5599,6 +5600,131 @@ void tst_QObject::connectFunctorArgDifference() QVERIFY(true); } +struct ComplexFunctor { + ComplexFunctor(int &overload, QList &result) : overload(overload), result(result) {} + void operator()(int a, int b) { + overload = 1; + result << a << b; + } + void operator()(double a, double b) { + overload = 2; + result << a << b; + } + void operator()(const QString &s) { + overload = 3; + result << s; + } + void operator()(const QString &) const { + Q_ASSERT(!"Should not be called because the non-const one should"); + overload = -1; + } + template + void operator()(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) { + overload = 4; + result << QVariant::fromValue(t1) << QVariant::fromValue(t2) << QVariant::fromValue(t3) << QVariant::fromValue(t4); + } + int &overload; + QList &result; +protected: + void operator()() const { + Q_ASSERT(!"Should not be called because it is protected"); + overload = -1; + } +}; + +struct ComplexFunctorDeriv : ComplexFunctor { + ComplexFunctorDeriv(int &overload, QList &result) : ComplexFunctor(overload, result) {} + + void operator()() const { + overload = 10; + } + void operator()(int a, int b) { + overload = 11; + result << a << b; + } + using ComplexFunctor::operator(); +private: + void operator()(int) { + Q_ASSERT(!"Should not be called because it is private"); + overload = -1; + } +}; + +class FunctorArgDifferenceObject : public QObject +{ + Q_OBJECT +signals: + void signal_ii(int,int); + void signal_iiS(int,int, const QString &); + void signal_dd(double,double); + void signal_ddS(double,double, const QString &); + void signal_S(const QString &); + void signal_SSSS(const QString &, const QString &, const QString &, const QString &); + void signal_iiSS(int, int, const QString &, const QString &); + void signal_VV(const QVariant &, const QVariant &); +}; + +template +void connectFunctorOverload_impl(Signal signal, int expOverload, QList expResult) +{ + FunctorArgDifferenceObject obj; + int overload; + QList result; + QVERIFY(QObject::connect(&obj, signal, Functor(overload, result))); + + obj.signal_ii(1,2); + obj.signal_iiS(3,4,"5"); + obj.signal_dd(6.6,7.7); + obj.signal_ddS(8.8,9.9,"10"); + obj.signal_S("11"); + obj.signal_SSSS("12", "13", "14", "15"); + obj.signal_iiSS(16, 17, "18", "19"); + obj.signal_VV(20,21); + + QCOMPARE(overload, expOverload); + QCOMPARE(result, expResult); +} + +void tst_QObject::connectFunctorOverloads() +{ +#if defined (Q_COMPILER_DECLTYPE) && defined (Q_COMPILER_VARIADIC_TEMPLATES) + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_ii, 1, + (QList() << 1 << 2)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_iiS, 1, + (QList() << 3 << 4)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_dd, 2, + (QList() << 6.6 << 7.7)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_ddS, 2, + (QList() << 8.8 << 9.9)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_S, 3, + (QList() << QString("11"))); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_SSSS, 4, + (QList() << QString("12") << QString("13") << QString("14") << QString("15"))); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_iiSS, 4, + (QList() << 16 << 17 << QString("18") << QString("19"))); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_ii, 11, + (QList() << 1 << 2)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_iiS, 11, + (QList() << 3 << 4)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_dd, 2, + (QList() << 6.6 << 7.7)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_ddS, 2, + (QList() << 8.8 << 9.9)); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_S, 3, + (QList() << QString("11"))); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_SSSS, 4, + (QList() << QString("12") << QString("13") << QString("14") << QString("15"))); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_iiSS, 4, + (QList() << 16 << 17 << QString("18") << QString("19"))); + connectFunctorOverload_impl(&FunctorArgDifferenceObject::signal_VV, 10, + (QList())); + + +#else + QSKIP("Does not compile without C++11 variadic template"); +#endif +} + static int countedStructObjectsCount = 0; struct CountedStruct { -- cgit v1.2.3