1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QMETATYPE_P_H
5#define QMETATYPE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/private/qglobal_p.h>
19#include "qmetatype.h"
20
21QT_BEGIN_NAMESPACE
22
23#define QMETATYPE_CONVERTER(To, From, assign_and_return) \
24 case makePair(QMetaType::To, QMetaType::From): \
25 if (onlyCheck) \
26 return true; \
27 { \
28 const From &source = *static_cast<const From *>(from); \
29 To &result = *static_cast<To *>(to); \
30 assign_and_return \
31 }
32#define QMETATYPE_CONVERTER_ASSIGN(To, From) \
33 QMETATYPE_CONVERTER(To, From, result = To(source); return true;)
34
35#define QMETATYPE_CONVERTER_FUNCTION(To, assign_and_return) \
36 { \
37 To &result = *static_cast<To *>(r); \
38 assign_and_return \
39 }
40
41class QMetaTypeModuleHelper
42{
43 Q_DISABLE_COPY_MOVE(QMetaTypeModuleHelper)
44protected:
45 QMetaTypeModuleHelper() = default;
46 ~QMetaTypeModuleHelper() = default;
47public:
48 static constexpr auto makePair(int from, int to) -> quint64
49 {
50 return (quint64(from) << 32) + quint64(to);
51 }
52
53 virtual const QtPrivate::QMetaTypeInterface *interfaceForType(int) const = 0;
54 virtual bool convert(const void *, int, void *, int) const { return false; }
55};
56
57extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper;
58extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeWidgetsHelper;
59
60namespace QtMetaTypePrivate {
61template<typename T>
62struct TypeDefinition
63{
64 static const bool IsAvailable = true;
65};
66
67// Ignore these types, as incomplete
68#ifdef QT_BOOTSTRAPPED
69template<> struct TypeDefinition<QBitArray> { static const bool IsAvailable = false; };
70template<> struct TypeDefinition<QCborArray> { static const bool IsAvailable = false; };
71template<> struct TypeDefinition<QCborMap> { static const bool IsAvailable = false; };
72template<> struct TypeDefinition<QCborSimpleType> { static const bool IsAvailable = false; };
73template<> struct TypeDefinition<QCborValue> { static const bool IsAvailable = false; };
74#if QT_CONFIG(easingcurve)
75template<> struct TypeDefinition<QEasingCurve> { static const bool IsAvailable = false; };
76#endif
77template<> struct TypeDefinition<QJsonArray> { static const bool IsAvailable = false; };
78template<> struct TypeDefinition<QJsonDocument> { static const bool IsAvailable = false; };
79template<> struct TypeDefinition<QJsonObject> { static const bool IsAvailable = false; };
80template<> struct TypeDefinition<QJsonValue> { static const bool IsAvailable = false; };
81template<> struct TypeDefinition<QUrl> { static const bool IsAvailable = false; };
82template<> struct TypeDefinition<QByteArrayList> { static const bool IsAvailable = false; };
83#endif
84#ifdef QT_NO_GEOM_VARIANT
85template<> struct TypeDefinition<QRect> { static const bool IsAvailable = false; };
86template<> struct TypeDefinition<QRectF> { static const bool IsAvailable = false; };
87template<> struct TypeDefinition<QSize> { static const bool IsAvailable = false; };
88template<> struct TypeDefinition<QSizeF> { static const bool IsAvailable = false; };
89template<> struct TypeDefinition<QLine> { static const bool IsAvailable = false; };
90template<> struct TypeDefinition<QLineF> { static const bool IsAvailable = false; };
91template<> struct TypeDefinition<QPoint> { static const bool IsAvailable = false; };
92template<> struct TypeDefinition<QPointF> { static const bool IsAvailable = false; };
93#endif
94#if !QT_CONFIG(regularexpression)
95template<> struct TypeDefinition<QRegularExpression> { static const bool IsAvailable = false; };
96#endif
97#ifdef QT_NO_CURSOR
98template<> struct TypeDefinition<QCursor> { static const bool IsAvailable = false; };
99#endif
100#ifdef QT_NO_MATRIX4X4
101template<> struct TypeDefinition<QMatrix4x4> { static const bool IsAvailable = false; };
102#endif
103#ifdef QT_NO_VECTOR2D
104template<> struct TypeDefinition<QVector2D> { static const bool IsAvailable = false; };
105#endif
106#ifdef QT_NO_VECTOR3D
107template<> struct TypeDefinition<QVector3D> { static const bool IsAvailable = false; };
108#endif
109#ifdef QT_NO_VECTOR4D
110template<> struct TypeDefinition<QVector4D> { static const bool IsAvailable = false; };
111#endif
112#ifdef QT_NO_QUATERNION
113template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable = false; };
114#endif
115#ifdef QT_NO_ICON
116template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false; };
117#endif
118
119template <typename T> inline bool isInterfaceFor(const QtPrivate::QMetaTypeInterface *iface)
120{
121 // typeId for built-in types are fixed and require no registration
122 static_assert(QMetaTypeId2<T>::IsBuiltIn, "This function only works for built-in types");
123 static constexpr int typeId = QtPrivate::BuiltinMetaType<T>::value;
124 return iface->typeId.loadRelaxed() == typeId;
125}
126
127template <typename FPointer>
128inline bool checkMetaTypeFlagOrPointer(const QtPrivate::QMetaTypeInterface *iface, FPointer ptr, QMetaType::TypeFlag Flag)
129{
130 // helper to the isXxxConstructible & isDestructible functions below: a
131 // meta type has the trait if the trait is trivial or we have the pointer
132 // to perform the operation
133 Q_ASSERT(!isInterfaceFor<void>(iface));
134 Q_ASSERT(iface->size);
135 return ptr != nullptr || (iface->flags & Flag) == 0;
136}
137
138inline bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
139{
140 return checkMetaTypeFlagOrPointer(iface, ptr: iface->defaultCtr, Flag: QMetaType::NeedsConstruction);
141}
142
143inline bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
144{
145 return checkMetaTypeFlagOrPointer(iface, ptr: iface->copyCtr, Flag: QMetaType::NeedsCopyConstruction);
146}
147
148inline bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
149{
150 return checkMetaTypeFlagOrPointer(iface, ptr: iface->moveCtr, Flag: QMetaType::NeedsMoveConstruction);
151}
152
153inline bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
154{
155 /* For metatypes of revision 1, the NeedsDestruction was set even for trivially
156 destructible types, but their dtor pointer would be null.
157 For that reason, we need the additional check here.
158 */
159 return iface->revision < 1 ||
160 checkMetaTypeFlagOrPointer(iface, ptr: iface->dtor, Flag: QMetaType::NeedsDestruction);
161}
162
163inline void defaultConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where)
164{
165 Q_ASSERT(isDefaultConstructible(iface));
166 if (iface->defaultCtr)
167 iface->defaultCtr(iface, where);
168 else
169 memset(s: where, c: 0, n: iface->size);
170}
171
172inline void copyConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy)
173{
174 Q_ASSERT(isCopyConstructible(iface));
175 if (iface->copyCtr)
176 iface->copyCtr(iface, where, copy);
177 else
178 memcpy(dest: where, src: copy, n: iface->size);
179}
180
181inline void moveConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, void *copy)
182{
183 Q_ASSERT(isMoveConstructible(iface));
184 if (iface->moveCtr)
185 iface->moveCtr(iface, where, copy);
186 else
187 memcpy(dest: where, src: copy, n: iface->size);
188}
189
190inline void construct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy)
191{
192 if (copy)
193 copyConstruct(iface, where, copy);
194 else
195 defaultConstruct(iface, where);
196}
197
198inline void destruct(const QtPrivate::QMetaTypeInterface *iface, void *where)
199{
200 Q_ASSERT(isDestructible(iface));
201 if (iface->dtor)
202 iface->dtor(iface, where);
203}
204
205const char *typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d);
206
207template<typename T>
208static const QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType()
209{
210 if constexpr (QtMetaTypePrivate::TypeDefinition<T>::IsAvailable) {
211 return &QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterfaceWrapper)<T>::metaType;
212 }
213 return nullptr;
214}
215
216#define QT_METATYPE_CONVERT_ID_TO_TYPE(MetaTypeName, MetaTypeId, RealName) \
217 case QMetaType::MetaTypeName: \
218 return QtMetaTypePrivate::getInterfaceFromType<RealName>();
219
220} //namespace QtMetaTypePrivate
221
222QT_END_NAMESPACE
223
224#endif // QMETATYPE_P_H
225

source code of qtbase/src/corelib/kernel/qmetatype_p.h