QTestLib: clean up qCompare specialisation/overload mix
authorMarc Mutz <marc.mutz@kdab.com>
Thu, 20 Sep 2012 14:36:51 +0000 (16:36 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Sun, 23 Sep 2012 21:29:42 +0000 (23:29 +0200)
qCompare() was both overloaded and specialised, but always as a template.
This lead to the QIcon specialisation actually invoking
   qCompare(QFlags<void*>, ...)
when specifically asking for qCompare<void*>() (detected by adding
underlying-type detection to QFlags).

Fix by preferring overloading and not specialising anything.

Change-Id: Ie001ebb9dfb0847c6c33a3f45177a61579fd61ee
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
dist/changes-5.0.0
src/testlib/qtest.h
src/testlib/qtest_gui.h
src/testlib/qtestcase.cpp
src/testlib/qtestcase.h

index 1d594b6..e02eb19 100644 (file)
@@ -120,6 +120,18 @@ information about a particular change.
     like SkipSingle -- skipping a non-data-driven test function or skipping
     only the current data row of a data-driven test function.  Every skipped
     data row is now reported in the test log.
+  * The qCompare() function template was both overloaded and specialised, which
+    made it almost impossible to specialise the correct primary template and
+    could lead to indecipherable error messages or surprising overload resolution
+    (such as going via qCompare(QFlags<void*>,int) to satisfy a request for
+    qCompare<void*>()). Now, specialisation has been replaced by overloading.
+    As a consquence, code such as qCompare<QString>(l, r) will no longer use the
+    QString-specific implementation and may fail to compile. We recommend you
+    replace specialisations with overloading, too. Also, don't pass explicit
+    template arguments to qCompare (e.g. qCompare<QString>(l, r)), but let
+    overload resolution pick the correct one, and cast arguments in case of
+    ambiguous overloads (e.g. qCompare(QString(l), r)). The resulting code will
+    continue to work against older QtTestlib versions.
 
 - The QSsl::TlsV1 enum value was renamed to QSsl::TlsV1_0 .
 
index 4aea51d..09af3b2 100644 (file)
@@ -173,13 +173,13 @@ template<>
 inline bool qCompare(QString const &t1, QLatin1String const &t2, const char *actual,
                     const char *expected, const char *file, int line)
 {
-    return qCompare<QString>(t1, QString(t2), actual, expected, file, line);
+    return qCompare(t1, QString(t2), actual, expected, file, line);
 }
 template<>
 inline bool qCompare(QLatin1String const &t1, QString const &t2, const char *actual,
                     const char *expected, const char *file, int line)
 {
-    return qCompare<QString>(QString(t1), t2, actual, expected, file, line);
+    return qCompare(QString(t1), t2, actual, expected, file, line);
 }
 
 template<>
index 3fb57a0..66e65f7 100644 (file)
@@ -77,16 +77,14 @@ QT_BEGIN_NAMESPACE
 namespace QTest
 {
 
-template<>
 inline bool qCompare(QIcon const &t1, QIcon const &t2, const char *actual, const char *expected,
                     const char *file, int line)
 {
     QTEST_ASSERT(sizeof(QIcon) == sizeof(void *));
-    return qCompare<void *>(*reinterpret_cast<void * const *>(&t1),
+    return qCompare(*reinterpret_cast<void * const *>(&t1),
                    *reinterpret_cast<void * const *>(&t2), actual, expected, file, line);
 }
 
-template<>
 inline bool qCompare(QImage const &t1, QImage const &t2,
                      const char *actual, const char *expected, const char *file, int line)
 {
@@ -121,7 +119,6 @@ inline bool qCompare(QImage const &t1, QImage const &t2,
                           toString(t1), toString(t2), actual, expected, file, line);
 }
 
-template<>
 inline bool qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, const char *expected,
                     const char *file, int line)
 {
index 6f95240..3c9d2a8 100644 (file)
@@ -2542,22 +2542,20 @@ bool QTest::compare_helper(bool success, const char *failureMsg,
     return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line);
 }
 
-/*! \fn bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line)
+/*! \fn bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line)
 \internal
  */
-template <>
-Q_TESTLIB_EXPORT bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,
+bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected,
                     const char *file, int line)
 {
     return compare_helper(qFuzzyCompare(t1, t2), "Compared floats are not the same (fuzzy compare)",
                           toString(t1), toString(t2), actual, expected, file, line);
 }
 
-/*! \fn bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line)
+/*! \fn bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line)
 \internal
  */
-template <>
-Q_TESTLIB_EXPORT bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,
+bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected,
                     const char *file, int line)
 {
     return compare_helper(qFuzzyCompare(t1, t2), "Compared doubles are not the same (fuzzy compare)",
index 79ec4c6..1bfefaf 100644 (file)
@@ -230,12 +230,10 @@ namespace QTest
                               toString<T>(t1), toString<T>(t2), actual, expected, file, line);
     }
 
-    template <>
-    Q_TESTLIB_EXPORT bool qCompare<float>(float const &t1, float const &t2,
+    Q_TESTLIB_EXPORT bool qCompare(float const &t1, float const &t2,
                     const char *actual, const char *expected, const char *file, int line);
 
-    template <>
-    Q_TESTLIB_EXPORT bool qCompare<double>(double const &t1, double const &t2,
+    Q_TESTLIB_EXPORT bool qCompare(double const &t1, double const &t2,
                     const char *actual, const char *expected, const char *file, int line);
 
     inline bool compare_ptr_helper(const void *t1, const void *t2, const char *actual,
@@ -267,18 +265,16 @@ namespace QTest
     template <typename T1, typename T2>
     bool qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int);
 
-    template <>
-    inline bool qCompare<double, float>(double const &t1, float const &t2, const char *actual,
+    inline bool qCompare(double const &t1, float const &t2, const char *actual,
                                  const char *expected, const char *file, int line)
     {
-        return qCompare<qreal>(qreal(t1), qreal(t2), actual, expected, file, line);
+        return qCompare(qreal(t1), qreal(t2), actual, expected, file, line);
     }
 
-    template <>
-    inline bool qCompare<float, double>(float const &t1, double const &t2, const char *actual,
+    inline bool qCompare(float const &t1, double const &t2, const char *actual,
                                  const char *expected, const char *file, int line)
     {
-        return qCompare<qreal>(qreal(t1), qreal(t2), actual, expected, file, line);
+        return qCompare(qreal(t1), qreal(t2), actual, expected, file, line);
     }
 
     template <typename T>
@@ -307,29 +303,25 @@ namespace QTest
         return compare_ptr_helper(const_cast<const T1 *>(t1),
                 static_cast<const T1 *>(const_cast<const T2 *>(t2)), actual, expected, file, line);
     }
-    template<>
-    inline bool qCompare<char>(const char *t1, const char *t2, const char *actual,
+    inline bool qCompare(const char *t1, const char *t2, const char *actual,
                                        const char *expected, const char *file, int line)
     {
         return compare_string_helper(t1, t2, actual, expected, file, line);
     }
-    template<>
-    inline bool qCompare<char>(char *t1, char *t2, const char *actual, const char *expected,
+    inline bool qCompare(char *t1, char *t2, const char *actual, const char *expected,
                         const char *file, int line)
     {
         return compare_string_helper(t1, t2, actual, expected, file, line);
     }
 
-    /* The next two specializations are for MSVC that shows problems with implicit
+    /* The next two overloads are for MSVC that shows problems with implicit
        conversions
      */
-    template<>
     inline bool qCompare(char *t1, const char *t2, const char *actual,
                          const char *expected, const char *file, int line)
     {
         return compare_string_helper(t1, t2, actual, expected, file, line);
     }
-    template<>
     inline bool qCompare(const char *t1, char *t2, const char *actual,
                          const char *expected, const char *file, int line)
     {
@@ -337,11 +329,10 @@ namespace QTest
     }
 
     // NokiaX86 and RVCT do not like implicitly comparing bool with int
-    template <>
     inline bool qCompare(bool const &t1, int const &t2,
                     const char *actual, const char *expected, const char *file, int line)
     {
-        return qCompare<int>(int(t1), t2, actual, expected, file, line);
+        return qCompare(int(t1), t2, actual, expected, file, line);
     }