QtBase  v6.3.1
qmetatype.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Copyright (C) 2018 Intel Corporation.
5 ** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
6 ** Contact: https://www.qt.io/licensing/
7 **
8 ** This file is part of the QtCore module of the Qt Toolkit.
9 **
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** Commercial License Usage
12 ** Licensees holding valid commercial Qt licenses may use this file in
13 ** accordance with the commercial license agreement provided with the
14 ** Software or, alternatively, in accordance with the terms contained in
15 ** a written agreement between you and The Qt Company. For licensing terms
16 ** and conditions see https://www.qt.io/terms-conditions. For further
17 ** information use the contact form at https://www.qt.io/contact-us.
18 **
19 ** GNU Lesser General Public License Usage
20 ** Alternatively, this file may be used under the terms of the GNU Lesser
21 ** General Public License version 3 as published by the Free Software
22 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
23 ** packaging of this file. Please review the following information to
24 ** ensure the GNU Lesser General Public License version 3 requirements
25 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26 **
27 ** GNU General Public License Usage
28 ** Alternatively, this file may be used under the terms of the GNU
29 ** General Public License version 2.0 or (at your option) the GNU General
30 ** Public license version 3 or any later version approved by the KDE Free
31 ** Qt Foundation. The licenses are as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33 ** included in the packaging of this file. Please review the following
34 ** information to ensure the GNU General Public License requirements will
35 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36 ** https://www.gnu.org/licenses/gpl-3.0.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QMETATYPE_H
43 #define QMETATYPE_H
44 
45 #include <QtCore/qglobal.h>
46 #include <QtCore/qatomic.h>
47 #include <QtCore/qbytearray.h>
48 #include <QtCore/qcompare.h>
49 #include <QtCore/qvarlengtharray.h>
50 #include <QtCore/qrefcount.h>
51 #include <QtCore/qscopeguard.h>
52 #include <QtCore/qdatastream.h>
53 #include <QtCore/qiterable.h>
54 #ifndef QT_NO_QOBJECT
55 #include <QtCore/qobjectdefs.h>
56 #endif
57 
58 #include <array>
59 #include <new>
60 #include <vector>
61 #include <list>
62 #include <map>
63 #include <functional>
64 
65 #ifdef Bool
66 #error qmetatype.h must be included before any header file that defines Bool
67 #endif
68 
70 
71 // from qcborcommon.h
72 enum class QCborSimpleType : quint8;
73 
74 template <typename T>
75 struct QMetaTypeId2;
76 
77 template <typename T>
78 inline constexpr int qMetaTypeId();
79 
80 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
81 #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
82  F(Void, 43, void) \
83  F(Bool, 1, bool) \
84  F(Int, 2, int) \
85  F(UInt, 3, uint) \
86  F(LongLong, 4, qlonglong) \
87  F(ULongLong, 5, qulonglong) \
88  F(Double, 6, double) \
89  F(Long, 32, long) \
90  F(Short, 33, short) \
91  F(Char, 34, char) \
92  F(Char16, 56, char16_t) \
93  F(Char32, 57, char32_t) \
94  F(ULong, 35, ulong) \
95  F(UShort, 36, ushort) \
96  F(UChar, 37, uchar) \
97  F(Float, 38, float) \
98  F(SChar, 40, signed char) \
99  F(Nullptr, 51, std::nullptr_t) \
100  F(QCborSimpleType, 52, QCborSimpleType) \
101 
102 #define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
103  F(VoidStar, 31, void*) \
104 
105 #if QT_CONFIG(easingcurve)
106 #define QT_FOR_EACH_STATIC_EASINGCURVE(F)\
107  F(QEasingCurve, 29, QEasingCurve)
108 #else
109 #define QT_FOR_EACH_STATIC_EASINGCURVE(F)
110 #endif
111 
112 #if QT_CONFIG(itemmodel)
113 #define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)\
114  F(QModelIndex, 42, QModelIndex) \
115  F(QPersistentModelIndex, 50, QPersistentModelIndex)
116 #else
117 #define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
118 #endif
119 
120 #if QT_CONFIG(regularexpression)
121 # define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \
122  F(QRegularExpression, 44, QRegularExpression)
123 #else
124 # define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F)
125 #endif
126 
127 #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
128  F(QChar, 7, QChar) \
129  F(QString, 10, QString) \
130  F(QByteArray, 12, QByteArray) \
131  F(QBitArray, 13, QBitArray) \
132  F(QDate, 14, QDate) \
133  F(QTime, 15, QTime) \
134  F(QDateTime, 16, QDateTime) \
135  F(QUrl, 17, QUrl) \
136  F(QLocale, 18, QLocale) \
137  F(QRect, 19, QRect) \
138  F(QRectF, 20, QRectF) \
139  F(QSize, 21, QSize) \
140  F(QSizeF, 22, QSizeF) \
141  F(QLine, 23, QLine) \
142  F(QLineF, 24, QLineF) \
143  F(QPoint, 25, QPoint) \
144  F(QPointF, 26, QPointF) \
145  QT_FOR_EACH_STATIC_EASINGCURVE(F) \
146  F(QUuid, 30, QUuid) \
147  F(QVariant, 41, QVariant) \
148  QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \
149  F(QJsonValue, 45, QJsonValue) \
150  F(QJsonObject, 46, QJsonObject) \
151  F(QJsonArray, 47, QJsonArray) \
152  F(QJsonDocument, 48, QJsonDocument) \
153  F(QCborValue, 53, QCborValue) \
154  F(QCborArray, 54, QCborArray) \
155  F(QCborMap, 55, QCborMap) \
156  QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
157 
158 #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
159  F(QObjectStar, 39, QObject*)
160 
161 #define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
162  F(QVariantMap, 8, QVariantMap) \
163  F(QVariantList, 9, QVariantList) \
164  F(QVariantHash, 28, QVariantHash) \
165  F(QVariantPair, 58, QVariantPair) \
166  F(QByteArrayList, 49, QByteArrayList) \
167  F(QStringList, 11, QStringList) \
168 
169 #if QT_CONFIG(shortcut)
170 #define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)\
171  F(QKeySequence, 0x100b, QKeySequence)
172 #else
173 #define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)
174 #endif
175 
176 #define QT_FOR_EACH_STATIC_GUI_CLASS(F)\
177  F(QFont, 0x1000, QFont) \
178  F(QPixmap, 0x1001, QPixmap) \
179  F(QBrush, 0x1002, QBrush) \
180  F(QColor, 0x1003, QColor) \
181  F(QPalette, 0x1004, QPalette) \
182  F(QIcon, 0x1005, QIcon) \
183  F(QImage, 0x1006, QImage) \
184  F(QPolygon, 0x1007, QPolygon) \
185  F(QRegion, 0x1008, QRegion) \
186  F(QBitmap, 0x1009, QBitmap) \
187  F(QCursor, 0x100a, QCursor) \
188  QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F) \
189  F(QPen, 0x100c, QPen) \
190  F(QTextLength, 0x100d, QTextLength) \
191  F(QTextFormat, 0x100e, QTextFormat) \
192  F(QTransform, 0x1010, QTransform) \
193  F(QMatrix4x4, 0x1011, QMatrix4x4) \
194  F(QVector2D, 0x1012, QVector2D) \
195  F(QVector3D, 0x1013, QVector3D) \
196  F(QVector4D, 0x1014, QVector4D) \
197  F(QQuaternion, 0x1015, QQuaternion) \
198  F(QPolygonF, 0x1016, QPolygonF) \
199  F(QColorSpace, 0x1017, QColorSpace) \
200 
201 
202 #define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
203  F(QSizePolicy, 0x2000, QSizePolicy) \
204 
205 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
206 #define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
207  F(ULong, -1, ulong, "unsigned long") \
208  F(UInt, -1, uint, "unsigned int") \
209  F(UShort, -1, ushort, "unsigned short") \
210  F(UChar, -1, uchar, "unsigned char") \
211  F(LongLong, -1, qlonglong, "long long") \
212  F(ULongLong, -1, qulonglong, "unsigned long long") \
213  F(SChar, -1, signed char, "qint8") \
214  F(UChar, -1, uchar, "quint8") \
215  F(Short, -1, short, "qint16") \
216  F(UShort, -1, ushort, "quint16") \
217  F(Int, -1, int, "qint32") \
218  F(UInt, -1, uint, "quint32") \
219  F(LongLong, -1, qlonglong, "qint64") \
220  F(ULongLong, -1, qulonglong, "quint64") \
221  F(QVariantList, -1, QVariantList, "QList<QVariant>") \
222  F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
223  F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
224  F(QVariantPair, -1, QVariantPair, "QPair<QVariant,QVariant>") \
225  F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \
226  F(QStringList, -1, QStringList, "QList<QString>") \
227 
228 #define QT_FOR_EACH_STATIC_TYPE(F)\
229  QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
230  QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
231  QT_FOR_EACH_STATIC_CORE_CLASS(F)\
232  QT_FOR_EACH_STATIC_CORE_POINTER(F)\
233  QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
234  QT_FOR_EACH_STATIC_GUI_CLASS(F)\
235  QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
236 
237 #define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
238  TypeName = Id,
239 
240 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
241  F(QList) \
242  F(QQueue) \
243  F(QStack) \
244  F(QSet) \
245  /*end*/
246 
247 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
248  F(QHash, class) \
249  F(QMap, class)
250 
251 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
252  F(QSharedPointer) \
253  F(QWeakPointer) \
254  F(QPointer)
255 
256 class QDataStream;
257 struct QMetaObject;
258 
259 namespace QtPrivate
260 {
261 
263 {
264 public:
265  ushort revision; // 0 in Qt 6.0. Can increase if new field are added
270 
271  using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
273 
274  const char *name;
275 
276  using DefaultCtrFn = void (*)(const QMetaTypeInterface *, void *);
278  using CopyCtrFn = void (*)(const QMetaTypeInterface *, void *, const void *);
280  using MoveCtrFn = void (*)(const QMetaTypeInterface *, void *, void *);
282  using DtorFn = void (*)(const QMetaTypeInterface *, void *);
284  using EqualsFn = bool (*)(const QMetaTypeInterface *, const void *, const void *);
286  using LessThanFn = bool (*)(const QMetaTypeInterface *, const void *, const void *);
288  using DebugStreamFn = void (*)(const QMetaTypeInterface *, QDebug &, const void *);
290  using DataStreamOutFn = void (*)(const QMetaTypeInterface *, QDataStream &, const void *);
292  using DataStreamInFn = void (*)(const QMetaTypeInterface *, QDataStream &, void *);
294 
295  using LegacyRegisterOp = void (*)();
297 };
298 
303 template<typename From, typename To>
304 To convertImplicit(const From& from)
305 {
306  return from;
307 }
308 
309  template<typename T, bool>
310  struct SequentialValueTypeIsMetaType;
311  template<typename T, bool>
313  template<typename T, bool>
314  struct IsMetaTypePair;
315  template<typename, typename>
317 
318  template<typename T>
319  struct IsQFlags : std::false_type {};
320 
321  template<typename Enum>
322  struct IsQFlags<QFlags<Enum>> : std::true_type {};
323 
324  template<typename T>
325  struct IsEnumOrFlags : std::disjunction<std::is_enum<T>, IsQFlags<T>> {};
326 } // namespace QtPrivate
327 
328 class Q_CORE_EXPORT QMetaType {
329 public:
330 #ifndef Q_CLANG_QDOC
331  // The code that actually gets compiled.
332  enum Type {
333  // these are merged with QVariant
335 
336  FirstCoreType = Bool,
337  LastCoreType = QVariantPair,
338  FirstGuiType = QFont,
339  LastGuiType = QColorSpace,
340  FirstWidgetsType = QSizePolicy,
341  LastWidgetsType = QSizePolicy,
342  HighestInternalId = LastWidgetsType,
343 
344  QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
345 
346  UnknownType = 0,
347  User = 65536
348  };
349 #else
350  // If we are using QDoc it fakes the Type enum looks like this.
351  enum Type {
352  UnknownType = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,
353  Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,
354  UChar = 37, Float = 38,
355  VoidStar = 31,
356  QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,
357  QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
358  QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
359  QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26,
360  QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,
362  QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48,
363  QByteArrayList = 49, QObjectStar = 39, SChar = 40,
364  Void = 43,
365  Nullptr = 51,
366  QVariantMap = 8, QVariantList = 9, QVariantHash = 28,
367  QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55,
368  Char16 = 56, Char32 = 57,
369 
370  // Gui types
371  QFont = 0x1000, QPixmap = 0x1001, QBrush = 0x1002, QColor = 0x1003, QPalette = 0x1004,
372  QIcon = 0x1005, QImage = 0x1006, QPolygon = 0x1007, QRegion = 0x1008, QBitmap = 0x1009,
373  QCursor = 0x100a, QKeySequence = 0x100b, QPen = 0x100c, QTextLength = 0x100d, QTextFormat = 0x100e,
374  QTransform = 0x1010, QMatrix4x4 = 0x1011, QVector2D = 0x1012,
375  QVector3D = 0x1013, QVector4D = 0x1014, QQuaternion = 0x1015, QPolygonF = 0x1016, QColorSpace = 0x1017,
376 
377  // Widget types
378  QSizePolicy = 0x2000,
379  LastCoreType = Char32,
380  LastGuiType = QColorSpace,
381  User = 65536
382  };
383 #endif
384 
385  enum TypeFlag {
386  NeedsConstruction = 0x1,
387  NeedsDestruction = 0x2,
388  RelocatableType = 0x4,
389 #if QT_DEPRECATED_SINCE(6, 0)
390  MovableType Q_DECL_ENUMERATOR_DEPRECATED_X("Use RelocatableType instead.") = RelocatableType,
391 #endif
392  PointerToQObject = 0x8,
393  IsEnumeration = 0x10,
394  SharedPointerToQObject = 0x20,
395  WeakPointerToQObject = 0x40,
396  TrackingPointerToQObject = 0x80,
397  IsUnsignedEnumeration = 0x100,
398  IsGadget = 0x200,
399  PointerToGadget = 0x400,
400  IsPointer = 0x800,
401  IsQmlList =0x1000, // used in the QML engine to recognize QQmlListProperty<T> and list<T>
402  IsConst = 0x2000,
403  };
404  Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
405 
406  static void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type);
407 
408 #if QT_DEPRECATED_SINCE(6, 0)
410  static int type(const char *typeName)
411  { return QMetaType::fromName(typeName).id(); }
413  static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
414  { return QMetaType::fromName(typeName).id(); }
416  static const char *typeName(int type)
417  { return QMetaType(type).name(); }
419  static int sizeOf(int type)
420  { return int(QMetaType(type).sizeOf()); }
422  static TypeFlags typeFlags(int type)
423  { return QMetaType(type).flags(); }
425  static const QMetaObject *metaObjectForType(int type)
426  { return QMetaType(type).metaObject(); }
428  static void *create(int type, const void *copy = nullptr)
429  { return QMetaType(type).create(copy); }
431  static void destroy(int type, void *data)
432  { return QMetaType(type).destroy(data); }
434  static void *construct(int type, void *where, const void *copy)
435  { return QMetaType(type).construct(where, copy); }
437  static void destruct(int type, void *where)
438  { return QMetaType(type).destruct(where); }
439 #endif
440  static bool isRegistered(int type);
441 
442  explicit QMetaType(int type);
443  explicit constexpr QMetaType(const QtPrivate::QMetaTypeInterface *d) : d_ptr(d) {}
444  constexpr QMetaType() = default;
445 
446  bool isValid() const;
447  bool isRegistered() const;
448 #if QT_CORE_REMOVED_SINCE(6, 1) || defined(Q_QDOC)
449  int id() const;
450 #else
451  // ### Qt 7: Remove traces of out of line version
452  // unused int parameter is used to avoid ODR violation
453  int id(int = 0) const
454  {
455  // keep in sync with the version in removed_api.cpp
456  if (d_ptr) {
457  if (int id = d_ptr->typeId.loadRelaxed())
458  return id;
459  return idHelper();
460  }
461  return 0;
462  }
463 #endif
464  constexpr qsizetype sizeOf() const;
465  constexpr qsizetype alignOf() const;
466  constexpr TypeFlags flags() const;
467  constexpr const QMetaObject *metaObject() const;
468  constexpr const char *name() const;
469 
470  void *create(const void *copy = nullptr) const;
471  void destroy(void *data) const;
472  void *construct(void *where, const void *copy = nullptr) const;
473  void destruct(void *data) const;
474  QPartialOrdering compare(const void *lhs, const void *rhs) const;
475  bool equals(const void *lhs, const void *rhs) const;
476 
477  bool isEqualityComparable() const;
478  bool isOrdered() const;
479 
480 #ifndef QT_NO_DATASTREAM
481  bool save(QDataStream &stream, const void *data) const;
482  bool load(QDataStream &stream, void *data) const;
483  bool hasRegisteredDataStreamOperators() const;
484 
485 #if QT_DEPRECATED_SINCE(6, 0)
487  static bool save(QDataStream &stream, int type, const void *data)
488  { return QMetaType(type).save(stream, data); }
490  static bool load(QDataStream &stream, int type, void *data)
491  { return QMetaType(type).load(stream, data); }
492 #endif
493 #endif
494 
495  template<typename T>
496  constexpr static QMetaType fromType();
497  static QMetaType fromName(QByteArrayView name);
498 
500  {
501  if (a.d_ptr == b.d_ptr)
502  return true;
503  if (!a.d_ptr || !b.d_ptr)
504  return false; // one type is undefined, the other is defined
505  // avoid id call if we already have the id
506  const int aId = a.id();
507  const int bId = b.id();
508  return aId == bId;
509  }
510  friend bool operator!=(QMetaType a, QMetaType b) { return !(a == b); }
511 
512 public:
513 
514 #ifndef QT_NO_DEBUG_STREAM
515  bool debugStream(QDebug& dbg, const void *rhs);
516  bool hasRegisteredDebugStreamOperator() const;
517 
518 #if QT_DEPRECATED_SINCE(6, 0)
520  static bool debugStream(QDebug& dbg, const void *rhs, int typeId)
521  { return QMetaType(typeId).debugStream(dbg, rhs); }
522  template<typename T>
524  static bool hasRegisteredDebugStreamOperator()
525  { return QMetaType::fromType<T>().hasRegisteredDebugStreamOperator(); }
527  static bool hasRegisteredDebugStreamOperator(int typeId)
528  { return QMetaType(typeId).hasRegisteredDebugStreamOperator(); }
529 #endif
530 #endif
531 
532  // type erased converter function
533  using ConverterFunction = std::function<bool(const void *src, void *target)>;
534 
535  // type erased mutable view, primarily for containers
536  using MutableViewFunction = std::function<bool(void *src, void *target)>;
537 
538  // implicit conversion supported like double -> float
539  template<typename From, typename To>
540  static bool registerConverter()
541  {
542  return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>);
543  }
544 
545  // member function as in "QString QFont::toString() const"
546  template<typename From, typename To>
547  static bool registerConverter(To(From::*function)() const)
548  {
550  "QMetaType::registerConverter: At least one of the types must be a custom type.");
551 
552  const QMetaType fromType = QMetaType::fromType<From>();
553  const QMetaType toType = QMetaType::fromType<To>();
554  auto converter = [function](const void *from, void *to) -> bool {
555  const From *f = static_cast<const From *>(from);
556  To *t = static_cast<To *>(to);
557  *t = (f->*function)();
558  return true;
559  };
560  return registerConverterImpl<From, To>(converter, fromType, toType);
561  }
562 
563  // member function
564  template<typename From, typename To>
565  static bool registerMutableView(To(From::*function)())
566  {
568  "QMetaType::registerMutableView: At least one of the types must be a custom type.");
569 
570  const QMetaType fromType = QMetaType::fromType<From>();
571  const QMetaType toType = QMetaType::fromType<To>();
572  auto view = [function](void *from, void *to) -> bool {
573  From *f = static_cast<From *>(from);
574  To *t = static_cast<To *>(to);
575  *t = (f->*function)();
576  return true;
577  };
578  return registerMutableViewImpl<From, To>(view, fromType, toType);
579  }
580 
581  // member function as in "double QString::toDouble(bool *ok = nullptr) const"
582  template<typename From, typename To>
583  static bool registerConverter(To(From::*function)(bool*) const)
584  {
586  "QMetaType::registerConverter: At least one of the types must be a custom type.");
587 
588  const QMetaType fromType = QMetaType::fromType<From>();
589  const QMetaType toType = QMetaType::fromType<To>();
590  auto converter = [function](const void *from, void *to) -> bool {
591  const From *f = static_cast<const From *>(from);
592  To *t = static_cast<To *>(to);
593  bool result = true;
594  *t = (f->*function)(&result);
595  if (!result)
596  *t = To();
597  return result;
598  };
599  return registerConverterImpl<From, To>(converter, fromType, toType);
600  }
601 
602  // functor or function pointer
603  template<typename From, typename To, typename UnaryFunction>
604  static bool registerConverter(UnaryFunction function)
605  {
607  "QMetaType::registerConverter: At least one of the types must be a custom type.");
608 
609  const QMetaType fromType = QMetaType::fromType<From>();
610  const QMetaType toType = QMetaType::fromType<To>();
611  auto converter = [function = std::move(function)](const void *from, void *to) -> bool {
612  const From *f = static_cast<const From *>(from);
613  To *t = static_cast<To *>(to);
614  *t = function(*f);
615  return true;
616  };
617  return registerConverterImpl<From, To>(std::move(converter), fromType, toType);
618  }
619 
620  // functor or function pointer
621  template<typename From, typename To, typename UnaryFunction>
622  static bool registerMutableView(UnaryFunction function)
623  {
625  "QMetaType::registerMutableView: At least one of the types must be a custom type.");
626 
627  const QMetaType fromType = QMetaType::fromType<From>();
628  const QMetaType toType = QMetaType::fromType<To>();
629  auto view = [function = std::move(function)](void *from, void *to) -> bool {
630  From *f = static_cast<From *>(from);
631  To *t = static_cast<To *>(to);
632  *t = function(*f);
633  return true;
634  };
635  return registerMutableViewImpl<From, To>(std::move(view), fromType, toType);
636  }
637 
638 private:
639  template<typename From, typename To>
640  static bool registerConverterImpl(ConverterFunction converter, QMetaType fromType, QMetaType toType)
641  {
642  if (registerConverterFunction(std::move(converter), fromType, toType)) {
643  static const auto unregister = qScopeGuard([=] {
644  unregisterConverterFunction(fromType, toType);
645  });
646  return true;
647  } else {
648  return false;
649  }
650  }
651 
652  template<typename From, typename To>
653  static bool registerMutableViewImpl(MutableViewFunction view, QMetaType fromType, QMetaType toType)
654  {
655  if (registerMutableViewFunction(std::move(view), fromType, toType)) {
656  static const auto unregister = qScopeGuard([=] {
657  unregisterMutableViewFunction(fromType, toType);
658  });
659  return true;
660  } else {
661  return false;
662  }
663  }
664 public:
665 
666  static bool convert(QMetaType fromType, const void *from, QMetaType toType, void *to);
667  static bool canConvert(QMetaType fromType, QMetaType toType);
668 
669  static bool view(QMetaType fromType, void *from, QMetaType toType, void *to);
670  static bool canView(QMetaType fromType, QMetaType toType);
671 #if QT_DEPRECATED_SINCE(6, 0)
673  static bool convert(const void *from, int fromTypeId, void *to, int toTypeId)
674  { return convert(QMetaType(fromTypeId), from, QMetaType(toTypeId), to); }
676  static bool compare(const void *lhs, const void *rhs, int typeId, int *result)
677  {
678  QMetaType t(typeId);
679  auto c = t.compare(lhs, rhs);
681  *result = 0;
682  return false;
683  } else if (c == QPartialOrdering::Less) {
684  *result = -1;
685  return true;
686  } else if (c == QPartialOrdering::Equivalent) {
687  *result = 0;
688  return true;
689  } else {
690  *result = 1;
691  return true;
692  }
693  }
695  static bool equals(const void *lhs, const void *rhs, int typeId, int *result)
696  {
697  QMetaType t(typeId);
698  if (!t.isEqualityComparable())
699  return false;
700  *result = t.equals(lhs, rhs) ? 0 : -1;
701  return true;
702  }
703 #endif
704 
705  template<typename From, typename To>
707  {
709  QMetaType::fromType<From>(), QMetaType::fromType<To>());
710  }
711 
712  static bool hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType);
713 
714  template<typename From, typename To>
716  {
717  return hasRegisteredMutableViewFunction(
718  QMetaType::fromType<From>(), QMetaType::fromType<To>());
719  }
720 
721  static bool hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType);
722 
723 #ifndef Q_CLANG_QDOC
724  template<typename, bool> friend struct QtPrivate::SequentialValueTypeIsMetaType;
725  template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
726  template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
727  template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper;
728 #endif
729  static bool registerConverterFunction(const ConverterFunction &f, QMetaType from, QMetaType to);
730  static void unregisterConverterFunction(QMetaType from, QMetaType to);
731 
732  static bool registerMutableViewFunction(const MutableViewFunction &f, QMetaType from, QMetaType to);
733  static void unregisterMutableViewFunction(QMetaType from, QMetaType to);
734 
735  static void unregisterMetaType(QMetaType type);
736 
737 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
738  const QtPrivate::QMetaTypeInterface *iface() { return d_ptr; }
739 #endif
740  const QtPrivate::QMetaTypeInterface *iface() const { return d_ptr; }
741 
742 private:
743  int idHelper() const;
744  friend class QVariant;
745  const QtPrivate::QMetaTypeInterface *d_ptr = nullptr;
746 };
747 
748 #undef QT_DEFINE_METATYPE_ID
749 
750 Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
751 
752 #define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F) \
753  } \
754  Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \
755  namespace QtMetaTypePrivate {
756 
757 
758 namespace QtMetaTypePrivate {
759 
761 {
762 public:
763  const void *_pair;
766 
767  typedef void (*getFunc)(const void * const *p, void *);
768 
769  getFunc _getFirst;
770  getFunc _getSecond;
771 
772  template<class T>
773  static void getFirstImpl(const void * const *pair, void *dataPtr)
774  { *static_cast<typename T::first_type *>(dataPtr) = static_cast<const T*>(*pair)->first; }
775  template<class T>
776  static void getSecondImpl(const void * const *pair, void *dataPtr)
777  { *static_cast<typename T::second_type *>(dataPtr) = static_cast<const T*>(*pair)->second; }
778 
779 public:
780  template<class T> QPairVariantInterfaceImpl(const T*p)
781  : _pair(p)
782  , _metaType_first(QMetaType::fromType<typename T::first_type>())
783  , _metaType_second(QMetaType::fromType<typename T::second_type>())
784  , _getFirst(getFirstImpl<T>)
785  , _getSecond(getSecondImpl<T>)
786  {
787  }
788 
790  : _pair(nullptr)
791  , _getFirst(nullptr)
792  , _getSecond(nullptr)
793  {
794  }
795 
796  inline void first(void *dataPtr) const { _getFirst(&_pair, dataPtr); }
797  inline void second(void *dataPtr) const { _getSecond(&_pair, dataPtr); }
798 };
800 
801 template<typename From>
803 
804 template<typename T, typename U>
806 {
807  QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const
808  {
809  return QPairVariantInterfaceImpl(&f);
810  }
811 };
812 
813 }
814 
815 class QObject;
816 
817 #define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
818  template <class T> class Name; \
819 
821 
822 namespace QtPrivate
823 {
824  template<typename T>
826  {
827  enum { Value = false };
828  };
829 
830  // Specialize to avoid sizeof(void) warning
831  template<>
833  {
834  enum { Value = false };
835  };
836  template<>
838  {
839  enum { Value = false };
840  };
841  template<>
843  {
844  enum { Value = true };
845  };
846 
847  template<typename T>
849  {
850  typedef qint8 yes_type;
851  typedef qint64 no_type;
852 
853 #ifndef QT_NO_QOBJECT
855  static yes_type checkType(const QObject* );
856 #endif
857  static no_type checkType(...);
858  static_assert(sizeof(T), "Type argument of Q_PROPERTY or Q_DECLARE_METATYPE(T*) must be fully defined");
859  enum { Value = sizeof(checkType(static_cast<T*>(nullptr))) == sizeof(yes_type) };
860  };
861 
862  template<typename T, typename Enable = void>
863  struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
864 
865  template<typename T>
866  struct IsGadgetHelper<T, typename T::QtGadgetHelper>
867  {
868  template <typename X>
869  static char checkType(void (X::*)());
870  static void *checkType(void (T::*)());
871  enum {
872  IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
873  IsGadgetOrDerivedFrom = true
874  };
875  };
876 
877  template<typename T, typename Enable = void>
878  struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
879 
880  template<typename T>
881  struct IsPointerToGadgetHelper<T*, typename T::QtGadgetHelper>
882  {
883  using BaseType = T;
884  template <typename X>
885  static char checkType(void (X::*)());
886  static void *checkType(void (T::*)());
887  enum {
888  IsRealGadget = !IsPointerToTypeDerivedFromQObject<T*>::Value && sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
889  IsGadgetOrDerivedFrom = !IsPointerToTypeDerivedFromQObject<T*>::Value
890  };
891  };
892 
893 
894  template<typename T> char qt_getEnumMetaObject(const T&);
895 
896  template<typename T>
897  struct IsQEnumHelper {
898  static const T &declval();
899  // If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject() declared in the
900  // Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*.
901  // Otherwise the chosen overload will be the catch all template function
902  // qt_getEnumMetaObject(T) which returns 'char'
903  enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
904  };
905  template<> struct IsQEnumHelper<void> { enum { Value = false }; };
906 
907  template<typename T, typename Enable = void>
909  {
910  static constexpr const QMetaObject *value() { return nullptr; }
911  using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
912  static constexpr MetaObjectFn metaObjectFunction = nullptr;
913  };
914 #ifndef QT_NO_QOBJECT
915  template<>
917  {
918  static constexpr const QMetaObject *value() { return nullptr; }
919  using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
920  static constexpr MetaObjectFn metaObjectFunction = nullptr;
921  };
922  template<typename T>
924  {
925  static constexpr const QMetaObject *value() { return &T::staticMetaObject; }
926  static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; }
927  };
928  template<typename T>
929  struct MetaObjectForType<T, typename std::enable_if<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
930  {
931  static constexpr const QMetaObject *value() { return &T::staticMetaObject; }
932  static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; }
933  };
934  template<typename T>
935  struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
936  {
937  static constexpr const QMetaObject *value()
938  {
940  }
941  static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); }
942  };
943  template<typename T>
944  struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type >
945  {
946  static constexpr const QMetaObject *value() { return qt_getEnumMetaObject(T()); }
947  static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); }
948  };
949 #endif
950 
951  template<typename T>
953  {
954  enum { Value = false };
955  };
956 
957  template<typename T>
959  {
960  };
961 
962  template<typename T>
964  {
965  enum { Value = false };
966  };
967 
968  template<typename T>
970  {
971  };
972 
973  template<typename T>
975  {
976  enum { Value = false };
977  };
978 
979  template<typename T>
981  {
982  enum { Value = true };
983  };
984 
985  template<typename T>
987  {
988  enum { Value = false };
989  };
990 
991  template<typename T>
993  {
994  enum { Value = false };
995  };
996 
999  {
1000  static bool registerConverter()
1001  {
1002  return false;
1003  }
1004 
1005  static bool registerMutableView()
1006  {
1007  return false;
1008  }
1009  };
1010 
1011  template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
1013  {
1014  static bool registerConverter()
1015  {
1016  return false;
1017  }
1018 
1019  static bool registerMutableView()
1020  {
1021  return false;
1022  }
1023  };
1024 
1025  template<typename T>
1027  {
1028  };
1029 
1032  {
1033  static bool registerConverter()
1034  {
1035  return false;
1036  }
1037 
1038  static bool registerMutableView()
1039  {
1040  return false;
1041  }
1042  };
1043 
1044  template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
1046  {
1047  static bool registerConverter()
1048  {
1049  return false;
1050  }
1051 
1052  static bool registerMutableView()
1053  {
1054  return false;
1055  }
1056  };
1057 
1058  template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
1060  {
1061  static bool registerConverter()
1062  {
1063  return false;
1064  }
1065 
1066  static bool registerMutableView()
1067  {
1068  return false;
1069  }
1070  };
1071 
1072  template<typename T>
1074  {
1075  };
1076 
1077  template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
1080  {
1081  static bool registerConverter()
1082  {
1083  return false;
1084  }
1085  };
1086 
1087  template<typename T>
1089  {
1090  inline static bool registerConverter();
1091  };
1092 
1093  template<typename T>
1094  struct IsPair
1095  {
1096  static bool registerConverter()
1097  {
1098  return false;
1099  }
1100  };
1101  template<typename T, typename U>
1102  struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
1103 
1104  template<typename T>
1105  struct MetaTypePairHelper : IsPair<T> {};
1106 
1107  template<typename T, typename = void>
1109  {
1110  static bool registerConverter() { return false; }
1111  };
1112 
1113 #if QT_CONFIG(future)
1114  template<typename T>
1115  struct MetaTypeQFutureHelper
1116  {
1117  static bool registerConverter() { return false; }
1118  };
1119 #endif
1120 
1121  Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
1122 } // namespace QtPrivate
1123 
1124 template <typename T, int =
1130 {
1131  enum {
1132  Defined = 0
1133  };
1134 };
1135 
1136 template <typename T>
1138 {
1139 };
1140 
1141 template <typename T>
1143 {
1145  enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
1146  static inline constexpr int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
1147 };
1148 
1149 template <typename T>
1151 
1152 template <typename T>
1153 struct QMetaTypeId2<T&> { enum {Defined = false }; };
1154 
1155 namespace QtPrivate {
1156  template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
1158  static inline constexpr int qt_metatype_id()
1159  { return QMetaTypeId2<T>::qt_metatype_id(); }
1160  };
1161  template <typename T> struct QMetaTypeIdHelper<T, false> {
1162  static inline constexpr int qt_metatype_id()
1163  { return -1; }
1164  };
1165 
1166  // Function pointers don't derive from QObject
1167  template <typename Result, typename... Args>
1168  struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
1169 
1170  template<typename T>
1171  inline constexpr bool IsQmlListType = false;
1172 
1174  constexpr bool IsUnsignedEnum = false;
1175  template<typename T>
1176  constexpr bool IsUnsignedEnum<T, true> = !std::is_signed_v<std::underlying_type_t<T>>;
1177 
1178  template<typename T>
1180  {
1192  | (IsUnsignedEnum<T> ? QMetaType::IsUnsignedEnumeration : 0)
1193  | (IsQmlListType<T> ? QMetaType::IsQmlList : 0)
1194  | (std::is_const_v<std::remove_pointer_t<T>> ? QMetaType::IsConst : 0)
1195  };
1196  };
1197 
1198  template<typename T, bool defined>
1200  {
1201  enum DefinedType { Defined = defined };
1202  };
1203 
1204  template<typename SmartPointer>
1206  {
1207  QObject* operator()(const SmartPointer &p) const
1208  {
1209  return p.operator->();
1210  }
1211  };
1212 
1213  // hack to delay name lookup to instantiation time by making
1214  // EnableInternalData a dependent name:
1215  template <typename T>
1216  struct EnableInternalDataWrap;
1217 
1218  template<typename T>
1220  {
1222  {
1224  }
1225  };
1226 }
1227 
1228 template <typename T>
1230 {
1231 #ifndef QT_NO_QOBJECT
1232  Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()),
1233  "qRegisterNormalizedMetaType",
1234  "qRegisterNormalizedMetaType was called with a not normalized type name, "
1235  "please call qRegisterMetaType instead.");
1236 #endif
1237 
1238  const QMetaType metaType = QMetaType::fromType<T>();
1239  const int id = metaType.id();
1240 
1247 #if QT_CONFIG(future)
1248  QtPrivate::MetaTypeQFutureHelper<T>::registerConverter();
1249 #endif
1250 
1251  if (normalizedTypeName != metaType.name())
1252  QMetaType::registerNormalizedTypedef(normalizedTypeName, metaType);
1253 
1254  return id;
1255 }
1256 
1257 // This primary template calls the -Implementation, like all other specialisations should.
1258 // But the split allows to
1259 // - in a header:
1260 // - define a specialization of this template calling an out-of-line function
1261 // (QT_DECL_METATYPE_EXTERN{,_TAGGED})
1262 // - in the .cpp file:
1263 // - define the out-of-line wrapper to call the -Implementation
1264 // (QT_IMPL_METATYPE_EXTERN{,_TAGGED})
1265 // The _TAGGED variants let you choose a tag (must be a C identifier) to disambiguate
1266 // the out-of-line function; the non-_TAGGED variants use the passed class name as tag.
1267 template <typename T>
1269 {
1270  return qRegisterNormalizedMetaTypeImplementation<T>(normalizedTypeName);
1271 }
1272 
1273 #define QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TAG, EXPORT) \
1274  QT_BEGIN_NAMESPACE \
1275  EXPORT int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &); \
1276  template <> inline int qRegisterNormalizedMetaType< TYPE >(const QByteArray &name) \
1277  { return qRegisterNormalizedMetaType_ ## TAG (name); } \
1278  QT_END_NAMESPACE \
1279  Q_DECLARE_METATYPE(TYPE) \
1280  /* end */
1281 #define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG) \
1282  int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &name) \
1283  { return qRegisterNormalizedMetaTypeImplementation< TYPE >(name); } \
1284  /* end */
1285 #define QT_DECL_METATYPE_EXTERN(TYPE, EXPORT) \
1286  QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TYPE, EXPORT)
1287 #define QT_IMPL_METATYPE_EXTERN(TYPE) \
1288  QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TYPE)
1289 
1290 template <typename T>
1291 int qRegisterMetaType(const char *typeName)
1292 {
1293 #ifdef QT_NO_QOBJECT
1294  QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
1295 #else
1297 #endif
1298  return qRegisterNormalizedMetaType<T>(normalizedTypeName);
1299 }
1300 
1301 template <typename T>
1302 inline constexpr int qMetaTypeId()
1303 {
1304  if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
1306  } else {
1307  return QMetaType::fromType<T>().id();
1308  }
1309 }
1310 
1311 template <typename T>
1312 inline constexpr int qRegisterMetaType()
1313 {
1314  int id = qMetaTypeId<T>();
1315  return id;
1316 }
1317 
1318 #ifndef QT_NO_QOBJECT
1319 template <typename T>
1321 {
1322  enum {
1323  Defined = 1
1324  };
1325 
1326  static int qt_metatype_id()
1327  {
1328  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1329  if (const int id = metatype_id.loadAcquire())
1330  return id;
1331  const char *const cName = T::staticMetaObject.className();
1333  typeName.reserve(strlen(cName) + 1);
1334  typeName.append(cName).append('*');
1335  const int newId = qRegisterNormalizedMetaType<T *>(typeName);
1336  metatype_id.storeRelease(newId);
1337  return newId;
1338  }
1339 };
1340 
1341 template <typename T>
1342 struct QMetaTypeIdQObject<T, QMetaType::IsGadget>
1343 {
1344  enum {
1346  };
1347 
1348  static int qt_metatype_id()
1349  {
1350  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1351  if (const int id = metatype_id.loadAcquire())
1352  return id;
1353  const char *const cName = T::staticMetaObject.className();
1354  const int newId = qRegisterNormalizedMetaType<T>(cName);
1355  metatype_id.storeRelease(newId);
1356  return newId;
1357  }
1358 };
1359 
1360 template <typename T>
1362 {
1363  enum {
1364  Defined = 1
1365  };
1366 
1367  static int qt_metatype_id()
1368  {
1369  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1370  if (const int id = metatype_id.loadAcquire())
1371  return id;
1372  const char *const cName = T::staticMetaObject.className();
1374  typeName.reserve(strlen(cName) + 1);
1375  typeName.append(cName).append('*');
1376  const int newId = qRegisterNormalizedMetaType<T *>(typeName);
1377  metatype_id.storeRelease(newId);
1378  return newId;
1379  }
1380 };
1381 
1382 template <typename T>
1383 struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
1384 {
1385  enum {
1386  Defined = 1
1387  };
1388 
1389  static int qt_metatype_id()
1390  {
1391  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1392  if (const int id = metatype_id.loadAcquire())
1393  return id;
1394  const char *eName = qt_getEnumName(T());
1395  const char *cName = qt_getEnumMetaObject(T())->className();
1397  typeName.reserve(strlen(cName) + 2 + strlen(eName));
1398  typeName.append(cName).append("::").append(eName);
1399  const int newId = qRegisterNormalizedMetaType<T>(typeName);
1400  metatype_id.storeRelease(newId);
1401  return newId;
1402  }
1403 };
1404 #endif
1405 
1406 #define Q_DECLARE_OPAQUE_POINTER(POINTER) \
1407  QT_BEGIN_NAMESPACE namespace QtPrivate { \
1408  template <> \
1409  struct IsPointerToTypeDerivedFromQObject<POINTER > \
1410  { \
1411  enum { Value = false }; \
1412  }; \
1413  } QT_END_NAMESPACE \
1414 
1415 
1416 #ifndef Q_MOC_RUN
1417 #define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
1418 #define Q_DECLARE_METATYPE_IMPL(TYPE) \
1419  QT_BEGIN_NAMESPACE \
1420  template <> \
1421  struct QMetaTypeId< TYPE > \
1422  { \
1423  enum { Defined = 1 }; \
1424  static int qt_metatype_id() \
1425  { \
1426  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1427  if (const int id = metatype_id.loadAcquire()) \
1428  return id; \
1429  constexpr auto arr = QtPrivate::typenameHelper<TYPE>(); \
1430  auto name = arr.data(); \
1431  if (QByteArrayView(name) == (#TYPE)) { \
1432  const int id = qRegisterNormalizedMetaType<TYPE>(name); \
1433  metatype_id.storeRelease(id); \
1434  return id; \
1435  } \
1436  const int newId = qRegisterMetaType< TYPE >(#TYPE); \
1437  metatype_id.storeRelease(newId); \
1438  return newId; \
1439  } \
1440  }; \
1441  QT_END_NAMESPACE
1442 #endif // Q_MOC_RUN
1443 
1444 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \
1445  QT_BEGIN_NAMESPACE \
1446  template<> struct QMetaTypeId2<NAME> \
1447  { \
1448  using NameAsArrayType = std::array<char, sizeof(#NAME)>; \
1449  enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID }; \
1450  static inline constexpr int qt_metatype_id() { return METATYPEID; } \
1451  static constexpr NameAsArrayType nameAsArray = { #NAME }; \
1452  }; \
1453  QT_END_NAMESPACE
1454 
1455 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
1456  class Name;
1457 
1461 
1462 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
1463 
1464 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
1465 QT_BEGIN_NAMESPACE \
1466 template <typename T> \
1467 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
1468 { \
1469  enum { \
1470  Defined = QMetaTypeId2<T>::Defined \
1471  }; \
1472  static int qt_metatype_id() \
1473  { \
1474  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1475  if (const int id = metatype_id.loadRelaxed()) \
1476  return id; \
1477  const char *tName = QMetaType::fromType<T>().name(); \
1478  Q_ASSERT(tName); \
1479  const size_t tNameLen = qstrlen(tName); \
1480  QByteArray typeName; \
1481  typeName.reserve(sizeof(#SINGLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + 1); \
1482  typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
1483  .append('<').append(tName, tNameLen); \
1484  typeName.append('>'); \
1485  const int newId = qRegisterNormalizedMetaType< SINGLE_ARG_TEMPLATE<T> >(typeName); \
1486  metatype_id.storeRelease(newId); \
1487  return newId; \
1488  } \
1489 }; \
1490 QT_END_NAMESPACE
1491 
1492 #define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
1493 QT_BEGIN_NAMESPACE \
1494 template<typename T, typename U> \
1495 struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
1496 { \
1497  enum { \
1498  Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
1499  }; \
1500  static int qt_metatype_id() \
1501  { \
1502  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1503  if (const int id = metatype_id.loadAcquire()) \
1504  return id; \
1505  const char *tName = QMetaType::fromType<T>().name(); \
1506  const char *uName = QMetaType::fromType<U>().name(); \
1507  Q_ASSERT(tName); \
1508  Q_ASSERT(uName); \
1509  const size_t tNameLen = qstrlen(tName); \
1510  const size_t uNameLen = qstrlen(uName); \
1511  QByteArray typeName; \
1512  typeName.reserve(sizeof(#DOUBLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
1513  typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
1514  .append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
1515  typeName.append('>'); \
1516  const int newId = qRegisterNormalizedMetaType< DOUBLE_ARG_TEMPLATE<T, U> >(typeName); \
1517  metatype_id.storeRelease(newId); \
1518  return newId; \
1519  } \
1520 }; \
1521 QT_END_NAMESPACE
1522 
1523 namespace QtPrivate {
1524 
1525 template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
1527 {
1528  enum {
1529  Defined = 0
1530  };
1531  static int qt_metatype_id()
1532  {
1533  return -1;
1534  }
1535 };
1536 
1537 }
1538 
1539 #define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
1540 QT_BEGIN_NAMESPACE \
1541 namespace QtPrivate { \
1542 template<typename T> \
1543 struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
1544 { \
1545  enum { \
1546  Defined = 1 \
1547  }; \
1548  static int qt_metatype_id() \
1549  { \
1550  static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1551  if (const int id = metatype_id.loadAcquire()) \
1552  return id; \
1553  const char * const cName = T::staticMetaObject.className(); \
1554  QByteArray typeName; \
1555  typeName.reserve(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1); \
1556  typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
1557  .append('<').append(cName).append('>'); \
1558  const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >(typeName); \
1559  metatype_id.storeRelease(newId); \
1560  return newId; \
1561  } \
1562 }; \
1563 template<typename T> \
1564 struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
1565  typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value && !std::is_const_v<T>>::type> \
1566 { \
1567  static bool registerConverter() \
1568  { \
1569  const QMetaType to = QMetaType(QMetaType::QObjectStar); \
1570  if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<SMART_POINTER<T>>(), to)) { \
1571  QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
1572  return QMetaType::registerConverter<SMART_POINTER<T>, QObject*>(o); \
1573  } \
1574  return true; \
1575  } \
1576 }; \
1577 } \
1578 template <typename T> \
1579 struct QMetaTypeId< SMART_POINTER<T> > \
1580  : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
1581  QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
1582 { \
1583 };\
1584 QT_END_NAMESPACE
1585 
1586 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(SINGLE_ARG_TEMPLATE) \
1587  QT_BEGIN_NAMESPACE \
1588  namespace QtPrivate { \
1589  template<typename T> \
1590  struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
1591  { \
1592  enum { Value = true }; \
1593  }; \
1594  } \
1595  QT_END_NAMESPACE \
1596  Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE)
1597 
1598 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
1599  Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(TEMPLATENAME)
1600 
1602 
1604 
1605 #undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
1606 
1609 
1610 #define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
1611  QT_BEGIN_NAMESPACE \
1612  namespace QtPrivate { \
1613  template<typename T, typename U> \
1614  struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
1615  { \
1616  enum { Value = true }; \
1617  }; \
1618  } \
1619  QT_END_NAMESPACE \
1620  Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
1621 
1625 
1627 
1628 #define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
1629  Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
1630 
1632 
1634 
1635 #undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
1636 
1638 
1640 
1641 
1643 
1644 template <typename T>
1646 {
1647  const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
1648  if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
1650  return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o);
1651  }
1652  return true;
1653 }
1654 
1655 namespace QtPrivate {
1656 
1657 template<typename From>
1659 {
1661  {
1662  return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1663  }
1664 };
1665 
1666 template<typename From>
1668 {
1670  {
1671  return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1672  }
1673 };
1674 
1675 template<typename T>
1677 {
1678  static bool registerConverter()
1679  {
1680  const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
1681  if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
1683  return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o);
1684  }
1685  return true;
1686  }
1687 
1688  static bool registerMutableView()
1689  {
1690  const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
1691  if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
1693  return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o);
1694  }
1695  return true;
1696  }
1697 };
1698 
1699 template<typename From>
1701 {
1703  {
1704  return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1705  }
1706 };
1707 
1708 template<typename From>
1710 {
1712  {
1713  return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1714  }
1715 };
1716 
1717 // Mapped type can be omitted, for example in case of a set.
1718 // However, if it is available, we want to instantiate the metatype here.
1719 template<typename T>
1721 {
1722  static bool registerConverter()
1723  {
1724  const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
1725  if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
1727  return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o);
1728  }
1729  return true;
1730  }
1731 
1732  static bool registerMutableView()
1733  {
1734  const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
1735  if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
1737  return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o);
1738  }
1739  return true;
1740  }
1741 };
1742 
1744 {
1745  char *output;
1746  int len = 0;
1747  char last = 0;
1748 
1749 private:
1750  static constexpr bool is_ident_char(char s)
1751  {
1752  return ((s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || (s >= '0' && s <= '9')
1753  || s == '_');
1754  }
1755  static constexpr bool is_space(char s) { return (s == ' ' || s == '\t' || s == '\n'); }
1756  static constexpr bool is_number(char s) { return s >= '0' && s <= '9'; }
1757  static constexpr bool starts_with_token(const char *b, const char *e, const char *token,
1758  bool msvcKw = false)
1759  {
1760  while (b != e && *token && *b == *token) {
1761  b++;
1762  token++;
1763  }
1764  if (*token)
1765  return false;
1766 #ifdef Q_CC_MSVC
1769  if (msvcKw)
1770  return true;
1771 #endif
1772  Q_UNUSED(msvcKw);
1773  return b == e || !is_ident_char(*b);
1774  }
1775  static constexpr bool skipToken(const char *&x, const char *e, const char *token,
1776  bool msvcKw = false)
1777  {
1778  if (!starts_with_token(x, e, token, msvcKw))
1779  return false;
1780  while (*token++)
1781  x++;
1782  while (x != e && is_space(*x))
1783  x++;
1784  return true;
1785  }
1786  static constexpr const char *skipString(const char *x, const char *e)
1787  {
1788  char delim = *x;
1789  x++;
1790  while (x != e && *x != delim) {
1791  if (*x == '\\') {
1792  x++;
1793  if (x == e)
1794  return e;
1795  }
1796  x++;
1797  }
1798  if (x != e)
1799  x++;
1800  return x;
1801  }
1802  static constexpr const char *skipTemplate(const char *x, const char *e, bool stopAtComa = false)
1803  {
1804  int scopeDepth = 0;
1805  int templateDepth = 0;
1806  while (x != e) {
1807  switch (*x) {
1808  case '<':
1809  if (!scopeDepth)
1810  templateDepth++;
1811  break;
1812  case ',':
1813  if (stopAtComa && !scopeDepth && !templateDepth)
1814  return x;
1815  break;
1816  case '>':
1817  if (!scopeDepth)
1818  if (--templateDepth < 0)
1819  return x;
1820  break;
1821  case '(':
1822  case '[':
1823  case '{':
1824  scopeDepth++;
1825  break;
1826  case '}':
1827  case ']':
1828  case ')':
1829  scopeDepth--;
1830  break;
1831  case '\'':
1832  if (is_number(x[-1]))
1833  break;
1834  Q_FALLTHROUGH();
1835  case '\"':
1836  x = skipString(x, e);
1837  continue;
1838  }
1839  x++;
1840  }
1841  return x;
1842  }
1843 
1844  constexpr void append(char x)
1845  {
1846  last = x;
1847  len++;
1848  if (output)
1849  *output++ = x;
1850  }
1851 
1852  constexpr void replaceLast(char x)
1853  {
1854  last = x;
1855  if (output)
1856  *(output - 1) = x;
1857  }
1858 
1859  constexpr void appendStr(const char *x)
1860  {
1861  while (*x)
1862  append(*x++);
1863  }
1864 
1865  constexpr void normalizeIntegerTypes(const char *&begin, const char *end)
1866  {
1867  int numLong = 0;
1868  int numSigned = 0;
1869  int numUnsigned = 0;
1870  int numInt = 0;
1871  int numShort = 0;
1872  int numChar = 0;
1873  while (begin < end) {
1874  if (skipToken(begin, end, "long")) {
1875  numLong++;
1876  continue;
1877  }
1878  if (skipToken(begin, end, "int")) {
1879  numInt++;
1880  continue;
1881  }
1882  if (skipToken(begin, end, "short")) {
1883  numShort++;
1884  continue;
1885  }
1886  if (skipToken(begin, end, "unsigned")) {
1887  numUnsigned++;
1888  continue;
1889  }
1890  if (skipToken(begin, end, "signed")) {
1891  numSigned++;
1892  continue;
1893  }
1894  if (skipToken(begin, end, "char")) {
1895  numChar++;
1896  continue;
1897  }
1898 #ifdef Q_CC_MSVC
1899  if (skipToken(begin, end, "__int64")) {
1900  numLong = 2;
1901  continue;
1902  }
1903 #endif
1904  break;
1905  }
1906  if (numLong == 2)
1907  append('q'); // q(u)longlong
1908  if (numSigned && numChar)
1909  appendStr("signed ");
1910  else if (numUnsigned)
1911  appendStr("u");
1912  if (numChar)
1913  appendStr("char");
1914  else if (numShort)
1915  appendStr("short");
1916  else if (numLong == 1)
1917  appendStr("long");
1918  else if (numLong == 2)
1919  appendStr("longlong");
1920  else if (numUnsigned || numSigned || numInt)
1921  appendStr("int");
1922  }
1923 
1924  constexpr void skipStructClassOrEnum(const char *&begin, const char *end)
1925  {
1926  // discard 'struct', 'class', and 'enum'; they are optional
1927  // and we don't want them in the normalized signature
1928  skipToken(begin, end, "struct", true) || skipToken(begin, end, "class", true)
1929  || skipToken(begin, end, "enum", true);
1930  }
1931 
1932  constexpr void skipQtNamespace(const char *&begin, const char *end)
1933  {
1934 #ifdef QT_NAMESPACE
1935  const char *nsbeg = begin;
1936  if (skipToken(nsbeg, end, QT_STRINGIFY(QT_NAMESPACE)) && nsbeg + 2 < end && nsbeg[0] == ':'
1937  && nsbeg[1] == ':') {
1938  begin = nsbeg + 2;
1939  while (begin != end && is_space(*begin))
1940  begin++;
1941  }
1942 #else
1943  Q_UNUSED(begin);
1944  Q_UNUSED(end);
1945 #endif
1946  }
1947 
1948 public:
1949 #if defined(Q_CC_CLANG) || defined (Q_CC_GNU)
1950  // this is much simpler than the full type normalization below
1951  // the reason is that the signature returned by Q_FUNC_INFO is already
1952  // normalized to the largest degree, and we need to do only small adjustments
1953  constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
1954  {
1955  // bail out if there is an anonymous struct
1956  std::string_view name(begin, end-begin);
1957 #if defined (Q_CC_CLANG)
1958  if (name.find("anonymous ") != std::string_view::npos)
1959  return normalizeType(begin, end);
1960 #endif
1961  if (name.find("unnamed ") != std::string_view::npos)
1962  return normalizeType(begin, end);
1963  while (begin < end) {
1964  if (*begin == ' ') {
1965  if (last == ',' || last == '>' || last == '<' || last == '*' || last == '&') {
1966  ++begin;
1967  continue;
1968  }
1969  }
1970  if (last == ' ') {
1971  if (*begin == '*' || *begin == '&' || *begin == '(') {
1972  replaceLast(*begin);
1973  ++begin;
1974  continue;
1975  }
1976  }
1977  if (!is_ident_char(last)) {
1978  skipStructClassOrEnum(begin, end);
1979  if (begin == end)
1980  break;
1981 
1982  skipQtNamespace(begin, end);
1983  if (begin == end)
1984  break;
1985 
1986  normalizeIntegerTypes(begin, end);
1987  if (begin == end)
1988  break;
1989  }
1990  append(*begin);
1991  ++begin;
1992  }
1993  return len;
1994  }
1995 #else
1996  // MSVC needs the full normalization, as it puts the const in a different
1997  // place than we expect
1998  constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
1999  { return normalizeType(begin, end); }
2000 #endif
2001 
2002  constexpr int normalizeType(const char *begin, const char *end, bool adjustConst = true)
2003  {
2004  // Trim spaces
2005  while (begin != end && is_space(*begin))
2006  begin++;
2007  while (begin != end && is_space(*(end - 1)))
2008  end--;
2009 
2010  // Convert 'char const *' into 'const char *'. Start at index 1,
2011  // not 0, because 'const char *' is already OK.
2012  const char *cst = begin + 1;
2013  if (*begin == '\'' || *begin == '"')
2014  cst = skipString(begin, end);
2015  bool seenStar = false;
2016  bool hasMiddleConst = false;
2017  while (cst < end) {
2018  if (*cst == '\"' || (*cst == '\'' && !is_number(cst[-1]))) {
2019  cst = skipString(cst, end);
2020  if (cst == end)
2021  break;
2022  }
2023 
2024  // We mustn't convert 'char * const *' into 'const char **'
2025  // and we must beware of 'Bar<const Bla>'.
2026  if (*cst == '&' || *cst == '*' || *cst == '[') {
2027  seenStar = *cst != '&' || cst != (end - 1);
2028  break;
2029  }
2030  if (*cst == '<') {
2031  cst = skipTemplate(cst + 1, end);
2032  if (cst == end)
2033  break;
2034  }
2035  cst++;
2036  const char *skipedCst = cst;
2037  if (!is_ident_char(*(cst - 1)) && skipToken(skipedCst, end, "const")) {
2038  const char *testEnd = end;
2039  while (skipedCst < testEnd--) {
2040  if (*testEnd == '*' || *testEnd == '['
2041  || (*testEnd == '&' && testEnd != (end - 1))) {
2042  seenStar = true;
2043  break;
2044  }
2045  if (*testEnd == '>')
2046  break;
2047  }
2048  if (adjustConst && !seenStar) {
2049  if (*(end - 1) == '&')
2050  end--;
2051  } else {
2052  appendStr("const ");
2053  }
2054  normalizeType(begin, cst, false);
2055  begin = skipedCst;
2056  hasMiddleConst = true;
2057  break;
2058  }
2059  }
2060  if (skipToken(begin, end, "const")) {
2061  if (adjustConst && !seenStar) {
2062  if (*(end - 1) == '&')
2063  end--;
2064  } else {
2065  appendStr("const ");
2066  }
2067  }
2068  if (seenStar && adjustConst) {
2069  const char *e = end;
2070  if (*(end - 1) == '&' && *(end - 2) != '&')
2071  e--;
2072  while (begin != e && is_space(*(e - 1)))
2073  e--;
2074  const char *token = "tsnoc"; // 'const' reverse, to check if it ends with const
2075  while (*token && begin != e && *(--e) == *token++)
2076  ;
2077  if (!*token && begin != e && !is_ident_char(*(e - 1))) {
2078  while (begin != e && is_space(*(e - 1)))
2079  e--;
2080  end = e;
2081  }
2082  }
2083 
2084  skipStructClassOrEnum(begin, end);
2085  skipQtNamespace(begin, end);
2086 
2087  if (skipToken(begin, end, "QVector")) {
2088  // Replace QVector by QList
2089  appendStr("QList");
2090  }
2091 
2092  if (skipToken(begin, end, "QPair")) {
2093  // replace QPair by std::pair
2094  appendStr("std::pair");
2095  }
2096 
2097  if (!hasMiddleConst)
2098  // Normalize the integer types
2099  normalizeIntegerTypes(begin, end);
2100 
2101  bool spaceSkiped = true;
2102  while (begin != end) {
2103  char c = *begin++;
2104  if (is_space(c)) {
2105  spaceSkiped = true;
2106  } else if ((c == '\'' && !is_number(last)) || c == '\"') {
2107  begin--;
2108  auto x = skipString(begin, end);
2109  while (begin < x)
2110  append(*begin++);
2111  } else {
2112  if (spaceSkiped && is_ident_char(last) && is_ident_char(c))
2113  append(' ');
2114  append(c);
2115  spaceSkiped = false;
2116  if (c == '<') {
2117  do {
2118  // template recursion
2119  const char *tpl = skipTemplate(begin, end, true);
2120  normalizeType(begin, tpl, false);
2121  if (tpl == end)
2122  return len;
2123  append(*tpl);
2124  begin = tpl;
2125  } while (*begin++ == ',');
2126  }
2127  }
2128  }
2129  return len;
2130  }
2131 };
2132 
2133 // Normalize the type between begin and end, and store the data in the output. Returns the length.
2134 // The idea is to first run this function with nullptr as output to allocate the output with the
2135 // size
2136 constexpr int qNormalizeType(const char *begin, const char *end, char *output)
2137 {
2138  return QTypeNormalizer { output }.normalizeType(begin, end);
2139 }
2140 
2141 template<typename T>
2142 struct is_std_pair : std::false_type {};
2143 
2144 template <typename T1_, typename T2_>
2145 struct is_std_pair<std::pair<T1_, T2_>> : std::true_type {
2146  using T1 = T1_;
2147  using T2 = T2_;
2148 };
2149 
2150 template<typename T>
2151 constexpr auto typenameHelper()
2152 {
2153  if constexpr (is_std_pair<T>::value) {
2154  using T1 = typename is_std_pair<T>::T1;
2155  using T2 = typename is_std_pair<T>::T2;
2156  std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T1>::IsBuiltIn), typename QMetaTypeId2<T1>::NameAsArrayType, decltype(typenameHelper<T1>())>> t1Name {};
2157  std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T2>::IsBuiltIn), typename QMetaTypeId2<T2>::NameAsArrayType, decltype(typenameHelper<T2>())>> t2Name {};
2158  if constexpr (bool (QMetaTypeId2<T1>::IsBuiltIn) ) {
2160  } else {
2161  t1Name = typenameHelper<T1>();
2162  }
2163  if constexpr (bool(QMetaTypeId2<T2>::IsBuiltIn)) {
2165  } else {
2166  t2Name = typenameHelper<T2>();
2167  }
2168  constexpr auto nonTypeDependentLen = sizeof("std::pair<,>");
2169  constexpr auto t1Len = t1Name.size() - 1;
2170  constexpr auto t2Len = t2Name.size() - 1;
2171  constexpr auto length = nonTypeDependentLen + t1Len + t2Len;
2172  std::array<char, length + 1> result {};
2173  constexpr auto prefix = "std::pair<";
2174  int currentLength = 0;
2175  for (; currentLength < int(sizeof("std::pair<") - 1); ++currentLength)
2176  result[currentLength] = prefix[currentLength];
2177  for (int i = 0; i < int(t1Len); ++currentLength, ++i)
2178  result[currentLength] = t1Name[i];
2179  result[currentLength++] = ',';
2180  for (int i = 0; i < int(t2Len); ++currentLength, ++i)
2181  result[currentLength] = t2Name[i];
2182  result[currentLength++] = '>';
2183  result[currentLength++] = '\0';
2184  return result;
2185  } else {
2186  constexpr auto prefix = sizeof(
2187 #ifdef QT_NAMESPACE
2188  QT_STRINGIFY(QT_NAMESPACE) "::"
2189 #endif
2190 #if defined(Q_CC_MSVC) && defined(Q_CC_CLANG)
2191  "auto __cdecl QtPrivate::typenameHelper(void) [T = "
2192 #elif defined(Q_CC_MSVC)
2193  "auto __cdecl QtPrivate::typenameHelper<"
2194 #elif defined(Q_CC_CLANG)
2195  "auto QtPrivate::typenameHelper() [T = "
2196 #elif defined(Q_CC_GHS)
2197  "auto QtPrivate::typenameHelper<T>()[with T="
2198 #else
2199  "constexpr auto QtPrivate::typenameHelper() [with T = "
2200 #endif
2201  ) - 1;
2202 #if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
2203  constexpr int suffix = sizeof(">(void)");
2204 #else
2205  constexpr int suffix = sizeof("]");
2206 #endif
2207 
2208 #if defined(Q_CC_GNU_ONLY) && Q_CC_GNU_ONLY < 804
2209  auto func = Q_FUNC_INFO;
2210  const char *begin = func + prefix;
2211  const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2212  // This is an upper bound of the size since the normalized signature should always be smaller
2213  constexpr int len = sizeof(Q_FUNC_INFO) - suffix - prefix;
2214 #else
2215  constexpr auto func = Q_FUNC_INFO;
2216  constexpr const char *begin = func + prefix;
2217  constexpr const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2218  constexpr int len = QTypeNormalizer{ nullptr }.normalizeTypeFromSignature(begin, end);
2219 #endif
2220  std::array<char, len + 1> result {};
2222  return result;
2223  }
2224 }
2225 
2226 template<typename T, typename = void>
2227 struct BuiltinMetaType : std::integral_constant<int, 0>
2228 {
2229 };
2230 template<typename T>
2231 struct BuiltinMetaType<T, std::enable_if_t<QMetaTypeId2<T>::IsBuiltIn>>
2232  : std::integral_constant<int, QMetaTypeId2<T>::MetaType>
2233 {
2234 };
2235 
2236 template<typename T, bool = (QTypeTraits::has_operator_equal_v<T> && !std::is_pointer_v<T>)>
2238 {
2241  static bool equals(const QMetaTypeInterface *, const void *a, const void *b)
2242  { return *reinterpret_cast<const T *>(a) == *reinterpret_cast<const T *>(b); }
2244 };
2245 
2246 template<typename T>
2248 {
2249  static constexpr QMetaTypeInterface::EqualsFn equals = nullptr;
2250 };
2251 
2252 template<typename T, bool = (QTypeTraits::has_operator_less_than_v<T> && !std::is_pointer_v<T>)>
2254 {
2255  static bool lessThan(const QMetaTypeInterface *, const void *a, const void *b)
2256  { return *reinterpret_cast<const T *>(a) < *reinterpret_cast<const T *>(b); }
2257 };
2258 
2259 template<typename T>
2261 {
2262  static constexpr QMetaTypeInterface::LessThanFn lessThan = nullptr;
2263 };
2264 
2265 template<typename T, bool = (QTypeTraits::has_ostream_operator_v<QDebug, T> && !std::is_pointer_v<T>)>
2267 {
2268  static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
2269  { dbg << *reinterpret_cast<const T *>(a); }
2270 };
2271 
2272 template<typename T>
2274 {
2275  static constexpr QMetaTypeInterface::DebugStreamFn debugStream = nullptr;
2276 };
2277 
2278 template<typename T, bool = QTypeTraits::has_stream_operator_v<QDataStream, T>>
2280 {
2281  static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
2282  { ds << *reinterpret_cast<const T *>(a); }
2283  static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
2284  { ds >> *reinterpret_cast<T *>(a); }
2285 };
2286 
2287 template<typename T>
2289 {
2290  static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr;
2291  static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
2292 };
2293 
2294 template<typename S>
2296 {
2297 public:
2298  static constexpr decltype(typenameHelper<S>()) name = typenameHelper<S>();
2299 
2300  static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr()
2301  {
2302  if constexpr (std::is_default_constructible_v<S>) {
2303  return [](const QMetaTypeInterface *, void *addr) { new (addr) S(); };
2304  } else {
2305  return nullptr;
2306  }
2307  }
2308 
2310  {
2311  if constexpr (std::is_copy_constructible_v<S>) {
2312  return [](const QMetaTypeInterface *, void *addr, const void *other) {
2313  new (addr) S(*reinterpret_cast<const S *>(other));
2314  };
2315  } else {
2316  return nullptr;
2317  }
2318  }
2319 
2321  {
2322  if constexpr (std::is_move_constructible_v<S>) {
2323  return [](const QMetaTypeInterface *, void *addr, void *other) {
2324  new (addr) S(std::move(*reinterpret_cast<S *>(other)));
2325  };
2326  } else {
2327  return nullptr;
2328  }
2329  }
2330 
2332  {
2333  if constexpr (std::is_destructible_v<S> && !std::is_trivially_destructible_v<S>)
2334  return [](const QMetaTypeInterface *, void *addr) {
2335  reinterpret_cast<S *>(addr)->~S();
2336  };
2337  else
2338  return nullptr;
2339  }
2340 
2342  {
2344  return []() { QMetaTypeId2<S>::qt_metatype_id(); };
2345  } else {
2346  return nullptr;
2347  }
2348  }
2349 
2350  static constexpr const char *getName()
2351  {
2352  if constexpr (bool(QMetaTypeId2<S>::IsBuiltIn)) {
2353  return QMetaTypeId2<S>::nameAsArray.data();
2354  } else {
2355  return name.data();
2356  }
2357  }
2358 };
2359 
2360 template<typename T>
2362 {
2363  static inline constexpr const QMetaTypeInterface metaType = {
2364  /*.revision=*/ 0,
2365  /*.alignment=*/ alignof(T),
2366  /*.size=*/ sizeof(T),
2367  /*.flags=*/ QMetaTypeTypeFlags<T>::Flags,
2368  /*.typeId=*/ BuiltinMetaType<T>::value,
2369  /*.metaObjectFn=*/ MetaObjectForType<T>::metaObjectFunction,
2370  /*.name=*/ QMetaTypeForType<T>::getName(),
2371  /*.defaultCtr=*/ QMetaTypeForType<T>::getDefaultCtr(),
2372  /*.copyCtr=*/ QMetaTypeForType<T>::getCopyCtr(),
2373  /*.moveCtr=*/ QMetaTypeForType<T>::getMoveCtr(),
2374  /*.dtor=*/ QMetaTypeForType<T>::getDtor(),
2380  /*.legacyRegisterOp=*/ QMetaTypeForType<T>::getLegacyRegister()
2381  };
2382 };
2383 
2384 
2385 template<>
2387 {
2388 public:
2389  static constexpr QMetaTypeInterface metaType =
2390  {
2391  /*.revision=*/ 0,
2392  /*.alignment=*/ 0,
2393  /*.size=*/ 0,
2394  /*.flags=*/ 0,
2395  /*.typeId=*/ BuiltinMetaType<void>::value,
2396  /*.metaObjectFn=*/ nullptr,
2397  /*.name=*/ "void",
2398  /*.defaultCtr=*/ nullptr,
2399  /*.copyCtr=*/ nullptr,
2400  /*.moveCtr=*/ nullptr,
2401  /*.dtor=*/ nullptr,
2402  /*.equals=*/ nullptr,
2403  /*.lessThan=*/ nullptr,
2404  /*.debugStream=*/ nullptr,
2405  /*.dataStreamOut=*/ nullptr,
2406  /*.dataStreamIn=*/ nullptr,
2407  /*.legacyRegisterOp=*/ nullptr
2408  };
2409 };
2410 #undef QT_METATYPE_CONSTEXPRLAMDA
2411 
2412 /*
2413  MSVC instantiates extern templates
2414 (https://developercommunity.visualstudio.com/t/c11-extern-templates-doesnt-work-for-class-templat/157868)
2415  */
2416 #if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC)
2417 
2418 #if !defined(QT_BUILD_CORE_LIB)
2419 #define QT_METATYPE_TEMPLATE_EXPORT Q_CORE_EXPORT
2420 #else
2421 #define QT_METATYPE_TEMPLATE_EXPORT
2422 #endif
2423 
2424 #define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \
2425  extern template class QT_METATYPE_TEMPLATE_EXPORT QMetaTypeForType<Name>;
2427 QT_WARNING_DISABLE_GCC("-Wattributes") // false positive because of QMetaTypeForType<void>
2434 #undef QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER
2435 #undef QT_METATYPE_TEMPLATE_EXPORT
2436 #endif
2437 
2438 template<typename T>
2440 {
2441  using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
2443 }
2444 
2445 namespace detail {
2446 template<typename T, typename ODR_VIOLATION_PREVENTER>
2448 {
2449  template<typename U>
2450  static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
2451  static auto check(...) -> std::false_type;
2452  using type = decltype(check(static_cast<T *>(nullptr)));
2453 };
2454 } // namespace detail
2455 
2456 template <typename T, typename ODR_VIOLATION_PREVENTER>
2457 struct is_complete : detail::is_complete_helper<T, ODR_VIOLATION_PREVENTER>::type {};
2458 
2459 template<typename T>
2461 {
2462  using type = std::remove_pointer_t<T>;
2463 };
2464 
2465 #define Q_REMOVE_POINTER_LIKE_IMPL(Pointer) \
2466 template <typename T> \
2467 struct qRemovePointerLike<Pointer<T>> \
2468 { \
2469  using type = T; \
2470 };
2471 
2473 template<typename T>
2475 #undef Q_REMOVE_POINTER_LIKE_IMPL
2476 
2477 template<typename T, typename ForceComplete_>
2479 {
2480  using type = T;
2481  using ForceComplete = ForceComplete_;
2482 };
2483 
2484 template<typename Unique, typename TypeCompletePair>
2486 {
2487  using T = typename TypeCompletePair::type;
2488  using ForceComplete = typename TypeCompletePair::ForceComplete;
2489  using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
2490  using Tz = qRemovePointerLike_t<Ty>;
2492  return nullptr;
2493  } else {
2495  }
2496 }
2497 
2498 } // namespace QtPrivate
2499 
2500 template<typename T>
2502 {
2503  return QMetaType(QtPrivate::qMetaTypeInterfaceForType<T>());
2504 }
2505 
2506 constexpr qsizetype QMetaType::sizeOf() const
2507 {
2508  return d_ptr ? d_ptr->size : 0;
2509 }
2510 
2512 {
2513  return d_ptr ? d_ptr->alignment : 0;
2514 }
2515 
2516 constexpr QMetaType::TypeFlags QMetaType::flags() const
2517 {
2518  return d_ptr ? TypeFlags(d_ptr->flags) : TypeFlags{};
2519 }
2520 
2521 constexpr const QMetaObject *QMetaType::metaObject() const
2522 {
2523  return d_ptr && d_ptr->metaObjectFn ? d_ptr->metaObjectFn(d_ptr) : nullptr;
2524 }
2525 
2526 template<typename... T>
2528  QtPrivate::qMetaTypeInterfaceForType<T>()...
2529 };
2530 
2531 constexpr const char *QMetaType::name() const
2532 {
2533  return d_ptr ? d_ptr->name : nullptr;
2534 }
2535 
2536 template<typename Unique,typename... T>
2538  QtPrivate::qTryMetaTypeInterfaceForType<Unique, T>()...
2539 };
2540 
2542 
2544  QPairVariantInterfaceImpl, Q_CORE_EXPORT)
2545 
2546 #endif // QMETATYPE_H
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
sizeof(AF_ModuleRec)
#define value
[5]
@ Float
@ Double
T loadAcquire() const noexcept
Definition: qbasicatomic.h:93
void storeRelease(T newValue) noexcept
Definition: qbasicatomic.h:94
The QBitArray class provides an array of bits.
Definition: qbitarray.h:49
The QBitmap class provides monochrome (1-bit depth) pixmaps.
Definition: qbitmap.h:52
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:66
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
const char * constData() const noexcept
Definition: qbytearray.h:144
The QByteArrayList class provides a list of byte arrays.
The QCborArray class is used to hold an array of CBOR elements.
Definition: qcborarray.h:56
The QCborMap class is used to hold an associative container representable in CBOR.
Definition: qcbormap.h:57
The QCborValue class encapsulates a value in CBOR.
Definition: qcborvalue.h:86
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
The QColorSpace class provides a color space abstraction.
Definition: qcolorspace.h:57
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition: qcursor.h:81
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
The QDate class provides date functions.
Definition: qdatetime.h:64
The QDateTime class provides date and time functions.
Definition: qdatetime.h:238
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
The QEasingCurve class provides easing curves for controlling animation.
Definition: qeasingcurve.h:55
The QFlags class provides a type-safe way of storing OR-combinations of enum values.
Definition: qflags.h:89
The QFont class specifies a query for a font used for drawing text.
Definition: qfont.h:56
The QIcon class provides scalable icons in different modes and states.
Definition: qicon.h:56
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
The QJsonArray class encapsulates a JSON array.
Definition: qjsonarray.h:54
The QJsonDocument class provides a way to read and write JSON documents.
Definition: qjsondocument.h:83
The QJsonObject class encapsulates a JSON object.
Definition: qjsonobject.h:56
The QJsonValue class encapsulates a value in JSON.
Definition: qjsonvalue.h:60
The QKeySequence class encapsulates a key sequence as used by shortcuts.
Definition: qkeysequence.h:71
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:215
The QLine class provides a two-dimensional vector using integer precision.
Definition: qline.h:53
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition: qmatrix4x4.h:61
The QMetaType class manages named types in the meta-object system.
Definition: qmetatype.h:328
void destruct(void *data) const
Definition: qmetatype.cpp:705
const QtPrivate::QMetaTypeInterface * iface() const
Definition: qmetatype.h:740
constexpr TypeFlags flags() const
Definition: qmetatype.h:2516
static bool hasRegisteredConverterFunction()
Definition: qmetatype.h:706
static bool registerMutableView(UnaryFunction function)
Definition: qmetatype.h:622
constexpr qsizetype sizeOf() const
Definition: qmetatype.h:2506
constexpr qsizetype alignOf() const
Definition: qmetatype.h:2511
bool debugStream(QDebug &dbg, const void *rhs)
Definition: qmetatype.cpp:1746
static QMetaType fromName(QByteArrayView name)
Definition: qmetatype.cpp:2789
static bool hasRegisteredMutableViewFunction()
Definition: qmetatype.h:715
static bool registerConverter(To(From::*function)() const)
Definition: qmetatype.h:547
int qMetaTypeId()
Definition: qmetatype.h:1302
void destroy(void *data) const
Definition: qmetatype.cpp:639
int id(int=0) const
Definition: qmetatype.h:453
static void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type)
Definition: qmetatype.cpp:2600
std::function< bool(void *src, void *target)> MutableViewFunction
Definition: qmetatype.h:536
friend bool operator==(QMetaType a, QMetaType b)
Definition: qmetatype.h:499
@ SharedPointerToQObject
Definition: qmetatype.h:394
@ NeedsDestruction
Definition: qmetatype.h:387
@ WeakPointerToQObject
Definition: qmetatype.h:395
@ IsUnsignedEnumeration
Definition: qmetatype.h:397
@ PointerToQObject
Definition: qmetatype.h:392
@ IsEnumeration
Definition: qmetatype.h:393
@ TrackingPointerToQObject
Definition: qmetatype.h:396
@ RelocatableType
Definition: qmetatype.h:388
@ NeedsConstruction
Definition: qmetatype.h:386
@ PointerToGadget
Definition: qmetatype.h:399
void * create(const void *copy=nullptr) const
Definition: qmetatype.cpp:616
std::function< bool(const void *src, void *target)> ConverterFunction
Definition: qmetatype.h:533
friend bool operator!=(QMetaType a, QMetaType b)
Definition: qmetatype.h:510
static bool registerConverter(To(From::*function)(bool *) const)
Definition: qmetatype.h:583
constexpr const QMetaObject * metaObject() const
Definition: qmetatype.h:2521
static bool registerConverter()
Definition: qmetatype.h:540
constexpr QMetaType(const QtPrivate::QMetaTypeInterface *d)
Definition: qmetatype.h:443
constexpr const char * name() const
Definition: qmetatype.h:2531
static bool registerConverter(UnaryFunction function)
Definition: qmetatype.h:604
void * construct(void *where, const void *copy=nullptr) const
Definition: qmetatype.cpp:678
bool load(QDataStream &stream, void *data) const
Definition: qmetatype.cpp:2740
constexpr QMetaType()=default
bool save(QDataStream &stream, const void *data) const
Definition: qmetatype.cpp:2699
constexpr static QMetaType fromType()
bool hasRegisteredDebugStreamOperator() const
Definition: qmetatype.cpp:1788
static bool registerMutableView(To(From::*function)())
Definition: qmetatype.h:565
The QModelIndex class is used to locate data in a data model.
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:55
static const QPartialOrdering Less
Definition: qcompare.h:75
static const QPartialOrdering Equivalent
Definition: qcompare.h:76
static const QPartialOrdering Unordered
Definition: qcompare.h:78
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:61
The QPersistentModelIndex class is used to locate data in a data model.
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QPointer class is a template class that provides guarded pointers to QObject.
Definition: qpointer.h:54
The QPolygonF class provides a list of points using floating point precision. \inmodule QtGui.
Definition: qpolygon.h:128
The QPolygon class provides a list of points using integer precision. \inmodule QtGui.
Definition: qpolygon.h:57
The QQuaternion class represents a quaternion consisting of a vector and scalar.
Definition: qquaternion.h:57
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:63
The QRegularExpression class provides pattern matching using regular expressions.
The QSharedPointer class holds a strong reference to a shared pointer.
The QSizeF class defines the size of a two-dimensional object using floating point precision.
Definition: qsize.h:235
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition: qsizepolicy.h:54
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QStringList class provides a list of strings.
The QTextFormat class provides formatting information for a QTextDocument. \inmodule QtGui.
Definition: qtextformat.h:126
The QTextLength class encapsulates the different types of length used in a QTextDocument....
Definition: qtextformat.h:81
The QTime class provides clock time functions.
Definition: qdatetime.h:166
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:56
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:130
The QUuid class stores a Universally Unique Identifier (UUID).
Definition: quuid.h:67
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
The QVector2D class represents a vector or vertex in 2D space.
Definition: qvectornd.h:62
The QVector3D class represents a vector or vertex in 3D space.
Definition: qvectornd.h:205
The QVector4D class represents a vector or vertex in 4D space.
Definition: qvectornd.h:369
The QWeakPointer class holds a weak reference to a shared pointer.
static void getSecondImpl(const void *const *pair, void *dataPtr)
Definition: qmetatype.h:776
static void getFirstImpl(const void *const *pair, void *dataPtr)
Definition: qmetatype.h:773
static constexpr QMetaTypeInterface::DtorFn getDtor()
Definition: qmetatype.h:2331
static constexpr QMetaTypeInterface::CopyCtrFn getCopyCtr()
Definition: qmetatype.h:2309
static constexpr QMetaTypeInterface::LegacyRegisterOp getLegacyRegister()
Definition: qmetatype.h:2341
static constexpr const char * getName()
Definition: qmetatype.h:2350
static constexpr QMetaTypeInterface::MoveCtrFn getMoveCtr()
Definition: qmetatype.h:2320
void(*)(const QMetaTypeInterface *, void *) DefaultCtrFn
Definition: qmetatype.h:276
void(*)(const QMetaTypeInterface *, void *, const void *) CopyCtrFn
Definition: qmetatype.h:278
DataStreamOutFn dataStreamOut
Definition: qmetatype.h:291
void(*)(const QMetaTypeInterface *, QDataStream &, const void *) DataStreamOutFn
Definition: qmetatype.h:290
void(*)(const QMetaTypeInterface *, QDataStream &, void *) DataStreamInFn
Definition: qmetatype.h:292
void(*)(const QMetaTypeInterface *, void *, void *) MoveCtrFn
Definition: qmetatype.h:280
DataStreamInFn dataStreamIn
Definition: qmetatype.h:293
const QMetaObject *(*)(const QMetaTypeInterface *) MetaObjectFn
Definition: qmetatype.h:271
void(*)(const QMetaTypeInterface *, void *) DtorFn
Definition: qmetatype.h:282
bool(*)(const QMetaTypeInterface *, const void *, const void *) LessThanFn
Definition: qmetatype.h:286
LegacyRegisterOp legacyRegisterOp
Definition: qmetatype.h:296
void(*)(const QMetaTypeInterface *, QDebug &, const void *) DebugStreamFn
Definition: qmetatype.h:288
bool(*)(const QMetaTypeInterface *, const void *, const void *) EqualsFn
Definition: qmetatype.h:284
[user-class]
Definition: user.h:59
#define T(x)
Definition: main.cpp:42
QMap< QString, QString > map
[6]
p1 load("image.bmp")
list append(new Employee("Blackpool", "Stephen"))
double e
#define true
Definition: ftrandom.c:51
unsigned short UShort
Definition: ftraster.c:310
long Long
Definition: ftraster.c:311
char Bool
Definition: ftraster.c:315
unsigned long ULong
Definition: ftraster.c:312
int Int
Definition: ftraster.c:307
unsigned int UInt
Definition: ftraster.c:308
short Short
Definition: ftraster.c:309
bool is_ident_char(char s)
auto it unsigned count const
Definition: hb-iter.hh:848
Token token
Definition: keywords.cpp:453
#define inline
Definition: md4c.c:45
#define S(cp)
HBUINT16 Value
const wchar_t * getName(QSslKeyPrivate::Cipher cipher)
typename qRemovePointerLike< T >::type qRemovePointerLike_t
Definition: qmetatype.h:2474
constexpr auto typenameHelper()
Definition: qmetatype.h:2151
constexpr bool IsQmlListType
Definition: qmetatype.h:1171
constexpr int qNormalizeType(const char *begin, const char *end, char *output)
Definition: qmetatype.h:2136
constexpr const QMetaTypeInterface * qTryMetaTypeInterfaceForType()
Definition: qmetatype.h:2485
constexpr bool IsUnsignedEnum
Definition: qmetatype.h:1174
constexpr const QMetaTypeInterface * qMetaTypeInterfaceForType()
constexpr bool IsUnsignedEnum< T, true >
Definition: qmetatype.h:1176
To convertImplicit(const From &from)
Definition: qmetatype.h:304
QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wattributes") QT_WARNING_POP template< typename T > const expr const QMetaTypeInterface *qMetaTypeInterfaceForType()
Definition: qmetatype.h:2427
char qt_getEnumMetaObject(const T &)
Definition: qfloat16.h:381
PCRE2_SIZE PRIV() strlen(PCRE2_SPTR str)
void
Definition: png.h:1080
#define Q_BASIC_ATOMIC_INITIALIZER(a)
QCborSimpleType
Definition: qcborcommon.h:59
#define Q_FALLTHROUGH()
#define Q_DECL_ENUMERATOR_DEPRECATED_X(x)
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_FLOAT_COMPARE
#define Q_FUNC_INFO
#define QT_WARNING_PUSH
QPair< QVariant, QVariant > QVariantPair
Definition: qcontainerfwd.h:77
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
EGLStreamKHR stream
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition: qflags.h:210
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition: qflags.h:227
Flags
#define QT_STRINGIFY(x)
Definition: qglobal.h:131
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
ptrdiff_t qsizetype
Definition: qglobal.h:308
unsigned int uint
Definition: qglobal.h:334
long long qint64
Definition: qglobal.h:298
#define QT_DEPRECATED_VERSION_6_0
Definition: qglobal.h:445
unsigned short ushort
Definition: qglobal.h:333
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition: qglobal.h:283
unsigned char quint8
Definition: qglobal.h:284
const char * typeName
Definition: qmetatype.cpp:869
constexpr int qMetaTypeId()
Definition: qmetatype.h:1302
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(SINGLE_ARG_TEMPLATE)
Definition: qmetatype.h:1586
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
Definition: qmetatype.h:1268
#define Q_REMOVE_POINTER_LIKE_IMPL(Pointer)
Definition: qmetatype.h:2465
#define QT_FOR_EACH_STATIC_GUI_CLASS(F)
Definition: qmetatype.h:176
constexpr const QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray[]
Definition: qmetatype.h:2537
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME)
Definition: qmetatype.h:1598
#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)
Definition: qmetatype.h:202
#define QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TAG, EXPORT)
Definition: qmetatype.h:1273
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)
Definition: qmetatype.h:158
int qRegisterMetaType(const char *typeName)
Definition: qmetatype.h:1291
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F)
Definition: qmetatype.h:251
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE)
Definition: qmetatype.h:1492
#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name)
Definition: qmetatype.h:817
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)
Definition: qmetatype.h:81
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F)
Definition: qmetatype.h:240
#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
Definition: qmetatype.h:161
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)
Definition: qmetatype.h:102
#define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME)
Definition: qmetatype.h:1444
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME)
Definition: qmetatype.h:1628
#define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name)
Definition: qmetatype.h:1455
constexpr const QtPrivate::QMetaTypeInterface *const qt_metaTypeArray[]
Definition: qmetatype.h:2527
#define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F)
Definition: qmetatype.h:752
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)
Definition: qmetatype.h:127
#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME)
Definition: qmetatype.h:1610
#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name)
Definition: qmetatype.h:237
int qRegisterNormalizedMetaTypeImplementation(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
Definition: qmetatype.h:1229
#define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name)
Definition: qmetatype.h:2424
#define QT_FOR_EACH_STATIC_TYPE(F)
Definition: qmetatype.h:228
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLenum GLuint id
[6]
Definition: qopengl.h:270
GLenum type
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLfloat GLfloat f
GLenum src
GLenum target
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLenum func
Definition: qopenglext.h:663
const GLubyte * c
Definition: qopenglext.h:12701
GLenum GLsizei len
Definition: qopenglext.h:3292
GLenum const void * addr
Definition: qopenglext.h:8875
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
#define Q_ASSERT_X(cond, x, msg)
Definition: qrandom.cpp:85
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition: qscopeguard.h:93
int QT_PREPEND_NAMESPACE(QSharedMemoryPrivate)
QT_BEGIN_NAMESPACE typedef char Char
@ Q_RELOCATABLE_TYPE
Definition: qtypeinfo.h:156
Q_UNUSED(salary)
[21]
HB_EXTERN hb_font_get_glyph_func_t void hb_destroy_func_t destroy
bool isBuiltinType(const QByteArray &type)
Definition: generator.cpp:63
bool is_space(char s)
Definition: utils.h:41
QList< int > vector
[14]
obj metaObject() -> className()
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QQuickView * view
[0]
view create()
QStringList list
[0]
Definition: main.cpp:58
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:165
static QByteArray normalizedType(const char *type)
void NameAsArrayType
Definition: qmetatype.h:1144
static constexpr int qt_metatype_id()
Definition: qmetatype.h:1146
QPairVariantInterfaceImpl operator()(const std::pair< T, U > &f) const
Definition: qmetatype.h:807
static T * internalData(const QWeakPointer< T > &p) noexcept
static bool registerConverter()
Definition: qmetatype.h:1081
static bool registerConverter()
Definition: qmetatype.h:1096
static yes_type checkType(const QObject *)
static const T & declval()
static constexpr const QMetaObject * metaObjectFunction(const QMetaTypeInterface *)
Definition: qmetatype.h:947
static constexpr const QMetaObject * value()
Definition: qmetatype.h:918
const QMetaObject *(*)(const QMetaTypeInterface *) MetaObjectFn
Definition: qmetatype.h:919
static constexpr const QMetaObject * value()
Definition: qmetatype.h:910
const QMetaObject *(*)(const QMetaTypeInterface *) MetaObjectFn
Definition: qmetatype.h:911
QIterable< QMetaAssociation > operator()(const From &f) const
Definition: qmetatype.h:1702
QIterable< QMetaAssociation > operator()(From &f) const
Definition: qmetatype.h:1711
static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
Definition: qmetatype.h:2283
static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
Definition: qmetatype.h:2281
static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
Definition: qmetatype.h:2268
QT_WARNING_PUSH static QT_WARNING_DISABLE_FLOAT_COMPARE bool equals(const QMetaTypeInterface *, const void *a, const void *b)
Definition: qmetatype.h:2241
static bool lessThan(const QMetaTypeInterface *, const void *a, const void *b)
Definition: qmetatype.h:2255
static constexpr int qt_metatype_id()
Definition: qmetatype.h:1162
static constexpr int qt_metatype_id()
Definition: qmetatype.h:1158
QIterable< QMetaSequence > operator()(const From &f) const
Definition: qmetatype.h:1660
QIterable< QMetaSequence > operator()(From &f) const
Definition: qmetatype.h:1669
QObject * operator()(const QWeakPointer< T > &p) const
Definition: qmetatype.h:1221
QObject * operator()(const SmartPointer &p) const
Definition: qmetatype.h:1207
constexpr int normalizeType(const char *begin, const char *end, bool adjustConst=true)
Definition: qmetatype.h:2002
constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
Definition: qmetatype.h:1998
static auto check(...) -> std::false_type
static auto check(U *) -> std::integral_constant< bool, sizeof(U) !=0 >
decltype(check(static_cast< T * >(nullptr))) type
Definition: qmetatype.h:2452
std::remove_pointer_t< T > type
Definition: qmetatype.h:2462
Definition: main.cpp:38
Definition: moc.h:48
void compare(Input input, FnUnderTest fn_under_test, const QByteArray &output)
bool hasRegisteredConverterFunction()
U convert(const T &t)
Enum
#define rhs