diff options
author | Nils Jeisecke <nils.jeisecke@saltation.com> | 2018-03-02 16:57:11 +0100 |
---|---|---|
committer | Nils Jeisecke <nils.jeisecke@saltation.com> | 2018-03-10 06:12:24 +0000 |
commit | fee8944cbe2a976e1b4a71c5df048e84a0bc6db0 (patch) | |
tree | 210fe33464d31b577f92a078faa2fed738540788 /src | |
parent | b767c7363f7ceda88553fb8abb6d4cb70b70bd2f (diff) |
Allow use of template class instances inheriting from a Q_GADGET in Qml
The Q_GADGET macro cannot be used in templates. It can however be useful
to derive a template class from a Q_GADGET enabled base class to benefit
from type safety features in C++ (e.g. the class could represent an id
or handle for some C++ type).
For proper wrapping of a QVariant with a gadget value in a QJSValue, the
QMetaType::IsGadget flag must be set for the registered template
instance type - which does not happen prior to the fix because
IsGadgetHelper requires qt_check_for_QGADGET_macro to be defined in the
registered class but not in an ancestor class - in other words: The
class must declare Q_GADGET.
To overcome this, IsGadgetHelper/IsPointerToGadgetHelper can now
differentiate between a Q_GADGET flagged class (allowing
automatic registration) and a derived class, e.g. a template class
(forcing Q_DECLARE_METATYPE to be used explicitly).
[ChangeLog][QtCore][QMetaObject] It is now possible to use template
class instances inheriting from a Q_GADGET in Qml
Task-number: QTBUG-66744
Change-Id: I7632ad45cff79fa422b3f852ca0b963f35fab155
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 455d0350e0..4674efe568 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1381,7 +1381,7 @@ namespace QtPrivate }; template<typename T, typename Enable = void> - struct IsGadgetHelper { enum { Value = false }; }; + struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; template<typename T> struct IsGadgetHelper<T, typename T::QtGadgetHelper> @@ -1389,11 +1389,14 @@ namespace QtPrivate template <typename X> static char checkType(void (X::*)()); static void *checkType(void (T::*)()); - enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + enum { + IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), + IsGadgetOrDerivedFrom = true + }; }; template<typename T, typename Enable = void> - struct IsPointerToGadgetHelper { enum { Value = false }; }; + struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; template<typename T> struct IsPointerToGadgetHelper<T*, typename T::QtGadgetHelper> @@ -1402,7 +1405,10 @@ namespace QtPrivate template <typename X> static char checkType(void (X::*)()); static void *checkType(void (T::*)()); - enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + enum { + IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), + IsGadgetOrDerivedFrom = true + }; }; @@ -1435,12 +1441,12 @@ namespace QtPrivate static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template<typename T> - struct MetaObjectForType<T, typename std::enable_if<IsGadgetHelper<T>::Value>::type> + struct MetaObjectForType<T, typename std::enable_if<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>::type> { static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template<typename T> - struct MetaObjectForType<T, typename QEnableIf<IsPointerToGadgetHelper<T>::Value>::Type> + struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type> { static inline const QMetaObject *value() { return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject; } }; @@ -1599,8 +1605,8 @@ namespace QtPrivate template <typename T, int = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : - QtPrivate::IsGadgetHelper<T>::Value ? QMetaType::IsGadget : - QtPrivate::IsPointerToGadgetHelper<T>::Value ? QMetaType::PointerToGadget : + QtPrivate::IsGadgetHelper<T>::IsRealGadget ? QMetaType::IsGadget : + QtPrivate::IsPointerToGadgetHelper<T>::IsRealGadget ? QMetaType::PointerToGadget : QtPrivate::IsQEnumHelper<T>::Value ? QMetaType::IsEnumeration : 0> struct QMetaTypeIdQObject { @@ -1653,8 +1659,8 @@ namespace QtPrivate { | (IsWeakPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::WeakPointerToQObject : 0) | (IsTrackingPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::TrackingPointerToQObject : 0) | (std::is_enum<T>::value ? QMetaType::IsEnumeration : 0) - | (IsGadgetHelper<T>::Value ? QMetaType::IsGadget : 0) - | (IsPointerToGadgetHelper<T>::Value ? QMetaType::PointerToGadget : 0) + | (IsGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::IsGadget : 0) + | (IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::PointerToGadget : 0) }; }; |