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

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