From 30da659af5ff4ee33c22a3fc81801cdcbc57d535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= Date: Wed, 23 Nov 2016 19:42:32 +0100 Subject: Introduce QMetaType::PointerToGadget flag for pointers to gadgets A Q_GADGET class can be used both as a value class and a pointer, but right now QMetaType::IsGadget is only set for value types. This change introduces PointerToGadget metatype flag which is set for pointers. This allow for better handling of gadgets in code as well as disambiguating between value types and pointers to value types. Change-Id: Id3bd9e18a8eec7ca1cc6b1c25ed03cdc8c0a75a1 Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qmetatype.h | 47 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'src/corelib/kernel/qmetatype.h') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 3674ebc1a1..5e2e746bbc 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -462,7 +462,8 @@ public: WeakPointerToQObject = 0x40, TrackingPointerToQObject = 0x80, WasDeclaredAsMetaType = 0x100, - IsGadget = 0x200 + IsGadget = 0x200, + PointerToGadget = 0x400 }; Q_DECLARE_FLAGS(TypeFlags, TypeFlag) @@ -1388,6 +1389,19 @@ namespace QtPrivate enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; }; + template + struct IsPointerToGadgetHelper { enum { Value = false }; }; + + template + struct IsPointerToGadgetHelper + { + using BaseType = T; + template + static char checkType(void (X::*)()); + static void *checkType(void (T::*)()); + enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + }; + template char qt_getEnumMetaObject(const T&); @@ -1423,6 +1437,11 @@ namespace QtPrivate static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template + struct MetaObjectForType::Value>::Type> + { + static inline const QMetaObject *value() { return &IsPointerToGadgetHelper::BaseType::staticMetaObject; } + }; + template struct MetaObjectForType::Value>::type > { static inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); } @@ -1578,6 +1597,7 @@ namespace QtPrivate template ::Value ? QMetaType::PointerToQObject : QtPrivate::IsGadgetHelper::Value ? QMetaType::IsGadget : + QtPrivate::IsPointerToGadgetHelper::Value ? QMetaType::PointerToGadget : QtPrivate::IsQEnumHelper::Value ? QMetaType::IsEnumeration : 0> struct QMetaTypeIdQObject { @@ -1631,6 +1651,7 @@ namespace QtPrivate { | (IsTrackingPointerToTypeDerivedFromQObject::Value ? QMetaType::TrackingPointerToQObject : 0) | (std::is_enum::value ? QMetaType::IsEnumeration : 0) | (IsGadgetHelper::Value ? QMetaType::IsGadget : 0) + | (IsPointerToGadgetHelper::Value ? QMetaType::PointerToGadget : 0) }; }; @@ -1797,6 +1818,30 @@ struct QMetaTypeIdQObject } }; +template +struct QMetaTypeIdQObject +{ + enum { + Defined = 1 + }; + + static int qt_metatype_id() + { + static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); + if (const int id = metatype_id.loadAcquire()) + return id; + const char * const cName = T::staticMetaObject.className(); + QByteArray typeName; + typeName.reserve(int(strlen(cName)) + 1); + typeName.append(cName).append('*'); + const int newId = qRegisterNormalizedMetaType( + typeName, + reinterpret_cast(quintptr(-1))); + metatype_id.storeRelease(newId); + return newId; + } +}; + template struct QMetaTypeIdQObject { -- cgit v1.2.3