1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qmetaobjectbuilder_p.h"
5
6#include "qobject_p.h"
7#include "qmetaobject_p.h"
8
9#include <vector>
10#include <stdlib.h>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \class QMetaObjectBuilder
16 \inmodule QtCore
17 \internal
18 \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime.
19
20*/
21
22/*!
23 \enum QMetaObjectBuilder::AddMember
24 This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject()
25
26 \value ClassName Add the class name.
27 \value SuperClass Add the super class.
28 \value Methods Add methods that aren't signals or slots.
29 \value Signals Add signals.
30 \value Slots Add slots.
31 \value Constructors Add constructors.
32 \value Properties Add properties.
33 \value Enumerators Add enumerators.
34 \value ClassInfos Add items of class information.
35 \value RelatedMetaObjects Add related meta objects.
36 \value StaticMetacall Add the static metacall function.
37 \value PublicMethods Add public methods (ignored for signals).
38 \value ProtectedMethods Add protected methods (ignored for signals).
39 \value PrivateMethods All private methods (ignored for signals).
40 \value AllMembers Add all members.
41 \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function.
42*/
43
44// copied from moc's generator.cpp
45namespace QtPrivate {
46Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type)
47{
48 int id = QMetaType::fromName(name: type).id();
49 if (!id && !type.isEmpty() && type != "void")
50 return false;
51 return (id < QMetaType::User);
52}
53} // namespace QtPrivate
54
55// copied from qmetaobject.cpp
56[[maybe_unused]] static inline const QMetaObjectPrivate *qmobPriv(const uint* data)
57{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
58
59class QMetaMethodBuilderPrivate
60{
61public:
62 QMetaMethodBuilderPrivate
63 (QMetaMethod::MethodType _methodType,
64 const QByteArray& _signature,
65 const QByteArray& _returnType = QByteArray("void"),
66 QMetaMethod::Access _access = QMetaMethod::Public,
67 int _revision = 0)
68 : signature(QMetaObject::normalizedSignature(method: _signature.constData())),
69 returnType(QMetaObject::normalizedType(type: _returnType)),
70 attributes(((int)_access) | (((int)_methodType) << 2)),
71 revision(_revision)
72 {
73 Q_ASSERT((_methodType == QMetaMethod::Constructor) == returnType.isNull());
74 }
75
76 QByteArray signature;
77 QByteArray returnType;
78 QList<QByteArray> parameterNames;
79 QByteArray tag;
80 int attributes;
81 int revision;
82
83 QMetaMethod::MethodType methodType() const
84 {
85 return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2);
86 }
87
88 QMetaMethod::Access access() const
89 {
90 return (QMetaMethod::Access)(attributes & AccessMask);
91 }
92
93 void setAccess(QMetaMethod::Access value)
94 {
95 attributes = ((attributes & ~AccessMask) | (int)value);
96 }
97
98 QList<QByteArray> parameterTypes() const
99 {
100 return QMetaObjectPrivate::parameterTypeNamesFromSignature(signature);
101 }
102
103 int parameterCount() const
104 {
105 return parameterTypes().size();
106 }
107
108 QByteArray name() const
109 {
110 return signature.left(n: qMax(a: signature.indexOf(c: '('), b: 0));
111 }
112};
113Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_RELOCATABLE_TYPE);
114
115class QMetaPropertyBuilderPrivate
116{
117public:
118 QMetaPropertyBuilderPrivate
119 (const QByteArray& _name, const QByteArray& _type, QMetaType _metaType, int notifierIdx=-1,
120 int _revision = 0)
121 : name(_name),
122 type(QMetaObject::normalizedType(type: _type.constData())),
123 metaType(_metaType),
124 flags(Readable | Writable | Scriptable), notifySignal(notifierIdx),
125 revision(_revision)
126 {
127
128 }
129
130 QByteArray name;
131 QByteArray type;
132 QMetaType metaType;
133 int flags;
134 int notifySignal;
135 int revision;
136
137 bool flag(int f) const
138 {
139 return ((flags & f) != 0);
140 }
141
142 void setFlag(int f, bool value)
143 {
144 if (value)
145 flags |= f;
146 else
147 flags &= ~f;
148 }
149};
150Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_RELOCATABLE_TYPE);
151
152class QMetaEnumBuilderPrivate
153{
154public:
155 QMetaEnumBuilderPrivate(const QByteArray &_name)
156 : name(_name), enumName(_name), isFlag(false), isScoped(false)
157 {
158 }
159
160 QByteArray name;
161 QByteArray enumName;
162 QMetaType metaType;
163 bool isFlag;
164 bool isScoped;
165 QList<QByteArray> keys;
166 QList<int> values;
167};
168Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_RELOCATABLE_TYPE);
169
170class QMetaObjectBuilderPrivate
171{
172public:
173 QMetaObjectBuilderPrivate()
174 : flags(0)
175 {
176 superClass = &QObject::staticMetaObject;
177 staticMetacallFunction = nullptr;
178 }
179
180 bool hasRevisionedMethods() const;
181
182 QByteArray className;
183 const QMetaObject *superClass;
184 QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
185 std::vector<QMetaMethodBuilderPrivate> methods;
186 std::vector<QMetaMethodBuilderPrivate> constructors;
187 std::vector<QMetaPropertyBuilderPrivate> properties;
188 QList<QByteArray> classInfoNames;
189 QList<QByteArray> classInfoValues;
190 std::vector<QMetaEnumBuilderPrivate> enumerators;
191 QList<const QMetaObject *> relatedMetaObjects;
192 MetaObjectFlags flags;
193};
194
195bool QMetaObjectBuilderPrivate::hasRevisionedMethods() const
196{
197 for (const auto &method : methods) {
198 if (method.revision)
199 return true;
200 }
201 return false;
202}
203
204/*!
205 Constructs a new QMetaObjectBuilder.
206*/
207QMetaObjectBuilder::QMetaObjectBuilder()
208{
209 d = new QMetaObjectBuilderPrivate();
210}
211
212/*!
213 Constructs a new QMetaObjectBuilder which is a copy of the
214 meta object information in \a prototype. Note: the super class
215 contents for \a prototype are not copied, only the immediate
216 class that is defined by \a prototype.
217
218 The \a members parameter indicates which members of \a prototype
219 should be added. The default is AllMembers.
220
221 \sa addMetaObject()
222*/
223QMetaObjectBuilder::QMetaObjectBuilder(const QMetaObject *prototype,
224 QMetaObjectBuilder::AddMembers members)
225{
226 d = new QMetaObjectBuilderPrivate();
227 addMetaObject(prototype, members);
228}
229
230/*!
231 Destroys this meta object builder.
232*/
233QMetaObjectBuilder::~QMetaObjectBuilder()
234{
235 delete d;
236}
237
238/*!
239 Returns the name of the class being constructed by this
240 meta object builder. The default value is an empty QByteArray.
241
242 \sa setClassName(), superClass()
243*/
244QByteArray QMetaObjectBuilder::className() const
245{
246 return d->className;
247}
248
249/*!
250 Sets the \a name of the class being constructed by this
251 meta object builder.
252
253 \sa className(), setSuperClass()
254*/
255void QMetaObjectBuilder::setClassName(const QByteArray &name)
256{
257 d->className = name;
258}
259
260/*!
261 Returns the superclass meta object of the class being constructed
262 by this meta object builder. The default value is the meta object
263 for QObject.
264
265 \sa setSuperClass(), className()
266*/
267const QMetaObject *QMetaObjectBuilder::superClass() const
268{
269 return d->superClass;
270}
271
272/*!
273 Sets the superclass meta object of the class being constructed
274 by this meta object builder to \a meta. The \a meta parameter
275 must not be null.
276
277 \sa superClass(), setClassName()
278*/
279void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta)
280{
281 Q_ASSERT(meta);
282 d->superClass = meta;
283}
284
285/*!
286 Returns the flags of the class being constructed by this meta object
287 builder.
288
289 \sa setFlags()
290*/
291MetaObjectFlags QMetaObjectBuilder::flags() const
292{
293 return d->flags;
294}
295
296/*!
297 Sets the \a flags of the class being constructed by this meta object
298 builder.
299
300 \sa flags()
301*/
302void QMetaObjectBuilder::setFlags(MetaObjectFlags flags)
303{
304 d->flags = flags;
305}
306
307/*!
308 Returns the number of methods in this class, excluding the number
309 of methods in the base class. These include signals and slots
310 as well as normal member functions.
311
312 \sa addMethod(), method(), removeMethod(), indexOfMethod()
313*/
314int QMetaObjectBuilder::methodCount() const
315{
316 return int(d->methods.size());
317}
318
319/*!
320 Returns the number of constructors in this class.
321
322 \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor()
323*/
324int QMetaObjectBuilder::constructorCount() const
325{
326 return int(d->constructors.size());
327}
328
329/*!
330 Returns the number of properties in this class, excluding the number
331 of properties in the base class.
332
333 \sa addProperty(), property(), removeProperty(), indexOfProperty()
334*/
335int QMetaObjectBuilder::propertyCount() const
336{
337 return int(d->properties.size());
338}
339
340/*!
341 Returns the number of enumerators in this class, excluding the
342 number of enumerators in the base class.
343
344 \sa addEnumerator(), enumerator(), removeEnumerator()
345 \sa indexOfEnumerator()
346*/
347int QMetaObjectBuilder::enumeratorCount() const
348{
349 return int(d->enumerators.size());
350}
351
352/*!
353 Returns the number of items of class information in this class,
354 exclusing the number of items of class information in the base class.
355
356 \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo()
357 \sa indexOfClassInfo()
358*/
359int QMetaObjectBuilder::classInfoCount() const
360{
361 return d->classInfoNames.size();
362}
363
364/*!
365 Returns the number of related meta objects that are associated
366 with this class.
367
368 Related meta objects are used when resolving the enumerated type
369 associated with a property, where the enumerated type is in a
370 different class from the property.
371
372 \sa addRelatedMetaObject(), relatedMetaObject()
373 \sa removeRelatedMetaObject()
374*/
375int QMetaObjectBuilder::relatedMetaObjectCount() const
376{
377 return d->relatedMetaObjects.size();
378}
379
380/*!
381 Adds a new public method to this class with the specified \a signature.
382 Returns an object that can be used to adjust the other attributes
383 of the method. The \a signature will be normalized before it is
384 added to the class.
385
386 \sa method(), methodCount(), removeMethod(), indexOfMethod()
387*/
388QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray &signature)
389{
390 int index = int(d->methods.size());
391 d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
392 return QMetaMethodBuilder(this, index);
393}
394
395/*!
396 Adds a new public method to this class with the specified
397 \a signature and \a returnType. Returns an object that can be
398 used to adjust the other attributes of the method. The \a signature
399 and \a returnType will be normalized before they are added to
400 the class.
401
402 \sa method(), methodCount(), removeMethod(), indexOfMethod()
403*/
404QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray &signature,
405 const QByteArray &returnType)
406{
407 int index = int(d->methods.size());
408 d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Method, signature, returnType));
409 return QMetaMethodBuilder(this, index);
410}
411
412/*!
413 Adds a new public method to this class that has the same information as
414 \a prototype. This is used to clone the methods of an existing
415 QMetaObject. Returns an object that can be used to adjust the
416 attributes of the method.
417
418 This function will detect if \a prototype is an ordinary method,
419 signal, slot, or constructor and act accordingly.
420
421 \sa method(), methodCount(), removeMethod(), indexOfMethod()
422*/
423QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod &prototype)
424{
425 QMetaMethodBuilder method;
426 if (prototype.methodType() == QMetaMethod::Method)
427 method = addMethod(signature: prototype.methodSignature());
428 else if (prototype.methodType() == QMetaMethod::Signal)
429 method = addSignal(signature: prototype.methodSignature());
430 else if (prototype.methodType() == QMetaMethod::Slot)
431 method = addSlot(signature: prototype.methodSignature());
432 else if (prototype.methodType() == QMetaMethod::Constructor)
433 method = addConstructor(signature: prototype.methodSignature());
434 method.setReturnType(prototype.typeName());
435 method.setParameterNames(prototype.parameterNames());
436 method.setTag(prototype.tag());
437 method.setAccess(prototype.access());
438 method.setAttributes(prototype.attributes());
439 method.setRevision(prototype.revision());
440 return method;
441}
442
443/*!
444 Adds a new public slot to this class with the specified \a signature.
445 Returns an object that can be used to adjust the other attributes
446 of the slot. The \a signature will be normalized before it is
447 added to the class.
448
449 \sa addMethod(), addSignal(), indexOfSlot()
450*/
451QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray &signature)
452{
453 int index = int(d->methods.size());
454 d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
455 return QMetaMethodBuilder(this, index);
456}
457
458/*!
459 Adds a new signal to this class with the specified \a signature.
460 Returns an object that can be used to adjust the other attributes
461 of the signal. The \a signature will be normalized before it is
462 added to the class.
463
464 \sa addMethod(), addSlot(), indexOfSignal()
465*/
466QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray &signature)
467{
468 int index = int(d->methods.size());
469 d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Signal, signature,
470 QByteArray("void"), QMetaMethod::Public));
471 return QMetaMethodBuilder(this, index);
472}
473
474/*!
475 Adds a new constructor to this class with the specified \a signature.
476 Returns an object that can be used to adjust the other attributes
477 of the constructor. The \a signature will be normalized before it is
478 added to the class.
479
480 \sa constructor(), constructorCount(), removeConstructor()
481 \sa indexOfConstructor()
482*/
483QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray &signature)
484{
485 int index = int(d->constructors.size());
486 d->constructors.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature,
487 /*returnType=*/QByteArray()));
488 return QMetaMethodBuilder(this, -(index + 1));
489}
490
491/*!
492 Adds a new constructor to this class that has the same information as
493 \a prototype. This is used to clone the constructors of an existing
494 QMetaObject. Returns an object that can be used to adjust the
495 attributes of the constructor.
496
497 This function requires that \a prototype be a constructor.
498
499 \sa constructor(), constructorCount(), removeConstructor()
500 \sa indexOfConstructor()
501*/
502QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod &prototype)
503{
504 Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
505 QMetaMethodBuilder ctor = addConstructor(signature: prototype.methodSignature());
506 ctor.setReturnType(prototype.typeName());
507 ctor.setParameterNames(prototype.parameterNames());
508 ctor.setTag(prototype.tag());
509 ctor.setAccess(prototype.access());
510 ctor.setAttributes(prototype.attributes());
511 return ctor;
512}
513
514/*!
515 Adds a new readable/writable property to this class with the
516 specified \a name and \a type. Returns an object that can be used
517 to adjust the other attributes of the property. The \a type will
518 be normalized before it is added to the class. \a notifierId will
519 be registered as the property's \e notify signal.
520
521 \sa property(), propertyCount(), removeProperty(), indexOfProperty()
522*/
523QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type,
524 int notifierId)
525{
526 return addProperty(name, type, metaType: QMetaType::fromName(name: type), notifierId);
527}
528
529/*!
530 \overload
531 */
532QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type, QMetaType metaType, int notifierId)
533{
534 int index = int(d->properties.size());
535 d->properties.push_back(x: QMetaPropertyBuilderPrivate(name, type, metaType, notifierId));
536 return QMetaPropertyBuilder(this, index);
537}
538
539/*!
540 Adds a new property to this class that has the same information as
541 \a prototype. This is used to clone the properties of an existing
542 QMetaObject. Returns an object that can be used to adjust the
543 attributes of the property.
544
545 \sa property(), propertyCount(), removeProperty(), indexOfProperty()
546*/
547QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty &prototype)
548{
549 QMetaPropertyBuilder property = addProperty(name: prototype.name(), type: prototype.typeName(), metaType: prototype.metaType());
550 property.setReadable(prototype.isReadable());
551 property.setWritable(prototype.isWritable());
552 property.setResettable(prototype.isResettable());
553 property.setDesignable(prototype.isDesignable());
554 property.setScriptable(prototype.isScriptable());
555 property.setStored(prototype.isStored());
556 property.setUser(prototype.isUser());
557 property.setStdCppSet(prototype.hasStdCppSet());
558 property.setEnumOrFlag(prototype.isEnumType());
559 property.setConstant(prototype.isConstant());
560 property.setFinal(prototype.isFinal());
561 property.setRevision(prototype.revision());
562 if (prototype.hasNotifySignal()) {
563 // Find an existing method for the notify signal, or add a new one.
564 QMetaMethod method = prototype.notifySignal();
565 int index = indexOfMethod(signature: method.methodSignature());
566 if (index == -1)
567 index = addMethod(prototype: method).index();
568 d->properties[property._index].notifySignal = index;
569 }
570 return property;
571}
572
573/*!
574 Adds a new enumerator to this class with the specified
575 \a name. Returns an object that can be used to adjust
576 the other attributes of the enumerator.
577
578 \sa enumerator(), enumeratorCount(), removeEnumerator()
579 \sa indexOfEnumerator()
580*/
581QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray &name)
582{
583 int index = int(d->enumerators.size());
584 d->enumerators.push_back(x: QMetaEnumBuilderPrivate(name));
585 return QMetaEnumBuilder(this, index);
586}
587
588/*!
589 Adds a new enumerator to this class that has the same information as
590 \a prototype. This is used to clone the enumerators of an existing
591 QMetaObject. Returns an object that can be used to adjust the
592 attributes of the enumerator.
593
594 \sa enumerator(), enumeratorCount(), removeEnumerator()
595 \sa indexOfEnumerator()
596*/
597QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum &prototype)
598{
599 QMetaEnumBuilder en = addEnumerator(name: prototype.name());
600 en.setEnumName(prototype.enumName());
601 en.setMetaType(prototype.metaType());
602 en.setIsFlag(prototype.isFlag());
603 en.setIsScoped(prototype.isScoped());
604 int count = prototype.keyCount();
605 for (int index = 0; index < count; ++index)
606 en.addKey(name: prototype.key(index), value: prototype.value(index));
607 return en;
608}
609
610/*!
611 Adds \a name and \a value as an item of class information to this class.
612 Returns the index of the new item of class information.
613
614 \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo()
615 \sa indexOfClassInfo()
616*/
617int QMetaObjectBuilder::addClassInfo(const QByteArray &name, const QByteArray &value)
618{
619 int index = d->classInfoNames.size();
620 d->classInfoNames += name;
621 d->classInfoValues += value;
622 return index;
623}
624
625/*!
626 Adds \a meta to this class as a related meta object. Returns
627 the index of the new related meta object entry.
628
629 Related meta objects are used when resolving the enumerated type
630 associated with a property, where the enumerated type is in a
631 different class from the property.
632
633 \sa relatedMetaObjectCount(), relatedMetaObject()
634 \sa removeRelatedMetaObject()
635*/
636int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta)
637{
638 Q_ASSERT(meta);
639 int index = d->relatedMetaObjects.size();
640 d->relatedMetaObjects.append(t: meta);
641 return index;
642}
643
644/*!
645 Adds the contents of \a prototype to this meta object builder.
646 This function is useful for cloning the contents of an existing QMetaObject.
647
648 The \a members parameter indicates which members of \a prototype
649 should be added. The default is AllMembers.
650*/
651void QMetaObjectBuilder::addMetaObject(const QMetaObject *prototype,
652 QMetaObjectBuilder::AddMembers members)
653{
654 Q_ASSERT(prototype);
655 int index;
656
657 if ((members & ClassName) != 0)
658 d->className = prototype->className();
659
660 if ((members & SuperClass) != 0)
661 d->superClass = prototype->superClass();
662
663 if ((members & (Methods | Signals | Slots)) != 0) {
664 for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) {
665 QMetaMethod method = prototype->method(index);
666 if (method.methodType() != QMetaMethod::Signal) {
667 if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0)
668 continue;
669 if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0)
670 continue;
671 if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0)
672 continue;
673 }
674 if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) {
675 addMethod(prototype: method);
676 } else if (method.methodType() == QMetaMethod::Signal &&
677 (members & Signals) != 0) {
678 addMethod(prototype: method);
679 } else if (method.methodType() == QMetaMethod::Slot &&
680 (members & Slots) != 0) {
681 addMethod(prototype: method);
682 }
683 }
684 }
685
686 if ((members & Constructors) != 0) {
687 for (index = 0; index < prototype->constructorCount(); ++index)
688 addConstructor(prototype: prototype->constructor(index));
689 }
690
691 if ((members & Properties) != 0) {
692 for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index)
693 addProperty(prototype: prototype->property(index));
694 }
695
696 if ((members & Enumerators) != 0) {
697 for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index)
698 addEnumerator(prototype: prototype->enumerator(index));
699 }
700
701 if ((members & ClassInfos) != 0) {
702 for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) {
703 QMetaClassInfo ci = prototype->classInfo(index);
704 addClassInfo(name: ci.name(), value: ci.value());
705 }
706 }
707
708 if ((members & RelatedMetaObjects) != 0) {
709 Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 2);
710 const auto *objects = prototype->d.relatedMetaObjects;
711 if (objects) {
712 while (*objects != nullptr) {
713 addRelatedMetaObject(meta: *objects);
714 ++objects;
715 }
716 }
717 }
718
719 if ((members & StaticMetacall) != 0) {
720 Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 6);
721 if (prototype->d.static_metacall)
722 setStaticMetacallFunction(prototype->d.static_metacall);
723 }
724}
725
726/*!
727 Returns the method at \a index in this class.
728
729 \sa methodCount(), addMethod(), removeMethod(), indexOfMethod()
730*/
731QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
732{
733 if (uint(index) < d->methods.size())
734 return QMetaMethodBuilder(this, index);
735 else
736 return QMetaMethodBuilder();
737}
738
739/*!
740 Returns the constructor at \a index in this class.
741
742 \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor()
743*/
744QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
745{
746 if (uint(index) < d->constructors.size())
747 return QMetaMethodBuilder(this, -(index + 1));
748 else
749 return QMetaMethodBuilder();
750}
751
752/*!
753 Returns the property at \a index in this class.
754
755 \sa methodCount(), addMethod(), removeMethod(), indexOfProperty()
756*/
757QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
758{
759 if (uint(index) < d->properties.size())
760 return QMetaPropertyBuilder(this, index);
761 else
762 return QMetaPropertyBuilder();
763}
764
765/*!
766 Returns the enumerator at \a index in this class.
767
768 \sa enumeratorCount(), addEnumerator(), removeEnumerator()
769 \sa indexOfEnumerator()
770*/
771QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const
772{
773 if (uint(index) < d->enumerators.size())
774 return QMetaEnumBuilder(this, index);
775 else
776 return QMetaEnumBuilder();
777}
778
779/*!
780 Returns the related meta object at \a index in this class.
781
782 Related meta objects are used when resolving the enumerated type
783 associated with a property, where the enumerated type is in a
784 different class from the property.
785
786 \sa relatedMetaObjectCount(), addRelatedMetaObject()
787 \sa removeRelatedMetaObject()
788*/
789const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const
790{
791 if (index >= 0 && index < d->relatedMetaObjects.size())
792 return d->relatedMetaObjects[index];
793 else
794 return nullptr;
795}
796
797/*!
798 Returns the name of the item of class information at \a index
799 in this class.
800
801 \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo()
802 \sa indexOfClassInfo()
803*/
804QByteArray QMetaObjectBuilder::classInfoName(int index) const
805{
806 if (index >= 0 && index < d->classInfoNames.size())
807 return d->classInfoNames[index];
808 else
809 return QByteArray();
810}
811
812/*!
813 Returns the value of the item of class information at \a index
814 in this class.
815
816 \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo()
817 \sa indexOfClassInfo()
818*/
819QByteArray QMetaObjectBuilder::classInfoValue(int index) const
820{
821 if (index >= 0 && index < d->classInfoValues.size())
822 return d->classInfoValues[index];
823 else
824 return QByteArray();
825}
826
827/*!
828 Removes the method at \a index from this class. The indices of
829 all following methods will be adjusted downwards by 1. If the
830 method is registered as a notify signal on a property, then the
831 notify signal will be removed from the property.
832
833 \sa methodCount(), addMethod(), method(), indexOfMethod()
834*/
835void QMetaObjectBuilder::removeMethod(int index)
836{
837 if (uint(index) < d->methods.size()) {
838 d->methods.erase(position: d->methods.begin() + index);
839 for (auto &property : d->properties) {
840 // Adjust the indices of property notify signal references.
841 if (property.notifySignal == index) {
842 property.notifySignal = -1;
843 } else if (property.notifySignal > index)
844 property.notifySignal--;
845 }
846 }
847}
848
849/*!
850 Removes the constructor at \a index from this class. The indices of
851 all following constructors will be adjusted downwards by 1.
852
853 \sa constructorCount(), addConstructor(), constructor()
854 \sa indexOfConstructor()
855*/
856void QMetaObjectBuilder::removeConstructor(int index)
857{
858 if (uint(index) < d->constructors.size())
859 d->constructors.erase(position: d->constructors.begin() + index);
860}
861
862/*!
863 Removes the property at \a index from this class. The indices of
864 all following properties will be adjusted downwards by 1.
865
866 \sa propertyCount(), addProperty(), property(), indexOfProperty()
867*/
868void QMetaObjectBuilder::removeProperty(int index)
869{
870 if (uint(index) < d->properties.size())
871 d->properties.erase(position: d->properties.begin() + index);
872}
873
874/*!
875 Removes the enumerator at \a index from this class. The indices of
876 all following enumerators will be adjusted downwards by 1.
877
878 \sa enumertorCount(), addEnumerator(), enumerator()
879 \sa indexOfEnumerator()
880*/
881void QMetaObjectBuilder::removeEnumerator(int index)
882{
883 if (uint(index) < d->enumerators.size())
884 d->enumerators.erase(position: d->enumerators.begin() + index);
885}
886
887/*!
888 Removes the item of class information at \a index from this class.
889 The indices of all following items will be adjusted downwards by 1.
890
891 \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue()
892 \sa indexOfClassInfo()
893*/
894void QMetaObjectBuilder::removeClassInfo(int index)
895{
896 if (index >= 0 && index < d->classInfoNames.size()) {
897 d->classInfoNames.removeAt(i: index);
898 d->classInfoValues.removeAt(i: index);
899 }
900}
901
902/*!
903 Removes the related meta object at \a index from this class.
904 The indices of all following related meta objects will be adjusted
905 downwards by 1.
906
907 Related meta objects are used when resolving the enumerated type
908 associated with a property, where the enumerated type is in a
909 different class from the property.
910
911 \sa relatedMetaObjectCount(), addRelatedMetaObject()
912 \sa relatedMetaObject()
913*/
914void QMetaObjectBuilder::removeRelatedMetaObject(int index)
915{
916 if (index >= 0 && index < d->relatedMetaObjects.size())
917 d->relatedMetaObjects.removeAt(i: index);
918}
919
920/*!
921 Finds a method with the specified \a signature and returns its index;
922 otherwise returns -1. The \a signature will be normalized by this method.
923
924 \sa method(), methodCount(), addMethod(), removeMethod()
925*/
926int QMetaObjectBuilder::indexOfMethod(const QByteArray &signature)
927{
928 QByteArray sig = QMetaObject::normalizedSignature(method: signature);
929 for (const auto &method : d->methods) {
930 if (sig == method.signature)
931 return int(&method - &d->methods.front());
932 }
933 return -1;
934}
935
936/*!
937 Finds a signal with the specified \a signature and returns its index;
938 otherwise returns -1. The \a signature will be normalized by this method.
939
940 \sa indexOfMethod(), indexOfSlot()
941*/
942int QMetaObjectBuilder::indexOfSignal(const QByteArray &signature)
943{
944 QByteArray sig = QMetaObject::normalizedSignature(method: signature);
945 for (const auto &method : d->methods) {
946 if (method.methodType() == QMetaMethod::Signal && sig == method.signature)
947 return int(&method - &d->methods.front());
948 }
949 return -1;
950}
951
952/*!
953 Finds a slot with the specified \a signature and returns its index;
954 otherwise returns -1. The \a signature will be normalized by this method.
955
956 \sa indexOfMethod(), indexOfSignal()
957*/
958int QMetaObjectBuilder::indexOfSlot(const QByteArray &signature)
959{
960 QByteArray sig = QMetaObject::normalizedSignature(method: signature);
961 for (const auto &method : d->methods) {
962 if (method.methodType() == QMetaMethod::Slot && sig == method.signature)
963 return int(&method - &d->methods.front());
964 }
965 return -1;
966}
967
968/*!
969 Finds a constructor with the specified \a signature and returns its index;
970 otherwise returns -1. The \a signature will be normalized by this method.
971
972 \sa constructor(), constructorCount(), addConstructor(), removeConstructor()
973*/
974int QMetaObjectBuilder::indexOfConstructor(const QByteArray &signature)
975{
976 QByteArray sig = QMetaObject::normalizedSignature(method: signature);
977 for (const auto &constructor : d->constructors) {
978 if (sig == constructor.signature)
979 return int(&constructor - &d->constructors.front());
980 }
981 return -1;
982}
983
984/*!
985 Finds a property with the specified \a name and returns its index;
986 otherwise returns -1.
987
988 \sa property(), propertyCount(), addProperty(), removeProperty()
989*/
990int QMetaObjectBuilder::indexOfProperty(const QByteArray &name)
991{
992 for (const auto &property : d->properties) {
993 if (name == property.name)
994 return int(&property - &d->properties.front());
995 }
996 return -1;
997}
998
999/*!
1000 Finds an enumerator with the specified \a name and returns its index;
1001 otherwise returns -1.
1002
1003 \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator()
1004*/
1005int QMetaObjectBuilder::indexOfEnumerator(const QByteArray &name)
1006{
1007 for (const auto &enumerator : d->enumerators) {
1008 if (name == enumerator.name)
1009 return int(&enumerator - &d->enumerators.front());
1010 }
1011 return -1;
1012}
1013
1014/*!
1015 Finds an item of class information with the specified \a name and
1016 returns its index; otherwise returns -1.
1017
1018 \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo()
1019 \sa removeClassInfo()
1020*/
1021int QMetaObjectBuilder::indexOfClassInfo(const QByteArray &name)
1022{
1023 for (int index = 0; index < d->classInfoNames.size(); ++index) {
1024 if (name == d->classInfoNames[index])
1025 return index;
1026 }
1027 return -1;
1028}
1029
1030// Align on a specific type boundary.
1031#ifdef ALIGN
1032# undef ALIGN
1033#endif
1034#define ALIGN(size,type) \
1035 (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
1036
1037/*!
1038 \class QMetaStringTable
1039 \inmodule QtCore
1040 \internal
1041 \brief The QMetaStringTable class can generate a meta-object string table at runtime.
1042*/
1043
1044QMetaStringTable::QMetaStringTable(const QByteArray &className)
1045 : m_index(0)
1046 , m_className(className)
1047{
1048 const int index = enter(value: m_className);
1049 Q_ASSERT(index == 0);
1050 Q_UNUSED(index);
1051}
1052
1053// Enters the given value into the string table (if it hasn't already been
1054// entered). Returns the index of the string.
1055int QMetaStringTable::enter(const QByteArray &value)
1056{
1057 Entries::iterator it = m_entries.find(key: value);
1058 if (it != m_entries.end())
1059 return it.value();
1060 int pos = m_index;
1061 m_entries.insert(key: value, value: pos);
1062 ++m_index;
1063 return pos;
1064}
1065
1066int QMetaStringTable::preferredAlignment()
1067{
1068 return alignof(uint);
1069}
1070
1071// Returns the size (in bytes) required for serializing this string table.
1072int QMetaStringTable::blobSize() const
1073{
1074 int size = int(m_entries.size() * 2 * sizeof(uint));
1075 Entries::const_iterator it;
1076 for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
1077 size += it.key().size() + 1;
1078 return size;
1079}
1080
1081static void writeString(char *out, int i, const QByteArray &str,
1082 const int offsetOfStringdataMember, int &stringdataOffset)
1083{
1084 int size = str.size();
1085 int offset = offsetOfStringdataMember + stringdataOffset;
1086 uint offsetLen[2] = { uint(offset), uint(size) };
1087
1088 memcpy(dest: out + 2 * i * sizeof(uint), src: &offsetLen, n: 2 * sizeof(uint));
1089
1090 memcpy(dest: out + offset, src: str.constData(), n: size);
1091 out[offset + size] = '\0';
1092
1093 stringdataOffset += size + 1;
1094}
1095
1096// Writes strings to string data struct.
1097// The struct consists of an array of QByteArrayData, followed by a char array
1098// containing the actual strings. This format must match the one produced by
1099// moc (see generator.cpp).
1100void QMetaStringTable::writeBlob(char *out) const
1101{
1102 Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment() - 1)));
1103
1104 int offsetOfStringdataMember = int(m_entries.size() * 2 * sizeof(uint));
1105 int stringdataOffset = 0;
1106
1107 // qt_metacast expects the first string in the string table to be the class name.
1108 writeString(out, /*index*/ i: 0, str: m_className, offsetOfStringdataMember, stringdataOffset);
1109
1110 for (Entries::ConstIterator it = m_entries.constBegin(), end = m_entries.constEnd();
1111 it != end; ++it) {
1112 const int i = it.value();
1113 if (i == 0)
1114 continue;
1115 const QByteArray &str = it.key();
1116
1117 writeString(out, i, str, offsetOfStringdataMember, stringdataOffset);
1118 }
1119}
1120
1121// Returns the sum of all parameters (including return type) for the given
1122// \a methods. This is needed for calculating the size of the methods'
1123// parameter type/name meta-data.
1124static int aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> &methods)
1125{
1126 int sum = 0;
1127 for (const auto &method : methods)
1128 sum += method.parameterCount() + 1; // +1 for return type
1129 return sum;
1130}
1131
1132enum Mode {
1133 Prepare, // compute the size of the metaobject
1134 Construct // construct metaobject in pre-allocated buffer
1135};
1136// Build a QMetaObject in "buf" based on the information in "d".
1137// If the mode is prepare, then return the number of bytes needed to
1138// build the QMetaObject.
1139template<Mode mode>
1140static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
1141 int expectedSize)
1142{
1143 Q_UNUSED(expectedSize); // Avoid warning in release mode
1144 Q_UNUSED(buf);
1145 qsizetype size = 0;
1146 int dataIndex;
1147 int paramsIndex;
1148 int enumIndex;
1149 int index;
1150 bool hasRevisionedMethods = d->hasRevisionedMethods();
1151
1152 // Create the main QMetaObject structure at the start of the buffer.
1153 QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf);
1154 size += sizeof(QMetaObject);
1155 ALIGN(size, int);
1156 if constexpr (mode == Construct) {
1157 meta->d.superdata = d->superClass;
1158 meta->d.relatedMetaObjects = nullptr;
1159 meta->d.extradata = nullptr;
1160 meta->d.metaTypes = nullptr;
1161 meta->d.static_metacall = d->staticMetacallFunction;
1162 }
1163
1164 // Populate the QMetaObjectPrivate structure.
1165 QMetaObjectPrivate *pmeta = buf ? reinterpret_cast<QMetaObjectPrivate *>(buf + size)
1166 : nullptr;
1167 //int pmetaSize = size;
1168 dataIndex = MetaObjectPrivateFieldCount;
1169 int methodParametersDataSize =
1170 ((aggregateParameterCount(methods: d->methods)
1171 + aggregateParameterCount(methods: d->constructors)) * 2) // types and parameter names
1172 - int(d->methods.size()) // return "parameters" don't have names
1173 - int(d->constructors.size()); // "this" parameters don't have names
1174 if constexpr (mode == Construct) {
1175 static_assert(QMetaObjectPrivate::OutputRevision == 12, "QMetaObjectBuilder should generate the same version as moc");
1176 pmeta->revision = QMetaObjectPrivate::OutputRevision;
1177 pmeta->flags = d->flags.toInt();
1178 pmeta->className = 0; // Class name is always the first string.
1179 //pmeta->signalCount is handled in the "output method loop" as an optimization.
1180
1181 pmeta->classInfoCount = d->classInfoNames.size();
1182 pmeta->classInfoData = dataIndex;
1183 dataIndex += 2 * d->classInfoNames.size();
1184
1185 pmeta->methodCount = int(d->methods.size());
1186 pmeta->methodData = dataIndex;
1187 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
1188 if (hasRevisionedMethods)
1189 dataIndex += int(d->methods.size());
1190 paramsIndex = dataIndex;
1191 dataIndex += methodParametersDataSize;
1192
1193 pmeta->propertyCount = int(d->properties.size());
1194 pmeta->propertyData = dataIndex;
1195 dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size());
1196
1197 pmeta->enumeratorCount = int(d->enumerators.size());
1198 pmeta->enumeratorData = dataIndex;
1199 dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size());
1200
1201 pmeta->constructorCount = int(d->constructors.size());
1202 pmeta->constructorData = dataIndex;
1203 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
1204 } else {
1205 dataIndex += 2 * int(d->classInfoNames.size());
1206 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
1207 if (hasRevisionedMethods)
1208 dataIndex += int(d->methods.size());
1209 paramsIndex = dataIndex;
1210 dataIndex += methodParametersDataSize;
1211 dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size());
1212 dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size());
1213 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
1214 }
1215
1216 // Allocate space for the enumerator key names and values.
1217 enumIndex = dataIndex;
1218 for (const auto &enumerator : d->enumerators)
1219 dataIndex += 2 * enumerator.keys.size();
1220
1221 // Zero terminator at the end of the data offset table.
1222 ++dataIndex;
1223
1224 // Find the start of the data and string tables.
1225 int *data = reinterpret_cast<int *>(pmeta);
1226 size += dataIndex * sizeof(int);
1227 ALIGN(size, void *);
1228 [[maybe_unused]] char *str = reinterpret_cast<char *>(buf + size);
1229 if constexpr (mode == Construct) {
1230 meta->d.stringdata = reinterpret_cast<const uint *>(str);
1231 meta->d.data = reinterpret_cast<uint *>(data);
1232 }
1233
1234 // Reset the current data position to just past the QMetaObjectPrivate.
1235 dataIndex = MetaObjectPrivateFieldCount;
1236
1237 QMetaStringTable strings(d->className);
1238
1239 // Output the class infos,
1240 Q_ASSERT(!buf || dataIndex == pmeta->classInfoData);
1241 for (index = 0; index < d->classInfoNames.size(); ++index) {
1242 [[maybe_unused]] int name = strings.enter(value: d->classInfoNames[index]);
1243 [[maybe_unused]] int value = strings.enter(value: d->classInfoValues[index]);
1244 if constexpr (mode == Construct) {
1245 data[dataIndex] = name;
1246 data[dataIndex + 1] = value;
1247 }
1248 dataIndex += 2;
1249 }
1250
1251 // Output the methods in the class.
1252 Q_ASSERT(!buf || dataIndex == pmeta->methodData);
1253 // property count + enum count + 1 for metatype of this metaobject
1254 int parameterMetaTypesIndex = int(d->properties.size()) + int(d->enumerators.size()) + 1;
1255 for (const auto &method : d->methods) {
1256 [[maybe_unused]] int name = strings.enter(value: method.name());
1257 int argc = method.parameterCount();
1258 [[maybe_unused]] int tag = strings.enter(value: method.tag);
1259 [[maybe_unused]] int attrs = method.attributes;
1260 if constexpr (mode == Construct) {
1261 data[dataIndex] = name;
1262 data[dataIndex + 1] = argc;
1263 data[dataIndex + 2] = paramsIndex;
1264 data[dataIndex + 3] = tag;
1265 data[dataIndex + 4] = attrs;
1266 data[dataIndex + 5] = parameterMetaTypesIndex;
1267 if (method.methodType() == QMetaMethod::Signal)
1268 pmeta->signalCount++;
1269 }
1270 dataIndex += QMetaObjectPrivate::IntsPerMethod;
1271 paramsIndex += 1 + argc * 2;
1272 parameterMetaTypesIndex += 1 + argc;
1273 }
1274 if (hasRevisionedMethods) {
1275 for (const auto &method : d->methods) {
1276 if constexpr (mode == Construct)
1277 data[dataIndex] = method.revision;
1278 ++dataIndex;
1279 }
1280 }
1281
1282 // Output the method parameters in the class.
1283 Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * QMetaObjectPrivate::IntsPerMethod
1284 + (hasRevisionedMethods ? int(d->methods.size()) : 0));
1285 for (int x = 0; x < 2; ++x) {
1286 const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
1287 for (const auto &method : methods) {
1288 const QList<QByteArray> paramTypeNames = method.parameterTypes();
1289 int paramCount = paramTypeNames.size();
1290 for (int i = -1; i < paramCount; ++i) {
1291 const QByteArray &typeName = (i < 0) ? method.returnType : paramTypeNames.at(i);
1292 [[maybe_unused]] int typeInfo;
1293 if (QtPrivate::isBuiltinType(type: typeName))
1294 typeInfo = QMetaType::fromName(name: typeName).id();
1295 else
1296 typeInfo = IsUnresolvedType | strings.enter(value: typeName);
1297 if constexpr (mode == Construct)
1298 data[dataIndex] = typeInfo;
1299 ++dataIndex;
1300 }
1301
1302 QList<QByteArray> paramNames = method.parameterNames;
1303 while (paramNames.size() < paramCount)
1304 paramNames.append(t: QByteArray());
1305 for (int i = 0; i < paramCount; ++i) {
1306 [[maybe_unused]] int stringIndex = strings.enter(value: paramNames.at(i));
1307 if constexpr (mode == Construct)
1308 data[dataIndex] = stringIndex;
1309 ++dataIndex;
1310 }
1311 }
1312 }
1313
1314 // Output the properties in the class.
1315 Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
1316 for (QMetaPropertyBuilderPrivate &prop : d->properties) {
1317 [[maybe_unused]] int name = strings.enter(value: prop.name);
1318
1319 // try to resolve the metatype again if it was unknown
1320 if (!prop.metaType.isValid())
1321 prop.metaType = QMetaType::fromName(name: prop.type);
1322 [[maybe_unused]] const int typeInfo = prop.metaType.isValid()
1323 ? prop.metaType.id()
1324 : IsUnresolvedType | strings.enter(value: prop.type);
1325
1326 [[maybe_unused]] int flags = prop.flags;
1327
1328 if (!QtPrivate::isBuiltinType(type: prop.type))
1329 flags |= EnumOrFlag;
1330
1331 if constexpr (mode == Construct) {
1332 data[dataIndex] = name;
1333 data[dataIndex + 1] = typeInfo;
1334 data[dataIndex + 2] = flags;
1335 data[dataIndex + 3] = prop.notifySignal;
1336 data[dataIndex + 4] = prop.revision;
1337 }
1338 dataIndex += QMetaObjectPrivate::IntsPerProperty;
1339 }
1340
1341 // Output the enumerators in the class.
1342 Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData);
1343 for (const auto &enumerator : d->enumerators) {
1344 [[maybe_unused]] int name = strings.enter(value: enumerator.name);
1345 [[maybe_unused]] int enumName = strings.enter(value: enumerator.enumName);
1346 [[maybe_unused]] int isFlag = enumerator.isFlag ? EnumIsFlag : 0;
1347 [[maybe_unused]] int isScoped = enumerator.isScoped ? EnumIsScoped : 0;
1348 int count = enumerator.keys.size();
1349 int enumOffset = enumIndex;
1350 if constexpr (mode == Construct) {
1351 data[dataIndex] = name;
1352 data[dataIndex + 1] = enumName;
1353 data[dataIndex + 2] = isFlag | isScoped;
1354 data[dataIndex + 3] = count;
1355 data[dataIndex + 4] = enumOffset;
1356 }
1357 for (int key = 0; key < count; ++key) {
1358 [[maybe_unused]] int keyIndex = strings.enter(value: enumerator.keys[key]);
1359 if constexpr (mode == Construct) {
1360 data[enumOffset++] = keyIndex;
1361 data[enumOffset++] = enumerator.values[key];
1362 }
1363 }
1364 dataIndex += QMetaObjectPrivate::IntsPerEnum;
1365 enumIndex += 2 * count;
1366 }
1367
1368 // Output the constructors in the class.
1369 Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
1370 for (const auto &ctor : d->constructors) {
1371 [[maybe_unused]] int name = strings.enter(value: ctor.name());
1372 int argc = ctor.parameterCount();
1373 [[maybe_unused]] int tag = strings.enter(value: ctor.tag);
1374 [[maybe_unused]] int attrs = ctor.attributes;
1375 if constexpr (mode == Construct) {
1376 data[dataIndex] = name;
1377 data[dataIndex + 1] = argc;
1378 data[dataIndex + 2] = paramsIndex;
1379 data[dataIndex + 3] = tag;
1380 data[dataIndex + 4] = attrs;
1381 data[dataIndex + 5] = parameterMetaTypesIndex;
1382 }
1383 dataIndex += QMetaObjectPrivate::IntsPerMethod;
1384 paramsIndex += 1 + argc * 2;
1385 parameterMetaTypesIndex += argc;
1386 }
1387
1388 size += strings.blobSize();
1389
1390 if constexpr (mode == Construct)
1391 strings.writeBlob(out: str);
1392
1393 // Output the zero terminator in the data array.
1394 if constexpr (mode == Construct)
1395 data[enumIndex] = 0;
1396
1397 // Create the relatedMetaObjects block if we need one.
1398 if (d->relatedMetaObjects.size() > 0) {
1399 using SuperData = QMetaObject::SuperData;
1400 ALIGN(size, SuperData);
1401 auto objects = reinterpret_cast<SuperData *>(buf + size);
1402 if constexpr (mode == Construct) {
1403 meta->d.relatedMetaObjects = objects;
1404 for (index = 0; index < d->relatedMetaObjects.size(); ++index)
1405 objects[index] = d->relatedMetaObjects[index];
1406 objects[index] = nullptr;
1407 }
1408 size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
1409 }
1410
1411 ALIGN(size, QtPrivate::QMetaTypeInterface *);
1412 auto types = reinterpret_cast<const QtPrivate::QMetaTypeInterface **>(buf + size);
1413 if constexpr (mode == Construct) {
1414 meta->d.metaTypes = types;
1415 for (const auto &prop : d->properties) {
1416 QMetaType mt = prop.metaType;
1417 *types = mt.iface();
1418 types++;
1419 }
1420 // add metatypes for enumerators
1421 for (const auto &enumerator: d->enumerators) {
1422 QMetaType mt = enumerator.metaType;
1423 mt.registerType();
1424 *types = mt.iface();
1425 types++;
1426 }
1427 // add metatype interface for this metaobject - must be null
1428 // as we can't know our metatype
1429 *types = nullptr;
1430 types++;
1431 for (const auto &method: d->methods) {
1432 QMetaType mt(QMetaType::fromName(name: method.returnType).id());
1433 *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
1434 types++;
1435 for (const auto &parameterType: method.parameterTypes()) {
1436 QMetaType mt = QMetaType::fromName(name: parameterType);
1437 *types = mt.iface();
1438 types++;
1439 }
1440 }
1441 for (const auto &constructor : d->constructors) {
1442 for (const auto &parameterType : constructor.parameterTypes()) {
1443 QMetaType mt = QMetaType::fromName(name: parameterType);
1444 *types = mt.iface();
1445 types++;
1446 }
1447 }
1448 }
1449 // parameterMetaTypesIndex is equal to the total number of metatypes
1450 size += sizeof(QMetaType) * parameterMetaTypesIndex;
1451
1452 // Align the final size and return it.
1453 ALIGN(size, void *);
1454 Q_ASSERT(!buf || size == expectedSize);
1455 return size;
1456}
1457
1458/*!
1459 Converts this meta object builder into a concrete QMetaObject.
1460 The return value should be deallocated using free() once it
1461 is no longer needed.
1462
1463 The returned meta object is a snapshot of the state of the
1464 QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder
1465 will not be reflected in previous meta objects returned by
1466 this method.
1467*/
1468QMetaObject *QMetaObjectBuilder::toMetaObject() const
1469{
1470 int size = buildMetaObject<Prepare>(d, buf: nullptr, expectedSize: 0);
1471 char *buf = reinterpret_cast<char *>(malloc(size: size));
1472 memset(s: buf, c: 0, n: size);
1473 buildMetaObject<Construct>(d, buf, expectedSize: size);
1474 return reinterpret_cast<QMetaObject *>(buf);
1475}
1476
1477/*!
1478 \typedef QMetaObjectBuilder::StaticMetacallFunction
1479
1480 Typedef for static metacall functions. The three parameters are
1481 the call type value, the constructor index, and the
1482 array of parameters.
1483*/
1484
1485/*!
1486 Returns the static metacall function to use to construct objects
1487 of this class. The default value is null.
1488
1489 \sa setStaticMetacallFunction()
1490*/
1491QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const
1492{
1493 return d->staticMetacallFunction;
1494}
1495
1496/*!
1497 Sets the static metacall function to use to construct objects
1498 of this class to \a value. The default value is null.
1499
1500 \sa staticMetacallFunction()
1501*/
1502void QMetaObjectBuilder::setStaticMetacallFunction
1503 (QMetaObjectBuilder::StaticMetacallFunction value)
1504{
1505 d->staticMetacallFunction = value;
1506}
1507
1508/*!
1509 \class QMetaMethodBuilder
1510 \inmodule QtCore
1511 \internal
1512 \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder.
1513*/
1514
1515QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
1516{
1517 // Positive indices indicate methods, negative indices indicate constructors.
1518 if (_mobj && _index >= 0 && _index < int(_mobj->d->methods.size()))
1519 return &(_mobj->d->methods[_index]);
1520 else if (_mobj && -_index >= 1 && -_index <= int(_mobj->d->constructors.size()))
1521 return &(_mobj->d->constructors[(-_index) - 1]);
1522 else
1523 return nullptr;
1524}
1525
1526/*!
1527 \fn QMetaMethodBuilder::QMetaMethodBuilder()
1528 \internal
1529*/
1530
1531/*!
1532 Returns the index of this method within its QMetaObjectBuilder.
1533*/
1534int QMetaMethodBuilder::index() const
1535{
1536 if (_index >= 0)
1537 return _index; // Method, signal, or slot
1538 else
1539 return (-_index) - 1; // Constructor
1540}
1541
1542/*!
1543 Returns the type of this method (signal, slot, method, or constructor).
1544*/
1545QMetaMethod::MethodType QMetaMethodBuilder::methodType() const
1546{
1547 QMetaMethodBuilderPrivate *d = d_func();
1548 if (d)
1549 return d->methodType();
1550 else
1551 return QMetaMethod::Method;
1552}
1553
1554/*!
1555 Returns the signature of this method.
1556
1557 \sa parameterNames(), returnType()
1558*/
1559QByteArray QMetaMethodBuilder::signature() const
1560{
1561 QMetaMethodBuilderPrivate *d = d_func();
1562 if (d)
1563 return d->signature;
1564 else
1565 return QByteArray();
1566}
1567
1568/*!
1569 Returns the return type for this method; empty if the method's
1570 return type is \c{void}.
1571
1572 \sa setReturnType(), signature()
1573*/
1574QByteArray QMetaMethodBuilder::returnType() const
1575{
1576 QMetaMethodBuilderPrivate *d = d_func();
1577 if (d)
1578 return d->returnType;
1579 else
1580 return QByteArray();
1581}
1582
1583/*!
1584 Sets the return type for this method to \a value. If \a value
1585 is empty, then the method's return type is \c{void}. The \a value
1586 will be normalized before it is added to the method.
1587
1588 \sa returnType(), parameterTypes(), signature()
1589*/
1590void QMetaMethodBuilder::setReturnType(const QByteArray &value)
1591{
1592 QMetaMethodBuilderPrivate *d = d_func();
1593 if (d)
1594 d->returnType = QMetaObject::normalizedType(type: value);
1595}
1596
1597/*!
1598 Returns the list of parameter types for this method.
1599
1600 \sa returnType(), parameterNames()
1601*/
1602QList<QByteArray> QMetaMethodBuilder::parameterTypes() const
1603{
1604 QMetaMethodBuilderPrivate *d = d_func();
1605 if (d)
1606 return d->parameterTypes();
1607 else
1608 return QList<QByteArray>();
1609}
1610
1611/*!
1612 Returns the list of parameter names for this method.
1613
1614 \sa setParameterNames()
1615*/
1616QList<QByteArray> QMetaMethodBuilder::parameterNames() const
1617{
1618 QMetaMethodBuilderPrivate *d = d_func();
1619 if (d)
1620 return d->parameterNames;
1621 else
1622 return QList<QByteArray>();
1623}
1624
1625/*!
1626 Sets the list of parameter names for this method to \a value.
1627
1628 \sa parameterNames()
1629*/
1630void QMetaMethodBuilder::setParameterNames(const QList<QByteArray> &value)
1631{
1632 QMetaMethodBuilderPrivate *d = d_func();
1633 if (d)
1634 d->parameterNames = value;
1635}
1636
1637/*!
1638 Returns the tag associated with this method.
1639
1640 \sa setTag()
1641*/
1642QByteArray QMetaMethodBuilder::tag() const
1643{
1644 QMetaMethodBuilderPrivate *d = d_func();
1645 if (d)
1646 return d->tag;
1647 else
1648 return QByteArray();
1649}
1650
1651/*!
1652 Sets the tag associated with this method to \a value.
1653
1654 \sa setTag()
1655*/
1656void QMetaMethodBuilder::setTag(const QByteArray &value)
1657{
1658 QMetaMethodBuilderPrivate *d = d_func();
1659 if (d)
1660 d->tag = value;
1661}
1662
1663/*!
1664 Returns the access specification of this method (private, protected,
1665 or public). The default value is QMetaMethod::Public for methods,
1666 slots, signals and constructors.
1667
1668 \sa setAccess()
1669*/
1670QMetaMethod::Access QMetaMethodBuilder::access() const
1671{
1672 QMetaMethodBuilderPrivate *d = d_func();
1673 if (d)
1674 return d->access();
1675 else
1676 return QMetaMethod::Public;
1677}
1678
1679/*!
1680 Sets the access specification of this method (private, protected,
1681 or public) to \a value. If the method is a signal, this function
1682 will be ignored.
1683
1684 \sa access()
1685*/
1686void QMetaMethodBuilder::setAccess(QMetaMethod::Access value)
1687{
1688 QMetaMethodBuilderPrivate *d = d_func();
1689 if (d && d->methodType() != QMetaMethod::Signal)
1690 d->setAccess(value);
1691}
1692
1693/*!
1694 Returns the additional attributes for this method.
1695
1696 \sa setAttributes()
1697*/
1698int QMetaMethodBuilder::attributes() const
1699{
1700 QMetaMethodBuilderPrivate *d = d_func();
1701 if (d)
1702 return (d->attributes >> 4) & 0x7;
1703 else
1704 return 0;
1705}
1706
1707/*!
1708 Sets the additional attributes for this method to \a value.
1709
1710 \sa attributes()
1711*/
1712void QMetaMethodBuilder::setAttributes(int value)
1713{
1714 QMetaMethodBuilderPrivate *d = d_func();
1715 if (d) {
1716 d->attributes &= ~0x70;
1717 d->attributes |= (value & 0x7) << 4;
1718 }
1719}
1720
1721/*!
1722 Returns true if the method is const qualified.
1723 */
1724int QMetaMethodBuilder::isConst() const
1725{
1726 QMetaMethodBuilderPrivate *d = d_func();
1727 if (!d)
1728 return false;
1729 return (d->attributes & MethodIsConst);
1730}
1731
1732void QMetaMethodBuilder::setConst(bool methodIsConst)
1733{
1734 QMetaMethodBuilderPrivate *d = d_func();
1735 if (!d)
1736 return;
1737 if (methodIsConst)
1738 d->attributes |= MethodIsConst;
1739 else
1740 d->attributes &= ~MethodIsConst;
1741}
1742
1743/*!
1744 Returns the revision of this method.
1745
1746 \sa setRevision()
1747*/
1748int QMetaMethodBuilder::revision() const
1749{
1750 QMetaMethodBuilderPrivate *d = d_func();
1751 if (d)
1752 return d->revision;
1753 return 0;
1754}
1755
1756/*!
1757 Sets the \a revision of this method.
1758
1759 \sa revision()
1760*/
1761void QMetaMethodBuilder::setRevision(int revision)
1762{
1763 QMetaMethodBuilderPrivate *d = d_func();
1764 if (d) {
1765 d->revision = revision;
1766 if (revision)
1767 d->attributes |= MethodRevisioned;
1768 else
1769 d->attributes &= ~MethodRevisioned;
1770 }
1771}
1772
1773/*!
1774 \class QMetaPropertyBuilder
1775 \inmodule QtCore
1776 \internal
1777 \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder.
1778*/
1779
1780QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
1781{
1782 if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size()))
1783 return &(_mobj->d->properties[_index]);
1784 else
1785 return nullptr;
1786}
1787
1788/*!
1789 \fn QMetaPropertyBuilder::QMetaPropertyBuilder()
1790 \internal
1791*/
1792
1793/*!
1794 \fn int QMetaPropertyBuilder::index() const
1795
1796 Returns the index of this property within its QMetaObjectBuilder.
1797*/
1798
1799/*!
1800 Returns the name associated with this property.
1801
1802 \sa type()
1803*/
1804QByteArray QMetaPropertyBuilder::name() const
1805{
1806 QMetaPropertyBuilderPrivate *d = d_func();
1807 if (d)
1808 return d->name;
1809 else
1810 return QByteArray();
1811}
1812
1813/*!
1814 Returns the type associated with this property.
1815
1816 \sa name()
1817*/
1818QByteArray QMetaPropertyBuilder::type() const
1819{
1820 QMetaPropertyBuilderPrivate *d = d_func();
1821 if (d)
1822 return d->type;
1823 else
1824 return QByteArray();
1825}
1826
1827/*!
1828 Returns \c true if this property has a notify signal; false otherwise.
1829
1830 \sa notifySignal(), setNotifySignal(), removeNotifySignal()
1831*/
1832bool QMetaPropertyBuilder::hasNotifySignal() const
1833{
1834 QMetaPropertyBuilderPrivate *d = d_func();
1835 if (d)
1836 return d->notifySignal != -1;
1837 else
1838 return false;
1839}
1840
1841/*!
1842 Returns the notify signal associated with this property.
1843
1844 \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal()
1845*/
1846QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const
1847{
1848 QMetaPropertyBuilderPrivate *d = d_func();
1849 if (d && d->notifySignal >= 0)
1850 return QMetaMethodBuilder(_mobj, d->notifySignal);
1851 else
1852 return QMetaMethodBuilder();
1853}
1854
1855/*!
1856 Sets the notify signal associated with this property to \a value.
1857
1858 \sa hasNotifySignal(), notifySignal(), removeNotifySignal()
1859*/
1860void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder &value)
1861{
1862 QMetaPropertyBuilderPrivate *d = d_func();
1863 if (d) {
1864 if (value._mobj) {
1865 d->notifySignal = value._index;
1866 } else {
1867 d->notifySignal = -1;
1868 }
1869 }
1870}
1871
1872/*!
1873 Removes the notify signal from this property.
1874
1875 \sa hasNotifySignal(), notifySignal(), setNotifySignal()
1876*/
1877void QMetaPropertyBuilder::removeNotifySignal()
1878{
1879 QMetaPropertyBuilderPrivate *d = d_func();
1880 if (d)
1881 d->notifySignal = -1;
1882}
1883
1884/*!
1885 Returns \c true if this property is readable; otherwise returns \c false.
1886 The default value is true.
1887
1888 \sa setReadable(), isWritable()
1889*/
1890bool QMetaPropertyBuilder::isReadable() const
1891{
1892 QMetaPropertyBuilderPrivate *d = d_func();
1893 if (d)
1894 return d->flag(f: Readable);
1895 else
1896 return false;
1897}
1898
1899/*!
1900 Returns \c true if this property is writable; otherwise returns \c false.
1901 The default value is true.
1902
1903 \sa setWritable(), isReadable()
1904*/
1905bool QMetaPropertyBuilder::isWritable() const
1906{
1907 QMetaPropertyBuilderPrivate *d = d_func();
1908 if (d)
1909 return d->flag(f: Writable);
1910 else
1911 return false;
1912}
1913
1914/*!
1915 Returns \c true if this property can be reset to a default value; otherwise
1916 returns \c false. The default value is false.
1917
1918 \sa setResettable()
1919*/
1920bool QMetaPropertyBuilder::isResettable() const
1921{
1922 QMetaPropertyBuilderPrivate *d = d_func();
1923 if (d)
1924 return d->flag(f: Resettable);
1925 else
1926 return false;
1927}
1928
1929/*!
1930 Returns \c true if this property is designable; otherwise returns \c false.
1931 This default value is false.
1932
1933 \sa setDesignable(), isScriptable(), isStored()
1934*/
1935bool QMetaPropertyBuilder::isDesignable() const
1936{
1937 QMetaPropertyBuilderPrivate *d = d_func();
1938 if (d)
1939 return d->flag(f: Designable);
1940 else
1941 return false;
1942}
1943
1944/*!
1945 Returns \c true if the property is scriptable; otherwise returns \c false.
1946 This default value is true.
1947
1948 \sa setScriptable(), isDesignable(), isStored()
1949*/
1950bool QMetaPropertyBuilder::isScriptable() const
1951{
1952 QMetaPropertyBuilderPrivate *d = d_func();
1953 if (d)
1954 return d->flag(f: Scriptable);
1955 else
1956 return false;
1957}
1958
1959/*!
1960 Returns \c true if the property is stored; otherwise returns \c false.
1961 This default value is false.
1962
1963 \sa setStored(), isDesignable(), isScriptable()
1964*/
1965bool QMetaPropertyBuilder::isStored() const
1966{
1967 QMetaPropertyBuilderPrivate *d = d_func();
1968 if (d)
1969 return d->flag(f: Stored);
1970 else
1971 return false;
1972}
1973
1974/*!
1975 Returns \c true if this property is designated as the \c USER
1976 property, i.e., the one that the user can edit or that is
1977 significant in some other way. Otherwise it returns
1978 false. This default value is false.
1979
1980 \sa setUser(), isDesignable(), isScriptable()
1981*/
1982bool QMetaPropertyBuilder::isUser() const
1983{
1984 QMetaPropertyBuilderPrivate *d = d_func();
1985 if (d)
1986 return d->flag(f: User);
1987 else
1988 return false;
1989}
1990
1991/*!
1992 Returns \c true if the property has a C++ setter function that
1993 follows Qt's standard "name" / "setName" pattern. Designer and uic
1994 query hasStdCppSet() in order to avoid expensive
1995 QObject::setProperty() calls. All properties in Qt [should] follow
1996 this pattern. The default value is false.
1997
1998 \sa setStdCppSet()
1999*/
2000bool QMetaPropertyBuilder::hasStdCppSet() const
2001{
2002 QMetaPropertyBuilderPrivate *d = d_func();
2003 if (d)
2004 return d->flag(f: StdCppSet);
2005 else
2006 return false;
2007}
2008
2009/*!
2010 Returns \c true if the property is an enumerator or flag type;
2011 otherwise returns \c false. This default value is false.
2012
2013 \sa setEnumOrFlag()
2014*/
2015bool QMetaPropertyBuilder::isEnumOrFlag() const
2016{
2017 QMetaPropertyBuilderPrivate *d = d_func();
2018 if (d)
2019 return d->flag(f: EnumOrFlag);
2020 else
2021 return false;
2022}
2023
2024/*!
2025 Returns \c true if the property is constant; otherwise returns \c false.
2026 The default value is false.
2027*/
2028bool QMetaPropertyBuilder::isConstant() const
2029{
2030 QMetaPropertyBuilderPrivate *d = d_func();
2031 if (d)
2032 return d->flag(f: Constant);
2033 else
2034 return false;
2035}
2036
2037/*!
2038 Returns \c true if the property is final; otherwise returns \c false.
2039 The default value is false.
2040*/
2041bool QMetaPropertyBuilder::isFinal() const
2042{
2043 QMetaPropertyBuilderPrivate *d = d_func();
2044 if (d)
2045 return d->flag(f: Final);
2046 else
2047 return false;
2048}
2049
2050/*!
2051 * Returns \c true if the property is an alias.
2052 * The default value is false
2053 */
2054bool QMetaPropertyBuilder::isAlias() const
2055{
2056 QMetaPropertyBuilderPrivate *d = d_func();
2057 if (d)
2058 return d->flag(f: Alias);
2059 else
2060 return false;
2061}
2062
2063/*!
2064 Returns \c true if the property is bindable
2065 The default value is false
2066 */
2067bool QMetaPropertyBuilder::isBindable() const
2068{
2069 if (auto d = d_func())
2070 return d->flag(f: Bindable);
2071 else
2072 return false;
2073}
2074
2075/*!
2076 Sets this property to readable if \a value is true.
2077
2078 \sa isReadable(), setWritable()
2079*/
2080void QMetaPropertyBuilder::setReadable(bool value)
2081{
2082 QMetaPropertyBuilderPrivate *d = d_func();
2083 if (d)
2084 d->setFlag(f: Readable, value);
2085}
2086
2087/*!
2088 Sets this property to writable if \a value is true.
2089
2090 \sa isWritable(), setReadable()
2091*/
2092void QMetaPropertyBuilder::setWritable(bool value)
2093{
2094 QMetaPropertyBuilderPrivate *d = d_func();
2095 if (d)
2096 d->setFlag(f: Writable, value);
2097}
2098
2099/*!
2100 Sets this property to resettable if \a value is true.
2101
2102 \sa isResettable()
2103*/
2104void QMetaPropertyBuilder::setResettable(bool value)
2105{
2106 QMetaPropertyBuilderPrivate *d = d_func();
2107 if (d)
2108 d->setFlag(f: Resettable, value);
2109}
2110
2111/*!
2112 Sets this property to designable if \a value is true.
2113
2114 \sa isDesignable(), setScriptable(), setStored()
2115*/
2116void QMetaPropertyBuilder::setDesignable(bool value)
2117{
2118 QMetaPropertyBuilderPrivate *d = d_func();
2119 if (d)
2120 d->setFlag(f: Designable, value);
2121}
2122
2123/*!
2124 Sets this property to scriptable if \a value is true.
2125
2126 \sa isScriptable(), setDesignable(), setStored()
2127*/
2128void QMetaPropertyBuilder::setScriptable(bool value)
2129{
2130 QMetaPropertyBuilderPrivate *d = d_func();
2131 if (d)
2132 d->setFlag(f: Scriptable, value);
2133}
2134
2135/*!
2136 Sets this property to storable if \a value is true.
2137
2138 \sa isStored(), setDesignable(), setScriptable()
2139*/
2140void QMetaPropertyBuilder::setStored(bool value)
2141{
2142 QMetaPropertyBuilderPrivate *d = d_func();
2143 if (d)
2144 d->setFlag(f: Stored, value);
2145}
2146
2147/*!
2148 Sets the \c USER flag on this property to \a value.
2149
2150 \sa isUser(), setDesignable(), setScriptable()
2151*/
2152void QMetaPropertyBuilder::setUser(bool value)
2153{
2154 QMetaPropertyBuilderPrivate *d = d_func();
2155 if (d)
2156 d->setFlag(f: User, value);
2157}
2158
2159/*!
2160 Sets the C++ setter flag on this property to \a value, which is
2161 true if the property has a C++ setter function that follows Qt's
2162 standard "name" / "setName" pattern.
2163
2164 \sa hasStdCppSet()
2165*/
2166void QMetaPropertyBuilder::setStdCppSet(bool value)
2167{
2168 QMetaPropertyBuilderPrivate *d = d_func();
2169 if (d)
2170 d->setFlag(f: StdCppSet, value);
2171}
2172
2173/*!
2174 Sets this property to be of an enumerator or flag type if
2175 \a value is true.
2176
2177 \sa isEnumOrFlag()
2178*/
2179void QMetaPropertyBuilder::setEnumOrFlag(bool value)
2180{
2181 QMetaPropertyBuilderPrivate *d = d_func();
2182 if (d)
2183 d->setFlag(f: EnumOrFlag, value);
2184}
2185
2186/*!
2187 Sets the \c CONSTANT flag on this property to \a value.
2188
2189 \sa isConstant()
2190*/
2191void QMetaPropertyBuilder::setConstant(bool value)
2192{
2193 QMetaPropertyBuilderPrivate *d = d_func();
2194 if (d)
2195 d->setFlag(f: Constant, value);
2196}
2197
2198/*!
2199 Sets the \c FINAL flag on this property to \a value.
2200
2201 \sa isFinal()
2202*/
2203void QMetaPropertyBuilder::setFinal(bool value)
2204{
2205 QMetaPropertyBuilderPrivate *d = d_func();
2206 if (d)
2207 d->setFlag(f: Final, value);
2208}
2209
2210/*!
2211 Sets the \c ALIAS flag on this property to \a value
2212 */
2213void QMetaPropertyBuilder::setAlias(bool value)
2214{
2215 QMetaPropertyBuilderPrivate *d = d_func();
2216 if (d)
2217 d->setFlag(f: Alias, value);
2218}
2219
2220/*!
2221 Sets the\c BINDABLE flag on this property to \a value
2222 */
2223void QMetaPropertyBuilder::setBindable(bool value)
2224{
2225 if (auto d = d_func())
2226 d->setFlag(f: Bindable, value);
2227}
2228
2229/*!
2230 Returns the revision of this property.
2231
2232 \sa setRevision()
2233*/
2234int QMetaPropertyBuilder::revision() const
2235{
2236 QMetaPropertyBuilderPrivate *d = d_func();
2237 if (d)
2238 return d->revision;
2239 return 0;
2240}
2241
2242/*!
2243 Sets the \a revision of this property.
2244
2245 \sa revision()
2246*/
2247void QMetaPropertyBuilder::setRevision(int revision)
2248{
2249 QMetaPropertyBuilderPrivate *d = d_func();
2250 if (d)
2251 d->revision = revision;
2252}
2253
2254/*!
2255 \class QMetaEnumBuilder
2256 \inmodule QtCore
2257 \internal
2258 \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
2259*/
2260
2261QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
2262{
2263 if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size()))
2264 return &(_mobj->d->enumerators[_index]);
2265 else
2266 return nullptr;
2267}
2268
2269/*!
2270 \fn QMetaEnumBuilder::QMetaEnumBuilder()
2271 \internal
2272*/
2273
2274/*!
2275 \fn int QMetaEnumBuilder::index() const
2276
2277 Returns the index of this enumerator within its QMetaObjectBuilder.
2278*/
2279
2280/*!
2281 Returns the type name of the enumerator (without the scope).
2282*/
2283QByteArray QMetaEnumBuilder::name() const
2284{
2285 QMetaEnumBuilderPrivate *d = d_func();
2286 if (d)
2287 return d->name;
2288 else
2289 return QByteArray();
2290}
2291
2292/*!
2293 Returns the enum name of the enumerator (without the scope).
2294
2295 \since 5.12
2296*/
2297QByteArray QMetaEnumBuilder::enumName() const
2298{
2299 QMetaEnumBuilderPrivate *d = d_func();
2300 if (d)
2301 return d->enumName;
2302 else
2303 return QByteArray();
2304}
2305
2306/*!
2307 Sets this enumerator to have the enum name \c alias.
2308
2309 \since 5.12
2310 \sa isFlag(), enumName()
2311*/
2312void QMetaEnumBuilder::setEnumName(const QByteArray &alias)
2313{
2314 QMetaEnumBuilderPrivate *d = d_func();
2315 if (d)
2316 d->enumName = alias;
2317}
2318
2319/*!
2320 Returns the meta type of the enumerator.
2321
2322 \since 6.6
2323*/
2324QMetaType QMetaEnumBuilder::metaType() const
2325{
2326 if (QMetaEnumBuilderPrivate *d = d_func())
2327 return d->metaType;
2328 return QMetaType();
2329}
2330
2331/*!
2332 Sets this enumerator to have the given \c metaType.
2333
2334 \since 6.6
2335 \sa metaType()
2336*/
2337void QMetaEnumBuilder::setMetaType(QMetaType metaType)
2338{
2339 QMetaEnumBuilderPrivate *d = d_func();
2340 if (d)
2341 d->metaType = metaType;
2342}
2343
2344/*!
2345 Returns \c true if this enumerator is used as a flag; otherwise returns
2346 false.
2347
2348 \sa setIsFlag()
2349*/
2350bool QMetaEnumBuilder::isFlag() const
2351{
2352 QMetaEnumBuilderPrivate *d = d_func();
2353 if (d)
2354 return d->isFlag;
2355 else
2356 return false;
2357}
2358
2359/*!
2360 Sets this enumerator to be used as a flag if \a value is true.
2361
2362 \sa isFlag()
2363*/
2364void QMetaEnumBuilder::setIsFlag(bool value)
2365{
2366 QMetaEnumBuilderPrivate *d = d_func();
2367 if (d)
2368 d->isFlag = value;
2369}
2370
2371/*!
2372 Return \c true if this enumerator should be considered scoped (C++11 enum class).
2373
2374 \sa setIsScoped()
2375*/
2376bool QMetaEnumBuilder::isScoped() const
2377{
2378 QMetaEnumBuilderPrivate *d = d_func();
2379 if (d)
2380 return d->isScoped;
2381 return false;
2382}
2383
2384/*!
2385 Sets this enumerator to be a scoped enum if \value is true
2386
2387 \sa isScoped()
2388*/
2389void QMetaEnumBuilder::setIsScoped(bool value)
2390{
2391 QMetaEnumBuilderPrivate *d = d_func();
2392 if (d)
2393 d->isScoped = value;
2394}
2395
2396/*!
2397 Returns the number of keys.
2398
2399 \sa key(), addKey()
2400*/
2401int QMetaEnumBuilder::keyCount() const
2402{
2403 QMetaEnumBuilderPrivate *d = d_func();
2404 if (d)
2405 return d->keys.size();
2406 else
2407 return 0;
2408}
2409
2410/*!
2411 Returns the key with the given \a index, or an empty QByteArray
2412 if no such key exists.
2413
2414 \sa keyCount(), addKey(), value()
2415*/
2416QByteArray QMetaEnumBuilder::key(int index) const
2417{
2418 QMetaEnumBuilderPrivate *d = d_func();
2419 if (d && index >= 0 && index < d->keys.size())
2420 return d->keys[index];
2421 else
2422 return QByteArray();
2423}
2424
2425/*!
2426 Returns the value with the given \a index; or returns -1 if there
2427 is no such value.
2428
2429 \sa keyCount(), addKey(), key()
2430*/
2431int QMetaEnumBuilder::value(int index) const
2432{
2433 QMetaEnumBuilderPrivate *d = d_func();
2434 if (d && index >= 0 && index < d->keys.size())
2435 return d->values[index];
2436 else
2437 return -1;
2438}
2439
2440/*!
2441 Adds a new key called \a name to this enumerator, associated
2442 with \a value. Returns the index of the new key.
2443
2444 \sa keyCount(), key(), value(), removeKey()
2445*/
2446int QMetaEnumBuilder::addKey(const QByteArray &name, int value)
2447{
2448 QMetaEnumBuilderPrivate *d = d_func();
2449 if (d) {
2450 int index = d->keys.size();
2451 d->keys += name;
2452 d->values += value;
2453 return index;
2454 } else {
2455 return -1;
2456 }
2457}
2458
2459/*!
2460 Removes the key at \a index from this enumerator.
2461
2462 \sa addKey()
2463*/
2464void QMetaEnumBuilder::removeKey(int index)
2465{
2466 QMetaEnumBuilderPrivate *d = d_func();
2467 if (d && index >= 0 && index < d->keys.size()) {
2468 d->keys.removeAt(i: index);
2469 d->values.removeAt(i: index);
2470 }
2471}
2472
2473QT_END_NAMESPACE
2474

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/corelib/kernel/qmetaobjectbuilder.cpp