summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-07-10 12:25:27 +0200
committerLars Knoll <lars.knoll@qt.io>2020-08-24 00:17:04 +0200
commit0daa9dbfc4c2d91dfa7110070834498693c6168a (patch)
tree3fd4732d6008e7d4e3e8663ba55b21616560a8e3
parentbd64f9397ac6c7aa4368d92138929e858e3df107 (diff)
Generate less code when creating QMetaTypeInterfaces
There is no need to generate wrapper functions for equals, lessThan or debugStream for pointer types, as those can easily be handled by a few lines of code in QMetaType itself. Change-Id: If79b3bc3a629249c1d17c9e592202f08b59f80ef Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/kernel/qmetatype.cpp24
-rw-r--r--src/corelib/kernel/qmetatype.h6
-rw-r--r--tests/auto/other/qvariant_common/tst_qvariant_common.h5
3 files changed, 23 insertions, 12 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index d732285f08..ce6971e177 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -47,6 +47,7 @@
#include "qstringlist.h"
#include "qlist.h"
#include "qlocale.h"
+#include "qdebug.h"
#if QT_CONFIG(easingcurve)
#include "qeasingcurve.h"
#endif
@@ -707,6 +708,9 @@ std::optional<int> QMetaType::compare(const void *lhs, const void *rhs) const
{
if (!lhs || !rhs)
return std::optional<int>{};
+ if (d_ptr->flags & QMetaType::IsPointer)
+ return std::less<const void *>()(*reinterpret_cast<const void * const *>(lhs),
+ *reinterpret_cast<const void * const *>(rhs));
if (d_ptr && d_ptr->lessThan) {
if (d_ptr->equals && d_ptr->equals(d_ptr, lhs, rhs))
return 0;
@@ -741,6 +745,9 @@ bool QMetaType::equals(const void *lhs, const void *rhs) const
if (!lhs || !rhs)
return false;
if (d_ptr) {
+ if (d_ptr->flags & QMetaType::IsPointer)
+ return *reinterpret_cast<const void * const *>(lhs) == *reinterpret_cast<const void * const *>(rhs);
+
if (d_ptr->equals)
return d_ptr->equals(d_ptr, lhs, rhs);
if (d_ptr->lessThan && !d_ptr->lessThan(d_ptr, lhs, rhs) && !d_ptr->lessThan(d_ptr, rhs, lhs))
@@ -757,7 +764,7 @@ bool QMetaType::equals(const void *lhs, const void *rhs) const
*/
bool QMetaType::isEqualityComparable() const
{
- return d_ptr && (d_ptr->equals != nullptr || d_ptr->lessThan != nullptr);
+ return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->equals != nullptr || d_ptr->lessThan != nullptr);
}
/*!
@@ -768,7 +775,7 @@ bool QMetaType::isEqualityComparable() const
*/
bool QMetaType::isOrdered() const
{
- return d_ptr && d_ptr->lessThan != nullptr;
+ return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->lessThan != nullptr);
}
void QtMetaTypePrivate::derefAndDestroy(NS(QtPrivate::QMetaTypeInterface) *d_ptr)
@@ -975,10 +982,15 @@ void QMetaType::unregisterConverterFunction(int from, int to)
*/
bool QMetaType::debugStream(QDebug& dbg, const void *rhs)
{
- if (!isValid() || !d_ptr->debugStream)
- return false;
- d_ptr->debugStream(d_ptr, dbg, rhs);
- return true;
+ if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
+ dbg << *reinterpret_cast<const void * const *>(rhs);
+ return true;
+ }
+ if (d_ptr && d_ptr->debugStream) {
+ d_ptr->debugStream(d_ptr, dbg, rhs);
+ return true;
+ }
+ return false;
}
/*!
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index ed4ff87f92..c5ed0c636a 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -2487,7 +2487,7 @@ struct BuiltinMetaType<T, std::enable_if_t<QMetaTypeId2<T>::IsBuiltIn>>
{
};
-template<typename T, bool = QTypeTraits::has_operator_equal_v<T>>
+template<typename T, bool = (QTypeTraits::has_operator_equal_v<T> && !std::is_pointer_v<T>)>
struct QEqualityOperatorForType
{
static bool equals(const QMetaTypeInterface *, const void *a, const void *b)
@@ -2500,7 +2500,7 @@ struct QEqualityOperatorForType <T, false>
static constexpr QMetaTypeInterface::EqualsFn equals = nullptr;
};
-template<typename T, bool = QTypeTraits::has_operator_less_than_v<T>>
+template<typename T, bool = (QTypeTraits::has_operator_less_than_v<T> && !std::is_pointer_v<T>)>
struct QLessThanOperatorForType
{
static bool lessThan(const QMetaTypeInterface *, const void *a, const void *b)
@@ -2513,7 +2513,7 @@ struct QLessThanOperatorForType <T, false>
static constexpr QMetaTypeInterface::LessThanFn lessThan = nullptr;
};
-template<typename T, bool = QTypeTraits::has_ostream_operator_v<QDebug, T>>
+template<typename T, bool = (QTypeTraits::has_ostream_operator_v<QDebug, T> && !std::is_pointer_v<T>)>
struct QDebugStreamOperatorForType
{
static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
diff --git a/tests/auto/other/qvariant_common/tst_qvariant_common.h b/tests/auto/other/qvariant_common/tst_qvariant_common.h
index d7e0b7786a..6b69d04a78 100644
--- a/tests/auto/other/qvariant_common/tst_qvariant_common.h
+++ b/tests/auto/other/qvariant_common/tst_qvariant_common.h
@@ -62,10 +62,9 @@ protected:
// Chars insert '\0' into the qdebug stream, it is not possible to find a real string length
return;
}
- if (QMetaType::typeFlags(currentId) & QMetaType::PointerToQObject) {
+ if (QMetaType::typeFlags(currentId) & QMetaType::IsPointer) {
QByteArray currentName = QMetaType::typeName(currentId);
- currentName.chop(1);
- ok &= (msg.contains(", " + currentName) || msg.contains(", 0x0"));
+ ok &= msg.contains(currentName + ", 0x");
}
ok &= msg.endsWith(QLatin1Char(')'));
QVERIFY2(ok, (QString::fromLatin1("Message is not correctly finished: '") + msg + '\'').toLatin1().constData());