diff options
author | Stephen Kelly <stephen.kelly@kdab.com> | 2013-09-08 12:08:22 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-09 21:28:41 +0200 |
commit | a1898f4466518bf3e1b6e9154eec05ecf9d909e3 (patch) | |
tree | 7bd00c197258d89038aa9e03941e326d174571a9 /src/corelib | |
parent | 7fb3906d4e7cec7c69feee007b8393c9c2a3a316 (diff) |
Metatype: Remove the need for runtime-registration of 3rd party containers.
Replace that need with a macro so that registration of the
container helper conversions is done at the time of registration
of the container (usually when it is put into a QVariant).
Change-Id: I823fb3fdbce306ebc9f146675ac43724cec678d5
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp | 31 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 65 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 102 |
3 files changed, 98 insertions, 100 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp index 4437313f0a..cb1346f74c 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp @@ -112,3 +112,34 @@ id = qMetaTypeId<MyStruct>(); // compile error if MyStruct not declared typedef QString CustomString; qRegisterMetaType<CustomString>("CustomString"); //! [9] + +//! [10] + +#include <deque> + +Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::deque) + +void someFunc() +{ + std::deque<QFile*> container; + QVariant var = QVariant::fromValue(container); + // ... +} + +//! [10] + +//! [11] + +#include <unordered_list> + +Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::unordered_map) + +void someFunc() +{ + std::unordered_map<int, bool> container; + QVariant var = QVariant::fromValue(container); + // ... +} + +//! [11] + diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 17fbbda720..2ab6681bb9 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -141,6 +141,40 @@ struct DefinedTypesFilter { */ /*! + \macro Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(Container) + \relates QMetaType + + This macro makes the container \a Container known to QMetaType as a sequential + container. This makes it possible to put an instance of Container<T> into + a QVariant, if T itself is known to QMetaType. + + Note that all of the Qt sequential containers already have built-in + support, and it is not necessary to use this macro with them. The + std::vector and std::list containers also have built-in support. + + This example shows a typical use of Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(): + + \snippet code/src_corelib_kernel_qmetatype.cpp 10 +*/ + +/*! + \macro Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(Container) + \relates QMetaType + + This macro makes the container \a Container known to QMetaType as an associative + container. This makes it possible to put an instance of Container<T, U> into + a QVariant, if T and U are themselves known to QMetaType. + + Note that all of the Qt associative containers already have built-in + support, and it is not necessary to use this macro with them. The + std::map container also has built-in support. + + This example shows a typical use of Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(): + + \snippet code/src_corelib_kernel_qmetatype.cpp 11 +*/ + +/*! \enum QMetaType::Type These are the built-in types supported by QMetaType: @@ -2085,37 +2119,6 @@ const QMetaObject *QMetaType::metaObjectForType(int type) \sa Q_DECLARE_METATYPE(), QMetaType::type() */ -/*! - \fn bool qRegisterSequentialConverter() - \relates QMetaType - \since 5.2 - - Registers a sequential container so that it can be converted to - a QVariantList. If compilation fails, then you probably forgot to - Q_DECLARE_METATYPE the value type. - - Note that it is not necessary to call this method for Qt containers (QList, - QVector etc) or for std::vector or std::list. Such containers are automatically - registered by Qt. - - \sa QVariant::canConvert() -*/ - -/*! - \fn bool qRegisterAssociativeConverter() - \relates QMetaType - \since 5.2 - - Registers an associative container so that it can be converted to - a QVariantHash or QVariantMap. If the key_type and mapped_type of the container - was not declared with Q_DECLARE_METATYPE(), compilation will fail. - - Note that it is not necessary to call this method for Qt containers (QHash, - QMap etc) or for std::map. Such containers are automatically registered by Qt. - - \sa QVariant::canConvert() -*/ - namespace { class TypeInfo { template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted> diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 6b1a988fce..bd4963e4f1 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1331,33 +1331,12 @@ namespace QtPrivate enum { Value = false }; }; -#define QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(CONTAINER) \ - template<typename T> \ - struct IsSequentialContainer<CONTAINER<T> > \ - { \ - enum { Value = true }; \ - }; - QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE) - QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(std::vector) - QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(std::list) - template<typename T> struct IsAssociativeContainer { enum { Value = false }; }; -#define QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(CONTAINER) \ - template<typename T, typename U> \ - struct IsAssociativeContainer<CONTAINER<T, U> > \ - { \ - enum { Value = true }; \ - }; - QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(QHash) - QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(QMap) - QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(std::map) - - template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value> struct SequentialContainerConverterHelper { @@ -1763,6 +1742,13 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \ return newId; \ } \ }; \ +namespace QtPrivate { \ +template<typename T> \ +struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \ +{ \ + enum { Value = true }; \ +}; \ +} \ QT_END_NAMESPACE #define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \ @@ -1851,7 +1837,7 @@ struct QMetaTypeId< SMART_POINTER<T> > \ };\ QT_END_NAMESPACE -#define Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER(TEMPLATENAME) \ +#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \ QT_BEGIN_NAMESPACE \ template <class T> class TEMPLATENAME; \ QT_END_NAMESPACE \ @@ -1859,25 +1845,42 @@ QT_END_NAMESPACE QT_END_NAMESPACE -QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER) +QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER) + +#undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER -#undef Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER +#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE Q_DECLARE_METATYPE_TEMPLATE_1ARG -Q_DECLARE_METATYPE_TEMPLATE_1ARG(std::vector) -Q_DECLARE_METATYPE_TEMPLATE_1ARG(std::list) +Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector) +Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list) -#define Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \ +#define Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \ QT_BEGIN_NAMESPACE \ template <class T1, class T2> CPPTYPE TEMPLATENAME; \ QT_END_NAMESPACE \ - Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME) -QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER) +QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER) #undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER +#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \ + QT_BEGIN_NAMESPACE \ + namespace QtPrivate { \ + template<typename T, typename U> \ + struct IsAssociativeContainer<TEMPLATENAME<T, U> > \ + { \ + enum { Value = true }; \ + }; \ + } \ + QT_END_NAMESPACE \ + Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME) + +Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash) +Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap) +Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map) + +Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair) Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair) -Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::map) #define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \ Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME) @@ -2009,45 +2012,6 @@ inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter(int id) return true; } - -#ifndef Q_QDOC -template<typename T> -#endif -bool qRegisterSequentialConverter() -{ - Q_STATIC_ASSERT_X(QMetaTypeId2<typename T::value_type>::Defined, - "The value_type of a sequential container must itself be a metatype."); - const int id = qMetaTypeId<T>(); - const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>(); - if (QMetaType::hasRegisteredConverterFunction(id, toId)) - return true; - - static const QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o; - static const QtPrivate::ConverterFunctor<T, - QtMetaTypePrivate::QSequentialIterableImpl, - QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o); - return QMetaType::registerConverterFunction(&f, id, toId); -} - -template<typename T> -bool qRegisterAssociativeConverter() -{ - Q_STATIC_ASSERT_X(QMetaTypeId2<typename T::key_type>::Defined - && QMetaTypeId2<typename T::mapped_type>::Defined, - "The key_type and mapped_type of an associative container must themselves be metatypes."); - - const int id = qMetaTypeId<T>(); - const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>(); - if (QMetaType::hasRegisteredConverterFunction(id, toId)) - return true; - static const QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o; - static const QtPrivate::ConverterFunctor<T, - QtMetaTypePrivate::QAssociativeIterableImpl, - QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o); - - return QMetaType::registerConverterFunction(&f, id, toId); -} - QT_END_NAMESPACE #endif // QMETATYPE_H |