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>
bb10
Lars Knoll 2020-07-10 12:25:27 +02:00
parent bd64f9397a
commit 0daa9dbfc4
3 changed files with 23 additions and 12 deletions

View File

@ -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;
}
/*!

View File

@ -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)

View File

@ -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());