summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp31
-rw-r--r--src/corelib/kernel/qmetatype.cpp65
-rw-r--r--src/corelib/kernel/qmetatype.h102
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