diff options
author | Christoph Schleifenbaum <christoph.schleifenbaum@kdab.com> | 2013-03-09 15:12:20 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-05-08 06:02:35 +0200 |
commit | f7b313e6d865ac7020c3164c2f6f0232f052eb9b (patch) | |
tree | 9afb8af0bf8283db844df7f72540613d1ef51319 /src/corelib/kernel/qmetatype.cpp | |
parent | 46d80dedb7794c3e494cc818c85e023beb65626e (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.cpp | 122 |
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 /*! |