1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#ifndef QMETAOBJECT_H
42#define QMETAOBJECT_H
43
44#include <QtCore/qobjectdefs.h>
45#include <QtCore/qvariant.h>
46
47QT_BEGIN_NAMESPACE
48
49class QUntypedBindable;
50
51#define Q_METAMETHOD_INVOKE_MAX_ARGS 10
52
53class Q_CORE_EXPORT QMetaMethod
54{
55public:
56 constexpr inline QMetaMethod() : mobj(nullptr), data({ nullptr }) {}
57
58 QByteArray methodSignature() const;
59 QByteArray name() const;
60 const char *typeName() const;
61 int returnType() const;
62 QMetaType returnMetaType() const;
63 int parameterCount() const;
64 int parameterType(int index) const;
65 QMetaType parameterMetaType(int index) const;
66 void getParameterTypes(int *types) const;
67 QList<QByteArray> parameterTypes() const;
68 QByteArray parameterTypeName(int index) const;
69 QList<QByteArray> parameterNames() const;
70 const char *tag() const;
71 enum Access { Private, Protected, Public };
72 Access access() const;
73 enum MethodType { Method, Signal, Slot, Constructor };
74 MethodType methodType() const;
75 enum Attributes { Compatibility = 0x1, Cloned = 0x2, Scriptable = 0x4 };
76 int attributes() const;
77 int methodIndex() const;
78 int relativeMethodIndex() const;
79 int revision() const;
80
81 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
82
83 bool invoke(QObject *object,
84 Qt::ConnectionType connectionType,
85 QGenericReturnArgument returnValue,
86 QGenericArgument val0 = QGenericArgument(nullptr),
87 QGenericArgument val1 = QGenericArgument(),
88 QGenericArgument val2 = QGenericArgument(),
89 QGenericArgument val3 = QGenericArgument(),
90 QGenericArgument val4 = QGenericArgument(),
91 QGenericArgument val5 = QGenericArgument(),
92 QGenericArgument val6 = QGenericArgument(),
93 QGenericArgument val7 = QGenericArgument(),
94 QGenericArgument val8 = QGenericArgument(),
95 QGenericArgument val9 = QGenericArgument()) const;
96 inline bool invoke(QObject *object,
97 QGenericReturnArgument returnValue,
98 QGenericArgument val0 = QGenericArgument(nullptr),
99 QGenericArgument val1 = QGenericArgument(),
100 QGenericArgument val2 = QGenericArgument(),
101 QGenericArgument val3 = QGenericArgument(),
102 QGenericArgument val4 = QGenericArgument(),
103 QGenericArgument val5 = QGenericArgument(),
104 QGenericArgument val6 = QGenericArgument(),
105 QGenericArgument val7 = QGenericArgument(),
106 QGenericArgument val8 = QGenericArgument(),
107 QGenericArgument val9 = QGenericArgument()) const
108 {
109 return invoke(object, Qt::AutoConnection, returnValue,
110 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
111 }
112 inline bool invoke(QObject *object,
113 Qt::ConnectionType connectionType,
114 QGenericArgument val0 = QGenericArgument(nullptr),
115 QGenericArgument val1 = QGenericArgument(),
116 QGenericArgument val2 = QGenericArgument(),
117 QGenericArgument val3 = QGenericArgument(),
118 QGenericArgument val4 = QGenericArgument(),
119 QGenericArgument val5 = QGenericArgument(),
120 QGenericArgument val6 = QGenericArgument(),
121 QGenericArgument val7 = QGenericArgument(),
122 QGenericArgument val8 = QGenericArgument(),
123 QGenericArgument val9 = QGenericArgument()) const
124 {
125 return invoke(object, connectionType, QGenericReturnArgument(),
126 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
127 }
128 inline bool invoke(QObject *object,
129 QGenericArgument val0 = QGenericArgument(nullptr),
130 QGenericArgument val1 = QGenericArgument(),
131 QGenericArgument val2 = QGenericArgument(),
132 QGenericArgument val3 = QGenericArgument(),
133 QGenericArgument val4 = QGenericArgument(),
134 QGenericArgument val5 = QGenericArgument(),
135 QGenericArgument val6 = QGenericArgument(),
136 QGenericArgument val7 = QGenericArgument(),
137 QGenericArgument val8 = QGenericArgument(),
138 QGenericArgument val9 = QGenericArgument()) const
139 {
140 return invoke(object, Qt::AutoConnection, QGenericReturnArgument(),
141 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
142 }
143 bool invokeOnGadget(void *gadget,
144 QGenericReturnArgument returnValue,
145 QGenericArgument val0 = QGenericArgument(nullptr),
146 QGenericArgument val1 = QGenericArgument(),
147 QGenericArgument val2 = QGenericArgument(),
148 QGenericArgument val3 = QGenericArgument(),
149 QGenericArgument val4 = QGenericArgument(),
150 QGenericArgument val5 = QGenericArgument(),
151 QGenericArgument val6 = QGenericArgument(),
152 QGenericArgument val7 = QGenericArgument(),
153 QGenericArgument val8 = QGenericArgument(),
154 QGenericArgument val9 = QGenericArgument()) const;
155 inline bool invokeOnGadget(void *gadget,
156 QGenericArgument val0 = QGenericArgument(nullptr),
157 QGenericArgument val1 = QGenericArgument(),
158 QGenericArgument val2 = QGenericArgument(),
159 QGenericArgument val3 = QGenericArgument(),
160 QGenericArgument val4 = QGenericArgument(),
161 QGenericArgument val5 = QGenericArgument(),
162 QGenericArgument val6 = QGenericArgument(),
163 QGenericArgument val7 = QGenericArgument(),
164 QGenericArgument val8 = QGenericArgument(),
165 QGenericArgument val9 = QGenericArgument()) const
166 {
167 return invokeOnGadget(gadget, QGenericReturnArgument(),
168 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
169 }
170
171 inline bool isValid() const { return mobj != nullptr; }
172
173 template <typename PointerToMemberFunction>
174 static inline QMetaMethod fromSignal(PointerToMemberFunction signal)
175 {
176 typedef QtPrivate::FunctionPointer<PointerToMemberFunction> SignalType;
177 static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
178 "No Q_OBJECT in the class with the signal");
179 return fromSignalImpl(&SignalType::Object::staticMetaObject,
180 reinterpret_cast<void **>(&signal));
181 }
182
183private:
184 static QMetaMethod fromSignalImpl(const QMetaObject *, void **);
185 static QMetaMethod fromRelativeMethodIndex(const QMetaObject *mobj, int index);
186 static QMetaMethod fromRelativeConstructorIndex(const QMetaObject *mobj, int index);
187
188 struct Data {
189 enum { Size = 6 };
190
191 uint name() const { return d[0]; }
192 uint argc() const { return d[1]; }
193 uint parameters() const { return d[2]; }
194 uint tag() const { return d[3]; }
195 uint flags() const { return d[4]; }
196 uint metaTypeOffset() const { return d[5]; }
197 bool operator==(const Data &other) const { return d == other.d; }
198
199 const uint *d;
200 };
201 constexpr QMetaMethod(const QMetaObject *metaObject, const Data &data_)
202 : mobj(metaObject), data(data_)
203 {}
204
205 const QMetaObject *mobj;
206 Data data;
207 friend class QMetaMethodPrivate;
208 friend struct QMetaObject;
209 friend struct QMetaObjectPrivate;
210 friend class QObject;
211 friend bool operator==(const QMetaMethod &m1, const QMetaMethod &m2) noexcept
212 { return m1.data == m2.data; }
213 friend bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2) noexcept
214 { return !(m1 == m2); }
215};
216Q_DECLARE_TYPEINFO(QMetaMethod, Q_RELOCATABLE_TYPE);
217
218class Q_CORE_EXPORT QMetaEnum
219{
220public:
221 constexpr inline QMetaEnum() : mobj(nullptr), data({ nullptr }) {}
222
223 const char *name() const;
224 const char *enumName() const;
225 bool isFlag() const;
226 bool isScoped() const;
227
228 int keyCount() const;
229 const char *key(int index) const;
230 int value(int index) const;
231
232 const char *scope() const;
233
234 int keyToValue(const char *key, bool *ok = nullptr) const;
235 const char *valueToKey(int value) const;
236 int keysToValue(const char *keys, bool *ok = nullptr) const;
237 QByteArray valueToKeys(int value) const;
238
239 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
240
241 inline bool isValid() const { return name() != nullptr; }
242
243 template<typename T>
244 static QMetaEnum fromType()
245 {
246 static_assert(QtPrivate::IsQEnumHelper<T>::Value,
247 "QMetaEnum::fromType only works with enums declared as "
248 "Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
249 const QMetaObject *metaObject = qt_getEnumMetaObject(T());
250 const char *name = qt_getEnumName(T());
251 return metaObject->enumerator(metaObject->indexOfEnumerator(name));
252 }
253
254private:
255 struct Data {
256 enum { Size = 5 };
257 quint32 name() const { return d[0]; }
258 quint32 alias() const { return d[1]; }
259 quint32 flags() const { return d[2]; }
260 qint32 keyCount() const { return static_cast<qint32>(d[3]); }
261 quint32 data() const { return d[4]; }
262
263 const uint *d;
264 };
265
266 QMetaEnum(const QMetaObject *mobj, int index);
267
268 const QMetaObject *mobj;
269 Data data;
270 friend struct QMetaObject;
271 friend struct QMetaObjectPrivate;
272};
273Q_DECLARE_TYPEINFO(QMetaEnum, Q_RELOCATABLE_TYPE);
274
275class Q_CORE_EXPORT QMetaProperty
276{
277public:
278 constexpr QMetaProperty() : mobj(nullptr), data({ nullptr }) {}
279
280 const char *name() const;
281 const char *typeName() const;
282#if QT_DEPRECATED_SINCE(6, 0)
283 QT_WARNING_PUSH
284 QT_WARNING_DISABLE_DEPRECATED
285 QT_DEPRECATED_VERSION_6_0
286 QVariant::Type type() const
287 { int t = userType(); return t >= QMetaType::User ? QVariant::UserType : QVariant::Type(t); }
288 QT_WARNING_POP
289#endif
290 int userType() const { return typeId(); }
291 int typeId() const { return metaType().id(); }
292 QMetaType metaType() const;
293 int propertyIndex() const;
294 int relativePropertyIndex() const;
295
296 bool isReadable() const;
297 bool isWritable() const;
298 bool isResettable() const;
299 bool isDesignable() const;
300 bool isScriptable() const;
301 bool isStored() const;
302 bool isUser() const;
303 bool isConstant() const;
304 bool isFinal() const;
305 bool isRequired() const;
306 bool isBindable() const;
307
308 bool isFlagType() const;
309 bool isEnumType() const;
310 QMetaEnum enumerator() const;
311
312 bool hasNotifySignal() const;
313 QMetaMethod notifySignal() const;
314 int notifySignalIndex() const;
315
316 int revision() const;
317
318 QVariant read(const QObject *obj) const;
319 bool write(QObject *obj, const QVariant &value) const;
320 bool reset(QObject *obj) const;
321
322 QUntypedBindable bindable(QObject *object) const;
323
324 QVariant readOnGadget(const void *gadget) const;
325 bool writeOnGadget(void *gadget, const QVariant &value) const;
326 bool resetOnGadget(void *gadget) const;
327
328 bool hasStdCppSet() const;
329 bool isAlias() const;
330 inline bool isValid() const { return isReadable(); }
331 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
332
333private:
334 int registerPropertyType() const;
335
336 struct Data {
337 enum { Size = 5 };
338
339 uint name() const { return d[0]; }
340 uint type() const { return d[1]; }
341 uint flags() const { return d[2]; }
342 uint notifyIndex() const { return d[3]; }
343 uint revision() const { return d[4]; }
344
345 int index(const QMetaObject *mobj) const;
346
347 const uint *d;
348 };
349
350 QMetaProperty(const QMetaObject *mobj, int index);
351 static Data getMetaPropertyData(const QMetaObject *mobj, int index);
352
353 const QMetaObject *mobj;
354 Data data;
355 QMetaEnum menum;
356 friend struct QMetaObject;
357 friend struct QMetaObjectPrivate;
358};
359
360class Q_CORE_EXPORT QMetaClassInfo
361{
362public:
363 constexpr inline QMetaClassInfo() : mobj(nullptr), data({ nullptr }) {}
364 const char *name() const;
365 const char *value() const;
366 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
367
368private:
369 struct Data {
370 enum { Size = 2 };
371
372 uint name() const { return d[0]; }
373 uint value() const { return d[1]; }
374
375 const uint *d;
376 };
377
378 const QMetaObject *mobj;
379 Data data;
380 friend struct QMetaObject;
381};
382Q_DECLARE_TYPEINFO(QMetaClassInfo, Q_RELOCATABLE_TYPE);
383
384QT_END_NAMESPACE
385
386#endif // QMETAOBJECT_H
387