diff options
Diffstat (limited to 'src/corelib/kernel/qmetatype_p.h')
-rw-r--r-- | src/corelib/kernel/qmetatype_p.h | 255 |
1 files changed, 126 insertions, 129 deletions
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index cdb140a965..7e0457771f 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QMETATYPE_P_H #define QMETATYPE_P_H @@ -56,91 +20,48 @@ QT_BEGIN_NAMESPACE -namespace QModulesPrivate { -enum Names { Core, Gui, Widgets, Unknown, ModulesCount /* ModulesCount has to be at the end */ }; - -static inline int moduleForType(const uint typeId) -{ - if (typeId <= QMetaType::LastCoreType) - return Core; - if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType) - return Gui; - if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType) - return Widgets; - return Unknown; -} - -template <typename T> -class QTypeModuleInfo +#define QMETATYPE_CONVERTER(To, From, assign_and_return) \ + case makePair(QMetaType::To, QMetaType::From): \ + if (onlyCheck) \ + return true; \ + { \ + const From &source = *static_cast<const From *>(from); \ + To &result = *static_cast<To *>(to); \ + assign_and_return \ + } +#define QMETATYPE_CONVERTER_ASSIGN(To, From) \ + QMETATYPE_CONVERTER(To, From, result = To(source); return true;) + +#define QMETATYPE_CONVERTER_FUNCTION(To, assign_and_return) \ + { \ + To &result = *static_cast<To *>(r); \ + assign_and_return \ + } + +class Q_CORE_EXPORT QMetaTypeModuleHelper { + Q_DISABLE_COPY_MOVE(QMetaTypeModuleHelper) +protected: + QMetaTypeModuleHelper() = default; + ~QMetaTypeModuleHelper() = default; public: - enum Module : bool { - IsCore = false, - IsWidget = false, - IsGui = false, - IsUnknown = true - }; -}; + Q_WEAK_OVERLOAD // prevent it from entering the ABI and rendering constexpr useless + static constexpr auto makePair(int from, int to) -> quint64 + { + return (quint64(from) << 32) + quint64(to); + } -#define QT_ASSIGN_TYPE_TO_MODULE(TYPE, MODULE) \ -template<> \ -class QTypeModuleInfo<TYPE > \ -{ \ -public: \ - enum Module : bool { \ - IsCore = (((MODULE) == (QModulesPrivate::Core))), \ - IsWidget = (((MODULE) == (QModulesPrivate::Widgets))), \ - IsGui = (((MODULE) == (QModulesPrivate::Gui))), \ - IsUnknown = !(IsCore || IsWidget || IsGui) \ - }; \ - static inline int module() { return MODULE; } \ - static_assert((IsUnknown && !(IsCore || IsWidget || IsGui)) \ - || (IsCore && !(IsUnknown || IsWidget || IsGui)) \ - || (IsWidget && !(IsUnknown || IsCore || IsGui)) \ - || (IsGui && !(IsUnknown || IsCore || IsWidget))); \ + virtual const QtPrivate::QMetaTypeInterface *interfaceForType(int) const = 0; + virtual bool convert(const void *, int, void *, int) const; }; - -#define QT_DECLARE_CORE_MODULE_TYPES_ITER(TypeName, TypeId, Name) \ - QT_ASSIGN_TYPE_TO_MODULE(Name, QModulesPrivate::Core); -#define QT_DECLARE_GUI_MODULE_TYPES_ITER(TypeName, TypeId, Name) \ - QT_ASSIGN_TYPE_TO_MODULE(Name, QModulesPrivate::Gui); -#define QT_DECLARE_WIDGETS_MODULE_TYPES_ITER(TypeName, TypeId, Name) \ - QT_ASSIGN_TYPE_TO_MODULE(Name, QModulesPrivate::Widgets); - -QT_WARNING_PUSH -#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 900 -QT_WARNING_DISABLE_CLANG("-Wconstant-logical-operand") -#endif - -QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(QT_DECLARE_CORE_MODULE_TYPES_ITER) -QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_DECLARE_CORE_MODULE_TYPES_ITER) -QT_FOR_EACH_STATIC_CORE_CLASS(QT_DECLARE_CORE_MODULE_TYPES_ITER) -QT_FOR_EACH_STATIC_CORE_POINTER(QT_DECLARE_CORE_MODULE_TYPES_ITER) -QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_DECLARE_CORE_MODULE_TYPES_ITER) -QT_FOR_EACH_STATIC_GUI_CLASS(QT_DECLARE_GUI_MODULE_TYPES_ITER) -QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_DECLARE_WIDGETS_MODULE_TYPES_ITER) - -QT_WARNING_POP -} // namespace QModulesPrivate - -#undef QT_DECLARE_CORE_MODULE_TYPES_ITER -#undef QT_DECLARE_GUI_MODULE_TYPES_ITER -#undef QT_DECLARE_WIDGETS_MODULE_TYPES_ITER - -class QMetaTypeModuleHelper -{ -public: - virtual QtPrivate::QMetaTypeInterface *interfaceForType(int) const = 0; -#ifndef QT_NO_DATASTREAM - virtual bool save(QDataStream &stream, int type, const void *data) const = 0; - virtual bool load(QDataStream &stream, int type, void *data) const = 0; -#endif -}; +extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper; +extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeWidgetsHelper; namespace QtMetaTypePrivate { template<typename T> -struct TypeDefinition { +struct TypeDefinition +{ static const bool IsAvailable = true; }; @@ -196,11 +117,99 @@ template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable = template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false; }; #endif +template <typename T> inline bool isInterfaceFor(const QtPrivate::QMetaTypeInterface *iface) +{ + // typeId for built-in types are fixed and require no registration + static_assert(QMetaTypeId2<T>::IsBuiltIn, "This function only works for built-in types"); + static constexpr int typeId = QtPrivate::BuiltinMetaType<T>::value; + return iface->typeId.loadRelaxed() == typeId; +} + +template <typename FPointer> +inline bool checkMetaTypeFlagOrPointer(const QtPrivate::QMetaTypeInterface *iface, FPointer ptr, QMetaType::TypeFlag Flag) +{ + // helper to the isXxxConstructible & isDestructible functions below: a + // meta type has the trait if the trait is trivial or we have the pointer + // to perform the operation + Q_ASSERT(!isInterfaceFor<void>(iface)); + Q_ASSERT(iface->size); + return ptr != nullptr || (iface->flags & Flag) == 0; +} + +inline bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return checkMetaTypeFlagOrPointer(iface, iface->defaultCtr, QMetaType::NeedsConstruction); +} + +inline bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return checkMetaTypeFlagOrPointer(iface, iface->copyCtr, QMetaType::NeedsCopyConstruction); +} + +inline bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return checkMetaTypeFlagOrPointer(iface, iface->moveCtr, QMetaType::NeedsMoveConstruction); +} + +inline bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + /* For metatypes of revision 1, the NeedsDestruction was set even for trivially + destructible types, but their dtor pointer would be null. + For that reason, we need the additional check here. + */ + return iface->revision < 1 || + checkMetaTypeFlagOrPointer(iface, iface->dtor, QMetaType::NeedsDestruction); +} + +inline void defaultConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where) +{ + Q_ASSERT(isDefaultConstructible(iface)); + if (iface->defaultCtr) + iface->defaultCtr(iface, where); + else + memset(where, 0, iface->size); +} + +inline void copyConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy) +{ + Q_ASSERT(isCopyConstructible(iface)); + if (iface->copyCtr) + iface->copyCtr(iface, where, copy); + else + memcpy(where, copy, iface->size); +} + +inline void moveConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, void *copy) +{ + Q_ASSERT(isMoveConstructible(iface)); + if (iface->moveCtr) + iface->moveCtr(iface, where, copy); + else + memcpy(where, copy, iface->size); +} + +inline void construct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy) +{ + if (copy) + copyConstruct(iface, where, copy); + else + defaultConstruct(iface, where); +} + +inline void destruct(const QtPrivate::QMetaTypeInterface *iface, void *where) +{ + Q_ASSERT(isDestructible(iface)); + if (iface->dtor) + iface->dtor(iface, where); +} + +const char *typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d); + template<typename T> -static QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType() +static const QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType() { if constexpr (QtMetaTypePrivate::TypeDefinition<T>::IsAvailable) { - return &QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeForType)<T>::metaType; + return &QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterfaceWrapper)<T>::metaType; } return nullptr; } @@ -209,18 +218,6 @@ static QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType case QMetaType::MetaTypeName: \ return QtMetaTypePrivate::getInterfaceFromType<RealName>(); -#define QT_METATYPE_DATASTREAM_SAVE(MetaTypeName, MetaTypeId, RealName) \ - case QMetaType::MetaTypeName: \ - QtMetaTypePrivate::QMetaTypeFunctionHelper<RealName, QtMetaTypePrivate::TypeDefinition<RealName>::IsAvailable>::Save(stream, data); \ - return true; - -#define QT_METATYPE_DATASTREAM_LOAD(MetaTypeName, MetaTypeId, RealName) \ - case QMetaType::MetaTypeName: \ - QtMetaTypePrivate::QMetaTypeFunctionHelper<RealName, QtMetaTypePrivate::TypeDefinition<RealName>::IsAvailable>::Load(stream, data); \ - return true; - -void derefAndDestroy(QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *d_ptr); - } //namespace QtMetaTypePrivate QT_END_NAMESPACE |