Add comparison operators == and != for QMetaMethod
authorKent Hansen <kent.hansen@nokia.com>
Sun, 22 Apr 2012 18:47:08 +0000 (20:47 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 25 Apr 2012 18:16:56 +0000 (20:16 +0200)
This is done in preparation of introducing the
QObject::connectNotify(QMetaMethod) function. Together with the
forthcoming QMetaMethod::fromSignal() function, which returns the
QMetaMethod corresponding to a Qt/C++ signal (member function), the
comparison operators provide an effective way of checking which
signal was connected to.

Change-Id: I2de48628c4884a7174fb8574895f272cb3fe5634
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
src/corelib/kernel/qmetaobject.cpp
src/corelib/kernel/qmetaobject.h
tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp

index 2439c22..359dbfc 100644 (file)
@@ -1477,6 +1477,24 @@ bool QMetaObject::invokeMethod(QObject *obj,
     invoked), otherwise returns false.
 */
 
+/*! \fn bool operator==(const QMetaMethod &m1, const QMetaMethod &m2)
+    \since 5.0
+    \relates QMetaMethod
+    \overload
+
+    Returns true if method \a m1 is equal to method \a m2,
+    otherwise returns false.
+*/
+
+/*! \fn bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
+    \since 5.0
+    \relates QMetaMethod
+    \overload
+
+    Returns true if method \a m1 is not equal to method \a m2,
+    otherwise returns false.
+*/
+
 /*!
     \fn const QMetaObject *QMetaMethod::enclosingMetaObject() const
     \internal
index 095b196..5204f04 100644 (file)
@@ -155,9 +155,16 @@ private:
     friend struct QMetaObject;
     friend struct QMetaObjectPrivate;
     friend class QObject;
+    friend bool operator==(const QMetaMethod &m1, const QMetaMethod &m2);
+    friend bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2);
 };
 Q_DECLARE_TYPEINFO(QMetaMethod, Q_MOVABLE_TYPE);
 
+inline bool operator==(const QMetaMethod &m1, const QMetaMethod &m2)
+{ return m1.mobj == m2.mobj && m1.handle == m2.handle; }
+inline bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
+{ return !(m1 == m2); }
+
 class Q_CORE_EXPORT QMetaEnum
 {
 public:
index 55997a3..b5ab614 100644 (file)
@@ -54,6 +54,8 @@ private slots:
     void method();
 
     void invalidMethod();
+
+    void comparisonOperators();
 };
 
 struct CustomType { };
@@ -672,5 +674,40 @@ void tst_QMetaMethod::invalidMethod()
     QVERIFY(!method3.isValid());
 }
 
+void tst_QMetaMethod::comparisonOperators()
+{
+    static const QMetaObject *mo = &MethodTestObject::staticMetaObject;
+    for (int x = 0; x < 2; ++x) {
+        int count = x ? mo->constructorCount() : mo->methodCount();
+        for (int i = 0; i < count; ++i) {
+            QMetaMethod method = x ? mo->constructor(i) : mo->method(i);
+            const QMetaObject *methodMo = method.enclosingMetaObject();
+            for (int j = 0; j < count; ++j) {
+                QMetaMethod other = x ? mo->constructor(j) : mo->method(j);
+                bool expectedEqual = ((methodMo == other.enclosingMetaObject())
+                                      && (i == j));
+                QCOMPARE(method == other, expectedEqual);
+                QCOMPARE(method != other, !expectedEqual);
+                QCOMPARE(other == method, expectedEqual);
+                QCOMPARE(other != method, !expectedEqual);
+            }
+
+            QVERIFY(method != QMetaMethod());
+            QVERIFY(QMetaMethod() != method);
+            QVERIFY(!(method == QMetaMethod()));
+            QVERIFY(!(QMetaMethod() == method));
+        }
+    }
+
+    // Constructors and normal methods with identical index should not
+    // compare equal
+    for (int i = 0; i < qMin(mo->methodCount(), mo->constructorCount()); ++i) {
+        QMetaMethod method = mo->method(i);
+        QMetaMethod constructor = mo->constructor(i);
+        QVERIFY(method != constructor);
+        QVERIFY(!(method == constructor));
+    }
+}
+
 QTEST_MAIN(tst_QMetaMethod)
 #include "tst_qmetamethod.moc"