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