1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QMETATYPE_P_H
41 #define QMETATYPE_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include <QtCore/private/qglobal_p.h>
55 #include "qmetatype.h"
56 
57 QT_BEGIN_NAMESPACE
58 
59 namespace QModulesPrivate {
60 enum Names { Core, Gui, Widgets, Unknown, ModulesCount /* ModulesCount has to be at the end */ };
61 
moduleForType(const uint typeId)62 static inline int moduleForType(const uint typeId)
63 {
64     if (typeId <= QMetaType::LastCoreType)
65         return Core;
66     if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType)
67         return Gui;
68     if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType)
69         return Widgets;
70     return Unknown;
71 }
72 
73 template <typename T>
74 class QTypeModuleInfo
75 {
76 public:
77     enum Module : bool {
78         IsCore = false,
79         IsWidget = false,
80         IsGui = false,
81         IsUnknown = true
82     };
83 };
84 
85 #define QT_ASSIGN_TYPE_TO_MODULE(TYPE, MODULE) \
86 template<> \
87 class QTypeModuleInfo<TYPE > \
88 { \
89 public: \
90     enum Module : bool { \
91         IsCore = (((MODULE) == (QModulesPrivate::Core))), \
92         IsWidget = (((MODULE) == (QModulesPrivate::Widgets))), \
93         IsGui = (((MODULE) == (QModulesPrivate::Gui))), \
94         IsUnknown = !(IsCore || IsWidget || IsGui) \
95     }; \
96     static inline int module() { return MODULE; } \
97     Q_STATIC_ASSERT((IsUnknown && !(IsCore || IsWidget || IsGui)) \
98                  || (IsCore && !(IsUnknown || IsWidget || IsGui)) \
99                  || (IsWidget && !(IsUnknown || IsCore || IsGui)) \
100                  || (IsGui && !(IsUnknown || IsCore || IsWidget))); \
101 };
102 
103 
104 #define QT_DECLARE_CORE_MODULE_TYPES_ITER(TypeName, TypeId, Name) \
105     QT_ASSIGN_TYPE_TO_MODULE(Name, QModulesPrivate::Core);
106 #define QT_DECLARE_GUI_MODULE_TYPES_ITER(TypeName, TypeId, Name) \
107     QT_ASSIGN_TYPE_TO_MODULE(Name, QModulesPrivate::Gui);
108 #define QT_DECLARE_WIDGETS_MODULE_TYPES_ITER(TypeName, TypeId, Name) \
109     QT_ASSIGN_TYPE_TO_MODULE(Name, QModulesPrivate::Widgets);
110 
111 QT_WARNING_PUSH
112 #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 900
113 QT_WARNING_DISABLE_CLANG("-Wconstant-logical-operand")
114 #endif
115 
116 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(QT_DECLARE_CORE_MODULE_TYPES_ITER)
117 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_DECLARE_CORE_MODULE_TYPES_ITER)
118 QT_FOR_EACH_STATIC_CORE_CLASS(QT_DECLARE_CORE_MODULE_TYPES_ITER)
119 QT_FOR_EACH_STATIC_CORE_POINTER(QT_DECLARE_CORE_MODULE_TYPES_ITER)
120 QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_DECLARE_CORE_MODULE_TYPES_ITER)
121 QT_FOR_EACH_STATIC_GUI_CLASS(QT_DECLARE_GUI_MODULE_TYPES_ITER)
122 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_DECLARE_WIDGETS_MODULE_TYPES_ITER)
123 
124 QT_WARNING_POP
125 } // namespace QModulesPrivate
126 
127 #undef QT_DECLARE_CORE_MODULE_TYPES_ITER
128 #undef QT_DECLARE_GUI_MODULE_TYPES_ITER
129 #undef QT_DECLARE_WIDGETS_MODULE_TYPES_ITER
130 
131 class QMetaTypeInterface
132 {
133 public:
134     QMetaType::SaveOperator saveOp;
135     QMetaType::LoadOperator loadOp;
136     QMetaType::Constructor constructor; // TODO Qt6: remove me
137     QMetaType::Destructor destructor;
138     int size;
139     QMetaType::TypeFlags::Int flags;
140     const QMetaObject *metaObject;
141     QMetaType::TypedConstructor typedConstructor;
142     QMetaType::TypedDestructor typedDestructor;
143 };
144 
145 #ifndef QT_NO_DATASTREAM
146 #  define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
147     /*saveOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Save), \
148     /*loadOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Load),
149 #  define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \
150     /*saveOp*/ nullptr, \
151     /*loadOp*/ nullptr,
152 #else
153 #  define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \
154     /*saveOp*/ nullptr, \
155     /*loadOp*/ nullptr,
156 #  define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
157     QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type)
158 #endif
159 
160 #ifndef QT_BOOTSTRAPPED
161 #define METAOBJECT_DELEGATE(Type) (QtPrivate::MetaObjectForType<Type>::value())
162 #else
163 #define METAOBJECT_DELEGATE(Type) nullptr
164 #endif
165 
166 #define QT_METATYPE_INTERFACE_INIT_IMPL(Type, DATASTREAM_DELEGATE) \
167 { \
168     DATASTREAM_DELEGATE(Type) \
169     /*constructor*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Construct), \
170     /*destructor*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Destruct), \
171     /*size*/(QTypeInfo<Type>::sizeOf), \
172     /*flags*/QtPrivate::QMetaTypeTypeFlags<Type>::Flags, \
173     /*metaObject*/METAOBJECT_DELEGATE(Type), \
174     /*typedConstructor*/ nullptr, \
175     /*typedDestructor*/ nullptr \
176 }
177 
178 
179 /* These  QT_METATYPE_INTERFACE_INIT* macros are used to initialize QMetaTypeInterface instance.
180 
181  - QT_METATYPE_INTERFACE_INIT(Type) -> It takes Type argument and creates all necessary wrapper functions for the Type,
182    it detects if QT_NO_DATASTREAM was defined. Probably it is the macro that you want to use.
183 
184  - QT_METATYPE_INTERFACE_INIT_EMPTY() -> It initializes an empty QMetaTypeInterface instance.
185 
186  - QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(Type) -> Temporary workaround for missing auto-detection of data stream
187    operators. It creates same instance as QT_METATYPE_INTERFACE_INIT(Type) but with null stream operators callbacks.
188  */
189 #define QT_METATYPE_INTERFACE_INIT(Type) QT_METATYPE_INTERFACE_INIT_IMPL(Type, QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL)
190 #define QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(Type) QT_METATYPE_INTERFACE_INIT_IMPL(Type, QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL)
191 #define QT_METATYPE_INTERFACE_INIT_EMPTY() \
192 { \
193     QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(void) \
194     /*constructor*/ nullptr, \
195     /*destructor*/ nullptr, \
196     /*size*/ 0, \
197     /*flags*/ 0, \
198     /*metaObject*/ nullptr , \
199     /*typedConstructor*/ nullptr, \
200     /*typedDestructor*/ nullptr \
201 }
202 
203 namespace QtMetaTypePrivate {
204 template<typename T>
205 struct TypeDefinition {
206     static const bool IsAvailable = true;
207 };
208 
209 // Ignore these types, as incomplete
210 #ifdef QT_BOOTSTRAPPED
211 template<> struct TypeDefinition<QBitArray> { static const bool IsAvailable = false; };
212 template<> struct TypeDefinition<QCborArray> { static const bool IsAvailable = false; };
213 template<> struct TypeDefinition<QCborMap> { static const bool IsAvailable = false; };
214 template<> struct TypeDefinition<QCborSimpleType> { static const bool IsAvailable = false; };
215 template<> struct TypeDefinition<QCborValue> { static const bool IsAvailable = false; };
216 #if QT_CONFIG(easingcurve)
217 template<> struct TypeDefinition<QEasingCurve> { static const bool IsAvailable = false; };
218 #endif
219 template<> struct TypeDefinition<QJsonArray> { static const bool IsAvailable = false; };
220 template<> struct TypeDefinition<QJsonDocument> { static const bool IsAvailable = false; };
221 template<> struct TypeDefinition<QJsonObject> { static const bool IsAvailable = false; };
222 template<> struct TypeDefinition<QJsonValue> { static const bool IsAvailable = false; };
223 template<> struct TypeDefinition<QUrl> { static const bool IsAvailable = false; };
224 template<> struct TypeDefinition<QByteArrayList> { static const bool IsAvailable = false; };
225 #endif
226 #ifdef QT_NO_GEOM_VARIANT
227 template<> struct TypeDefinition<QRect> { static const bool IsAvailable = false; };
228 template<> struct TypeDefinition<QRectF> { static const bool IsAvailable = false; };
229 template<> struct TypeDefinition<QSize> { static const bool IsAvailable = false; };
230 template<> struct TypeDefinition<QSizeF> { static const bool IsAvailable = false; };
231 template<> struct TypeDefinition<QLine> { static const bool IsAvailable = false; };
232 template<> struct TypeDefinition<QLineF> { static const bool IsAvailable = false; };
233 template<> struct TypeDefinition<QPoint> { static const bool IsAvailable = false; };
234 template<> struct TypeDefinition<QPointF> { static const bool IsAvailable = false; };
235 #endif
236 #ifdef QT_NO_REGEXP
237 template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = false; };
238 #endif
239 #if !QT_CONFIG(regularexpression)
240 template<> struct TypeDefinition<QRegularExpression> { static const bool IsAvailable = false; };
241 #endif
242 #ifdef QT_NO_SHORTCUT
243 template<> struct TypeDefinition<QKeySequence> { static const bool IsAvailable = false; };
244 #endif
245 #ifdef QT_NO_CURSOR
246 template<> struct TypeDefinition<QCursor> { static const bool IsAvailable = false; };
247 #endif
248 #ifdef QT_NO_MATRIX4X4
249 template<> struct TypeDefinition<QMatrix4x4> { static const bool IsAvailable = false; };
250 #endif
251 #ifdef QT_NO_VECTOR2D
252 template<> struct TypeDefinition<QVector2D> { static const bool IsAvailable = false; };
253 #endif
254 #ifdef QT_NO_VECTOR3D
255 template<> struct TypeDefinition<QVector3D> { static const bool IsAvailable = false; };
256 #endif
257 #ifdef QT_NO_VECTOR4D
258 template<> struct TypeDefinition<QVector4D> { static const bool IsAvailable = false; };
259 #endif
260 #ifdef QT_NO_QUATERNION
261 template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable = false; };
262 #endif
263 #ifdef QT_NO_ICON
264 template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false; };
265 #endif
266 } //namespace QtMetaTypePrivate
267 
268 QT_END_NAMESPACE
269 
270 #endif // QMETATYPE_P_H
271