1 /****************************************************************************
2 **
3 ** DQt - D bindings for the Qt Toolkit
4 **
5 ** GNU Lesser General Public License Usage
6 ** This file may be used under the terms of the GNU Lesser
7 ** General Public License version 3 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
9 ** packaging of this file. Please review the following information to
10 ** ensure the GNU Lesser General Public License version 3 requirements
11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
12 **
13 ****************************************************************************/
14 module qt.core.objectdefs;
15 extern(C++):
16 
17 import qt.config;
18 import qt.core.bytearray;
19 import qt.core.metaobject;
20 import qt.core.namespace;
21 import qt.core.object;
22 import qt.core.objectdefs_impl;
23 import qt.core.point;
24 import qt.helpers;
25 import std.traits;
26 import std.meta;
27 version(QT_NO_TRANSLATION){}else
28     import qt.core.string;
29 
30 /+ #if defined(__OBJC__) && !defined(__cplusplus)
31 #  warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
32 #endif
33 
34 
35 
36 class QByteArray;
37 struct QArrayData;
38 
39 class QString;
40 #ifndef Q_MOC_OUTPUT_REVISION
41 #define Q_MOC_OUTPUT_REVISION 67
42 #endif
43 
44 // The following macros can be defined by tools that understand Qt
45 // to have the information from the macro.
46 #ifndef QT_ANNOTATE_CLASS
47 # define QT_ANNOTATE_CLASS(type, ...)
48 #endif
49 #ifndef QT_ANNOTATE_CLASS2
50 # define QT_ANNOTATE_CLASS2(type, a1, a2)
51 #endif
52 #ifndef QT_ANNOTATE_FUNCTION
53 # define QT_ANNOTATE_FUNCTION(x)
54 #endif
55 #ifndef QT_ANNOTATE_ACCESS_SPECIFIER
56 # define QT_ANNOTATE_ACCESS_SPECIFIER(x)
57 #endif
58 
59 // The following macros are our "extensions" to C++
60 // They are used, strictly speaking, only by the moc.
61 
62 #ifndef Q_MOC_RUN +/
63 /+ #ifndef QT_NO_META_MACROS
64 # if defined(QT_NO_KEYWORDS)
65 #  define QT_NO_EMIT
66 # else
67 #   ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
68 #     define slots Q_SLOTS
69 #     define signals Q_SIGNALS
70 #   endif
71 # endif
72 # define Q_SLOTS QT_ANNOTATE_ACCESS_SPECIFIER(qt_slot)
73 # define Q_SIGNALS public QT_ANNOTATE_ACCESS_SPECIFIER(qt_signal)
74 # define Q_PRIVATE_SLOT(d, signature) QT_ANNOTATE_CLASS2(qt_private_slot, d, signature)
75 # define Q_EMIT
76 #ifndef QT_NO_EMIT
77 # define emit
78 #endif
79 #ifndef Q_CLASSINFO
80 # define Q_CLASSINFO(name, value)
81 #endif
82 #define Q_PLUGIN_METADATA(x) QT_ANNOTATE_CLASS(qt_plugin_metadata, x)
83 #define Q_INTERFACES(x) QT_ANNOTATE_CLASS(qt_interfaces, x)
84 #define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)
85 #define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text)
86 #ifndef Q_REVISION
87 # define Q_REVISION(v)
88 #endif
89 #define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text)
90 #define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text)
91 #define Q_ENUMS(x) QT_ANNOTATE_CLASS(qt_enums, x)
92 #define Q_FLAGS(x) QT_ANNOTATE_CLASS(qt_enums, x)
93 #define Q_ENUM_IMPL(ENUM) \
94     friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
95     friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
96 #define Q_ENUM(x) Q_ENUMS(x) Q_ENUM_IMPL(x)
97 #define Q_FLAG(x) Q_FLAGS(x) Q_ENUM_IMPL(x)
98 #define Q_ENUM_NS_IMPL(ENUM) \
99     inline Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
100     inline Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
101 #define Q_ENUM_NS(x) Q_ENUMS(x) Q_ENUM_NS_IMPL(x)
102 #define Q_FLAG_NS(x) Q_FLAGS(x) Q_ENUM_NS_IMPL(x)
103 #define Q_SCRIPTABLE QT_ANNOTATE_FUNCTION(qt_scriptable)
104 #define Q_INVOKABLE  QT_ANNOTATE_FUNCTION(qt_invokable)
105 #define Q_SIGNAL QT_ANNOTATE_FUNCTION(qt_signal)
106 #define Q_SLOT QT_ANNOTATE_FUNCTION(qt_slot)
107 #endif +/ // QT_NO_META_MACROS
108 
109 version(QT_NO_TRANSLATION){}else
110 {
111 // full set of tr functions
112 /+ #  define QT_TR_FUNCTIONS \
113     static inline QString tr(const char *s, const char *c = nullptr, int n = -1) \
114         { return staticMetaObject.tr(s, c, n); } \
115     QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) \
116         { return staticMetaObject.tr(s, c, n); } +/
117 enum QT_TR_FUNCTIONS =
118         q{pragma(inline, true) static imported!"qt.core.string".QString tr(const(char)* s, const(char)* c = null, int n = -1)
119             { return staticMetaObject.tr(s, c, n); }
120         /+ QT_DEPRECATED +/ pragma(inline, true) static imported!"qt.core.string".QString trUtf8(const(char)* s, const(char)* c = null, int n = -1)
121             { return staticMetaObject.tr(s, c, n); }};
122 }
123 version(QT_NO_TRANSLATION)
124 {
125 // inherit the ones from QObject
126 /+ # define QT_TR_FUNCTIONS +/
127 }
128 
129 /+ #ifdef Q_CLANG_QDOC
130 #define QT_TR_FUNCTIONS
131 #endif
132 
133 // ### Qt6: remove
134 #define Q_OBJECT_CHECK  /* empty, unused since Qt 5.2 */
135 
136 #if defined(Q_CC_INTEL)
137 // Cannot redefine the visibility of a method in an exported class
138 # define Q_DECL_HIDDEN_STATIC_METACALL
139 #else
140 # define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN
141 #endif
142 
143 #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
144 #  define Q_OBJECT_NO_OVERRIDE_WARNING      QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
145 #elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501
146 #  define Q_OBJECT_NO_OVERRIDE_WARNING      QT_WARNING_DISABLE_GCC("-Wsuggest-override")
147 #else
148 #  define Q_OBJECT_NO_OVERRIDE_WARNING
149 #endif
150 
151 #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 600
152 #  define Q_OBJECT_NO_ATTRIBUTES_WARNING    QT_WARNING_DISABLE_GCC("-Wattributes")
153 #else
154 #  define Q_OBJECT_NO_ATTRIBUTES_WARNING
155 #endif +/
156 
157 /* qmake ignore Q_OBJECT */
158 /+ #define Q_OBJECT \
159 public: \
160     QT_WARNING_PUSH \
161     Q_OBJECT_NO_OVERRIDE_WARNING \
162     static const QMetaObject staticMetaObject; \
163     virtual const QMetaObject *metaObject() const; \
164     virtual void *qt_metacast(const char *); \
165     virtual int qt_metacall(QMetaObject::Call, int, void **); \
166     QT_TR_FUNCTIONS \
167 private: \
168     Q_OBJECT_NO_ATTRIBUTES_WARNING \
169     Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
170     QT_WARNING_POP \
171     struct QPrivateSignal {}; \
172     QT_ANNOTATE_CLASS(qt_qobject, "") +/
173 enum Q_OBJECT =
174 q{    public:
175         /+ QT_WARNING_PUSH
176         Q_OBJECT_NO_OVERRIDE_WARNING +/
177         extern(C++) extern } ~ exportOnWindows ~ q{static __gshared const(imported!q{qt.core.objectdefs}.QMetaObject) staticMetaObject;
178         extern(C++) override /+ virtual +/ const(imported!q{qt.core.objectdefs}.QMetaObject)* metaObject() const;
179         extern(C++) override /+ virtual +/ void* qt_metacast(const(char)* );
180         extern(C++) override /+ virtual +/ int qt_metacall(imported!q{qt.core.objectdefs}.QMetaObject.Call, int, void** );
181         } ~ QT_TR_FUNCTIONS ~ q{
182     private:
183         /+ Q_OBJECT_NO_ATTRIBUTES_WARNING +/
184         /+ Q_DECL_HIDDEN_STATIC_METACALL +/ static void qt_static_metacall(imported!"qt.core.object".QObject , imported!q{qt.core.objectdefs}.QMetaObject.Call, int, void** );
185         /+ QT_WARNING_POP +/
186         extern(C++) struct QPrivateSignal {}};
187         /+ QT_ANNOTATE_CLASS(qt_qobject, "") +/
188 
189 /* qmake ignore Q_OBJECT */
190 /+ #define Q_OBJECT_FAKE Q_OBJECT QT_ANNOTATE_CLASS(qt_fake, "")
191 
192 #ifndef QT_NO_META_MACROS +/
193 /* qmake ignore Q_GADGET */
194 
195 struct CPPMemberFunctionPointer(T)
196 {
197     void *ptr;
198     uint adj;
199 }
200 
201 template memberFunctionExternDeclaration(alias F)
202 {
203     mixin((){
204             string code;
205             version(Windows)
206                 static if(packageName!(F).length > 3 && packageName!(F)[0..3] == "qt.")
207                     code ~= "export ";
208             code ~= "extern(" ~ functionLinkage!F ~ ")";
209             code ~= q{pragma(mangle, F.mangleof) ReturnType!F memberFunctionExternDeclaration(__traits(parent, F), Parameters!F);};
210             return code;
211         }());
212 }
213 
214 enum NotIsConstructor(alias F) = __traits(identifier, F) != "__ctor";
215 
216 template MetaObjectImpl(T)
217 {
218     import qt.core.refcount;
219     import qt.core.metatype;
220     extern(D):
221 
222     alias Overloads(string name) = __traits(getOverloads, T, name);
223     //pragma(msg, staticMap!(Overloads, __traits(derivedMembers, T)));
224     alias allFunctions = Filter!(NotIsConstructor, staticMap!(Overloads, __traits(derivedMembers, T)));
225     alias allSignals = Filter!(IsQSignal, allFunctions);
226     alias allSlots = Filter!(IsQSlot, allFunctions);
227     alias allInvokables = Filter!(IsQInvokable, allFunctions);
228     alias allMethods = std.meta.AliasSeq!(allSignals, allSlots, allInvokables);
229 
230     /*pragma(msg, allSignals);
231     pragma(msg, allSlots);
232     pragma(msg, allInvokables);*/
233 
234     template signalIndex(alias F)
235     {
236         enum signalIndex = staticIndexOf!(F, allSignals);
237     }
238 
239     enum CODE = (){
240         import std.conv;
241 
242         string concatenatedStrings;
243         string stringLiteralsCode;
244         size_t numStrings;
245         size_t[string] stringCache;
246 
247         size_t addString(string s)
248         {
249             if(s in stringCache)
250                 return stringCache[s];
251             stringLiteralsCode ~= text("QT_MOC_LITERAL(", numStrings, ", ", concatenatedStrings.length, ", " , s.length, "),\n");
252             concatenatedStrings ~= s;
253             concatenatedStrings ~= "\0";
254             stringCache[s] = numStrings;
255             return numStrings++;
256         }
257 
258         addString(__traits(identifier, T));
259 
260         size_t currentOutputIndex = 0;
261 
262         currentOutputIndex += 14;
263 
264         size_t methodsStartIndex = currentOutputIndex;
265 
266         string metaDataCode = mixin(interpolateMixin(q{
267              // content:
268                    8,       // revision
269                    0,       // classname
270                    0,    0, // classinfo
271                    $(text(allMethods.length)),   $(text(methodsStartIndex)), // methods
272                    0,    0, // properties
273                    0,    0, // enums/sets
274                    0,    0, // constructors
275                    0,       // flags
276                    $(text(allSignals.length)),       // signalCount
277 
278         }));
279 
280         assert(methodsStartIndex == currentOutputIndex);
281         currentOutputIndex += 5 * allMethods.length;
282 
283         string typeToMeta(T2)()
284         {
285             import qt.core.list: QList;
286             import qt.core.vector: QVector;
287             static if(is(T2 == int))
288                 return "QMetaType.Type.Int";
289             else static if(is(T2 == uint))
290                 return "QMetaType.Type.UInt";
291             else static if(is(T2 == bool))
292                 return "QMetaType.Type.Bool";
293             else static if(is(T2 == double))
294                 return "QMetaType.Type.Double";
295             else static if(is(const(T2) == const(QString)))
296                 return "QMetaType.Type.QString";
297             else static if(is(const(T2) == const(QList!int)))
298                 return text("0x80000000 | ", addString("QList<int>"));
299             else static if(is(const(T2) == const(QVector!int)))
300                 return text("0x80000000 | ", addString("QVector<int>"));
301             else static if(is(const(T2) == const(QPoint)))
302                 return "QMetaType.Type.QPoint";
303             else static if(is(T2 == int*))
304                 return text("0x80000000 | ", addString("int*"));
305             else
306                 static assert("TODO: Type not yet supported ", T2.stringof);
307         }
308 
309         void addMethods(M...)(string typename, uint type)
310         {
311             if(M.length)
312                 metaDataCode ~= "    // " ~ typename ~ ": name, argc, parameters, tag, flags\n";
313             static foreach(i; 0..M.length)
314             {{
315                 size_t nameId = addString(__traits(identifier, M[i]));
316                 size_t parameterCount = Parameters!(M[i]).length;
317                 uint flags;
318                 flags |= 2; // Public // TODO
319                 metaDataCode ~= mixin(interpolateMixin(q{
320                        $(text(nameId)),    $(text(parameterCount)),   $(text(currentOutputIndex)),    2, $(text(flags)), $("// " ~ __traits(identifier, M[i]))
321                 }));
322                 currentOutputIndex += 1 + 2 * parameterCount;
323             }}
324         }
325         addMethods!(allSignals)("signals", 4);
326         addMethods!(allSlots)("slots", 8);
327         addMethods!(allInvokables)("methods", 0);
328         void addMethodParameters(M...)(string typename)
329         {
330             if(M.length)
331                 metaDataCode ~= "    // " ~ typename ~ ": parameters\n";
332             static foreach(i; 0..M.length)
333             {
334                 metaDataCode ~= "                    QMetaType.Type.Void, "; // TODO: correct return type
335                 foreach(P; Parameters!(M[i]))
336                     metaDataCode ~= typeToMeta!(P) ~ ", ";
337                 foreach(j, P; Parameters!(M[i]))
338                     metaDataCode ~= text(addString(ParameterIdentifierTuple!(M[i])[j]), ", ");
339                 metaDataCode ~= "// " ~ __traits(identifier, M[i]) ~ "\n";
340             }
341         }
342         addMethodParameters!(allSignals)("signals");
343         addMethodParameters!(allSlots)("slots");
344         addMethodParameters!(allInvokables)("methods");
345 
346         addString("");
347 
348         string concatenatedStringsCode = "\"";
349         foreach(char c; concatenatedStrings)
350         {
351             if(c == '\0')
352                 concatenatedStringsCode ~= "\\0";
353             else if(c == '\\')
354                 concatenatedStringsCode ~= "\\\\";
355             else if(c == '\n')
356                 concatenatedStringsCode ~= "\\n";
357             else if(c == '\r')
358                 concatenatedStringsCode ~= "\\r";
359             else if(c == '\"')
360                 concatenatedStringsCode ~= "\\\"";
361             else if(c == '\'')
362                 concatenatedStringsCode ~= "\\\'";
363             else
364                 concatenatedStringsCode ~= c;
365         }
366         concatenatedStringsCode ~= "\"";
367 
368         return mixin(interpolateMixin(q{
369             extern(C++) struct stringdata_t {
370                 QByteArrayData[$(text(numStrings))] data;
371                 char[$(text(concatenatedStrings.length))] stringdata0;
372             };
373 
374             extern(C++) const(QByteArrayData) Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(int size, size_t offset)
375             {
376                 return const(QByteArrayData)(Q_REFCOUNT_INITIALIZE_STATIC, size, 0,/* 0,*/ offset);
377             }
378 
379             extern(C++) const(QByteArrayData) QT_MOC_LITERAL(size_t idx, size_t ofs, int len)
380             {
381                 return Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len,
382                     ptrdiff_t(stringdata_t.stringdata0.offsetof + ofs
383                         - idx * QByteArrayData.sizeof)
384                     );
385             }
386 
387             extern(C++) static __gshared const stringdata_t stringdata = {
388                 [
389                     $(stringLiteralsCode)
390                 ],
391                 $(concatenatedStringsCode)
392             };
393 
394             extern(C++) static __gshared const uint[$(text(currentOutputIndex + 1))] meta_data = [
395                     $(metaDataCode)
396                    0        // eod
397             ];
398 
399             version(Windows)
400             {
401                 pragma(mangle, T.staticMetaObject.mangleof)
402                 extern(C++) static __gshared const(QMetaObject) staticMetaObject = { {
403                     null,
404                     &stringdata,
405                     meta_data.ptr,
406                     &T.qt_static_metacall,
407                     null,
408                     null
409                 } };
410                 shared static this()
411                 {
412                     // Necessary for Windows, because staticMetaObject from a DLL can't be used directly.
413                     (cast(QMetaObject*)&staticMetaObject).d.superdata.direct = &BaseClassesTuple!(T)[0].staticMetaObject;
414                 }
415             }
416             else
417             {
418                 pragma(mangle, T.staticMetaObject.mangleof)
419                 extern(C++) static __gshared const(QMetaObject) staticMetaObject = { {
420                     QMetaObject.SuperData.link!(BaseClassesTuple!(T)[0].staticMetaObject)(),
421                     &stringdata,
422                     meta_data.ptr,
423                     &T.qt_static_metacall,
424                     null,
425                     null
426                 } };
427             }
428         }));
429     }();
430     //pragma(msg, CODE);
431     mixin(CODE);
432 }
433 
434 enum Q_OBJECT_D = q{
435     public:
436         extern(C++) extern static __gshared const(imported!q{qt.core.objectdefs}.QMetaObject) staticMetaObject;
437         extern(C++) override const(imported!q{qt.core.objectdefs}.QMetaObject)* metaObject() const
438         {
439             import qt.core.object;
440             return qt.core.object.QObject.d_ptr.metaObject ? qt.core.object.QObject.d_ptr.dynamicMetaObject() : &staticMetaObject;
441         }
442         extern(C++) override void * qt_metacast(const(char)* _clname)
443         {
444             import qt.core.objectdefs;
445             if (!_clname) return null;
446             import core.stdc.string;
447             if (!core.stdc..string.strcmp(_clname, qt.core.objectdefs.MetaObjectImpl!(typeof(this)).stringdata.stringdata0.ptr))
448                 return static_cast!(void*)(this);
449             return super.qt_metacast(_clname);
450         }
451         extern(C++) override int qt_metacall(imported!q{qt.core.objectdefs}.QMetaObject.Call  _c, int _id, void **_a)
452         {
453             import qt.core.objectdefs;
454             _id = super.qt_metacall(_c, _id, _a);
455             if (_id < 0)
456                 return _id;
457             alias allMethods = qt.core.objectdefs.MetaObjectImpl!(typeof(this)).allMethods;
458             if (_c == qt.core.objectdefs.QMetaObject.Call.InvokeMetaMethod) {
459                 if (_id < allMethods.length)
460                     qt_static_metacall(this, _c, _id, _a);
461                 _id -= allMethods.length;
462             } else if (_c == qt.core.objectdefs.QMetaObject.Call.RegisterMethodArgumentMetaType) {
463                 if (_id < allMethods.length)
464                     *reinterpret_cast!(int*)(_a[0]) = -1;
465                 _id -= allMethods.length;
466             }
467             return _id;
468         }
469         extern(C++) static void qt_static_metacall(imported!"qt.core.object".QObject _o, imported!q{qt.core.objectdefs}.QMetaObject.Call _c, int _id, void **_a)
470         {
471             import qt.core.objectdefs;
472             if (_c == qt.core.objectdefs.QMetaObject.Call.InvokeMetaMethod) {
473                 alias allMethods = qt.core.objectdefs.MetaObjectImpl!(typeof(this)).allMethods;
474                 import std.conv, std.traits;
475                 auto _t = static_cast!(typeof(this))(_o);
476                 //Q_UNUSED(_t)
477                 switch (_id) {
478                     mixin((){
479                             string methodCallCases;
480                             static foreach(i; 0..allMethods.length)
481                             {{
482                                 methodCallCases ~= text("\n                    case ", i, ": _t.", __traits(identifier, allMethods[i]), "(");
483                                 static foreach(j, P; Parameters!(allMethods[i]))
484                                 {
485                                     methodCallCases ~= text("*cast(Parameters!(allMethods[", i, "])[", j, "]*)(_a[", j + 1, "]), ");
486                                 }
487                                 methodCallCases ~= "); break;";
488                             }}
489                             return methodCallCases;
490                         }());
491                 default: {}
492                 }
493             } else if (_c == qt.core.objectdefs.QMetaObject.Call.RegisterMethodArgumentMetaType) {
494                 // TODO
495             } else if (_c == qt.core.objectdefs.QMetaObject.Call.IndexOfMethod) {
496                 alias allSignals = qt.core.objectdefs.MetaObjectImpl!(typeof(this)).allSignals;
497                 int *result = reinterpret_cast!(int *)(_a[0]);
498                 static foreach(i; 0..allSignals.length)
499                 {{
500                     alias _t = qt.core.objectdefs.CPPMemberFunctionPointer!(typeof(this));
501 
502                     auto fp = &memberFunctionExternDeclaration!(allSignals[i]);
503                     qt.core.objectdefs.CPPMemberFunctionPointer!(typeof(this)) memberFunction = qt.core.objectdefs.CPPMemberFunctionPointer!(typeof(this))(fp);
504 
505                     if (*reinterpret_cast!(_t *)(_a[1]) == memberFunction) {
506                         *result = i;
507                         return;
508                     }
509                 }}
510             }
511             //Q_UNUSED(_a);
512         }
513         } ~ QT_TR_FUNCTIONS ~ q{
514     private:
515         struct QPrivateSignal {}
516 };
517 
518 enum Q_SIGNAL_IMPL_D = q{
519     struct Dummy{}
520     import std.traits;
521     void*[std.traits.Parameters!(__traits(parent, Dummy)).length + 1] _a = mixin((){
522         string r = "[null";
523         static foreach(i; 0..std.traits.Parameters!(__traits(parent, Dummy)).length)
524             r ~= " , cast(void*)&" ~ std.traits.ParameterIdentifierTuple!(__traits(parent, Dummy))[i];
525         r ~= "]";
526         return r;
527         }());
528     imported!q{qt.core.objectdefs}.QMetaObject.activate(this, &staticMetaObject, imported!q{qt.core.objectdefs}.MetaObjectImpl!(typeof(this)).signalIndex!(__traits(parent, Dummy)), _a.ptr);
529 };
530 
531 /+ #define Q_GADGET \
532 public: \
533     static const QMetaObject staticMetaObject; \
534     void qt_check_for_QGADGET_macro(); \
535     typedef void QtGadgetHelper; \
536 private: \
537     QT_WARNING_PUSH \
538     Q_OBJECT_NO_ATTRIBUTES_WARNING \
539     Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
540     QT_WARNING_POP \
541     QT_ANNOTATE_CLASS(qt_qgadget, "") \
542     /*end*/ +/
543 enum Q_GADGET =
544 q{    public:
545         extern static __gshared const(imported!q{qt.core.objectdefs}.QMetaObject) staticMetaObject;
546         /+ void qt_check_for_QGADGET_macro(); +/
547         alias QtGadgetHelper = void;
548     private:
549         /+ QT_WARNING_PUSH
550         Q_OBJECT_NO_ATTRIBUTES_WARNING +/
551         /+ Q_DECL_HIDDEN_STATIC_METACALL +/ static void qt_static_metacall(imported!q{qt.core.object}.QObject , imported!q{qt.core.objectdefs}.QMetaObject.Call, int, void** );};
552         /+ QT_WARNING_POP
553         QT_ANNOTATE_CLASS(qt_qgadget, "") +/
554         /*end*/
555 
556 /* qmake ignore Q_NAMESPACE_EXPORT */
557 /+ #define Q_NAMESPACE_EXPORT(...) \
558     extern __VA_ARGS__ const QMetaObject staticMetaObject; \
559     QT_ANNOTATE_CLASS(qt_qnamespace, "") \
560     /*end*/
561 
562 /* qmake ignore Q_NAMESPACE */
563 #define Q_NAMESPACE Q_NAMESPACE_EXPORT() \
564     /*end*/ +/
565 
566 /+ #endif +/ // QT_NO_META_MACROS
567 
568 /+ #else // Q_MOC_RUN
569 #define slots slots
570 #define signals signals
571 #define Q_SLOTS Q_SLOTS
572 #define Q_SIGNALS Q_SIGNALS
573 #define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value)
574 #define Q_INTERFACES(x) Q_INTERFACES(x)
575 #define Q_PROPERTY(text) Q_PROPERTY(text)
576 #define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
577 #define Q_REVISION(v) Q_REVISION(v)
578 #define Q_OVERRIDE(text) Q_OVERRIDE(text)
579 #define Q_ENUMS(x) Q_ENUMS(x)
580 #define Q_FLAGS(x) Q_FLAGS(x)
581 #define Q_ENUM(x) Q_ENUM(x)
582 #define Q_FLAGS(x) Q_FLAGS(x)
583  /* qmake ignore Q_OBJECT */
584 #define Q_OBJECT Q_OBJECT
585  /* qmake ignore Q_OBJECT */
586 #define Q_OBJECT_FAKE Q_OBJECT_FAKE
587  /* qmake ignore Q_GADGET */
588 #define Q_GADGET Q_GADGET
589 #define Q_SCRIPTABLE Q_SCRIPTABLE
590 #define Q_INVOKABLE Q_INVOKABLE
591 #define Q_SIGNAL Q_SIGNAL
592 #define Q_SLOT Q_SLOT
593 #endif //Q_MOC_RUN
594 
595 #ifndef QT_NO_META_MACROS
596 // macro for onaming members
597 #ifdef METHOD
598 #undef METHOD
599 #endif
600 #ifdef SLOT
601 #undef SLOT
602 #endif
603 #ifdef SIGNAL
604 #undef SIGNAL
605 #endif
606 #endif +/ // QT_NO_META_MACROS
607 
608 /+ Q_CORE_EXPORT +/ const(char)* qFlagLocation(const(char)* method);
609 
610 /+ #ifndef QT_NO_META_MACROS +/
611 /+ #ifndef QT_NO_DEBUG
612 # define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
613 # ifndef QT_NO_KEYWORDS
614 #  define METHOD(a)   qFlagLocation("0"#a QLOCATION)
615 # endif
616 # define SLOT(a)     qFlagLocation("1"#a QLOCATION)
617 # define SIGNAL(a)   qFlagLocation("2"#a QLOCATION)
618 #else +/
619 /+ # ifndef QT_NO_KEYWORDS
620 #  define METHOD(a)   "0"#a
621 # endif +/
622 /+ # define SLOT(a)     "1"#a +/
623 extern(D) alias SLOT = function string(string a)
624 {
625     return     mixin(interpolateMixin(q{"1" ~$(stringifyMacroParameter(a))}));
626 };
627 /+ # define SIGNAL(a)   "2"#a +/
628 extern(D) alias SIGNAL = function string(string a)
629 {
630     return   mixin(interpolateMixin(q{"2" ~$(stringifyMacroParameter(a))}));
631 };
632 /+ #endif
633 
634 #define QMETHOD_CODE  0                        // member type codes
635 #define QSLOT_CODE    1
636 #define QSIGNAL_CODE  2 +/
637 /+ #endif // QT_NO_META_MACROS
638 
639 #define Q_ARG(type, data) QArgument<type >(#type, data)
640 #define Q_RETURN_ARG(type, data) QReturnArgument<type >(#type, data)
641 
642 class QObject;
643 class QMetaMethod;
644 class QMetaEnum;
645 class QMetaProperty;
646 class QMetaClassInfo; +/
647 
648 
649 extern(C++, class) struct /+ Q_CORE_EXPORT +/ QGenericArgument
650 {
651 public:
652     pragma(inline, true) this(const(char)* aName/+ = null+/, const(void)* aData = null)
653     {
654         this._data = aData;
655         this._name = aName;
656     }
657     pragma(inline, true) void* data() const { return const_cast!(void*)(_data); }
658     pragma(inline, true) const(char)* name() const { return _name; }
659 
660 private:
661     const(void)* _data = null;
662     const(char)* _name = null;
663 }
664 
665 extern(C++, class) struct /+ Q_CORE_EXPORT +/ QGenericReturnArgument
666 {
667     public QGenericArgument base0;
668     alias base0 this;
669 public:
670     pragma(inline, true) this(const(char)* aName/+ = null+/, void* aData = null)
671     {
672         this.base0 = QGenericArgument(aName, aData);
673     }
674 }
675 
676 class QArgument(T): QGenericArgument
677 {
678 public:
679     pragma(inline, true) this(const(char)* aName, ref const(T) aData)
680     {
681         super(aName, static_cast!(const(void)*)(&aData));
682     }
683 }
684 /+ template <class T>
685 class QArgument<T &>: public QGenericArgument
686 {
687 public:
688     inline QArgument(const char *aName, T &aData)
689         : QGenericArgument(aName, static_cast<const void *>(&aData))
690         {}
691 }; +/
692 
693 
694 class QReturnArgument(T): QGenericReturnArgument
695 {
696 public:
697     pragma(inline, true) this(const(char)* aName, ref T aData)
698     {
699         super(aName, static_cast!(void*)(&aData));
700     }
701 }
702 
703 struct /+ Q_CORE_EXPORT +/ QMetaObject
704 {
705     /+
706     extern(C++, class) struct Connection;
707     +/extern(C++, class) struct /+ Q_CORE_EXPORT +/ Connection {
708     private:
709         void* d_ptr; //QObjectPrivate::Connection*
710         /+ explicit +/this(void* data)
711         {
712             this.d_ptr = data;
713         }
714         /+ friend class QObject; +/
715         /+ friend class QObjectPrivate; +/
716         /+ friend struct QMetaObject; +/
717         bool isConnected_helper() const;
718     public:
719         ~this();
720 
721         this(ref const(Connection) other);
722         /+ref Connection operator =(ref const(Connection) other);+/
723     /+ #ifdef Q_QDOC
724         operator bool() const;
725     #else +/
726         alias RestrictedBool = void*/+ Connection::* +/*;
727         /+auto opCast(T : RestrictedBool)() const { return d_ptr && isConnected_helper() ? &Connection.d_ptr : null; }+/
728     /+ #endif +/
729 
730         /+ Connection(Connection &&o) noexcept : d_ptr(o.d_ptr) { o.d_ptr = nullptr; } +/
731         /+ Connection &operator=(Connection &&other) noexcept
732         { qSwap(d_ptr, other.d_ptr); return *this; } +/
733     }
734 
735     const(char)* className() const;
736 /+    pragma(inline, true) const(QMetaObject)* superClass() const
737     { return cast(const(QMetaObject)*)(d.superdata); }+/
738 
739     bool inherits(const(QMetaObject)* metaObject) const/+ noexcept+/;
740     /*QObject cast_(QObject obj) const;
741     const(QObject) cast_(const(QObject) obj) const;*/
742 
743     version(QT_NO_TRANSLATION){}else
744     {
745         QString tr(const(char)* s, const(char)* c, int n = -1) const;
746     }
747 
748     int methodOffset() const;
749     int enumeratorOffset() const;
750     int propertyOffset() const;
751     int classInfoOffset() const;
752 
753     int constructorCount() const;
754     int methodCount() const;
755     int enumeratorCount() const;
756     int propertyCount() const;
757     int classInfoCount() const;
758 
759     int indexOfConstructor(const(char)* constructor) const;
760     int indexOfMethod(const(char)* method) const;
761     int indexOfSignal(const(char)* signal) const;
762     int indexOfSlot(const(char)* slot) const;
763     int indexOfEnumerator(const(char)* name) const;
764     int indexOfProperty(const(char)* name) const;
765     int indexOfClassInfo(const(char)* name) const;
766 
767     QMetaMethod constructor(int index) const;
768     QMetaMethod method(int index) const;
769     QMetaEnum enumerator(int index) const;
770     QMetaProperty property(int index) const;
771     QMetaClassInfo classInfo(int index) const;
772     QMetaProperty userProperty() const;
773 
774     static bool checkConnectArgs(const(char)* signal, const(char)* method);
775     static bool checkConnectArgs(ref const(QMetaMethod) signal,
776                                      ref const(QMetaMethod) method);
777     static QByteArray normalizedSignature(const(char)* method);
778     static QByteArray normalizedType(const(char)* type);
779 
780     // internal index-based connect
781     /+ static Connection connect(const QObject *sender, int signal_index,
782                         const QObject *receiver, int method_index,
783                         int type = 0, int *types = nullptr); +/
784     // internal index-based disconnect
785     /+ static bool disconnect(const QObject *sender, int signal_index,
786                            const QObject *receiver, int method_index); +/
787     static bool disconnectOne(const(QObject) sender, int signal_index,
788                                   const(QObject) receiver, int method_index);
789     // internal slot-name based connect
790     static void connectSlotsByName(QObject o);
791 
792     // internal index-based signal activation
793     static void activate(QObject sender, int signal_index, void** argv);
794     static void activate(QObject sender, const(QMetaObject)* , int local_signal_index, void** argv);
795     static void activate(QObject sender, int signal_offset, int local_signal_index, void** argv);
796 
797     static bool invokeMethod(QObject obj, const(char)* member,
798                                  /+ Qt:: +/qt.core.namespace.ConnectionType,
799                                  QGenericReturnArgument ret,
800                                  QGenericArgument val0 = QGenericArgument(null),
801                                  QGenericArgument val1 = QGenericArgument(),
802                                  QGenericArgument val2 = QGenericArgument(),
803                                  QGenericArgument val3 = QGenericArgument(),
804                                  QGenericArgument val4 = QGenericArgument(),
805                                  QGenericArgument val5 = QGenericArgument(),
806                                  QGenericArgument val6 = QGenericArgument(),
807                                  QGenericArgument val7 = QGenericArgument(),
808                                  QGenericArgument val8 = QGenericArgument(),
809                                  QGenericArgument val9 = QGenericArgument());
810 
811 /+    pragma(inline, true) static bool invokeMethod(QObject obj, const(char)* member,
812                                  QGenericReturnArgument ret,
813                                  QGenericArgument val0 = QGenericArgument(null),
814                                  QGenericArgument val1 = QGenericArgument(),
815                                  QGenericArgument val2 = QGenericArgument(),
816                                  QGenericArgument val3 = QGenericArgument(),
817                                  QGenericArgument val4 = QGenericArgument(),
818                                  QGenericArgument val5 = QGenericArgument(),
819                                  QGenericArgument val6 = QGenericArgument(),
820                                  QGenericArgument val7 = QGenericArgument(),
821                                  QGenericArgument val8 = QGenericArgument(),
822                                  QGenericArgument val9 = QGenericArgument())
823     {
824         return invokeMethod(obj, member, /+ Qt:: +/qt.core.namespace.ConnectionType.AutoConnection, ret, val0, val1, val2, val3,
825                 val4, val5, val6, val7, val8, val9);
826     }+/
827 
828 /+    pragma(inline, true) static bool invokeMethod(QObject obj, const(char)* member,
829                                  /+ Qt:: +/qt.core.namespace.ConnectionType type,
830                                  QGenericArgument val0 = QGenericArgument(null),
831                                  QGenericArgument val1 = QGenericArgument(),
832                                  QGenericArgument val2 = QGenericArgument(),
833                                  QGenericArgument val3 = QGenericArgument(),
834                                  QGenericArgument val4 = QGenericArgument(),
835                                  QGenericArgument val5 = QGenericArgument(),
836                                  QGenericArgument val6 = QGenericArgument(),
837                                  QGenericArgument val7 = QGenericArgument(),
838                                  QGenericArgument val8 = QGenericArgument(),
839                                  QGenericArgument val9 = QGenericArgument())
840     {
841         return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2,
842                                  val3, val4, val5, val6, val7, val8, val9);
843     }+/
844 
845 /+    pragma(inline, true) static bool invokeMethod(QObject obj, const(char)* member,
846                                  QGenericArgument val0 = QGenericArgument(null),
847                                  QGenericArgument val1 = QGenericArgument(),
848                                  QGenericArgument val2 = QGenericArgument(),
849                                  QGenericArgument val3 = QGenericArgument(),
850                                  QGenericArgument val4 = QGenericArgument(),
851                                  QGenericArgument val5 = QGenericArgument(),
852                                  QGenericArgument val6 = QGenericArgument(),
853                                  QGenericArgument val7 = QGenericArgument(),
854                                  QGenericArgument val8 = QGenericArgument(),
855                                  QGenericArgument val9 = QGenericArgument())
856     {
857         return invokeMethod(obj, member, /+ Qt:: +/qt.core.namespace.ConnectionType.AutoConnection, QGenericReturnArgument(), val0,
858                 val1, val2, val3, val4, val5, val6, val7, val8, val9);
859     }+/
860 
861 /+ #ifdef Q_CLANG_QDOC
862     template<typename Functor, typename FunctorReturnType>
863     static bool invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr);
864     template<typename Functor, typename FunctorReturnType>
865     static bool invokeMethod(QObject *context, Functor function, FunctorReturnType *ret);
866 #else +/
867 
868     // invokeMethod() for member function pointer
869     /+ template <typename Func> +/
870     /+ static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
871                                    && !std::is_convertible<Func, const char*>::value
872                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
873     invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object,
874                  Func function,
875                  Qt::ConnectionType type = Qt::AutoConnection,
876                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr)
877     {
878         return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), type, ret);
879     } +/
880 
881     /+ template <typename Func> +/
882     /+ static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
883                                    && !std::is_convertible<Func, const char*>::value
884                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
885     invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object,
886                  Func function,
887                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret)
888     {
889         return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), Qt::AutoConnection, ret);
890     } +/
891 
892     // invokeMethod() for function pointer (not member)
893     /+ template <typename Func> +/
894     /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
895                                    && !std::is_convertible<Func, const char*>::value
896                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
897     invokeMethod(QObject *context, Func function,
898                  Qt::ConnectionType type = Qt::AutoConnection,
899                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr)
900     {
901         return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), type, ret);
902     } +/
903 
904     /+ template <typename Func> +/
905     /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
906                                    && !std::is_convertible<Func, const char*>::value
907                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
908     invokeMethod(QObject *context, Func function,
909                  typename QtPrivate::FunctionPointer<Func>::ReturnType *ret)
910     {
911         return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), Qt::AutoConnection, ret);
912     } +/
913 
914     // invokeMethod() for Functor
915     /+ template <typename Func> +/
916     /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
917                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
918                                    && !std::is_convertible<Func, const char*>::value, bool>::type
919     invokeMethod(QObject *context, Func function,
920                  Qt::ConnectionType type = Qt::AutoConnection, decltype(function()) *ret = nullptr)
921     {
922         return invokeMethodImpl(context,
923                                 new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
924                                 type,
925                                 ret);
926     } +/
927 
928     /+ template <typename Func> +/
929     /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
930                                    && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
931                                    && !std::is_convertible<Func, const char*>::value, bool>::type
932     invokeMethod(QObject *context, Func function, decltype(function()) *ret)
933     {
934         return invokeMethodImpl(context,
935                                 new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
936                                 Qt::AutoConnection,
937                                 ret);
938     } +/
939 
940 /+ #endif +/
941 
942     QObject newInstance(QGenericArgument val0 = QGenericArgument(null),
943                              QGenericArgument val1 = QGenericArgument(),
944                              QGenericArgument val2 = QGenericArgument(),
945                              QGenericArgument val3 = QGenericArgument(),
946                              QGenericArgument val4 = QGenericArgument(),
947                              QGenericArgument val5 = QGenericArgument(),
948                              QGenericArgument val6 = QGenericArgument(),
949                              QGenericArgument val7 = QGenericArgument(),
950                              QGenericArgument val8 = QGenericArgument(),
951                              QGenericArgument val9 = QGenericArgument()) const;
952 
953     enum Call {
954         InvokeMetaMethod,
955         ReadProperty,
956         WriteProperty,
957         ResetProperty,
958         QueryPropertyDesignable,
959         QueryPropertyScriptable,
960         QueryPropertyStored,
961         QueryPropertyEditable,
962         QueryPropertyUser,
963         CreateInstance,
964         IndexOfMethod,
965         RegisterPropertyMetaType,
966         RegisterMethodArgumentMetaType
967     }
968 
969     int static_metacall(Call, int, void** ) const;
970     static int metacall(QObject , Call, int, void** );
971 
972     static const(QMetaObject*) staticMetaObject(alias MO)()
973     {
974         return &MO;
975     }
976 
977     struct SuperData {
978         const(QMetaObject)* direct;
979         /+ SuperData() = default; +/
980         /+ constexpr +/this(typeof(null))
981         {
982             this.direct = null;
983         }
984         /+ constexpr +/this(const(QMetaObject)* mo)
985         {
986             this.direct = mo;
987         }
988 
989         /+/+ constexpr +/ const(QMetaObject)* operator ->() const { return operator const QMetaObject *(); }+/
990 
991         version(QT_NO_DATA_RELOCATION)
992         {
993             alias Getter = ExternCPPFunc!(const(QMetaObject)* function());
994             Getter indirect = null;
995             /+ constexpr +/this(Getter g)
996             {
997                 this.direct = null;
998                 this.indirect = g;
999             }
1000             /+/+ constexpr +/ auto opCast(T : const(QMetaObject))() const
1001             { return indirect ? cast(const(QMetaObject))(indirect()) : cast(const(QMetaObject))(direct); }+/
1002             /+ template <const QMetaObject &MO> +/ /+ static constexpr SuperData link()
1003             { return SuperData(QMetaObject::staticMetaObject<MO>); } +/
1004         }
1005         else
1006         {
1007             /+/+ constexpr +/ auto opCast(T : const(QMetaObject))() const
1008             { return cast(const(QMetaObject))(direct); }+/
1009             static SuperData link(alias MO)()
1010             { return SuperData(QMetaObject.staticMetaObject!(MO)()); }
1011         }
1012     }
1013 
1014     struct generated_qobjectdefs_0 { // private data
1015         SuperData superdata;
1016         const(void)* stringdata;
1017         const(uint)* data;
1018         alias StaticMetacallFunction = ExternCPPFunc!(void function(QObject , QMetaObject.Call, int, void** ));
1019         StaticMetacallFunction static_metacall;
1020         const(SuperData)* relatedMetaObjects;
1021         void* extradata; //reserved for future use
1022     }generated_qobjectdefs_0 d;
1023 
1024 private:
1025     static bool invokeMethodImpl(QObject object, /+ QtPrivate:: +/qt.core.objectdefs_impl.QSlotObjectBase* slot, /+ Qt:: +/qt.core.namespace.ConnectionType type, void* ret);
1026     /+ friend class QTimer; +/
1027 }
1028 
1029 extern(C++, "QtPrivate") {
1030     /* Trait that tells is a the Object has a Q_OBJECT macro */
1031     struct HasQ_OBJECT_Macro(Object) {
1032         /+ template <typename T> +/
1033         /+ static char test(int (T::*)(QMetaObject::Call, int, void **)); +/
1034         static int test(ExternCPPFunc!(int function(QMetaObject.Call, int, void** ))/+ Object::* +/ );
1035         enum { Value =  (test(&Object.qt_metacall)). sizeof == int.sizeof }
1036     }
1037 }
1038