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);
212 friend bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2);
213};
214Q_DECLARE_TYPEINFO(QMetaMethod, Q_MOVABLE_TYPE);
215
216inline bool operator==(const QMetaMethod &m1, const QMetaMethod &m2)
217{ return m1.data == m2.data; }
218inline bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
219{ return !(m1 == m2); }
220
221class Q_CORE_EXPORT QMetaEnum
222{
223public:
224 constexpr inline QMetaEnum() : mobj(nullptr), data({ nullptr }) {}
225
226 const char *name() const;
227 const char *enumName() const;
228 bool isFlag() const;
229 bool isScoped() const;
230
231 int keyCount() const;
232 const char *key(int index) const;
233 int value(int index) const;
234
235 const char *scope() const;
236
237 int keyToValue(const char *key, bool *ok = nullptr) const;
238 const char *valueToKey(int value) const;
239 int keysToValue(const char *keys, bool *ok = nullptr) const;
240 QByteArray valueToKeys(int value) const;
241
242 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
243
244 inline bool isValid() const { return name() != nullptr; }
245
246 template<typename T>
247 static QMetaEnum fromType()
248 {
249 static_assert(QtPrivate::IsQEnumHelper<T>::Value,
250 "QMetaEnum::fromType only works with enums declared as "
251 "Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
252 const QMetaObject *metaObject = qt_getEnumMetaObject(T());
253 const char *name = qt_getEnumName(T());
254 return metaObject->enumerator(metaObject->indexOfEnumerator(name));
255 }
256
257private:
258 struct Data {
259 enum { Size = 5 };
260 quint32 name() const { return d[0]; }
261 quint32 alias() const { return d[1]; }
262 quint32 flags() const { return d[2]; }
263 qint32 keyCount() const { return static_cast<qint32>(d[3]); }
264 quint32 data() const { return d[4]; }
265
266 const uint *d;
267 };
268
269 QMetaEnum(const QMetaObject *mobj, int index);
270
271 const QMetaObject *mobj;
272 Data data;
273 friend struct QMetaObject;
274 friend struct QMetaObjectPrivate;
275};
276Q_DECLARE_TYPEINFO(QMetaEnum, Q_MOVABLE_TYPE);
277
278class Q_CORE_EXPORT QMetaProperty
279{
280public:
281 constexpr QMetaProperty() : mobj(nullptr), data({ nullptr }) {}
282
283 const char *name() const;
284 const char *typeName() const;
285#if QT_DEPRECATED_SINCE(6, 0)
286 QT_WARNING_PUSH
287 QT_WARNING_DISABLE_DEPRECATED
288 QT_DEPRECATED_VERSION_6_0
289 QVariant::Type type() const
290 { int t = userType(); return t >= QMetaType::User ? QVariant::UserType : QVariant::Type(t); }
291 QT_WARNING_POP
292#endif
293 int userType() const { return metaType().id(); }
294 QMetaType metaType() const;
295 int propertyIndex() const;
296 int relativePropertyIndex() const;
297
298 bool isReadable() const;
299 bool isWritable() const;
300 bool isResettable() const;
301 bool isDesignable() const;
302 bool isScriptable() const;
303 bool isStored() const;
304 bool isUser() const;
305 bool isConstant() const;
306 bool isFinal() const;
307 bool isRequired() const;
308 bool isBindable() const;
309
310 bool isFlagType() const;
311 bool isEnumType() const;
312 QMetaEnum enumerator() const;
313
314 bool hasNotifySignal() const;
315 QMetaMethod notifySignal() const;
316 int notifySignalIndex() const;
317
318 int revision() const;
319
320 QVariant read(const QObject *obj) const;
321 bool write(QObject *obj, const QVariant &value) const;
322 bool reset(QObject *obj) const;
323
324 QUntypedBindable bindable(QObject *object) const;
325
326 QVariant readOnGadget(const void *gadget) const;
327 bool writeOnGadget(void *gadget, const QVariant &value) const;
328 bool resetOnGadget(void *gadget) const;
329
330 bool hasStdCppSet() const;
331 bool isAlias() const;
332 inline bool isValid() const { return isReadable(); }
333 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
334
335private:
336 int registerPropertyType() const;
337
338 struct Data {
339 enum { Size = 5 };
340
341 uint name() const { return d[0]; }
342 uint type() const { return d[1]; }
343 uint flags() const { return d[2]; }
344 uint notifyIndex() const { return d[3]; }
345 uint revision() const { return d[4]; }
346
347 int index(const QMetaObject *mobj) const;
348
349 const uint *d;
350 };
351
352 QMetaProperty(const QMetaObject *mobj, int index);
353
354 const QMetaObject *mobj;
355 Data data;
356 QMetaEnum menum;
357 friend struct QMetaObject;
358 friend struct QMetaObjectPrivate;
359};
360
361class Q_CORE_EXPORT QMetaClassInfo
362{
363public:
364 constexpr inline QMetaClassInfo() : mobj(nullptr), data({ nullptr }) {}
365 const char *name() const;
366 const char *value() const;
367 inline const QMetaObject *enclosingMetaObject() const { return mobj; }
368
369private:
370 struct Data {
371 enum { Size = 2 };
372
373 uint name() const { return d[0]; }
374 uint value() const { return d[1]; }
375
376 const uint *d;
377 };
378
379 const QMetaObject *mobj;
380 Data data;
381 friend struct QMetaObject;
382};
383Q_DECLARE_TYPEINFO(QMetaClassInfo, Q_MOVABLE_TYPE);
384
385QT_END_NAMESPACE
386
387#endif // QMETAOBJECT_H
388