diff options
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 201 |
1 files changed, 156 insertions, 45 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 7a45e21253..55f8fc9b2c 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1,7 +1,8 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com> +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -10,9 +11,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +24,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -62,6 +63,7 @@ template <typename T> inline Q_DECL_CONSTEXPR int qMetaTypeId(); // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType) +// ### Qt6: reorder the types to match the C++ integral type ranking #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\ F(Void, 43, void) \ F(Bool, 1, bool) \ @@ -111,6 +113,7 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId(); F(QJsonObject, 46, QJsonObject) \ F(QJsonArray, 47, QJsonArray) \ F(QJsonDocument, 48, QJsonDocument) \ + F(QPersistentModelIndex, 50, QPersistentModelIndex) \ #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\ F(QObjectStar, 39, QObject*) @@ -289,6 +292,24 @@ struct BuiltInComparatorFunction : public AbstractComparatorFunction } }; +template<typename T> +struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction +{ + BuiltInEqualsComparatorFunction() + : AbstractComparatorFunction(0, equals, destroy) {} + static bool equals(const AbstractComparatorFunction *, const void *l, const void *r) + { + const T *lhs = static_cast<const T *>(l); + const T *rhs = static_cast<const T *>(r); + return *lhs == *rhs; + } + + static void destroy(AbstractComparatorFunction *_this) + { + delete static_cast<BuiltInEqualsComparatorFunction *>(_this); + } +}; + struct AbstractConverterFunction { typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*); @@ -387,7 +408,7 @@ public: QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID) FirstCoreType = Bool, - LastCoreType = QByteArrayList, + LastCoreType = QPersistentModelIndex, FirstGuiType = QFont, LastGuiType = QPolygonF, FirstWidgetsType = QSizePolicy, @@ -411,7 +432,7 @@ public: QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22, QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27, QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42, - QRegularExpression = 44, + QPersistentModelIndex = 50, QRegularExpression = 44, QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48, QByteArrayList = 49, QObjectStar = 39, SChar = 40, Void = 43, @@ -435,7 +456,8 @@ public: SharedPointerToQObject = 0x20, WeakPointerToQObject = 0x40, TrackingPointerToQObject = 0x80, - WasDeclaredAsMetaType = 0x100 + WasDeclaredAsMetaType = 0x100, + IsGadget = 0x200 }; Q_DECLARE_FLAGS(TypeFlags, TypeFlag) @@ -469,9 +491,19 @@ public: int size, QMetaType::TypeFlags flags, const QMetaObject *metaObject); + static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Destructor destructor, + Constructor constructor, + int size, + QMetaType::TypeFlags flags, + const QMetaObject *metaObject); static int registerTypedef(const char *typeName, int aliasId); static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId); static int type(const char *typeName); +#ifndef Q_QDOC + static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName); +#else + static int type(const QByteArray &typeName); +#endif static const char *typeName(int type); static int sizeOf(int type); static TypeFlags typeFlags(int type); @@ -517,6 +549,16 @@ public: return registerComparatorFunction( &f, typeId); } template<typename T> + static bool registerEqualsComparator() + { + Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn), + "QMetaType::registerEqualsComparator: The type must be a custom type."); + const int typeId = qMetaTypeId<T>(); + static const QtPrivate::BuiltInEqualsComparatorFunction<T> f; + return registerComparatorFunction( &f, typeId); + } + + template<typename T> static bool hasRegisteredComparators() { return hasRegisteredComparators(qMetaTypeId<T>()); @@ -597,6 +639,7 @@ public: static bool convert(const void *from, int fromTypeId, void *to, int toTypeId); static bool compare(const void *lhs, const void *rhs, int typeId, int* result); + static bool equals(const void *lhs, const void *rhs, int typeId, int* result); static bool debugStream(QDebug& dbg, const void *rhs, int typeId); template<typename From, typename To> @@ -640,16 +683,13 @@ private: static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type); #endif +// ### Qt6: FIXME: Remove the special Q_CC_MSVC handling, it was introduced to maintain BC. #if !defined(Q_NO_TEMPLATE_FRIENDS) && !defined(Q_CC_MSVC) #ifndef Q_QDOC - template<typename T> - friend bool qRegisterSequentialConverter(); template<typename, bool> friend struct QtPrivate::ValueTypeIsMetaType; template<typename, typename> friend struct QtPrivate::ConverterMemberFunction; template<typename, typename> friend struct QtPrivate::ConverterMemberFunctionOk; template<typename, typename, typename> friend struct QtPrivate::ConverterFunctor; - template<typename T> - friend bool qRegisterAssociativeConverter(); template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType; template<typename, bool> friend struct QtPrivate::IsMetaTypePair; template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper; @@ -661,8 +701,8 @@ public: static void unregisterConverterFunction(int from, int to); private: - Creator m_creator; - Deleter m_deleter; + Creator m_creator_unused; + Deleter m_deleter_unused; SaveOperator m_saveOp; LoadOperator m_loadOp; Constructor m_constructor; @@ -702,18 +742,6 @@ ConverterFunctor<From, To, UnaryFunction>::~ConverterFunctor() namespace QtMetaTypePrivate { template <typename T, bool Accepted = true> struct QMetaTypeFunctionHelper { - static void Delete(void *t) - { - delete static_cast<T*>(t); - } - - static void *Create(const void *t) - { - if (t) - return new T(*static_cast<const T*>(t)); - return new T(); - } - static void Destruct(void *t) { Q_UNUSED(t) // Silence MSVC that warns for POD types. @@ -741,8 +769,6 @@ struct QMetaTypeFunctionHelper { template <typename T> struct QMetaTypeFunctionHelper<T, /* Accepted */ false> { - static void Delete(void *) {} - static void *Create(const void *) { return 0; } static void Destruct(void *) {} static void *Construct(void *, const void *) { return 0; } #ifndef QT_NO_DATASTREAM @@ -1330,17 +1356,51 @@ namespace QtPrivate enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) }; }; - template<typename T, bool = IsPointerToTypeDerivedFromQObject<T>::Value> + template<typename T> + struct IsGadgetHelper + { + template<typename X> static typename X::QtGadgetHelper *checkType(X*); + static char checkType(void*); + enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(void*) }; + }; + + template<typename T> char qt_getEnumMetaObject(const T&); + + template<typename T> + struct IsQEnumHelper { + static const T &declval(); + // If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject() declared in the + // Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*. + // Otherwise the chosen overload will be the catch all template function + // qt_getEnumMetaObject(T) which returns 'char' + enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) }; + }; + + template<typename T, typename Enable = void> struct MetaObjectForType { static inline const QMetaObject *value() { return 0; } }; - + template<> + struct MetaObjectForType<void> + { + static inline const QMetaObject *value() { return Q_NULLPTR; } + }; + template<typename T> + struct MetaObjectForType<T*, typename QEnableIf<IsPointerToTypeDerivedFromQObject<T*>::Value>::Type> + { + static inline const QMetaObject *value() { return &T::staticMetaObject; } + }; template<typename T> - struct MetaObjectForType<T*, /* isPointerToTypeDerivedFromQObject = */ true> + struct MetaObjectForType<T, typename QEnableIf<IsGadgetHelper<T>::Value>::Type> { static inline const QMetaObject *value() { return &T::staticMetaObject; } }; + template<typename T> + struct MetaObjectForType<T, typename QEnableIf<IsQEnumHelper<T>::Value>::Type > + { + static inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); } + }; template<typename T> struct IsSharedPointerToTypeDerivedFromQObject @@ -1489,7 +1549,10 @@ namespace QtPrivate Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type); } // namespace QtPrivate -template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value> +template <typename T, int = + QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : + QtPrivate::IsGadgetHelper<T>::Value ? QMetaType::IsGadget : + QtPrivate::IsQEnumHelper<T>::Value ? QMetaType::IsEnumeration : 0> struct QMetaTypeIdQObject { enum { @@ -1512,6 +1575,9 @@ struct QMetaTypeId2 template <typename T> struct QMetaTypeId2<const T&> : QMetaTypeId2<T> {}; +template <typename T> +struct QMetaTypeId2<T&> { enum {Defined = false }; }; + namespace QtPrivate { template <typename T, bool Defined = QMetaTypeId2<T>::Defined> struct QMetaTypeIdHelper { @@ -1545,6 +1611,7 @@ namespace QtPrivate { | (IsWeakPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::WeakPointerToQObject : 0) | (IsTrackingPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::TrackingPointerToQObject : 0) | (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0) + | (IsGadgetHelper<T>::Value ? QMetaType::IsGadget : 0) }; }; @@ -1594,8 +1661,6 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz flags |= QMetaType::WasDeclaredAsMetaType; const int id = QMetaType::registerNormalizedType(normalizedTypeName, - QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Delete, - QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Create, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct, int(sizeof(T)), @@ -1667,8 +1732,9 @@ QT_DEPRECATED inline Q_DECL_CONSTEXPR int qRegisterMetaType(T *) #endif #endif +#ifndef QT_NO_QOBJECT template <typename T> -struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true> +struct QMetaTypeIdQObject<T*, QMetaType::PointerToQObject> { enum { Defined = 1 @@ -1691,6 +1757,53 @@ struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true> } }; +template <typename T> +struct QMetaTypeIdQObject<T, QMetaType::IsGadget> +{ + 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(); + const int newId = qRegisterNormalizedMetaType<T>( + cName, + reinterpret_cast<T*>(quintptr(-1))); + metatype_id.storeRelease(newId); + return newId; + } +}; + +template <typename T> +struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration> +{ + 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 *eName = qt_getEnumName(T()); + const char *cName = qt_getEnumMetaObject(T())->className(); + QByteArray typeName; + typeName.reserve(int(strlen(cName) + 2 + strlen(eName))); + typeName.append(cName).append("::").append(eName); + const int newId = qRegisterNormalizedMetaType<T>( + typeName, + reinterpret_cast<T*>(quintptr(-1))); + metatype_id.storeRelease(newId); + return newId; + } +}; +#endif + #ifndef QT_NO_DATASTREAM template <typename T> inline int qRegisterMetaTypeStreamOperators() @@ -1964,8 +2077,8 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI uint theTypeFlags, int typeId, const QMetaObject *_metaObject) - : m_creator(creator) - , m_deleter(deleter) + : m_creator_unused(creator) + , m_deleter_unused(deleter) , m_saveOp(saveOp) , m_loadOp(loadOp) , m_constructor(constructor) @@ -1999,16 +2112,14 @@ inline bool QMetaType::isRegistered() const inline void *QMetaType::create(const void *copy) const { - if (Q_UNLIKELY(isExtended(CreateEx))) - return createExtended(copy); - return m_creator(copy); + // ### TODO Qt6 remove the extension + return createExtended(copy); } inline void QMetaType::destroy(void *data) const { - if (Q_UNLIKELY(isExtended(DestroyEx))) - return destroyExtended(data); - m_deleter(data); + // ### TODO Qt6 remove the extension + destroyExtended(data); } inline void *QMetaType::construct(void *where, const void *copy) const |