1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Copyright (C) 2019 Intel Corporation.
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 QOBJECTDEFS_H
42 #define QOBJECTDEFS_H
43 
44 #if defined(__OBJC__) && !defined(__cplusplus)
45 #  warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
46 #endif
47 
48 #include <QtCore/qnamespace.h>
49 
50 #include <QtCore/qobjectdefs_impl.h>
51 
52 QT_BEGIN_NAMESPACE
53 
54 
55 class QByteArray;
56 struct QArrayData;
57 typedef QArrayData QByteArrayData;
58 
59 class QString;
60 #ifndef Q_MOC_OUTPUT_REVISION
61 #define Q_MOC_OUTPUT_REVISION 67
62 #endif
63 
64 // The following macros can be defined by tools that understand Qt
65 // to have the information from the macro.
66 #ifndef QT_ANNOTATE_CLASS
67 # define QT_ANNOTATE_CLASS(type, ...)
68 #endif
69 #ifndef QT_ANNOTATE_CLASS2
70 # define QT_ANNOTATE_CLASS2(type, a1, a2)
71 #endif
72 #ifndef QT_ANNOTATE_FUNCTION
73 # define QT_ANNOTATE_FUNCTION(x)
74 #endif
75 #ifndef QT_ANNOTATE_ACCESS_SPECIFIER
76 # define QT_ANNOTATE_ACCESS_SPECIFIER(x)
77 #endif
78 
79 // The following macros are our "extensions" to C++
80 // They are used, strictly speaking, only by the moc.
81 
82 #ifndef Q_MOC_RUN
83 #ifndef QT_NO_META_MACROS
84 # if defined(QT_NO_KEYWORDS)
85 #  define QT_NO_EMIT
86 # else
87 #   ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
88 #     define slots Q_SLOTS
89 #     define signals Q_SIGNALS
90 #   endif
91 # endif
92 # define Q_SLOTS QT_ANNOTATE_ACCESS_SPECIFIER(qt_slot)
93 # define Q_SIGNALS public QT_ANNOTATE_ACCESS_SPECIFIER(qt_signal)
94 # define Q_PRIVATE_SLOT(d, signature) QT_ANNOTATE_CLASS2(qt_private_slot, d, signature)
95 # define Q_EMIT
96 #ifndef QT_NO_EMIT
97 # define emit
98 #endif
99 #ifndef Q_CLASSINFO
100 # define Q_CLASSINFO(name, value)
101 #endif
102 #define Q_PLUGIN_METADATA(x) QT_ANNOTATE_CLASS(qt_plugin_metadata, x)
103 #define Q_INTERFACES(x) QT_ANNOTATE_CLASS(qt_interfaces, x)
104 #define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)
105 #define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text)
106 #ifndef Q_REVISION
107 # define Q_REVISION(v)
108 #endif
109 #define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text)
110 #define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text)
111 #define Q_ENUMS(x) QT_ANNOTATE_CLASS(qt_enums, x)
112 #define Q_FLAGS(x) QT_ANNOTATE_CLASS(qt_enums, x)
113 #define Q_ENUM_IMPL(ENUM) \
114     friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
115     friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
116 #define Q_ENUM(x) Q_ENUMS(x) Q_ENUM_IMPL(x)
117 #define Q_FLAG(x) Q_FLAGS(x) Q_ENUM_IMPL(x)
118 #define Q_ENUM_NS_IMPL(ENUM) \
119     inline Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
120     inline Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
121 #define Q_ENUM_NS(x) Q_ENUMS(x) Q_ENUM_NS_IMPL(x)
122 #define Q_FLAG_NS(x) Q_FLAGS(x) Q_ENUM_NS_IMPL(x)
123 #define Q_SCRIPTABLE QT_ANNOTATE_FUNCTION(qt_scriptable)
124 #define Q_INVOKABLE  QT_ANNOTATE_FUNCTION(qt_invokable)
125 #define Q_SIGNAL QT_ANNOTATE_FUNCTION(qt_signal)
126 #define Q_SLOT QT_ANNOTATE_FUNCTION(qt_slot)
127 #endif // QT_NO_META_MACROS
128 
129 #ifndef QT_NO_TRANSLATION
130 // full set of tr functions
131 #  define QT_TR_FUNCTIONS \
132     static inline QString tr(const char *s, const char *c = nullptr, int n = -1) \
133         { return staticMetaObject.tr(s, c, n); } \
134     QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) \
135         { return staticMetaObject.tr(s, c, n); }
136 #else
137 // inherit the ones from QObject
138 # define QT_TR_FUNCTIONS
139 #endif
140 
141 #ifdef Q_CLANG_QDOC
142 #define QT_TR_FUNCTIONS
143 #endif
144 
145 // ### Qt6: remove
146 #define Q_OBJECT_CHECK  /* empty, unused since Qt 5.2 */
147 
148 #if defined(Q_CC_INTEL)
149 // Cannot redefine the visibility of a method in an exported class
150 # define Q_DECL_HIDDEN_STATIC_METACALL
151 #else
152 # define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN
153 #endif
154 
155 #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
156 #  define Q_OBJECT_NO_OVERRIDE_WARNING      QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
157 #elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501
158 #  define Q_OBJECT_NO_OVERRIDE_WARNING      QT_WARNING_DISABLE_GCC("-Wsuggest-override")
159 #else
160 #  define Q_OBJECT_NO_OVERRIDE_WARNING
161 #endif
162 
163 #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 600
164 #  define Q_OBJECT_NO_ATTRIBUTES_WARNING    QT_WARNING_DISABLE_GCC("-Wattributes")
165 #else
166 #  define Q_OBJECT_NO_ATTRIBUTES_WARNING
167 #endif
168 
169 /* qmake ignore Q_OBJECT */
170 #define Q_OBJECT \
171 public: \
172     QT_WARNING_PUSH \
173     Q_OBJECT_NO_OVERRIDE_WARNING \
174     static const QMetaObject staticMetaObject; \
175     virtual const QMetaObject *metaObject() const; \
176     virtual void *qt_metacast(const char *); \
177     virtual int qt_metacall(QMetaObject::Call, int, void **); \
178     QT_TR_FUNCTIONS \
179 private: \
180     Q_OBJECT_NO_ATTRIBUTES_WARNING \
181     Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
182     QT_WARNING_POP \
183     struct QPrivateSignal {}; \
184     QT_ANNOTATE_CLASS(qt_qobject, "")
185 
186 /* qmake ignore Q_OBJECT */
187 #define Q_OBJECT_FAKE Q_OBJECT QT_ANNOTATE_CLASS(qt_fake, "")
188 
189 #ifndef QT_NO_META_MACROS
190 /* qmake ignore Q_GADGET */
191 #define Q_GADGET \
192 public: \
193     static const QMetaObject staticMetaObject; \
194     void qt_check_for_QGADGET_macro(); \
195     typedef void QtGadgetHelper; \
196 private: \
197     QT_WARNING_PUSH \
198     Q_OBJECT_NO_ATTRIBUTES_WARNING \
199     Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
200     QT_WARNING_POP \
201     QT_ANNOTATE_CLASS(qt_qgadget, "") \
202     /*end*/
203 
204 /* qmake ignore Q_NAMESPACE_EXPORT */
205 #define Q_NAMESPACE_EXPORT(...) \
206     extern __VA_ARGS__ const QMetaObject staticMetaObject; \
207     QT_ANNOTATE_CLASS(qt_qnamespace, "") \
208     /*end*/
209 
210 /* qmake ignore Q_NAMESPACE */
211 #define Q_NAMESPACE Q_NAMESPACE_EXPORT() \
212     /*end*/
213 
214 #endif // QT_NO_META_MACROS
215 
216 #else // Q_MOC_RUN
217 #define slots slots
218 #define signals signals
219 #define Q_SLOTS Q_SLOTS
220 #define Q_SIGNALS Q_SIGNALS
221 #define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value)
222 #define Q_INTERFACES(x) Q_INTERFACES(x)
223 #define Q_PROPERTY(text) Q_PROPERTY(text)
224 #define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
225 #define Q_REVISION(v) Q_REVISION(v)
226 #define Q_OVERRIDE(text) Q_OVERRIDE(text)
227 #define Q_ENUMS(x) Q_ENUMS(x)
228 #define Q_FLAGS(x) Q_FLAGS(x)
229 #define Q_ENUM(x) Q_ENUM(x)
230 #define Q_FLAGS(x) Q_FLAGS(x)
231  /* qmake ignore Q_OBJECT */
232 #define Q_OBJECT Q_OBJECT
233  /* qmake ignore Q_OBJECT */
234 #define Q_OBJECT_FAKE Q_OBJECT_FAKE
235  /* qmake ignore Q_GADGET */
236 #define Q_GADGET Q_GADGET
237 #define Q_SCRIPTABLE Q_SCRIPTABLE
238 #define Q_INVOKABLE Q_INVOKABLE
239 #define Q_SIGNAL Q_SIGNAL
240 #define Q_SLOT Q_SLOT
241 #endif //Q_MOC_RUN
242 
243 #ifndef QT_NO_META_MACROS
244 // macro for onaming members
245 #ifdef METHOD
246 #undef METHOD
247 #endif
248 #ifdef SLOT
249 #undef SLOT
250 #endif
251 #ifdef SIGNAL
252 #undef SIGNAL
253 #endif
254 #endif // QT_NO_META_MACROS
255 
256 Q_CORE_EXPORT const char *qFlagLocation(const char *method);
257 
258 #ifndef QT_NO_META_MACROS
259 #ifndef QT_NO_DEBUG
260 # define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
261 # ifndef QT_NO_KEYWORDS
262 #  define METHOD(a)   qFlagLocation("0"#a QLOCATION)
263 # endif
264 # define SLOT(a)     qFlagLocation("1"#a QLOCATION)
265 # define SIGNAL(a)   qFlagLocation("2"#a QLOCATION)
266 #else
267 # ifndef QT_NO_KEYWORDS
268 #  define METHOD(a)   "0"#a
269 # endif
270 # define SLOT(a)     "1"#a
271 # define SIGNAL(a)   "2"#a
272 #endif
273 
274 #define QMETHOD_CODE  0                        // member type codes
275 #define QSLOT_CODE    1
276 #define QSIGNAL_CODE  2
277 #endif // QT_NO_META_MACROS
278 
279 #define Q_ARG(type, data) QArgument<type >(#type, data)
280 #define Q_RETURN_ARG(type, data) QReturnArgument<type >(#type, data)
281 
282 class QObject;
283 class QMetaMethod;
284 class QMetaEnum;
285 class QMetaProperty;
286 class QMetaClassInfo;
287 
288 
289 class Q_CORE_EXPORT QGenericArgument
290 {
291 public:
292     inline QGenericArgument(const char *aName = nullptr, const void *aData = nullptr)
_data(aData)293         : _data(aData), _name(aName) {}
data()294     inline void *data() const { return const_cast<void *>(_data); }
name()295     inline const char *name() const { return _name; }
296 
297 private:
298     const void *_data;
299     const char *_name;
300 };
301 
302 class Q_CORE_EXPORT QGenericReturnArgument: public QGenericArgument
303 {
304 public:
305     inline QGenericReturnArgument(const char *aName = nullptr, void *aData = nullptr)
QGenericArgument(aName,aData)306         : QGenericArgument(aName, aData)
307         {}
308 };
309 
310 template <class T>
311 class QArgument: public QGenericArgument
312 {
313 public:
QArgument(const char * aName,const T & aData)314     inline QArgument(const char *aName, const T &aData)
315         : QGenericArgument(aName, static_cast<const void *>(&aData))
316         {}
317 };
318 template <class T>
319 class QArgument<T &>: public QGenericArgument
320 {
321 public:
QArgument(const char * aName,T & aData)322     inline QArgument(const char *aName, T &aData)
323         : QGenericArgument(aName, static_cast<const void *>(&aData))
324         {}
325 };
326 
327 
328 template <typename T>
329 class QReturnArgument: public QGenericReturnArgument
330 {
331 public:
QReturnArgument(const char * aName,T & aData)332     inline QReturnArgument(const char *aName, T &aData)
333         : QGenericReturnArgument(aName, static_cast<void *>(&aData))
334         {}
335 };
336 
337 struct Q_CORE_EXPORT QMetaObject
338 {
339     class Connection;
340     const char *className() const;
341     const QMetaObject *superClass() const;
342 
343     bool inherits(const QMetaObject *metaObject) const noexcept;
344     QObject *cast(QObject *obj) const;
345     const QObject *cast(const QObject *obj) const;
346 
347 #if !defined(QT_NO_TRANSLATION) || defined(Q_CLANG_QDOC)
348     QString tr(const char *s, const char *c, int n = -1) const;
349 #endif // QT_NO_TRANSLATION
350 
351     int methodOffset() const;
352     int enumeratorOffset() const;
353     int propertyOffset() const;
354     int classInfoOffset() const;
355 
356     int constructorCount() const;
357     int methodCount() const;
358     int enumeratorCount() const;
359     int propertyCount() const;
360     int classInfoCount() const;
361 
362     int indexOfConstructor(const char *constructor) const;
363     int indexOfMethod(const char *method) const;
364     int indexOfSignal(const char *signal) const;
365     int indexOfSlot(const char *slot) const;
366     int indexOfEnumerator(const char *name) const;
367     int indexOfProperty(const char *name) const;
368     int indexOfClassInfo(const char *name) const;
369 
370     QMetaMethod constructor(int index) const;
371     QMetaMethod method(int index) const;
372     QMetaEnum enumerator(int index) const;
373     QMetaProperty property(int index) const;
374     QMetaClassInfo classInfo(int index) const;
375     QMetaProperty userProperty() const;
376 
377     static bool checkConnectArgs(const char *signal, const char *method);
378     static bool checkConnectArgs(const QMetaMethod &signal,
379                                  const QMetaMethod &method);
380     static QByteArray normalizedSignature(const char *method);
381     static QByteArray normalizedType(const char *type);
382 
383     // internal index-based connect
384     static Connection connect(const QObject *sender, int signal_index,
385                         const QObject *receiver, int method_index,
386                         int type = 0, int *types = nullptr);
387     // internal index-based disconnect
388     static bool disconnect(const QObject *sender, int signal_index,
389                            const QObject *receiver, int method_index);
390     static bool disconnectOne(const QObject *sender, int signal_index,
391                               const QObject *receiver, int method_index);
392     // internal slot-name based connect
393     static void connectSlotsByName(QObject *o);
394 
395     // internal index-based signal activation
396     static void activate(QObject *sender, int signal_index, void **argv);
397     static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
398     static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv);
399 
400     static bool invokeMethod(QObject *obj, const char *member,
401                              Qt::ConnectionType,
402                              QGenericReturnArgument ret,
403                              QGenericArgument val0 = QGenericArgument(nullptr),
404                              QGenericArgument val1 = QGenericArgument(),
405                              QGenericArgument val2 = QGenericArgument(),
406                              QGenericArgument val3 = QGenericArgument(),
407                              QGenericArgument val4 = QGenericArgument(),
408                              QGenericArgument val5 = QGenericArgument(),
409                              QGenericArgument val6 = QGenericArgument(),
410                              QGenericArgument val7 = QGenericArgument(),
411                              QGenericArgument val8 = QGenericArgument(),
412                              QGenericArgument val9 = QGenericArgument());
413 
414     static inline bool invokeMethod(QObject *obj, const char *member,
415                              QGenericReturnArgument ret,
416                              QGenericArgument val0 = QGenericArgument(nullptr),
417                              QGenericArgument val1 = QGenericArgument(),
418                              QGenericArgument val2 = QGenericArgument(),
419                              QGenericArgument val3 = QGenericArgument(),
420                              QGenericArgument val4 = QGenericArgument(),
421                              QGenericArgument val5 = QGenericArgument(),
422                              QGenericArgument val6 = QGenericArgument(),
423                              QGenericArgument val7 = QGenericArgument(),
424                              QGenericArgument val8 = QGenericArgument(),
425                              QGenericArgument val9 = QGenericArgument())
426     {
427         return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3,
428                 val4, val5, val6, val7, val8, val9);
429     }
430 
431     static inline bool invokeMethod(QObject *obj, const char *member,
432                              Qt::ConnectionType type,
433                              QGenericArgument val0 = QGenericArgument(nullptr),
434                              QGenericArgument val1 = QGenericArgument(),
435                              QGenericArgument val2 = QGenericArgument(),
436                              QGenericArgument val3 = QGenericArgument(),
437                              QGenericArgument val4 = QGenericArgument(),
438                              QGenericArgument val5 = QGenericArgument(),
439                              QGenericArgument val6 = QGenericArgument(),
440                              QGenericArgument val7 = QGenericArgument(),
441                              QGenericArgument val8 = QGenericArgument(),
442                              QGenericArgument val9 = QGenericArgument())
443     {
444         return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2,
445                                  val3, val4, val5, val6, val7, val8, val9);
446     }
447 
448     static inline bool invokeMethod(QObject *obj, const char *member,
449                              QGenericArgument val0 = QGenericArgument(nullptr),
450                              QGenericArgument val1 = QGenericArgument(),
451                              QGenericArgument val2 = QGenericArgument(),
452                              QGenericArgument val3 = QGenericArgument(),
453                              QGenericArgument val4 = QGenericArgument(),
454                              QGenericArgument val5 = QGenericArgument(),
455                              QGenericArgument val6 = QGenericArgument(),
456                              QGenericArgument val7 = QGenericArgument(),
457                              QGenericArgument val8 = QGenericArgument(),
458                              QGenericArgument val9 = QGenericArgument())
459     {
460         return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0,
461                 val1, val2, val3, val4, val5, val6, val7, val8, val9);
462     }
463 
464 #ifdef Q_CLANG_QDOC
465     template<typename Functor, typename FunctorReturnType>
466     static bool invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr);
467     template<typename Functor, typename FunctorReturnType>
468     static bool invokeMethod(QObject *context, Functor function, FunctorReturnType *ret);
469 #else
470 
471     // invokeMethod() for member function pointer
472     template <typename Func>
473     static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
474                                    && !std::is_convertible<Func, const char*>::value
475                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
476     invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object,
477                  Func function,
478                  Qt::ConnectionType type = Qt::AutoConnection,
479                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr)
480     {
481         return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), type, ret);
482     }
483 
484     template <typename Func>
485     static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
486                                    && !std::is_convertible<Func, const char*>::value
487                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
invokeMethodQMetaObject488     invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object,
489                  Func function,
490                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret)
491     {
492         return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), Qt::AutoConnection, ret);
493     }
494 
495     // invokeMethod() for function pointer (not member)
496     template <typename Func>
497     static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
498                                    && !std::is_convertible<Func, const char*>::value
499                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
500     invokeMethod(QObject *context, Func function,
501                  Qt::ConnectionType type = Qt::AutoConnection,
502                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr)
503     {
504         return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), type, ret);
505     }
506 
507     template <typename Func>
508     static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
509                                    && !std::is_convertible<Func, const char*>::value
510                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
invokeMethodQMetaObject511     invokeMethod(QObject *context, Func function,
512                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret)
513     {
514         return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), Qt::AutoConnection, ret);
515     }
516 
517     // invokeMethod() for Functor
518     template <typename Func>
519     static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
520                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
521                                    && !std::is_convertible<Func, const char*>::value, bool>::type
522     invokeMethod(QObject *context, Func function,
523                  Qt::ConnectionType type = Qt::AutoConnection, decltype(function()) *ret = nullptr)
524     {
525         return invokeMethodImpl(context,
526                                 new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
527                                 type,
528                                 ret);
529     }
530 
531     template <typename Func>
532     static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
533                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
534                                    && !std::is_convertible<Func, const char*>::value, bool>::type
invokeMethodQMetaObject535     invokeMethod(QObject *context, Func function, decltype(function()) *ret)
536     {
537         return invokeMethodImpl(context,
538                                 new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
539                                 Qt::AutoConnection,
540                                 ret);
541     }
542 
543 #endif
544 
545     QObject *newInstance(QGenericArgument val0 = QGenericArgument(nullptr),
546                          QGenericArgument val1 = QGenericArgument(),
547                          QGenericArgument val2 = QGenericArgument(),
548                          QGenericArgument val3 = QGenericArgument(),
549                          QGenericArgument val4 = QGenericArgument(),
550                          QGenericArgument val5 = QGenericArgument(),
551                          QGenericArgument val6 = QGenericArgument(),
552                          QGenericArgument val7 = QGenericArgument(),
553                          QGenericArgument val8 = QGenericArgument(),
554                          QGenericArgument val9 = QGenericArgument()) const;
555 
556     enum Call {
557         InvokeMetaMethod,
558         ReadProperty,
559         WriteProperty,
560         ResetProperty,
561         QueryPropertyDesignable,
562         QueryPropertyScriptable,
563         QueryPropertyStored,
564         QueryPropertyEditable,
565         QueryPropertyUser,
566         CreateInstance,
567         IndexOfMethod,
568         RegisterPropertyMetaType,
569         RegisterMethodArgumentMetaType
570     };
571 
572     int static_metacall(Call, int, void **) const;
573     static int metacall(QObject *, Call, int, void **);
574 
staticMetaObjectQMetaObject575     template <const QMetaObject &MO> static constexpr const QMetaObject *staticMetaObject()
576     {
577         return &MO;
578     }
579 
580     struct SuperData {
581         const QMetaObject *direct;
582         SuperData() = default;
SuperDataQMetaObject::SuperData583         constexpr SuperData(std::nullptr_t) : direct(nullptr) {}
SuperDataQMetaObject::SuperData584         constexpr SuperData(const QMetaObject *mo) : direct(mo) {}
585 
586         constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); }
587 
588 #ifdef QT_NO_DATA_RELOCATION
589         using Getter = const QMetaObject *(*)();
590         Getter indirect = nullptr;
SuperDataQMetaObject::SuperData591         constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {}
592         constexpr operator const QMetaObject *() const
593         { return indirect ? indirect() : direct; }
linkQMetaObject::SuperData594         template <const QMetaObject &MO> static constexpr SuperData link()
595         { return SuperData(QMetaObject::staticMetaObject<MO>); }
596 #else
597         constexpr operator const QMetaObject *() const
598         { return direct; }
linkQMetaObject::SuperData599         template <const QMetaObject &MO> static constexpr SuperData link()
600         { return SuperData(QMetaObject::staticMetaObject<MO>()); }
601 #endif
602     };
603 
604     struct { // private data
605         SuperData superdata;
606         const QByteArrayData *stringdata;
607         const uint *data;
608         typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
609         StaticMetacallFunction static_metacall;
610         const SuperData *relatedMetaObjects;
611         void *extradata; //reserved for future use
612     } d;
613 
614 private:
615     static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret);
616     friend class QTimer;
617 };
618 
619 class Q_CORE_EXPORT QMetaObject::Connection {
620     void *d_ptr; //QObjectPrivate::Connection*
Connection(void * data)621     explicit Connection(void *data) : d_ptr(data) {  }
622     friend class QObject;
623     friend class QObjectPrivate;
624     friend struct QMetaObject;
625     bool isConnected_helper() const;
626 public:
627     ~Connection();
628     Connection();
629     Connection(const Connection &other);
630     Connection &operator=(const Connection &other);
631 #ifdef Q_QDOC
632     operator bool() const;
633 #else
634     typedef void *Connection::*RestrictedBool;
RestrictedBool()635     operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : nullptr; }
636 #endif
637 
Connection(Connection && o)638     Connection(Connection &&o) noexcept : d_ptr(o.d_ptr) { o.d_ptr = nullptr; }
639     Connection &operator=(Connection &&other) noexcept
640     { qSwap(d_ptr, other.d_ptr); return *this; }
641 };
642 
superClass()643 inline const QMetaObject *QMetaObject::superClass() const
644 { return d.superdata; }
645 
646 namespace QtPrivate {
647     /* Trait that tells is a the Object has a Q_OBJECT macro */
648     template <typename Object> struct HasQ_OBJECT_Macro {
649         template <typename T>
650         static char test(int (T::*)(QMetaObject::Call, int, void **));
651         static int test(int (Object::*)(QMetaObject::Call, int, void **));
652         enum { Value =  sizeof(test(&Object::qt_metacall)) == sizeof(int) };
653     };
654 }
655 
656 QT_END_NAMESPACE
657 
658 #endif // QOBJECTDEFS_H
659