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