summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.h
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2013-09-08 08:49:29 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-11 12:24:42 +0200
commit546d52e605b6a74d9a5be26fb374b831a46f2550 (patch)
treec48f2e75179c44f5bee37ee2c5d8b8afcc4d072a /src/corelib/kernel/qmetatype.h
parent3256856bbea22da03109b84ef407e8dbc69930e7 (diff)
Add a convenient way to get a type-erased smart pointer from a QVariant.
Any known smart pointer in a QVariant can be handled in this way. The metatype system can be informed of new smart pointer types using an existing macro which is now documented. This is very similar to the existing infrastructure for containers. Change-Id: Iac4f9fabbc5a0626c04e1185d51d720b8b54603d Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r--src/corelib/kernel/qmetatype.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index bd4963e4f1..2d9133dbae 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -373,6 +373,8 @@ struct ConverterFunctor : public AbstractConverterFunction
struct AssociativeValueTypeIsMetaType;
template<typename T, bool>
struct IsMetaTypePair;
+ template<typename, typename>
+ struct MetaTypeSmartPointerHelper;
}
class Q_CORE_EXPORT QMetaType {
@@ -656,6 +658,7 @@ private:
friend bool qRegisterAssociativeConverter();
template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
+ template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper;
#endif
#else
public:
@@ -1463,6 +1466,12 @@ namespace QtPrivate
template<typename T>
struct MetaTypePairHelper : IsPair<T> {};
+ template<typename T, typename = void>
+ struct MetaTypeSmartPointerHelper
+ {
+ static bool registerConverter(int) { return false; }
+ };
+
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
@@ -1530,6 +1539,24 @@ namespace QtPrivate {
{
enum DefinedType { Defined = defined };
};
+
+ template<typename SmartPointer>
+ struct QSmartPointerConvertFunctor
+ {
+ QObject* operator()(const SmartPointer &p) const
+ {
+ return p.operator->();
+ }
+ };
+
+ template<typename T>
+ struct QSmartPointerConvertFunctor<QWeakPointer<T> >
+ {
+ QObject* operator()(const QWeakPointer<T> &p) const
+ {
+ return p.data();
+ }
+ };
}
template <typename T>
@@ -1565,6 +1592,7 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
+ QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id);
}
return id;
@@ -1828,6 +1856,23 @@ struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
return newId; \
} \
}; \
+template<typename T> \
+struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
+ typename QEnableIf<IsPointerToTypeDerivedFromQObject<T*>::Value >::Type> \
+{ \
+ static bool registerConverter(int id) \
+ { \
+ const int toId = QMetaType::QObjectStar; \
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { \
+ QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
+ static const QtPrivate::ConverterFunctor<SMART_POINTER<T>, \
+ QObject*, \
+ QSmartPointerConvertFunctor<SMART_POINTER<T> > > f(o); \
+ return QMetaType::registerConverterFunction(&f, id, toId); \
+ } \
+ return true; \
+ } \
+}; \
} \
template <typename T> \
struct QMetaTypeId< SMART_POINTER<T> > \