summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@theqtcompany.com>2015-01-09 11:55:43 +0100
committerAlex Blasche <alexander.blasche@theqtcompany.com>2015-01-13 12:18:47 +0100
commit0d4485fd78d5a14797c3511ecf808fcfa0768ac9 (patch)
tree0179c758de2113537aed53d601ce7d6425fdfe42 /src/corelib/kernel
parent8fdd1bb8cb68332db605c9f250c64dd114747c45 (diff)
Support QMetaType::equals()
This avoids having to define operator< for types where operator== is required but operator< doesn't make any sense (e.g. QGeoCoordinate). Change-Id: I81f6a9d8fc0009a4514c974b5e02b446c50d1e31 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qmetatype.cpp35
-rw-r--r--src/corelib/kernel/qmetatype.h29
-rw-r--r--src/corelib/kernel/qvariant.cpp2
3 files changed, 62 insertions, 4 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 294b1fc07c..aae772ffeb 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -577,11 +577,19 @@ Q_GLOBAL_STATIC(QMetaTypeDebugStreamRegistry, customTypesDebugStreamRegistry)
/*!
\fn bool QMetaType::registerComparators()
\since 5.2
- Registers comparison operetarors for the user-registered type T. This requires T to have
+ Registers comparison operators for the user-registered type T. This requires T to have
both an operator== and an operator<.
Returns \c true if the registration succeeded, otherwise false.
*/
+/*!
+ \fn bool QMetaType::registerEqualsComparator()
+ \since 5.5
+ Registers equals operator for the user-registered type T. This requires T to have
+ an operator==.
+ Returns \c true if the registration succeeded, otherwise false.
+*/
+
#ifndef QT_NO_DEBUG_STREAM
/*!
\fn bool QMetaType::registerDebugStreamOperator()
@@ -687,7 +695,7 @@ bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId
/*!
Compares the objects at \a lhs and \a rhs. Both objects need to be of type \a typeId.
\a result is set to less than, equal to or greater than zero, if \a lhs is less than, equal to
- or greater than \a rhs. Returns \c true, if the comparison succeeded, otherwiess false.
+ or greater than \a rhs. Returns \c true, if the comparison succeeded, otherwise \c false.
\since 5.2
*/
bool QMetaType::compare(const void *lhs, const void *rhs, int typeId, int* result)
@@ -698,8 +706,29 @@ bool QMetaType::compare(const void *lhs, const void *rhs, int typeId, int* resul
return false;
if (f->equals(f, lhs, rhs))
*result = 0;
- else
+ else if (f->lessThan)
*result = f->lessThan(f, lhs, rhs) ? -1 : 1;
+ else
+ return false;
+ return true;
+}
+
+/*!
+ Compares the objects at \a lhs and \a rhs. Both objects need to be of type \a typeId.
+ \a result is set to zero, if \a lhs equals to rhs. Returns \c true, if the comparison
+ succeeded, otherwise \c false.
+ \since 5.5
+*/
+bool QMetaType::equals(const void *lhs, const void *rhs, int typeId, int *result)
+{
+ const QtPrivate::AbstractComparatorFunction * const f
+ = customTypesComparatorRegistry()->function(typeId);
+ if (!f)
+ return false;
+ if (f->equals(f, lhs, rhs))
+ *result = 0;
+ else
+ *result = -1;
return true;
}
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 5b8c5a6b3d..2ff695b833 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -291,6 +291,24 @@ struct BuiltInComparatorFunction : public AbstractComparatorFunction
}
};
+template<typename T>
+struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction
+{
+ BuiltInEqualsComparatorFunction()
+ : AbstractComparatorFunction(0, equals, destroy) {}
+ static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
+ {
+ const T *lhs = static_cast<const T *>(l);
+ const T *rhs = static_cast<const T *>(r);
+ return *lhs == *rhs;
+ }
+
+ static void destroy(AbstractComparatorFunction *_this)
+ {
+ delete static_cast<BuiltInEqualsComparatorFunction *>(_this);
+ }
+};
+
struct AbstractConverterFunction
{
typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);
@@ -530,6 +548,16 @@ public:
return registerComparatorFunction( &f, typeId);
}
template<typename T>
+ static bool registerEqualsComparator()
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
+ "QMetaType::registerEqualsComparator: The type must be a custom type.");
+ const int typeId = qMetaTypeId<T>();
+ static const QtPrivate::BuiltInEqualsComparatorFunction<T> f;
+ return registerComparatorFunction( &f, typeId);
+ }
+
+ template<typename T>
static bool hasRegisteredComparators()
{
return hasRegisteredComparators(qMetaTypeId<T>());
@@ -610,6 +638,7 @@ public:
static bool convert(const void *from, int fromTypeId, void *to, int toTypeId);
static bool compare(const void *lhs, const void *rhs, int typeId, int* result);
+ static bool equals(const void *lhs, const void *rhs, int typeId, int* result);
static bool debugStream(QDebug& dbg, const void *rhs, int typeId);
template<typename From, typename To>
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 1e71bb8978..3f958138b3 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -3313,7 +3313,7 @@ bool QVariant::cmp(const QVariant &v) const
}
if (v1.d.type >= QMetaType::User) {
int result;
- if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(v1.d)), QT_PREPEND_NAMESPACE(constData(v2.d)), v1.d.type, &result))
+ if (QMetaType::equals(QT_PREPEND_NAMESPACE(constData(v1.d)), QT_PREPEND_NAMESPACE(constData(v2.d)), v1.d.type, &result))
return result == 0;
}
return handlerManager[v1.d.type]->compare(&v1.d, &v2.d);