summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.cpp
diff options
context:
space:
mode:
authorChristoph Schleifenbaum <christoph.schleifenbaum@kdab.com>2013-03-09 15:12:20 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-08 06:02:35 +0200
commitf7b313e6d865ac7020c3164c2f6f0232f052eb9b (patch)
tree9afb8af0bf8283db844df7f72540613d1ef51319 /src/corelib/kernel/qmetatype.cpp
parent46d80dedb7794c3e494cc818c85e023beb65626e (diff)
Core: Support for converting user defined QVariant types.
This patchs allows the user to convert defined QMetaType types like MyType to be converted by using e.g. QVariant::toString(), mapping to MyType::toString(). Also all the other QVariant::toXYZ() methods are supported so far. The patch adds static methods QMetaType::registerConverter supporting: - implicit convertion - conversion using member method of source type - conversion using unary functor Change-Id: I4f1db83d9c78bcc9df5c42f82f95cce0480cdcc3 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com> Reviewed-by: Christoph Schleifenbaum <christoph.schleifenbaum@kdab.com> Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
Diffstat (limited to 'src/corelib/kernel/qmetatype.cpp')
-rw-r--r--src/corelib/kernel/qmetatype.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index b9f7462b12..44246e05ca 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -420,6 +420,49 @@ public:
int alias;
};
+class QMetaTypeConversionRegistry
+{
+public:
+ typedef QPair<int, int> Key;
+
+ ~QMetaTypeConversionRegistry()
+ {
+ const QWriteLocker locker(&lock);
+ Q_FOREACH (QtPrivate::AbstractConverterFunction *f, map)
+ f->destroy(f);
+ map.clear();
+ }
+
+ bool contains(int from, int to) const
+ {
+ const Key k(from, to);
+ const QReadLocker locker(&lock);
+ return map.contains(k);
+ }
+
+ bool insertIfNotContains(int from, int to, QtPrivate::AbstractConverterFunction *f)
+ {
+ const Key k(from, to);
+ const QWriteLocker locker(&lock);
+ QtPrivate::AbstractConverterFunction* &fun = map[k];
+ if (fun != 0)
+ return false;
+ fun = f;
+ return true;
+ }
+
+ QtPrivate::AbstractConverterFunction *function(int from, int to) const
+ {
+ const Key k(from, to);
+ const QReadLocker locker(&lock);
+ return map.value(k, 0);
+ }
+
+private:
+ mutable QReadWriteLock lock;
+ QHash<Key, QtPrivate::AbstractConverterFunction *> map;
+};
+
namespace
{
union CheckThatItIsPod
@@ -431,6 +474,85 @@ union CheckThatItIsPod
Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
+Q_GLOBAL_STATIC(QMetaTypeConversionRegistry, customTypesConversionRegistry)
+
+/*!
+ \fn bool QMetaType::registerConverter()
+ \since 5.1
+ Registers the possibility of an implicit conversion from type From to type To in the meta
+ type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(MemberFunction function)
+ \since 5.1
+ \overload
+ Registers a method \a function like To From::function() const as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(MemberFunctionOk function)
+ \since 5.1
+ \overload
+ Registers a method \a function like To From::function(bool *ok) const as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(UnaryFunction function)
+ \since 5.1
+ \overload
+ Registers a unary function object \a function as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ Registers function \a f as converter function from type id \a from to \a to.
+ If there's already a conversion registered, this does nothing but deleting \a f.
+ Returns true if the registration succeeded, otherwise false.
+ \since 5.1
+ \internal
+*/
+bool QMetaType::registerConverterFunction(QtPrivate::AbstractConverterFunction *f, int from, int to)
+{
+ if (!customTypesConversionRegistry()->insertIfNotContains(from, to, f)) {
+ qWarning("Type conversion already registered from type %s to type %s",
+ QMetaType::typeName(from), QMetaType::typeName(to));
+ if (f)
+ f->destroy(f);
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Converts the object at \a from from \a fromTypeId to the preallocated space at \a to
+ typed \a toTypeId. Returns true, if the conversion succeeded, otherwise false.
+ \since 5.1
+*/
+bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId)
+{
+ const QtPrivate::AbstractConverterFunction * const f = customTypesConversionRegistry()->function(fromTypeId, toTypeId);
+ return f && f->convert(f, from, to);
+}
+
+/*!
+ \fn bool QMetaType::hasRegisteredConverterFunction()
+ Returns true, if the meta type system has a registered conversion from type From to type To.
+ \since 5.1
+ \overload
+ */
+
+/*!
+ Returns true, if the meta type system has a registered conversion from meta type id \a fromTypeId
+ to \a toTypeId
+ \since 5.1
+*/
+bool QMetaType::hasRegisteredConverterFunction(int fromTypeId, int toTypeId)
+{
+ return customTypesConversionRegistry()->contains(fromTypeId, toTypeId);
+}
#ifndef QT_NO_DATASTREAM
/*!