1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QMETAOBJECT_H
6#define QMETAOBJECT_H
7
8#include <QtCore/qobjectdefs.h>
9#include <QtCore/qvariant.h>
10
11QT_BEGIN_NAMESPACE
12
13class QUntypedBindable;
14
15#define Q_METAMETHOD_INVOKE_MAX_ARGS 10
16
17class Q_CORE_EXPORT QMetaMethod
18{
19public:
20 constexpr inline QMetaMethod() : mobj(nullptr), data({ .d: nullptr }) {}
21
22 QByteArray methodSignature() const;
23 QByteArray name() const;
24 const char *typeName() const;
25 int returnType() const;
26 QMetaType returnMetaType() const;
27 int parameterCount() const;
28 int parameterType(int index) const;
29 QMetaType parameterMetaType(int index) const;
30 void getParameterTypes(int *types) const;
31 QList<QByteArray> parameterTypes() const;
32 QByteArray parameterTypeName(int index) const;
33 QList<QByteArray> parameterNames() const;
34 const char *tag() const;
35 enum Access { Private, Protected, Public };
36 Access access() const;
37 enum MethodType { Method, Signal, Slot, Constructor };
38 MethodType methodType() const;
39 enum Attributes { Compatibility = 0x1, Cloned = 0x2, Scriptable = 0x4 };
40 int attributes() const;
41 int methodIndex() const;
42 int relativeMethodIndex() const;
43 int revision() const;
44 bool isConst() const;
45
46 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
47
48#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
49 bool invoke(QObject *object,
50 Qt::ConnectionType connectionType,
51 QGenericReturnArgument returnValue,
52 QGenericArgument val0 = QGenericArgument(nullptr),
53 QGenericArgument val1 = QGenericArgument(),
54 QGenericArgument val2 = QGenericArgument(),
55 QGenericArgument val3 = QGenericArgument(),
56 QGenericArgument val4 = QGenericArgument(),
57 QGenericArgument val5 = QGenericArgument(),
58 QGenericArgument val6 = QGenericArgument(),
59 QGenericArgument val7 = QGenericArgument(),
60 QGenericArgument val8 = QGenericArgument(),
61 QGenericArgument val9 = QGenericArgument()) const;
62 inline bool invoke(QObject *object,
63 QGenericReturnArgument returnValue,
64 QGenericArgument val0 = QGenericArgument(nullptr),
65 QGenericArgument val1 = QGenericArgument(),
66 QGenericArgument val2 = QGenericArgument(),
67 QGenericArgument val3 = QGenericArgument(),
68 QGenericArgument val4 = QGenericArgument(),
69 QGenericArgument val5 = QGenericArgument(),
70 QGenericArgument val6 = QGenericArgument(),
71 QGenericArgument val7 = QGenericArgument(),
72 QGenericArgument val8 = QGenericArgument(),
73 QGenericArgument val9 = QGenericArgument()) const
74 {
75 return invoke(object, connectionType: Qt::AutoConnection, returnValue,
76 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
77 }
78 inline bool invoke(QObject *object,
79 Qt::ConnectionType connectionType,
80 QGenericArgument val0,
81 QGenericArgument val1 = QGenericArgument(),
82 QGenericArgument val2 = QGenericArgument(),
83 QGenericArgument val3 = QGenericArgument(),
84 QGenericArgument val4 = QGenericArgument(),
85 QGenericArgument val5 = QGenericArgument(),
86 QGenericArgument val6 = QGenericArgument(),
87 QGenericArgument val7 = QGenericArgument(),
88 QGenericArgument val8 = QGenericArgument(),
89 QGenericArgument val9 = QGenericArgument()) const
90 {
91 return invoke(object, connectionType, returnValue: QGenericReturnArgument(),
92 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
93 }
94 inline bool invoke(QObject *object,
95 QGenericArgument val0,
96 QGenericArgument val1 = QGenericArgument(),
97 QGenericArgument val2 = QGenericArgument(),
98 QGenericArgument val3 = QGenericArgument(),
99 QGenericArgument val4 = QGenericArgument(),
100 QGenericArgument val5 = QGenericArgument(),
101 QGenericArgument val6 = QGenericArgument(),
102 QGenericArgument val7 = QGenericArgument(),
103 QGenericArgument val8 = QGenericArgument(),
104 QGenericArgument val9 = QGenericArgument()) const
105 {
106 return invoke(object, connectionType: Qt::AutoConnection, returnValue: QGenericReturnArgument(),
107 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
108 }
109 bool invokeOnGadget(void *gadget,
110 QGenericReturnArgument returnValue,
111 QGenericArgument val0 = QGenericArgument(nullptr),
112 QGenericArgument val1 = QGenericArgument(),
113 QGenericArgument val2 = QGenericArgument(),
114 QGenericArgument val3 = QGenericArgument(),
115 QGenericArgument val4 = QGenericArgument(),
116 QGenericArgument val5 = QGenericArgument(),
117 QGenericArgument val6 = QGenericArgument(),
118 QGenericArgument val7 = QGenericArgument(),
119 QGenericArgument val8 = QGenericArgument(),
120 QGenericArgument val9 = QGenericArgument()) const;
121 inline bool invokeOnGadget(void *gadget,
122 QGenericArgument val0,
123 QGenericArgument val1 = QGenericArgument(),
124 QGenericArgument val2 = QGenericArgument(),
125 QGenericArgument val3 = QGenericArgument(),
126 QGenericArgument val4 = QGenericArgument(),
127 QGenericArgument val5 = QGenericArgument(),
128 QGenericArgument val6 = QGenericArgument(),
129 QGenericArgument val7 = QGenericArgument(),
130 QGenericArgument val8 = QGenericArgument(),
131 QGenericArgument val9 = QGenericArgument()) const
132 {
133 return invokeOnGadget(gadget, returnValue: QGenericReturnArgument(),
134 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
135 }
136#endif
137
138 template <typename... Args>
139#ifdef Q_QDOC
140 bool
141#else
142 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
143#endif
144 invoke(QObject *obj, Qt::ConnectionType c, QMetaMethodReturnArgument r,
145 Args &&... arguments) const
146 {
147 auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
148 return invokeImpl(self: *this, target: obj, c, paramCount: h.parameterCount(), parameters: h.parameters.data(),
149 typeNames: h.typeNames.data(), metaTypes: h.metaTypes.data());
150 }
151
152 template <typename... Args>
153#ifdef Q_QDOC
154 bool
155#else
156 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
157#endif
158 invoke(QObject *obj, Qt::ConnectionType c, Args &&... arguments) const
159 {
160 return invoke(obj, c, QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
161 }
162
163 template <typename... Args>
164#ifdef Q_QDOC
165 bool
166#else
167 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
168#endif
169 invoke(QObject *obj, QMetaMethodReturnArgument r, Args &&... arguments) const
170 {
171 return invoke(obj, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
172 }
173
174 template <typename... Args>
175#ifdef Q_QDOC
176 bool
177#else
178 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
179#endif
180 invoke(QObject *obj, Args &&... arguments) const
181 {
182 return invoke(obj, Qt::AutoConnection, std::forward<Args>(arguments)...);
183 }
184
185 template <typename... Args>
186#ifdef Q_QDOC
187 bool
188#else
189 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
190#endif
191 invokeOnGadget(void *gadget, QMetaMethodReturnArgument r, Args &&... arguments) const
192 {
193 auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
194 return invokeImpl(self: *this, target: gadget, Qt::ConnectionType(-1), paramCount: h.parameterCount(),
195 parameters: h.parameters.data(), typeNames: h.typeNames.data(), metaTypes: h.metaTypes.data());
196 }
197
198 template <typename... Args>
199#ifdef Q_QDOC
200 bool
201#else
202 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
203#endif
204 invokeOnGadget(void *gadget, Args &&... arguments) const
205 {
206 return invokeOnGadget(gadget, QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
207 }
208
209 inline bool isValid() const { return mobj != nullptr; }
210
211 template <typename PointerToMemberFunction>
212 static inline QMetaMethod fromSignal(PointerToMemberFunction signal)
213 {
214 typedef QtPrivate::FunctionPointer<PointerToMemberFunction> SignalType;
215 static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
216 "No Q_OBJECT in the class with the signal");
217 return fromSignalImpl(&SignalType::Object::staticMetaObject,
218 reinterpret_cast<void **>(&signal));
219 }
220
221private:
222 static bool invokeImpl(QMetaMethod self, void *target, Qt::ConnectionType, qsizetype paramCount,
223 const void *const *parameters, const char *const *typeNames,
224 const QtPrivate::QMetaTypeInterface *const *metaTypes);
225 static QMetaMethod fromSignalImpl(const QMetaObject *, void **);
226 static QMetaMethod fromRelativeMethodIndex(const QMetaObject *mobj, int index);
227 static QMetaMethod fromRelativeConstructorIndex(const QMetaObject *mobj, int index);
228
229protected:
230 struct Data {
231 enum { Size = 6 };
232
233 uint name() const { return d[0]; }
234 uint argc() const { return d[1]; }
235 uint parameters() const { return d[2]; }
236 uint tag() const { return d[3]; }
237 uint flags() const { return d[4]; }
238 uint metaTypeOffset() const { return d[5]; }
239 bool operator==(const Data &other) const { return d == other.d; }
240
241 const uint *d;
242 };
243private:
244 constexpr QMetaMethod(const QMetaObject *metaObject, const Data &data_)
245 : mobj(metaObject), data(data_)
246 {}
247protected:
248
249 const QMetaObject *mobj;
250 Data data;
251 friend struct QMetaObject;
252 friend struct QMetaObjectPrivate;
253 friend class QObject;
254 friend bool operator==(const QMetaMethod &m1, const QMetaMethod &m2) noexcept
255 { return m1.data == m2.data; }
256 friend bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2) noexcept
257 { return !(m1 == m2); }
258};
259Q_DECLARE_TYPEINFO(QMetaMethod, Q_RELOCATABLE_TYPE);
260
261class Q_CORE_EXPORT QMetaEnum
262{
263public:
264 constexpr inline QMetaEnum() : mobj(nullptr), data({ .d: nullptr }) {}
265
266 const char *name() const;
267 const char *enumName() const;
268 QMetaType metaType() const;
269
270 bool isFlag() const;
271 bool isScoped() const;
272
273 int keyCount() const;
274 const char *key(int index) const;
275 int value(int index) const;
276
277 const char *scope() const;
278
279 int keyToValue(const char *key, bool *ok = nullptr) const;
280 const char *valueToKey(int value) const;
281 int keysToValue(const char *keys, bool *ok = nullptr) const;
282 QByteArray valueToKeys(int value) const;
283
284 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
285
286 inline bool isValid() const { return name() != nullptr; }
287
288 template<typename T>
289 static QMetaEnum fromType()
290 {
291 static_assert(QtPrivate::IsQEnumHelper<T>::Value,
292 "QMetaEnum::fromType only works with enums declared as "
293 "Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
294 const QMetaObject *metaObject = qt_getEnumMetaObject(T());
295 const char *name = qt_getEnumName(T());
296 return metaObject->enumerator(index: metaObject->indexOfEnumerator(name));
297 }
298
299private:
300 struct Data {
301 enum { Size = 5 };
302 quint32 name() const { return d[0]; }
303 quint32 alias() const { return d[1]; }
304 quint32 flags() const { return d[2]; }
305 qint32 keyCount() const { return static_cast<qint32>(d[3]); }
306 quint32 data() const { return d[4]; }
307 int index(const QMetaObject *mobj) const;
308
309 const uint *d;
310 };
311
312 QMetaEnum(const QMetaObject *mobj, int index);
313
314 const QMetaObject *mobj;
315 Data data;
316 friend struct QMetaObject;
317 friend struct QMetaObjectPrivate;
318};
319Q_DECLARE_TYPEINFO(QMetaEnum, Q_RELOCATABLE_TYPE);
320
321class Q_CORE_EXPORT QMetaProperty
322{
323public:
324 constexpr QMetaProperty() : mobj(nullptr), data({ .d: nullptr }) {}
325
326 const char *name() const;
327 const char *typeName() const;
328#if QT_DEPRECATED_SINCE(6, 0)
329 QT_WARNING_PUSH
330 QT_WARNING_DISABLE_DEPRECATED
331 QT_DEPRECATED_VERSION_6_0
332 QVariant::Type type() const
333 { int t = userType(); return t >= QMetaType::User ? QVariant::UserType : QVariant::Type(t); }
334 QT_WARNING_POP
335#endif
336 int userType() const { return typeId(); }
337 int typeId() const { return metaType().id(); }
338 QMetaType metaType() const;
339 int propertyIndex() const;
340 int relativePropertyIndex() const;
341
342 bool isReadable() const;
343 bool isWritable() const;
344 bool isResettable() const;
345 bool isDesignable() const;
346 bool isScriptable() const;
347 bool isStored() const;
348 bool isUser() const;
349 bool isConstant() const;
350 bool isFinal() const;
351 bool isRequired() const;
352 bool isBindable() const;
353
354 bool isFlagType() const;
355 bool isEnumType() const;
356 QMetaEnum enumerator() const;
357
358 bool hasNotifySignal() const;
359 QMetaMethod notifySignal() const;
360 int notifySignalIndex() const;
361
362 int revision() const;
363
364 QVariant read(const QObject *obj) const;
365 bool write(QObject *obj, const QVariant &value) const;
366 bool write(QObject *obj, QVariant &&value) const;
367 bool reset(QObject *obj) const;
368
369 QUntypedBindable bindable(QObject *object) const;
370
371 QVariant readOnGadget(const void *gadget) const;
372 bool writeOnGadget(void *gadget, const QVariant &value) const;
373 bool writeOnGadget(void *gadget, QVariant &&value) const;
374 bool resetOnGadget(void *gadget) const;
375
376 bool hasStdCppSet() const;
377 bool isAlias() const;
378 inline bool isValid() const { return isReadable(); }
379 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
380
381private:
382#if QT_DEPRECATED_SINCE(6, 4)
383 QT_DEPRECATED_VERSION_X_6_4("obsolete, simply returns typeId()")
384 int registerPropertyType() const;
385#endif
386
387 struct Data {
388 enum { Size = 5 };
389
390 uint name() const { return d[0]; }
391 uint type() const { return d[1]; }
392 uint flags() const { return d[2]; }
393 uint notifyIndex() const { return d[3]; }
394 uint revision() const { return d[4]; }
395
396 int index(const QMetaObject *mobj) const;
397
398 const uint *d;
399 };
400
401 QMetaProperty(const QMetaObject *mobj, int index);
402 static Data getMetaPropertyData(const QMetaObject *mobj, int index);
403
404 const QMetaObject *mobj;
405 Data data;
406 QMetaEnum menum;
407 friend struct QMetaObject;
408 friend struct QMetaObjectPrivate;
409};
410
411class Q_CORE_EXPORT QMetaClassInfo
412{
413public:
414 constexpr inline QMetaClassInfo() : mobj(nullptr), data({ .d: nullptr }) {}
415 const char *name() const;
416 const char *value() const;
417 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
418
419private:
420 struct Data {
421 enum { Size = 2 };
422
423 uint name() const { return d[0]; }
424 uint value() const { return d[1]; }
425
426 const uint *d;
427 };
428
429 const QMetaObject *mobj;
430 Data data;
431 friend struct QMetaObject;
432};
433Q_DECLARE_TYPEINFO(QMetaClassInfo, Q_RELOCATABLE_TYPE);
434
435QT_END_NAMESPACE
436
437#endif // QMETAOBJECT_H
438

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