From 1d5e55c2a34b0d5693a148075e3840aed9cab8b7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 12 Sep 2017 10:17:02 +0200 Subject: Improve performance of QVariant::canConvert() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an early check if both types are the same. Change-Id: If6fc60a58fce641521c083bf920e72bf3d2d4c28 Reviewed-by: Jędrzej Nowacki Reviewed-by: Thiago Macieira --- src/corelib/kernel/qvariant.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index e6262124fb..a0bbcc235e 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3052,6 +3052,9 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject) */ bool QVariant::canConvert(int targetTypeId) const { + if (d.type == targetTypeId) + return true; + if ((targetTypeId == QMetaType::QModelIndex && d.type == QMetaType::QPersistentModelIndex) || (targetTypeId == QMetaType::QPersistentModelIndex && d.type == QMetaType::QModelIndex)) return true; -- cgit v1.2.3 From b6e99ec056387e8720ef5acff824089fe585e00a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 4 Sep 2017 16:36:03 +0200 Subject: Optimize QVariant::cmp() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't always copy the variants that we want to compare. This can in some cases be a relatively expensive operation. Change-Id: I2b3fd246ac136b19d8a8d281fbdcfb0417c8fb6c Reviewed-by: Sean Harmer Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qvariant.cpp | 89 +++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 40 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index a0bbcc235e..36fd4567a7 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3517,29 +3517,36 @@ static int numericCompare(const QVariant::Private *d1, const QVariant::Private * */ bool QVariant::cmp(const QVariant &v) const { + auto cmp_helper = [] (const QVariant::Private &d1, const QVariant::Private &d2) + { + Q_ASSERT(d1.type == d2.type); + if (d1.type >= QMetaType::User) { + int result; + if (QMetaType::equals(QT_PREPEND_NAMESPACE(constData(d1)), QT_PREPEND_NAMESPACE(constData(d2)), d1.type, &result)) + return result == 0; + } + return handlerManager[d1.type]->compare(&d1, &d2); + }; + // try numerics first, with C++ type promotion rules (no conversion) if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) return numericCompare(&d, &v.d) == 0; + if (d.type == v.d.type) + return cmp_helper(d, v.d); + QVariant v1 = *this; QVariant v2 = v; - if (d.type != v2.d.type) { - if (v2.canConvert(v1.d.type)) { - if (!v2.convert(v1.d.type)) - return false; - } else { - // try the opposite conversion, it might work - qSwap(v1, v2); - if (!v2.convert(v1.d.type)) - return false; - } - } - if (v1.d.type >= QMetaType::User) { - int result; - if (QMetaType::equals(QT_PREPEND_NAMESPACE(constData(v1.d)), QT_PREPEND_NAMESPACE(constData(v2.d)), v1.d.type, &result)) - return result == 0; + if (v2.canConvert(v1.d.type)) { + if (!v2.convert(v1.d.type)) + return false; + } else { + // try the opposite conversion, it might work + qSwap(v1, v2); + if (!v2.convert(v1.d.type)) + return false; } - return handlerManager[v1.d.type]->compare(&v1.d, &v2.d); + return cmp_helper(v1.d, v2.d); } /*! @@ -3555,51 +3562,53 @@ int QVariant::compare(const QVariant &v) const if (cmp(v)) return 0; - QVariant v1 = *this; - QVariant v2 = v; + const QVariant *v1 = this; + const QVariant *v2 = &v; + QVariant converted1; + QVariant converted2; - if (v1.d.type != v2.d.type) { + if (d.type != v.d.type) { // if both types differ, try to convert - if (v2.canConvert(v1.d.type)) { - QVariant temp = v2; - if (temp.convert(v1.d.type)) - v2 = temp; + if (v2->canConvert(v1->d.type)) { + converted2 = *v2; + if (converted2.convert(v1->d.type)) + v2 = &converted2; } - if (v1.d.type != v2.d.type && v1.canConvert(v2.d.type)) { - QVariant temp = v1; - if (temp.convert(v2.d.type)) - v1 = temp; + if (v1->d.type != v2->d.type && v1->canConvert(v2->d.type)) { + converted1 = *v1; + if (converted1.convert(v2->d.type)) + v1 = &converted1; } - if (v1.d.type != v2.d.type) { + if (v1->d.type != v2->d.type) { // if conversion fails, default to toString - int r = v1.toString().compare(v2.toString(), Qt::CaseInsensitive); + int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive); if (r == 0) { // cmp(v) returned false, so we should try to agree with it. - return (v1.d.type < v2.d.type) ? -1 : 1; + return (v1->d.type < v2->d.type) ? -1 : 1; } return r; } // did we end up with two numerics? If so, restart - if (qIsNumericType(v1.d.type) && qIsNumericType(v2.d.type)) - return v1.compare(v2); + if (qIsNumericType(v1->d.type) && qIsNumericType(v2->d.type)) + return v1->compare(*v2); } - if (v1.d.type >= QMetaType::User) { + if (v1->d.type >= QMetaType::User) { int result; - if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v2.d)), d.type, &result)) + if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v2->d)), d.type, &result)) return result; } - switch (v1.d.type) { + switch (v1->d.type) { case QVariant::Date: - return v1.toDate() < v2.toDate() ? -1 : 1; + return v1->toDate() < v2->toDate() ? -1 : 1; case QVariant::Time: - return v1.toTime() < v2.toTime() ? -1 : 1; + return v1->toTime() < v2->toTime() ? -1 : 1; case QVariant::DateTime: - return v1.toDateTime() < v2.toDateTime() ? -1 : 1; + return v1->toDateTime() < v2->toDateTime() ? -1 : 1; case QVariant::StringList: - return v1.toStringList() < v2.toStringList() ? -1 : 1; + return v1->toStringList() < v2->toStringList() ? -1 : 1; } - int r = v1.toString().compare(v2.toString(), Qt::CaseInsensitive); + int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive); if (r == 0) { // cmp(v) returned false, so we should try to agree with it. return (d.type < v.d.type) ? -1 : 1; -- cgit v1.2.3 From 81a19050d8127e7b05006f793a8797c8f5248191 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 12 Sep 2017 11:42:23 +0100 Subject: QSharedPointer: fix undefined behavior in operator< Pointers belonging to different arrays must be compared using std::less. Change-Id: Ib77af7b1b2da58d7243fa77273a8a45ee9035a1a Reviewed-by: Thiago Macieira --- src/corelib/tools/qsharedpointer_impl.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 15573c5588..ede54c155d 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -850,17 +850,20 @@ Q_INLINE_TEMPLATE typename QSharedPointer::difference_type operator-(T *ptr1, template Q_INLINE_TEMPLATE bool operator<(const QSharedPointer &ptr1, const QSharedPointer &ptr2) { - return ptr1.data() < ptr2.data(); + using CT = typename std::common_type::type; + return std::less()(ptr1.data(), ptr2.data()); } template Q_INLINE_TEMPLATE bool operator<(const QSharedPointer &ptr1, X *ptr2) { - return ptr1.data() < ptr2; + using CT = typename std::common_type::type; + return std::less()(ptr1.data(), ptr2); } template Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer &ptr2) { - return ptr1 < ptr2.data(); + using CT = typename std::common_type::type; + return std::less()(ptr1, ptr2.data()); } // -- cgit v1.2.3 From 54a242f7edb96bc18876422f78a475e9e7b57b5a Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Mon, 18 Sep 2017 01:47:46 -0700 Subject: Add missing pwd.h include This file uses functions declared in this header, and it is not pulled in transitively on all platforms. Change-Id: I6654118883a8dc22dacf1beb7b9b1c662719d25c Reviewed-by: Tuomas Heimonen Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_unix.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/corelib') diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 7600c9a613..7fed54f733 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -45,6 +45,7 @@ #include +#include #include // for realpath() #include #include -- cgit v1.2.3