1 /**************************************************************************** 2 ** 3 ** DQt - D bindings for the Qt Toolkit 4 ** 5 ** GNU Lesser General Public License Usage 6 ** This file may be used under the terms of the GNU Lesser 7 ** General Public License version 3 as published by the Free Software 8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 9 ** packaging of this file. Please review the following information to 10 ** ensure the GNU Lesser General Public License version 3 requirements 11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 12 ** 13 ****************************************************************************/ 14 module qt.core.metatype; 15 extern(C++): 16 17 import qt.config; 18 import qt.core.bytearray; 19 import qt.core.datastream; 20 import qt.core.flags; 21 import qt.core.global; 22 import qt.core.list; 23 import qt.core.metatype; 24 import qt.core.object; 25 import qt.core.objectdefs; 26 import qt.core.variant; 27 import qt.helpers; 28 29 /+ #ifndef QT_NO_QOBJECT 30 #endif 31 #ifdef Bool 32 #error qmetatype.h must be included before any header file that defines Bool 33 #endif 34 35 36 // from qcborcommon.h 37 enum class QCborSimpleType : quint8; 38 39 template <typename T> 40 struct QMetaTypeId2; 41 42 template <typename T> 43 inline int qMetaTypeId(); 44 45 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType) 46 // ### Qt6: reorder the types to match the C++ integral type ranking 47 #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\ 48 F(Void, 43, void) \ 49 F(Bool, 1, bool) \ 50 F(Int, 2, int) \ 51 F(UInt, 3, uint) \ 52 F(LongLong, 4, qlonglong) \ 53 F(ULongLong, 5, qulonglong) \ 54 F(Double, 6, double) \ 55 F(Long, 32, long) \ 56 F(Short, 33, short) \ 57 F(Char, 34, char) \ 58 F(ULong, 35, ulong) \ 59 F(UShort, 36, ushort) \ 60 F(UChar, 37, uchar) \ 61 F(Float, 38, float) \ 62 F(SChar, 40, signed char) \ 63 F(Nullptr, 51, std::nullptr_t) \ 64 F(QCborSimpleType, 52, QCborSimpleType) \ 65 66 #define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\ 67 F(VoidStar, 31, void*) \ 68 69 #if QT_CONFIG(easingcurve) 70 #define QT_FOR_EACH_STATIC_EASINGCURVE(F)\ 71 F(QEasingCurve, 29, QEasingCurve) 72 #else 73 #define QT_FOR_EACH_STATIC_EASINGCURVE(F) 74 #endif 75 76 #if QT_CONFIG(itemmodel) 77 #define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)\ 78 F(QModelIndex, 42, QModelIndex) \ 79 F(QPersistentModelIndex, 50, QPersistentModelIndex) 80 #else 81 #define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F) 82 #endif 83 84 #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\ 85 F(QChar, 7, QChar) \ 86 F(QString, 10, QString) \ 87 F(QStringList, 11, QStringList) \ 88 F(QByteArray, 12, QByteArray) \ 89 F(QBitArray, 13, QBitArray) \ 90 F(QDate, 14, QDate) \ 91 F(QTime, 15, QTime) \ 92 F(QDateTime, 16, QDateTime) \ 93 F(QUrl, 17, QUrl) \ 94 F(QLocale, 18, QLocale) \ 95 F(QRect, 19, QRect) \ 96 F(QRectF, 20, QRectF) \ 97 F(QSize, 21, QSize) \ 98 F(QSizeF, 22, QSizeF) \ 99 F(QLine, 23, QLine) \ 100 F(QLineF, 24, QLineF) \ 101 F(QPoint, 25, QPoint) \ 102 F(QPointF, 26, QPointF) \ 103 F(QRegExp, 27, QRegExp) \ 104 QT_FOR_EACH_STATIC_EASINGCURVE(F) \ 105 F(QUuid, 30, QUuid) \ 106 F(QVariant, 41, QVariant) \ 107 F(QRegularExpression, 44, QRegularExpression) \ 108 F(QJsonValue, 45, QJsonValue) \ 109 F(QJsonObject, 46, QJsonObject) \ 110 F(QJsonArray, 47, QJsonArray) \ 111 F(QJsonDocument, 48, QJsonDocument) \ 112 F(QCborValue, 53, QCborValue) \ 113 F(QCborArray, 54, QCborArray) \ 114 F(QCborMap, 55, QCborMap) \ 115 QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F) 116 117 #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\ 118 F(QObjectStar, 39, QObject*) 119 120 #define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\ 121 F(QVariantMap, 8, QVariantMap) \ 122 F(QVariantList, 9, QVariantList) \ 123 F(QVariantHash, 28, QVariantHash) \ 124 F(QByteArrayList, 49, QByteArrayList) \ 125 126 #define QT_FOR_EACH_STATIC_GUI_CLASS(F)\ 127 F(QFont, 64, QFont) \ 128 F(QPixmap, 65, QPixmap) \ 129 F(QBrush, 66, QBrush) \ 130 F(QColor, 67, QColor) \ 131 F(QPalette, 68, QPalette) \ 132 F(QIcon, 69, QIcon) \ 133 F(QImage, 70, QImage) \ 134 F(QPolygon, 71, QPolygon) \ 135 F(QRegion, 72, QRegion) \ 136 F(QBitmap, 73, QBitmap) \ 137 F(QCursor, 74, QCursor) \ 138 F(QKeySequence, 75, QKeySequence) \ 139 F(QPen, 76, QPen) \ 140 F(QTextLength, 77, QTextLength) \ 141 F(QTextFormat, 78, QTextFormat) \ 142 F(QMatrix, 79, QMatrix) \ 143 F(QTransform, 80, QTransform) \ 144 F(QMatrix4x4, 81, QMatrix4x4) \ 145 F(QVector2D, 82, QVector2D) \ 146 F(QVector3D, 83, QVector3D) \ 147 F(QVector4D, 84, QVector4D) \ 148 F(QQuaternion, 85, QQuaternion) \ 149 F(QPolygonF, 86, QPolygonF) \ 150 F(QColorSpace, 87, QColorSpace) \ 151 152 153 #define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\ 154 F(QSizePolicy, 121, QSizePolicy) \ 155 156 // ### FIXME kill that set 157 #define QT_FOR_EACH_STATIC_HACKS_TYPE(F)\ 158 F(QMetaTypeId2<qreal>::MetaType, -1, qreal) 159 160 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType") 161 #define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\ 162 F(ULong, -1, ulong, "unsigned long") \ 163 F(UInt, -1, uint, "unsigned int") \ 164 F(UShort, -1, ushort, "unsigned short") \ 165 F(UChar, -1, uchar, "unsigned char") \ 166 F(LongLong, -1, qlonglong, "long long") \ 167 F(ULongLong, -1, qulonglong, "unsigned long long") \ 168 F(SChar, -1, signed char, "qint8") \ 169 F(UChar, -1, uchar, "quint8") \ 170 F(Short, -1, short, "qint16") \ 171 F(UShort, -1, ushort, "quint16") \ 172 F(Int, -1, int, "qint32") \ 173 F(UInt, -1, uint, "quint32") \ 174 F(LongLong, -1, qlonglong, "qint64") \ 175 F(ULongLong, -1, qulonglong, "quint64") \ 176 F(QVariantList, -1, QVariantList, "QList<QVariant>") \ 177 F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \ 178 F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \ 179 F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \ 180 181 #define QT_FOR_EACH_STATIC_TYPE(F)\ 182 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\ 183 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\ 184 QT_FOR_EACH_STATIC_CORE_CLASS(F)\ 185 QT_FOR_EACH_STATIC_CORE_POINTER(F)\ 186 QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\ 187 QT_FOR_EACH_STATIC_GUI_CLASS(F)\ 188 QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\ 189 190 #define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \ 191 TypeName = Id, 192 193 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \ 194 F(QList) \ 195 F(QVector) \ 196 F(QQueue) \ 197 F(QStack) \ 198 F(QSet) \ 199 /*end*/ 200 201 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \ 202 F(QHash, class) \ 203 F(QMap, class) \ 204 F(QPair, struct) 205 206 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \ 207 F(QSharedPointer) \ 208 F(QWeakPointer) \ 209 F(QPointer) 210 211 class QDataStream; +/ 212 extern(C++, class) struct QMetaTypeInterface; 213 /+ struct QMetaObject; +/ 214 215 extern(C++, "QtPrivate") 216 { 217 /*! 218 This template is used for implicit conversion from type From to type To. 219 \internal 220 */ 221 To convertImplicit(From, To)(ref const(From) from) 222 { 223 return from; 224 } 225 226 /+ #ifndef QT_NO_DEBUG_STREAM 227 struct AbstractDebugStreamFunction 228 { 229 typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *); 230 typedef void (*Destroy)(AbstractDebugStreamFunction *); 231 explicit AbstractDebugStreamFunction(Stream s = nullptr, Destroy d = nullptr) 232 : stream(s), destroy(d) {} 233 Q_DISABLE_COPY(AbstractDebugStreamFunction) 234 Stream stream; 235 Destroy destroy; 236 }; 237 238 template<typename T> 239 struct BuiltInDebugStreamFunction : public AbstractDebugStreamFunction 240 { 241 BuiltInDebugStreamFunction() 242 : AbstractDebugStreamFunction(stream, destroy) {} 243 static void stream(const AbstractDebugStreamFunction *, QDebug& dbg, const void *r) 244 { 245 const T *rhs = static_cast<const T *>(r); 246 operator<<(dbg, *rhs); 247 } 248 249 static void destroy(AbstractDebugStreamFunction *_this) 250 { 251 delete static_cast<BuiltInDebugStreamFunction *>(_this); 252 } 253 }; 254 #endif +/ 255 256 struct AbstractComparatorFunction 257 { 258 alias LessThan = ExternCPPFunc!(bool function(const(AbstractComparatorFunction)* , const(void)* , const(void)* )); 259 alias Equals = ExternCPPFunc!(bool function(const(AbstractComparatorFunction)* , const(void)* , const(void)* )); 260 alias Destroy = ExternCPPFunc!(void function(AbstractComparatorFunction* )); 261 @disable this(); 262 /+ explicit +/this(LessThan lt/+ = null+/, Equals e = null, Destroy d = null) 263 { 264 this.lessThan = lt; 265 this.equals = e; 266 this.destroy = d; 267 } 268 /+ Q_DISABLE_COPY(AbstractComparatorFunction) +/ 269 @disable this(this); 270 /+this(ref const(AbstractComparatorFunction));+//+ref AbstractComparatorFunction operator =(ref const(AbstractComparatorFunction));+/ LessThan lessThan; 271 Equals equals; 272 Destroy destroy; 273 } 274 275 struct BuiltInComparatorFunction(T) 276 { 277 public AbstractComparatorFunction base0; 278 alias base0 this; 279 @disable this(); 280 /+this() 281 { 282 this.base0 = AbstractComparatorFunction(lessThan, equals, destroy); 283 }+/ 284 static bool lessThan(const(AbstractComparatorFunction)* , const(void)* l, const(void)* r) 285 { 286 const(T)* lhs = static_cast!(const(T)*)(l); 287 const(T)* rhs = static_cast!(const(T)*)(r); 288 return *lhs < *rhs; 289 } 290 291 static bool equals(const(AbstractComparatorFunction)* , const(void)* l, const(void)* r) 292 { 293 const(T)* lhs = static_cast!(const(T)*)(l); 294 const(T)* rhs = static_cast!(const(T)*)(r); 295 return *lhs == *rhs; 296 } 297 298 static void destroy(AbstractComparatorFunction* _this) 299 { 300 import core.stdcpp.new_; 301 302 cpp_delete(static_cast!(BuiltInComparatorFunction*)(_this)); 303 } 304 } 305 306 struct BuiltInEqualsComparatorFunction(T) 307 { 308 public AbstractComparatorFunction base0; 309 alias base0 this; 310 @disable this(); 311 /+this() 312 { 313 this.base0 = AbstractComparatorFunction(null, equals, destroy); 314 }+/ 315 static bool equals(const(AbstractComparatorFunction)* , const(void)* l, const(void)* r) 316 { 317 const(T)* lhs = static_cast!(const(T)*)(l); 318 const(T)* rhs = static_cast!(const(T)*)(r); 319 return *lhs == *rhs; 320 } 321 322 static void destroy(AbstractComparatorFunction* _this) 323 { 324 import core.stdcpp.new_; 325 326 cpp_delete(static_cast!(BuiltInEqualsComparatorFunction*)(_this)); 327 } 328 } 329 330 struct AbstractConverterFunction 331 { 332 alias Converter = ExternCPPFunc!(bool function(const(AbstractConverterFunction)* , const(void)* , void*)); 333 @disable this(); 334 /+ explicit +/this(Converter c/+ = null+/) 335 { 336 this.convert = c; 337 } 338 /+ Q_DISABLE_COPY(AbstractConverterFunction) +/ 339 @disable this(this); 340 /+this(ref const(AbstractConverterFunction));+//+ref AbstractConverterFunction operator =(ref const(AbstractConverterFunction));+/ Converter convert; 341 } 342 343 /+ template<typename From, typename To> 344 struct ConverterMemberFunction : public AbstractConverterFunction 345 { 346 explicit ConverterMemberFunction(To(From::*function)() const) 347 : AbstractConverterFunction(convert), 348 m_function(function) {} 349 ~ConverterMemberFunction(); 350 static bool convert(const AbstractConverterFunction *_this, const void *in, void *out) 351 { 352 const From *f = static_cast<const From *>(in); 353 To *t = static_cast<To *>(out); 354 const ConverterMemberFunction *_typedThis = 355 static_cast<const ConverterMemberFunction *>(_this); 356 *t = (f->*_typedThis->m_function)(); 357 return true; 358 } 359 360 To(From::* const m_function)() const; 361 }; 362 363 template<typename From, typename To> 364 struct ConverterMemberFunctionOk : public AbstractConverterFunction 365 { 366 explicit ConverterMemberFunctionOk(To(From::*function)(bool *) const) 367 : AbstractConverterFunction(convert), 368 m_function(function) {} 369 ~ConverterMemberFunctionOk(); 370 static bool convert(const AbstractConverterFunction *_this, const void *in, void *out) 371 { 372 const From *f = static_cast<const From *>(in); 373 To *t = static_cast<To *>(out); 374 bool ok = false; 375 const ConverterMemberFunctionOk *_typedThis = 376 static_cast<const ConverterMemberFunctionOk *>(_this); 377 *t = (f->*_typedThis->m_function)(&ok); 378 if (!ok) 379 *t = To(); 380 return ok; 381 } 382 383 To(From::* const m_function)(bool*) const; 384 }; 385 386 template<typename From, typename To, typename UnaryFunction> 387 struct ConverterFunctor : public AbstractConverterFunction 388 { 389 explicit ConverterFunctor(UnaryFunction function) 390 : AbstractConverterFunction(convert), 391 m_function(function) {} 392 ~ConverterFunctor(); 393 static bool convert(const AbstractConverterFunction *_this, const void *in, void *out) 394 { 395 const From *f = static_cast<const From *>(in); 396 To *t = static_cast<To *>(out); 397 const ConverterFunctor *_typedThis = 398 static_cast<const ConverterFunctor *>(_this); 399 *t = _typedThis->m_function(*f); 400 return true; 401 } 402 403 UnaryFunction m_function; 404 }; 405 406 template<typename T, bool> 407 struct ValueTypeIsMetaType; 408 template<typename T, bool> 409 struct AssociativeValueTypeIsMetaType; 410 template<typename T, bool> 411 struct IsMetaTypePair; 412 template<typename, typename> 413 struct MetaTypeSmartPointerHelper; +/ 414 } 415 416 extern(C++, class) struct /+ Q_CORE_EXPORT +/ QMetaType { 417 private: 418 enum ExtensionFlag { NoExtensionFlags, 419 CreateEx = 0x1, DestroyEx = 0x2, 420 ConstructEx = 0x4, DestructEx = 0x8, 421 NameEx = 0x10, SizeEx = 0x20, 422 CtorEx = 0x40, DtorEx = 0x80, 423 FlagsEx = 0x100, MetaObjectEx = 0x200 424 } 425 public: 426 /+ #ifndef Q_CLANG_QDOC +/ 427 // The code that actually gets compiled. 428 enum Type { 429 // these are merged with QVariant 430 /+ QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID) +/ 431 Void=43,Bool=1,Int=2,UInt=3,LongLong=4,ULongLong=5,Double=6,Long=32,Short=33,Char=34,ULong=35,UShort=36,UChar=37,Float=38,SChar=40,Nullptr=51,QCborSimpleType=52,VoidStar=31,QChar=7,QString=10,QStringList=11,QByteArray=12,QBitArray=13,QDate=14,QTime=15,QDateTime=16,QUrl=17,QLocale=18,QRect=19,QRectF=20,QSize=21,QSizeF=22,QLine=23,QLineF=24,QPoint=25,QPointF=26,QRegExp=27,QEasingCurve=29,QUuid=30,QVariant=41,QRegularExpression=44,QJsonValue=45,QJsonObject=46,QJsonArray=47,QJsonDocument=48,QCborValue=53,QCborArray=54,QCborMap=55,QModelIndex=42,QPersistentModelIndex=50,QObjectStar=39,QVariantMap=8,QVariantList=9,QVariantHash=28,QByteArrayList=49,QFont=64,QPixmap=65,QBrush=66,QColor=67,QPalette=68,QIcon=69,QImage=70,QPolygon=71,QRegion=72,QBitmap=73,QCursor=74,QKeySequence=75,QPen=76,QTextLength=77,QTextFormat=78,QMatrix=79,QTransform=80,QMatrix4x4=81,QVector2D=82,QVector3D=83,QVector4D=84,QQuaternion=85,QPolygonF=86,QColorSpace=87,QSizePolicy=121, 432 FirstCoreType = Type.Bool, 433 LastCoreType = Type.QCborMap, 434 FirstGuiType = Type.QFont, 435 LastGuiType = Type.QColorSpace, 436 FirstWidgetsType = Type.QSizePolicy, 437 LastWidgetsType = Type.QSizePolicy, 438 HighestInternalId = Type.LastWidgetsType, 439 440 QReal = qreal.sizeof == double.sizeof ? Type.Double : Type.Float, 441 442 UnknownType = 0, 443 User = 1024 444 } 445 /+ #else 446 // If we are using QDoc it fakes the Type enum looks like this. 447 enum Type { 448 UnknownType = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5, 449 Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36, 450 UChar = 37, Float = 38, 451 VoidStar = 31, 452 QChar = 7, QString = 10, QStringList = 11, QByteArray = 12, 453 QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17, 454 QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22, 455 QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27, 456 QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42, 457 QPersistentModelIndex = 50, QRegularExpression = 44, 458 QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48, 459 QByteArrayList = 49, QObjectStar = 39, SChar = 40, 460 Void = 43, 461 Nullptr = 51, 462 QVariantMap = 8, QVariantList = 9, QVariantHash = 28, 463 QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55, 464 465 // Gui types 466 QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68, 467 QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73, 468 QCursor = 74, QKeySequence = 75, QPen = 76, QTextLength = 77, QTextFormat = 78, 469 QMatrix = 79, QTransform = 80, QMatrix4x4 = 81, QVector2D = 82, 470 QVector3D = 83, QVector4D = 84, QQuaternion = 85, QPolygonF = 86, QColorSpace = 87, 471 472 // Widget types 473 QSizePolicy = 121, 474 LastCoreType = QCborMap, 475 LastGuiType = QColorSpace, 476 User = 1024 477 }; 478 #endif +/ 479 480 enum TypeFlag { 481 NeedsConstruction = 0x1, 482 NeedsDestruction = 0x2, 483 MovableType = 0x4, 484 PointerToQObject = 0x8, 485 IsEnumeration = 0x10, 486 SharedPointerToQObject = 0x20, 487 WeakPointerToQObject = 0x40, 488 TrackingPointerToQObject = 0x80, 489 WasDeclaredAsMetaType = 0x100, 490 IsGadget = 0x200, 491 PointerToGadget = 0x400 492 } 493 /+ Q_DECLARE_FLAGS(TypeFlags, TypeFlag) +/ 494 alias TypeFlags = QFlags!(TypeFlag); 495 alias Deleter = ExternCPPFunc!(void function(void* )); 496 alias Creator = ExternCPPFunc!(void* function(const(void)* )); 497 498 /+ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/ 499 alias Destructor = ExternCPPFunc!(void function(void* )); 500 alias Constructor = ExternCPPFunc!(void* function(void* , const(void)* )); // TODO Qt6: remove me 501 /+ #endif +/ 502 alias TypedDestructor = ExternCPPFunc!(void function(int, void* )); 503 alias TypedConstructor = ExternCPPFunc!(void* function(int, void* , const(void)* )); 504 505 alias SaveOperator = ExternCPPFunc!(void function(ref QDataStream , const(void)* )); 506 alias LoadOperator = ExternCPPFunc!(void function(ref QDataStream , void* )); 507 version(QT_NO_DATASTREAM){}else 508 { 509 static void registerStreamOperators(const(char)* typeName, SaveOperator saveOp, 510 LoadOperator loadOp); 511 static void registerStreamOperators(int type, SaveOperator saveOp, 512 LoadOperator loadOp); 513 } 514 static int registerType(const(char)* typeName, Deleter deleter, 515 Creator creator); 516 static int registerType(const(char)* typeName, Deleter deleter, 517 Creator creator, 518 Destructor destructor, 519 Constructor constructor, 520 int size, 521 QMetaType.TypeFlags flags, 522 const(QMetaObject)* metaObject); 523 static int registerType(const(char)* typeName, 524 TypedDestructor destructor, 525 TypedConstructor constructor, 526 int size, 527 QMetaType.TypeFlags flags, 528 const(QMetaObject)* metaObject); 529 static bool unregisterType(int type); 530 /+ static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter, 531 Creator creator, 532 Destructor destructor, 533 Constructor constructor, 534 int size, 535 QMetaType::TypeFlags flags, 536 const QMetaObject *metaObject); +/ 537 /+ static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Destructor destructor, 538 Constructor constructor, 539 int size, 540 QMetaType::TypeFlags flags, 541 const QMetaObject *metaObject); +/ 542 /+ static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, TypedDestructor destructor, 543 TypedConstructor constructor, 544 int size, 545 QMetaType::TypeFlags flags, 546 const QMetaObject *metaObject); +/ 547 static int registerTypedef(const(char)* typeName, int aliasId); 548 /+ static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId); +/ 549 static int type(const(char)* typeName); 550 551 static int type(/+ QT_PREPEND_NAMESPACE(QByteArray) +/ ref const(.QByteArray) typeName); 552 static const(char)* typeName(int type); 553 static int sizeOf(int type); 554 static TypeFlags typeFlags(int type); 555 static const(QMetaObject)* metaObjectForType(int type); 556 static bool isRegistered(int type); 557 /+ static void *create(int type, const void *copy = nullptr); +/ 558 /+ #if QT_DEPRECATED_SINCE(5, 0) 559 QT_DEPRECATED static void *construct(int type, const void *copy = nullptr) 560 { return create(type, copy); } 561 #endif +/ 562 static void destroy(int type, void* data); 563 static void* construct(int type, void* where, const(void)* copy); 564 static void destruct(int type, void* where); 565 566 version(QT_NO_DATASTREAM){}else 567 { 568 static bool save(ref QDataStream stream, int type, const(void)* data); 569 static bool load(ref QDataStream stream, int type, void* data); 570 } 571 572 @disable this(); 573 /+ explicit +/this(const(int) type/+ = QMetaType.Type.UnknownType+/); // ### Qt6: drop const 574 pragma(inline, true) ~this() 575 { 576 if (/+ Q_UNLIKELY +/(isExtended(ExtensionFlag.DtorEx))) 577 dtor(); 578 } 579 580 pragma(inline, true) bool isValid() const 581 { 582 return m_typeId != Type.UnknownType; 583 } 584 pragma(inline, true) bool isRegistered() const 585 { 586 return isValid(); 587 } 588 pragma(inline, true) int id() const 589 { 590 return m_typeId; 591 } 592 pragma(inline, true) int sizeOf() const 593 { 594 if (/+ Q_UNLIKELY +/(isExtended(ExtensionFlag.SizeEx))) 595 return sizeExtended(); 596 return m_size; 597 } 598 /+ pragma(inline, true) TypeFlags flags() const 599 /+pragma(inline, true) QMetaType.TypeFlags flags() const+/ 600 { 601 if (/+ Q_UNLIKELY +/(isExtended(ExtensionFlag.FlagsEx))) 602 return flagsExtended(); 603 return QMetaType.TypeFlags(cast(QFlag)(m_typeFlags)); 604 } 605 pragma(inline, true) const(QMetaObject)* metaObject() const 606 { 607 if (/+ Q_UNLIKELY +/(isExtended(ExtensionFlag.MetaObjectEx))) 608 return metaObjectExtended(); 609 return m_metaObject; 610 }+/ 611 /+ QT_PREPEND_NAMESPACE(QByteArray) +/.QByteArray name() const; 612 613 /+ inline void *create(const void *copy = nullptr) const; +/ 614 pragma(inline, true) void destroy(void* data) const 615 { 616 // ### TODO Qt6 remove the extension 617 destroyExtended(data); 618 } 619 pragma(inline, true) void* construct(void* where, const(void)* copy = null) const 620 { 621 if (/+ Q_UNLIKELY +/(isExtended(ExtensionFlag.ConstructEx))) 622 return constructExtended(where, copy); 623 return m_constructor(where, copy); 624 } 625 pragma(inline, true) void destruct(void* data) const 626 { 627 if (/+ Q_UNLIKELY +/(isExtended(ExtensionFlag.DestructEx))) 628 return destructExtended(data); 629 if (/+ Q_UNLIKELY +/(!data)) 630 return; 631 m_destructor(data); 632 } 633 634 /+ template<typename T> +/ 635 /+ static QMetaType fromType() 636 { return QMetaType(qMetaTypeId<T>()); } +/ 637 638 /+ friend bool operator==(const QMetaType &a, const QMetaType &b) 639 { return a.m_typeId == b.m_typeId; } +/ 640 641 /+ friend bool operator!=(const QMetaType &a, const QMetaType &b) 642 { return a.m_typeId != b.m_typeId; } +/ 643 644 645 public: 646 /+ template<typename T> +/ 647 /+ static bool registerComparators() 648 { 649 Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn), 650 "QMetaType::registerComparators: The type must be a custom type."); 651 652 const int typeId = qMetaTypeId<T>(); 653 static const QtPrivate::BuiltInComparatorFunction<T> f; 654 return registerComparatorFunction( &f, typeId); 655 } +/ 656 /+ template<typename T> +/ 657 /+ static bool registerEqualsComparator() 658 { 659 Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn), 660 "QMetaType::registerEqualsComparator: The type must be a custom type."); 661 const int typeId = qMetaTypeId<T>(); 662 static const QtPrivate::BuiltInEqualsComparatorFunction<T> f; 663 return registerComparatorFunction( &f, typeId); 664 } +/ 665 666 /+ template<typename T> +/ 667 /+ static bool hasRegisteredComparators() 668 { 669 return hasRegisteredComparators(qMetaTypeId<T>()); 670 } +/ 671 static bool hasRegisteredComparators(int typeId); 672 673 674 /+ #ifndef QT_NO_DEBUG_STREAM 675 template<typename T> 676 static bool registerDebugStreamOperator() 677 { 678 Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn), 679 "QMetaType::registerDebugStreamOperator: The type must be a custom type."); 680 681 const int typeId = qMetaTypeId<T>(); 682 static const QtPrivate::BuiltInDebugStreamFunction<T> f; 683 return registerDebugStreamOperatorFunction(&f, typeId); 684 } 685 template<typename T> 686 static bool hasRegisteredDebugStreamOperator() 687 { 688 return hasRegisteredDebugStreamOperator(qMetaTypeId<T>()); 689 } 690 static bool hasRegisteredDebugStreamOperator(int typeId); 691 #endif +/ 692 693 // implicit conversion supported like double -> float 694 /+ template<typename From, typename To> +/ 695 /+ static bool registerConverter() 696 { 697 return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>); 698 } +/ 699 700 /+ #ifdef Q_CLANG_QDOC 701 template<typename MemberFunction, int> 702 static bool registerConverter(MemberFunction function); 703 template<typename MemberFunctionOk, char> 704 static bool registerConverter(MemberFunctionOk function); 705 template<typename UnaryFunction> 706 static bool registerConverter(UnaryFunction function); 707 #else +/ 708 // member function as in "QString QFont::toString() const" 709 /+ template<typename From, typename To> +/ 710 /+ static bool registerConverter(To(From::*function)() const) 711 { 712 Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn), 713 "QMetaType::registerConverter: At least one of the types must be a custom type."); 714 715 const int fromTypeId = qMetaTypeId<From>(); 716 const int toTypeId = qMetaTypeId<To>(); 717 static const QtPrivate::ConverterMemberFunction<From, To> f(function); 718 return registerConverterFunction(&f, fromTypeId, toTypeId); 719 } +/ 720 721 // member function as in "double QString::toDouble(bool *ok = nullptr) const" 722 /+ template<typename From, typename To> +/ 723 /+ static bool registerConverter(To(From::*function)(bool*) const) 724 { 725 Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn), 726 "QMetaType::registerConverter: At least one of the types must be a custom type."); 727 728 const int fromTypeId = qMetaTypeId<From>(); 729 const int toTypeId = qMetaTypeId<To>(); 730 static const QtPrivate::ConverterMemberFunctionOk<From, To> f(function); 731 return registerConverterFunction(&f, fromTypeId, toTypeId); 732 } +/ 733 734 // functor or function pointer 735 /+ template<typename From, typename To, typename UnaryFunction> +/ 736 /+ static bool registerConverter(UnaryFunction function) 737 { 738 Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn), 739 "QMetaType::registerConverter: At least one of the types must be a custom type."); 740 741 const int fromTypeId = qMetaTypeId<From>(); 742 const int toTypeId = qMetaTypeId<To>(); 743 static const QtPrivate::ConverterFunctor<From, To, UnaryFunction> f(function); 744 return registerConverterFunction(&f, fromTypeId, toTypeId); 745 } +/ 746 /+ #endif +/ 747 748 static bool convert(const(void)* from, int fromTypeId, void* to, int toTypeId); 749 static bool compare(const(void)* lhs, const(void)* rhs, int typeId, int* result); 750 static bool equals(const(void)* lhs, const(void)* rhs, int typeId, int* result); 751 /+ static bool debugStream(QDebug& dbg, const void *rhs, int typeId); +/ 752 753 /+ template<typename From, typename To> +/ 754 /+ static bool hasRegisteredConverterFunction() 755 { 756 return hasRegisteredConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>()); 757 } +/ 758 759 /+ static bool hasRegisteredConverterFunction(int fromTypeId, int toTypeId); +/ 760 761 private: 762 static QMetaType typeInfo(const(int) type); 763 pragma(inline, true) this(const(ExtensionFlag) extensionFlags, const(QMetaTypeInterface)* info, 764 TypedConstructor creator, 765 TypedDestructor deleter, 766 SaveOperator saveOp, 767 LoadOperator loadOp, 768 Constructor constructor, 769 Destructor destructor, 770 uint size, 771 uint theTypeFlags, 772 int typeId, 773 const(QMetaObject)* _metaObject) 774 { 775 this.m_typedConstructor = creator; 776 this.m_typedDestructor = deleter; 777 this.m_saveOp = saveOp; 778 this.m_loadOp = loadOp; 779 this.m_constructor = constructor; 780 this.m_destructor = destructor; 781 this.m_extension = null; 782 this.m_size = size; 783 this.m_typeFlags = theTypeFlags; 784 this.m_extensionFlags = extensionFlags; 785 this.m_typeId = typeId; 786 this.m_metaObject = _metaObject; 787 788 if (/+ Q_UNLIKELY +/(isExtended(ExtensionFlag.CtorEx) || typeId == QMetaType.Type.Void)) 789 ctor(info); 790 } 791 @disable this(this); 792 this(ref const(QMetaType) other); 793 /+ref QMetaType operator =(ref const(QMetaType) );+/ 794 pragma(inline, true) bool isExtended(const(ExtensionFlag) flag) const { return (m_extensionFlags & flag) != 0; } 795 796 // Methods used for future binary compatible extensions 797 void ctor(const(QMetaTypeInterface)* info); 798 void dtor(); 799 uint sizeExtended() const; 800 QMetaType.TypeFlags flagsExtended() const; 801 const(QMetaObject)* metaObjectExtended() const; 802 void* createExtended(const(void)* copy = null) const; 803 void destroyExtended(void* data) const; 804 void* constructExtended(void* where, const(void)* copy = null) const; 805 void destructExtended(void* data) const; 806 807 static bool registerComparatorFunction(const(/+ QtPrivate:: +/AbstractComparatorFunction)* f, int type); 808 /+ #ifndef QT_NO_DEBUG_STREAM 809 static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type); 810 #endif 811 812 // ### Qt6: FIXME: Remove the special Q_CC_MSVC handling, it was introduced to maintain BC. 813 #if !defined(Q_NO_TEMPLATE_FRIENDS) && !defined(Q_CC_MSVC) 814 #ifndef Q_CLANG_QDOC +/ 815 static if(!defined!"Q_NO_TEMPLATE_FRIENDS") 816 { 817 /+ template<typename, bool> +/ /+ friend struct QtPrivate::ValueTypeIsMetaType; +/ 818 /+ template<typename, typename> +/ /+ friend struct QtPrivate::ConverterMemberFunction; +/ 819 /+ template<typename, typename> +/ /+ friend struct QtPrivate::ConverterMemberFunctionOk; +/ 820 /+ template<typename, typename, typename> +/ /+ friend struct QtPrivate::ConverterFunctor; +/ 821 /+ template<typename, bool> +/ /+ friend struct QtPrivate::AssociativeValueTypeIsMetaType; +/ 822 /+ template<typename, bool> +/ /+ friend struct QtPrivate::IsMetaTypePair; +/ 823 /+ template<typename, typename> +/ /+ friend struct QtPrivate::MetaTypeSmartPointerHelper; +/ 824 } 825 else 826 { 827 /+ #endif 828 #else +/ 829 public: 830 } 831 /+ #endif +/ 832 static bool registerConverterFunction(const(/+ QtPrivate:: +/AbstractConverterFunction)* f, int from, int to); 833 static void unregisterConverterFunction(int from, int to); 834 private: 835 836 TypedConstructor m_typedConstructor; 837 TypedDestructor m_typedDestructor; 838 SaveOperator m_saveOp; 839 LoadOperator m_loadOp; 840 Constructor m_constructor; 841 Destructor m_destructor; 842 void* m_extension; // space reserved for future use 843 uint m_size; 844 uint m_typeFlags; 845 uint m_extensionFlags; 846 int m_typeId; 847 const(QMetaObject)* m_metaObject; 848 } 849 850 /+ #undef QT_DEFINE_METATYPE_ID +/ 851 /+pragma(inline, true) QFlags!(QMetaType.TypeFlags.enum_type) operator |(QMetaType.TypeFlags.enum_type f1, QMetaType.TypeFlags.enum_type f2)/+noexcept+/{return QFlags!(QMetaType.TypeFlags.enum_type)(f1)|f2;}+/ 852 /+pragma(inline, true) QFlags!(QMetaType.TypeFlags.enum_type) operator |(QMetaType.TypeFlags.enum_type f1, QFlags!(QMetaType.TypeFlags.enum_type) f2)/+noexcept+/{return f2|f1;}+/ 853 /+pragma(inline, true) QIncompatibleFlag operator |(QMetaType.TypeFlags.enum_type f1, int f2)/+noexcept+/{return QIncompatibleFlag(int(f1)|f2);}+/ 854 855 /+ Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags) 856 namespace QtPrivate { 857 858 } 859 860 #define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F) \ 861 } \ 862 Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \ 863 namespace QtMetaTypePrivate { +/ 864 865 extern(C++, "QtMetaTypePrivate") { 866 struct QMetaTypeFunctionHelper(T, bool Accepted=true) { 867 static void Destruct(void* t) 868 { 869 /+ Q_UNUSED(t) +/ // Silence MSVC that warns for POD types. 870 destroy!false(static_cast!(T*)(t)); 871 } 872 873 static void* Construct(void* where, const(void)* t) 874 { 875 import core.lifetime; 876 877 if (t) 878 return emplace!T(where, *static_cast!(const(T)*)(t)); 879 return emplace!T(where); 880 } 881 version(QT_NO_DATASTREAM){}else 882 { 883 static void Save(ref QDataStream stream, const(void)* t) 884 { 885 stream << *static_cast!(const(T)*)(t); 886 } 887 888 static void Load(ref QDataStream stream, void* t) 889 { 890 stream >> *static_cast!(T*)(t); 891 } 892 } 893 } 894 895 /+ template <typename T> 896 struct QMetaTypeFunctionHelper<T, /* Accepted */ false> { 897 static void Destruct(void *) {} 898 static void *Construct(void *, const void *) { return nullptr; } 899 #ifndef QT_NO_DATASTREAM 900 static void Save(QDataStream &, const void *) {} 901 static void Load(QDataStream &, void *) {} 902 #endif // QT_NO_DATASTREAM 903 }; 904 template <> 905 struct QMetaTypeFunctionHelper<void, /* Accepted */ true> 906 : public QMetaTypeFunctionHelper<void, /* Accepted */ false> 907 {}; +/ 908 909 struct VariantData 910 { 911 this(const(int) metaTypeId_, 912 const(void)* data_, 913 const(uint) flags_) 914 { 915 this.metaTypeId = metaTypeId_; 916 this.data = data_; 917 this.flags = flags_; 918 } 919 @disable this(this); 920 this(ref const(VariantData) other) 921 { 922 this.metaTypeId = other.metaTypeId; 923 this.data = other.data; 924 this.flags = other.flags; 925 } 926 const(int) metaTypeId; 927 const(void)* data; 928 const(uint) flags; 929 private: 930 // copy constructor allowed to be implicit to silence level 4 warning from MSVC 931 /+ref VariantData operator =(ref const(VariantData) ) /+ = delete +/;+/ 932 } 933 934 struct IteratorOwnerCommon(const_iterator) 935 { 936 static void assign(void** ptr, const_iterator iterator) 937 { 938 import core.stdcpp.new_; 939 940 *ptr = cpp_new!const_iterator(iterator); 941 } 942 static void assign(void** ptr, void* /+ const +/ * src) 943 { 944 import core.stdcpp.new_; 945 946 *ptr = cpp_new!const_iterator(*static_cast!(const_iterator*)(*src)); 947 } 948 949 static void advance(void** iterator, int step) 950 { 951 ref const_iterator it = *static_cast!(const_iterator*)(*iterator); 952 /+ std:: +/advance(it, step); 953 } 954 955 static void destroy(void** ptr) 956 { 957 import core.stdcpp.new_; 958 959 cpp_delete(static_cast!(const_iterator*)(*ptr)); 960 } 961 962 static bool equal(void* /+ const +/ * it, void* /+ const +/ * other) 963 { 964 return *static_cast!(const_iterator*)(*it) == *static_cast!(const_iterator*)(*other); 965 } 966 } 967 968 struct IteratorOwner(const_iterator) 969 { 970 IteratorOwnerCommon!(const_iterator) base0; 971 alias base0 this; 972 static const(void)* getData(void* /+ const +/ * iterator) 973 { 974 return &**static_cast!(const_iterator*)(*iterator); 975 } 976 977 static const(void)* getData(const_iterator it) 978 { 979 return &*it; 980 } 981 } 982 983 struct /+ Q_CORE_EXPORT +/ VectorBoolElements 984 { 985 extern static __gshared const(bool) true_element; 986 extern static __gshared const(bool) false_element; 987 } 988 989 /+ template<> 990 struct IteratorOwner<std::vector<bool>::const_iterator> : IteratorOwnerCommon<std::vector<bool>::const_iterator> 991 { 992 public: 993 static const void *getData(void * const *iterator) 994 { 995 return **static_cast<std::vector<bool>::const_iterator*>(*iterator) ? 996 &VectorBoolElements::true_element : &VectorBoolElements::false_element; 997 } 998 999 static const void *getData(const std::vector<bool>::const_iterator& it) 1000 { 1001 return *it ? &VectorBoolElements::true_element : &VectorBoolElements::false_element; 1002 } 1003 }; 1004 1005 template<typename value_type> 1006 struct IteratorOwner<const value_type*> 1007 { 1008 private: 1009 // We need to disable typed overloads of assign() and getData() if the value_type 1010 // is void* to avoid overloads conflicts. We do it by injecting unaccessible Dummy 1011 // type as part of the overload signature. 1012 struct Dummy {}; 1013 typedef typename std::conditional<std::is_same<value_type, void*>::value, Dummy, value_type>::type value_type_OR_Dummy; 1014 public: 1015 static void assign(void **ptr, const value_type_OR_Dummy *iterator ) 1016 { 1017 *ptr = const_cast<value_type*>(iterator); 1018 } 1019 static void assign(void **ptr, void * const * src) 1020 { 1021 *ptr = static_cast<value_type*>(*src); 1022 } 1023 1024 static void advance(void **iterator, int step) 1025 { 1026 value_type *it = static_cast<value_type*>(*iterator); 1027 std::advance(it, step); 1028 *iterator = it; 1029 } 1030 1031 static void destroy(void **) 1032 { 1033 } 1034 1035 static const void *getData(void * const *iterator) 1036 { 1037 return *iterator; 1038 } 1039 1040 static const void *getData(const value_type_OR_Dummy *it) 1041 { 1042 return it; 1043 } 1044 1045 static bool equal(void * const *it, void * const *other) 1046 { 1047 return static_cast<value_type*>(*it) == static_cast<value_type*>(*other); 1048 } 1049 }; +/ 1050 1051 enum IteratorCapability 1052 { 1053 ForwardCapability = 1, 1054 BiDirectionalCapability = 2, 1055 RandomAccessCapability = 4 1056 } 1057 1058 enum ContainerCapability 1059 { 1060 ContainerIsAppendable = 1 1061 } 1062 1063 /+ template<typename Container, typename T = void> 1064 struct ContainerCapabilitiesImpl 1065 { 1066 enum {ContainerCapabilities = 0}; 1067 using appendFunction = void(*)(const void *container, const void *newElement); 1068 static constexpr const appendFunction appendImpl = nullptr; 1069 }; 1070 1071 template<typename Container> 1072 struct ContainerCapabilitiesImpl<Container, decltype(std::declval<Container>().push_back(std::declval<typename Container::value_type>()))> 1073 { 1074 enum {ContainerCapabilities = ContainerIsAppendable}; 1075 1076 // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl 1077 // pointed to a const object to begin with 1078 static void appendImpl(const void *container, const void *value) 1079 { static_cast<Container *>(const_cast<void *>(container))->push_back(*static_cast<const typename Container::value_type *>(value)); } 1080 }; +/ 1081 1082 extern(C++, "QtPrivate") { 1083 /+ namespace ContainerCapabilitiesMetaProgrammingHelper { 1084 template<typename... Ts> 1085 using void_t = void; 1086 } +/ 1087 } 1088 } 1089 1090 /+ template<typename Container> 1091 struct ContainerCapabilitiesImpl<Container, QtPrivate::ContainerCapabilitiesMetaProgrammingHelper::void_t<decltype(std::declval<Container>().insert(std::declval<typename Container::value_type>())), decltype(std::declval<typename Container::value_type>() == std::declval<typename Container::value_type>())>> 1092 { 1093 enum {ContainerCapabilities = ContainerIsAppendable}; 1094 1095 // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl 1096 // pointed to a const object to begin with 1097 static void appendImpl(const void *container, const void *value) 1098 { static_cast<Container *>(const_cast<void *>(container))->insert(*static_cast<const typename Container::value_type *>(value)); } 1099 }; 1100 1101 template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category> 1102 struct CapabilitiesImpl; 1103 1104 template<typename T> 1105 struct CapabilitiesImpl<T, std::forward_iterator_tag> 1106 { enum { IteratorCapabilities = ForwardCapability }; }; 1107 template<typename T> 1108 struct CapabilitiesImpl<T, std::bidirectional_iterator_tag> 1109 { enum { IteratorCapabilities = BiDirectionalCapability | ForwardCapability }; }; 1110 template<typename T> 1111 struct CapabilitiesImpl<T, std::random_access_iterator_tag> 1112 { enum { IteratorCapabilities = RandomAccessCapability | BiDirectionalCapability | ForwardCapability }; }; 1113 1114 template<typename T> 1115 struct ContainerAPI : CapabilitiesImpl<T> 1116 { 1117 static int size(const T *t) { return int(std::distance(t->begin(), t->end())); } 1118 }; 1119 1120 template<typename T> 1121 struct ContainerAPI<QList<T> > : CapabilitiesImpl<QList<T> > 1122 { static int size(const QList<T> *t) { return t->size(); } }; 1123 1124 template<typename T> 1125 struct ContainerAPI<QVector<T> > : CapabilitiesImpl<QVector<T> > 1126 { static int size(const QVector<T> *t) { return t->size(); } }; 1127 1128 template<typename T> 1129 struct ContainerAPI<std::vector<T> > : CapabilitiesImpl<std::vector<T> > 1130 { static int size(const std::vector<T> *t) { return int(t->size()); } }; 1131 1132 template<typename T> 1133 struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> > 1134 { static int size(const std::list<T> *t) { return int(t->size()); } }; 1135 1136 /* 1137 revision 0: _iteratorCapabilities is simply a uint, where the bits at _revision were never set 1138 revision 1: _iteratorCapabilties is treated as a bitfield, the remaining bits are used to introduce 1139 _revision, _containerCapabilities and _unused. The latter contains 21 bits that are 1140 not used yet 1141 */ 1142 class QSequentialIterableImpl 1143 { 1144 public: 1145 const void * _iterable; 1146 void *_iterator; 1147 int _metaType_id; 1148 uint _metaType_flags; 1149 uint _iteratorCapabilities; 1150 // Iterator capabilities looks actually like 1151 // uint _iteratorCapabilities:4; 1152 // uint _revision:3; 1153 // uint _containerCapabilities:4; 1154 // uint _unused:21;*/ 1155 typedef int(*sizeFunc)(const void *p); 1156 typedef const void * (*atFunc)(const void *p, int); 1157 typedef void (*moveIteratorFunc)(const void *p, void **); 1158 enum Position { ToBegin, ToEnd }; 1159 typedef void (*moveIteratorFunc2)(const void *p, void **, Position position); 1160 typedef void (*advanceFunc)(void **p, int); 1161 typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags); 1162 typedef void (*destroyIterFunc)(void **p); 1163 typedef bool (*equalIterFunc)(void * const *p, void * const *other); 1164 typedef void (*copyIterFunc)(void **, void * const *); 1165 typedef void(*appendFunction)(const void *container, const void *newElement); 1166 1167 IteratorCapability iteratorCapabilities() {return static_cast<IteratorCapability>(_iteratorCapabilities & 0xF);} 1168 uint revision() {return _iteratorCapabilities >> 4 & 0x7;} 1169 uint containerCapabilities() {return _iteratorCapabilities >> 7 & 0xF;} 1170 1171 sizeFunc _size; 1172 atFunc _at; 1173 union { 1174 moveIteratorFunc _moveToBegin; 1175 moveIteratorFunc2 _moveTo; 1176 }; 1177 union { 1178 moveIteratorFunc _moveToEnd; 1179 appendFunction _append; 1180 }; 1181 advanceFunc _advance; 1182 getFunc _get; 1183 destroyIterFunc _destroyIter; 1184 equalIterFunc _equalIter; 1185 copyIterFunc _copyIter; 1186 1187 template<class T> 1188 static int sizeImpl(const void *p) 1189 { return ContainerAPI<T>::size(static_cast<const T*>(p)); } 1190 1191 template<class T> 1192 static const void* atImpl(const void *p, int idx) 1193 { 1194 typename T::const_iterator i = static_cast<const T*>(p)->begin(); 1195 std::advance(i, idx); 1196 return IteratorOwner<typename T::const_iterator>::getData(i); 1197 } 1198 1199 template<class T> 1200 static void moveToBeginImpl(const void *container, void **iterator) 1201 { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); } 1202 1203 template<class T> 1204 static void moveToEndImpl(const void *container, void **iterator) 1205 { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); } 1206 1207 template<class Container> 1208 static void moveToImpl(const void *container, void **iterator, Position position) 1209 { 1210 if (position == ToBegin) 1211 moveToBeginImpl<Container>(container, iterator); 1212 else 1213 moveToEndImpl<Container>(container, iterator); 1214 } 1215 1216 template<class T> 1217 static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags) 1218 { return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); } 1219 1220 public: 1221 template<class T> QSequentialIterableImpl(const T*p) 1222 : _iterable(p) 1223 , _iterator(nullptr) 1224 , _metaType_id(qMetaTypeId<typename T::value_type>()) 1225 , _metaType_flags(QTypeInfo<typename T::value_type>::isPointer) 1226 , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities | (1 << 4) | (ContainerCapabilitiesImpl<T>::ContainerCapabilities << (4+3))) 1227 , _size(sizeImpl<T>) 1228 , _at(atImpl<T>) 1229 , _moveTo(moveToImpl<T>) 1230 , _append(ContainerCapabilitiesImpl<T>::appendImpl) 1231 , _advance(IteratorOwner<typename T::const_iterator>::advance) 1232 , _get(getImpl<T>) 1233 , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy) 1234 , _equalIter(IteratorOwner<typename T::const_iterator>::equal) 1235 , _copyIter(IteratorOwner<typename T::const_iterator>::assign) 1236 { 1237 } 1238 1239 QSequentialIterableImpl() 1240 : _iterable(nullptr) 1241 , _iterator(nullptr) 1242 , _metaType_id(QMetaType::UnknownType) 1243 , _metaType_flags(0) 1244 , _iteratorCapabilities(0 | (1 << 4) ) // no iterator capabilities, revision 1 1245 , _size(nullptr) 1246 , _at(nullptr) 1247 , _moveToBegin(nullptr) 1248 , _moveToEnd(nullptr) 1249 , _advance(nullptr) 1250 , _get(nullptr) 1251 , _destroyIter(nullptr) 1252 , _equalIter(nullptr) 1253 , _copyIter(nullptr) 1254 { 1255 } 1256 1257 inline void moveToBegin() { 1258 if (revision() == 0) 1259 _moveToBegin(_iterable, &_iterator); 1260 else 1261 _moveTo(_iterable, &_iterator, ToBegin); 1262 } 1263 inline void moveToEnd() { 1264 if (revision() == 0) 1265 _moveToEnd(_iterable, &_iterator); 1266 else 1267 _moveTo(_iterable, &_iterator, ToEnd); 1268 } 1269 inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); } 1270 inline QSequentialIterableImpl &advance(int i) { 1271 Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability); 1272 _advance(&_iterator, i); 1273 return *this; 1274 } 1275 1276 inline void append(const void *newElement) { 1277 if (containerCapabilities() & ContainerIsAppendable) 1278 _append(_iterable, newElement); 1279 } 1280 1281 inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); } 1282 1283 VariantData at(int idx) const 1284 { return VariantData(_metaType_id, _at(_iterable, idx), _metaType_flags); } 1285 1286 int size() const { Q_ASSERT(_iterable); return _size(_iterable); } 1287 1288 inline void destroyIter() { _destroyIter(&_iterator); } 1289 1290 void copy(const QSequentialIterableImpl &other) 1291 { 1292 *this = other; 1293 _copyIter(&_iterator, &other._iterator); 1294 } 1295 }; 1296 QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QSequentialIterableImpl, Q_MOVABLE_TYPE) 1297 template<typename From> 1298 struct QSequentialIterableConvertFunctor 1299 { 1300 QSequentialIterableImpl operator()(const From &f) const 1301 { 1302 return QSequentialIterableImpl(&f); 1303 } 1304 }; 1305 } 1306 1307 namespace QtMetaTypePrivate { 1308 1309 template<typename T, bool = std::is_same<typename T::const_iterator::value_type, typename T::mapped_type>::value> 1310 struct AssociativeContainerAccessor 1311 { 1312 static const typename T::key_type& getKey(const typename T::const_iterator &it) 1313 { 1314 return it.key(); 1315 } 1316 1317 static const typename T::mapped_type& getValue(const typename T::const_iterator &it) 1318 { 1319 return it.value(); 1320 } 1321 }; 1322 1323 template<typename T, bool = std::is_same<typename T::const_iterator::value_type, std::pair<const typename T::key_type, typename T::mapped_type> >::value> 1324 struct StlStyleAssociativeContainerAccessor; 1325 1326 template<typename T> 1327 struct StlStyleAssociativeContainerAccessor<T, true> 1328 { 1329 static const typename T::key_type& getKey(const typename T::const_iterator &it) 1330 { 1331 return it->first; 1332 } 1333 1334 static const typename T::mapped_type& getValue(const typename T::const_iterator &it) 1335 { 1336 return it->second; 1337 } 1338 }; 1339 1340 template<typename T> 1341 struct AssociativeContainerAccessor<T, false> : public StlStyleAssociativeContainerAccessor<T> 1342 { 1343 }; 1344 1345 class QAssociativeIterableImpl 1346 { 1347 public: 1348 const void *_iterable; 1349 void *_iterator; 1350 int _metaType_id_key; 1351 uint _metaType_flags_key; 1352 int _metaType_id_value; 1353 uint _metaType_flags_value; 1354 typedef int(*sizeFunc)(const void *p); 1355 typedef void (*findFunc)(const void *container, const void *p, void **iterator); 1356 typedef void (*beginFunc)(const void *p, void **); 1357 typedef void (*advanceFunc)(void **p, int); 1358 typedef VariantData (*getFunc)(void * const *p, int metaTypeId, uint flags); 1359 typedef void (*destroyIterFunc)(void **p); 1360 typedef bool (*equalIterFunc)(void * const *p, void * const *other); 1361 typedef void (*copyIterFunc)(void **, void * const *); 1362 1363 sizeFunc _size; 1364 findFunc _find; 1365 beginFunc _begin; 1366 beginFunc _end; 1367 advanceFunc _advance; 1368 getFunc _getKey; 1369 getFunc _getValue; 1370 destroyIterFunc _destroyIter; 1371 equalIterFunc _equalIter; 1372 copyIterFunc _copyIter; 1373 1374 template<class T> 1375 static int sizeImpl(const void *p) 1376 { return int(std::distance(static_cast<const T*>(p)->begin(), 1377 static_cast<const T*>(p)->end())); } 1378 1379 template<class T> 1380 static void findImpl(const void *container, const void *p, void **iterator) 1381 { IteratorOwner<typename T::const_iterator>::assign(iterator, 1382 static_cast<const T*>(container)->find(*static_cast<const typename T::key_type*>(p))); } 1383 1384 QT_WARNING_PUSH 1385 QT_WARNING_DISABLE_DEPRECATED // Hits on the deprecated QHash::iterator::operator--() 1386 template<class T> 1387 static void advanceImpl(void **p, int step) 1388 { std::advance(*static_cast<typename T::const_iterator*>(*p), step); } 1389 QT_WARNING_POP 1390 1391 template<class T> 1392 static void beginImpl(const void *container, void **iterator) 1393 { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); } 1394 1395 template<class T> 1396 static void endImpl(const void *container, void **iterator) 1397 { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); } 1398 1399 template<class T> 1400 static VariantData getKeyImpl(void * const *iterator, int metaTypeId, uint flags) 1401 { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getKey(*static_cast<typename T::const_iterator*>(*iterator)), flags); } 1402 1403 template<class T> 1404 static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags) 1405 { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); } 1406 1407 public: 1408 template<class T> QAssociativeIterableImpl(const T*p) 1409 : _iterable(p) 1410 , _iterator(nullptr) 1411 , _metaType_id_key(qMetaTypeId<typename T::key_type>()) 1412 , _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer) 1413 , _metaType_id_value(qMetaTypeId<typename T::mapped_type>()) 1414 , _metaType_flags_value(QTypeInfo<typename T::mapped_type>::isPointer) 1415 , _size(sizeImpl<T>) 1416 , _find(findImpl<T>) 1417 , _begin(beginImpl<T>) 1418 , _end(endImpl<T>) 1419 , _advance(advanceImpl<T>) 1420 , _getKey(getKeyImpl<T>) 1421 , _getValue(getValueImpl<T>) 1422 , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy) 1423 , _equalIter(IteratorOwner<typename T::const_iterator>::equal) 1424 , _copyIter(IteratorOwner<typename T::const_iterator>::assign) 1425 { 1426 } 1427 1428 QAssociativeIterableImpl() 1429 : _iterable(nullptr) 1430 , _iterator(nullptr) 1431 , _metaType_id_key(QMetaType::UnknownType) 1432 , _metaType_flags_key(0) 1433 , _metaType_id_value(QMetaType::UnknownType) 1434 , _metaType_flags_value(0) 1435 , _size(nullptr) 1436 , _find(nullptr) 1437 , _begin(nullptr) 1438 , _end(nullptr) 1439 , _advance(nullptr) 1440 , _getKey(nullptr) 1441 , _getValue(nullptr) 1442 , _destroyIter(nullptr) 1443 , _equalIter(nullptr) 1444 , _copyIter(nullptr) 1445 { 1446 } 1447 1448 inline void begin() { _begin(_iterable, &_iterator); } 1449 inline void end() { _end(_iterable, &_iterator); } 1450 inline bool equal(const QAssociativeIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); } 1451 inline QAssociativeIterableImpl &advance(int i) { _advance(&_iterator, i); return *this; } 1452 1453 inline void destroyIter() { _destroyIter(&_iterator); } 1454 1455 inline VariantData getCurrentKey() const { return _getKey(&_iterator, _metaType_id_key, _metaType_flags_key); } 1456 inline VariantData getCurrentValue() const { return _getValue(&_iterator, _metaType_id_value, _metaType_flags_value); } 1457 1458 inline void find(const VariantData &key) 1459 { _find(_iterable, key.data, &_iterator); } 1460 1461 int size() const { Q_ASSERT(_iterable); return _size(_iterable); } 1462 1463 void copy(const QAssociativeIterableImpl &other) 1464 { 1465 *this = other; 1466 _copyIter(&_iterator, &other._iterator); 1467 } 1468 }; 1469 QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QAssociativeIterableImpl, Q_MOVABLE_TYPE) 1470 1471 template<typename From> 1472 struct QAssociativeIterableConvertFunctor 1473 { 1474 QAssociativeIterableImpl operator()(const From& f) const 1475 { 1476 return QAssociativeIterableImpl(&f); 1477 } 1478 }; 1479 1480 class QPairVariantInterfaceImpl 1481 { 1482 const void *_pair; 1483 int _metaType_id_first; 1484 uint _metaType_flags_first; 1485 int _metaType_id_second; 1486 uint _metaType_flags_second; 1487 1488 typedef VariantData (*getFunc)(const void * const *p, int metaTypeId, uint flags); 1489 1490 getFunc _getFirst; 1491 getFunc _getSecond; 1492 1493 template<class T> 1494 static VariantData getFirstImpl(const void * const *pair, int metaTypeId, uint flags) 1495 { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->first, flags); } 1496 template<class T> 1497 static VariantData getSecondImpl(const void * const *pair, int metaTypeId, uint flags) 1498 { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->second, flags); } 1499 1500 public: 1501 template<class T> QPairVariantInterfaceImpl(const T*p) 1502 : _pair(p) 1503 , _metaType_id_first(qMetaTypeId<typename T::first_type>()) 1504 , _metaType_flags_first(QTypeInfo<typename T::first_type>::isPointer) 1505 , _metaType_id_second(qMetaTypeId<typename T::second_type>()) 1506 , _metaType_flags_second(QTypeInfo<typename T::second_type>::isPointer) 1507 , _getFirst(getFirstImpl<T>) 1508 , _getSecond(getSecondImpl<T>) 1509 { 1510 } 1511 1512 QPairVariantInterfaceImpl() 1513 : _pair(nullptr) 1514 , _metaType_id_first(QMetaType::UnknownType) 1515 , _metaType_flags_first(0) 1516 , _metaType_id_second(QMetaType::UnknownType) 1517 , _metaType_flags_second(0) 1518 , _getFirst(nullptr) 1519 , _getSecond(nullptr) 1520 { 1521 } 1522 1523 inline VariantData first() const { return _getFirst(&_pair, _metaType_id_first, _metaType_flags_first); } 1524 inline VariantData second() const { return _getSecond(&_pair, _metaType_id_second, _metaType_flags_second); } 1525 }; 1526 QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QPairVariantInterfaceImpl, Q_MOVABLE_TYPE) 1527 template<typename From> 1528 struct QPairVariantInterfaceConvertFunctor; 1529 1530 template<typename T, typename U> 1531 struct QPairVariantInterfaceConvertFunctor<QPair<T, U> > 1532 { 1533 QPairVariantInterfaceImpl operator()(const QPair<T, U>& f) const 1534 { 1535 return QPairVariantInterfaceImpl(&f); 1536 } 1537 }; 1538 1539 template<typename T, typename U> 1540 struct QPairVariantInterfaceConvertFunctor<std::pair<T, U> > 1541 { 1542 QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const 1543 { 1544 return QPairVariantInterfaceImpl(&f); 1545 } 1546 }; 1547 1548 } 1549 1550 class QObject; 1551 class QWidget; 1552 1553 #define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \ 1554 template <class T> class Name; \ 1555 1556 1557 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER) 1558 namespace QtPrivate 1559 { 1560 template<typename T> 1561 struct IsPointerToTypeDerivedFromQObject 1562 { 1563 enum { Value = false }; 1564 }; 1565 1566 // Specialize to avoid sizeof(void) warning 1567 template<> 1568 struct IsPointerToTypeDerivedFromQObject<void*> 1569 { 1570 enum { Value = false }; 1571 }; 1572 template<> 1573 struct IsPointerToTypeDerivedFromQObject<const void*> 1574 { 1575 enum { Value = false }; 1576 }; 1577 template<> 1578 struct IsPointerToTypeDerivedFromQObject<QObject*> 1579 { 1580 enum { Value = true }; 1581 }; 1582 1583 template<typename T> 1584 struct IsPointerToTypeDerivedFromQObject<T*> 1585 { 1586 typedef qint8 yes_type; 1587 typedef qint64 no_type; 1588 1589 #ifndef QT_NO_QOBJECT 1590 static yes_type checkType(QObject* ); 1591 #endif 1592 static no_type checkType(...); 1593 Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined"); 1594 enum { Value = sizeof(checkType(static_cast<T*>(nullptr))) == sizeof(yes_type) }; 1595 }; 1596 1597 template<typename T, typename Enable = void> 1598 struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; 1599 1600 template<typename T> 1601 struct IsGadgetHelper<T, typename T::QtGadgetHelper> 1602 { 1603 template <typename X> 1604 static char checkType(void (X::*)()); 1605 static void *checkType(void (T::*)()); 1606 enum { 1607 IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), 1608 IsGadgetOrDerivedFrom = true 1609 }; 1610 }; 1611 1612 template<typename T, typename Enable = void> 1613 struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; 1614 1615 template<typename T> 1616 struct IsPointerToGadgetHelper<T*, typename T::QtGadgetHelper> 1617 { 1618 using BaseType = T; 1619 template <typename X> 1620 static char checkType(void (X::*)()); 1621 static void *checkType(void (T::*)()); 1622 enum { 1623 IsRealGadget = !IsPointerToTypeDerivedFromQObject<T*>::Value && sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), 1624 IsGadgetOrDerivedFrom = !IsPointerToTypeDerivedFromQObject<T*>::Value 1625 }; 1626 }; 1627 1628 1629 template<typename T> char qt_getEnumMetaObject(const T&); 1630 1631 template<typename T> 1632 struct IsQEnumHelper { 1633 static const T &declval(); 1634 // If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject() declared in the 1635 // Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*. 1636 // Otherwise the chosen overload will be the catch all template function 1637 // qt_getEnumMetaObject(T) which returns 'char' 1638 enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) }; 1639 }; 1640 template<> struct IsQEnumHelper<void> { enum { Value = false }; }; 1641 1642 template<typename T, typename Enable = void> 1643 struct MetaObjectForType 1644 { 1645 static inline const QMetaObject *value() { return nullptr; } 1646 }; 1647 template<> 1648 struct MetaObjectForType<void> 1649 { 1650 static inline const QMetaObject *value() { return nullptr; } 1651 }; 1652 template<typename T> 1653 struct MetaObjectForType<T*, typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type> 1654 { 1655 static inline const QMetaObject *value() { return &T::staticMetaObject; } 1656 }; 1657 template<typename T> 1658 struct MetaObjectForType<T, typename std::enable_if<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>::type> 1659 { 1660 static inline const QMetaObject *value() { return &T::staticMetaObject; } 1661 }; 1662 template<typename T> 1663 struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type> 1664 { 1665 static inline const QMetaObject *value() { return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject; } 1666 }; 1667 template<typename T> 1668 struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type > 1669 { 1670 static inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); } 1671 }; 1672 1673 template<typename T> 1674 struct IsSharedPointerToTypeDerivedFromQObject 1675 { 1676 enum { Value = false }; 1677 }; 1678 1679 template<typename T> 1680 struct IsSharedPointerToTypeDerivedFromQObject<QSharedPointer<T> > : IsPointerToTypeDerivedFromQObject<T*> 1681 { 1682 }; 1683 1684 template<typename T> 1685 struct IsWeakPointerToTypeDerivedFromQObject 1686 { 1687 enum { Value = false }; 1688 }; 1689 1690 template<typename T> 1691 struct IsWeakPointerToTypeDerivedFromQObject<QWeakPointer<T> > : IsPointerToTypeDerivedFromQObject<T*> 1692 { 1693 }; 1694 1695 template<typename T> 1696 struct IsTrackingPointerToTypeDerivedFromQObject 1697 { 1698 enum { Value = false }; 1699 }; 1700 1701 template<typename T> 1702 struct IsTrackingPointerToTypeDerivedFromQObject<QPointer<T> > 1703 { 1704 enum { Value = true }; 1705 }; 1706 1707 template<typename T> 1708 struct IsSequentialContainer 1709 { 1710 enum { Value = false }; 1711 }; 1712 1713 template<typename T> 1714 struct IsAssociativeContainer 1715 { 1716 enum { Value = false }; 1717 }; 1718 1719 template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value> 1720 struct SequentialContainerConverterHelper 1721 { 1722 static bool registerConverter(int) 1723 { 1724 return false; 1725 } 1726 }; 1727 1728 template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined> 1729 struct ValueTypeIsMetaType 1730 { 1731 static bool registerConverter(int) 1732 { 1733 return false; 1734 } 1735 }; 1736 1737 template<typename T> 1738 struct SequentialContainerConverterHelper<T, true> : ValueTypeIsMetaType<T> 1739 { 1740 }; 1741 1742 template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value> 1743 struct AssociativeContainerConverterHelper 1744 { 1745 static bool registerConverter(int) 1746 { 1747 return false; 1748 } 1749 }; 1750 1751 template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined> 1752 struct AssociativeValueTypeIsMetaType 1753 { 1754 static bool registerConverter(int) 1755 { 1756 return false; 1757 } 1758 }; 1759 1760 template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined> 1761 struct KeyAndValueTypeIsMetaType 1762 { 1763 static bool registerConverter(int) 1764 { 1765 return false; 1766 } 1767 }; 1768 1769 template<typename T> 1770 struct KeyAndValueTypeIsMetaType<T, true> : AssociativeValueTypeIsMetaType<T> 1771 { 1772 }; 1773 1774 template<typename T> 1775 struct AssociativeContainerConverterHelper<T, true> : KeyAndValueTypeIsMetaType<T> 1776 { 1777 }; 1778 1779 template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined 1780 && QMetaTypeId2<typename T::second_type>::Defined> 1781 struct IsMetaTypePair 1782 { 1783 static bool registerConverter(int) 1784 { 1785 return false; 1786 } 1787 }; 1788 1789 template<typename T> 1790 struct IsMetaTypePair<T, true> 1791 { 1792 inline static bool registerConverter(int id); 1793 }; 1794 1795 template<typename T> 1796 struct IsPair 1797 { 1798 static bool registerConverter(int) 1799 { 1800 return false; 1801 } 1802 }; 1803 template<typename T, typename U> 1804 struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {}; 1805 template<typename T, typename U> 1806 struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {}; 1807 1808 template<typename T> 1809 struct MetaTypePairHelper : IsPair<T> {}; 1810 1811 template<typename T, typename = void> 1812 struct MetaTypeSmartPointerHelper 1813 { 1814 static bool registerConverter(int) { return false; } 1815 }; 1816 1817 Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type); 1818 } // namespace QtPrivate 1819 1820 template <typename T, int = 1821 QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 1822 QtPrivate::IsGadgetHelper<T>::IsRealGadget ? QMetaType::IsGadget : 1823 QtPrivate::IsPointerToGadgetHelper<T>::IsRealGadget ? QMetaType::PointerToGadget : 1824 QtPrivate::IsQEnumHelper<T>::Value ? QMetaType::IsEnumeration : 0> 1825 struct QMetaTypeIdQObject 1826 { 1827 enum { 1828 Defined = 0 1829 }; 1830 }; 1831 1832 template <typename T> 1833 struct QMetaTypeId : public QMetaTypeIdQObject<T> 1834 { 1835 }; 1836 1837 template <typename T> 1838 struct QMetaTypeId2 1839 { 1840 enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false }; 1841 static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); } 1842 }; 1843 1844 template <typename T> 1845 struct QMetaTypeId2<const T&> : QMetaTypeId2<T> {}; 1846 1847 template <typename T> 1848 struct QMetaTypeId2<T&> { enum {Defined = false }; }; +/ 1849 1850 extern(C++, "QtPrivate") { 1851 struct QMetaTypeIdHelper(T, bool Defined=QMetaTypeId2!(T).Defined) { 1852 pragma(inline, true) static int qt_metatype_id() 1853 { return QMetaTypeId2!(T).qt_metatype_id(); } 1854 } 1855 /+ template <typename T> struct QMetaTypeIdHelper<T, false> { 1856 static inline int qt_metatype_id() 1857 { return -1; } 1858 }; 1859 1860 // Function pointers don't derive from QObject 1861 template <typename Result, typename... Args> 1862 struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; }; 1863 1864 template<typename T> 1865 struct QMetaTypeTypeFlags 1866 { 1867 enum { Flags = (QTypeInfoQuery<T>::isRelocatable ? QMetaType::MovableType : 0) 1868 | (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0) 1869 | (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0) 1870 | (IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 0) 1871 | (IsSharedPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::SharedPointerToQObject : 0) 1872 | (IsWeakPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::WeakPointerToQObject : 0) 1873 | (IsTrackingPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::TrackingPointerToQObject : 0) 1874 | (std::is_enum<T>::value ? QMetaType::IsEnumeration : 0) 1875 | (IsGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::IsGadget : 0) 1876 | (IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::PointerToGadget : 0) 1877 }; 1878 }; +/ 1879 1880 struct MetaTypeDefinedHelper(T, bool defined) 1881 { 1882 enum DefinedType { Defined = defined } 1883 } 1884 1885 struct QSmartPointerConvertFunctor(SmartPointer) 1886 { 1887 /+QObject operator ()(ref const(SmartPointer) p) const 1888 { 1889 return p.operator->(); 1890 }+/ 1891 } 1892 1893 // hack to delay name lookup to instantiation time by making 1894 // EnableInternalData a dependent name: 1895 /+ template <typename T> 1896 struct EnableInternalDataWrap; 1897 1898 template<typename T> 1899 struct QSmartPointerConvertFunctor<QWeakPointer<T> > 1900 { 1901 QObject* operator()(const QWeakPointer<T> &p) const 1902 { 1903 return QtPrivate::EnableInternalDataWrap<T>::internalData(p); 1904 } 1905 }; +/ 1906 1907 } 1908 1909 /+ template <typename T> 1910 int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName 1911 #ifndef Q_CLANG_QDOC 1912 , T * dummy = 0 1913 , typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined 1914 #endif 1915 ) 1916 { 1917 #ifndef QT_NO_QOBJECT 1918 Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()), "qRegisterNormalizedMetaType", "qRegisterNormalizedMetaType was called with a not normalized type name, please call qRegisterMetaType instead."); 1919 #endif 1920 const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id(); 1921 if (typedefOf != -1) 1922 return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf); 1923 1924 QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags); 1925 1926 if (defined) 1927 flags |= QMetaType::WasDeclaredAsMetaType; 1928 1929 const int id = QMetaType::registerNormalizedType(normalizedTypeName, 1930 QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct, 1931 QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct, 1932 int(sizeof(T)), 1933 flags, 1934 QtPrivate::MetaObjectForType<T>::value()); 1935 1936 if (id > 0) { 1937 QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id); 1938 QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id); 1939 QtPrivate::MetaTypePairHelper<T>::registerConverter(id); 1940 QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id); 1941 } 1942 1943 return id; 1944 } +/ 1945 1946 int qRegisterMetaType(T)(const(char)* typeName 1947 /+ #ifndef Q_CLANG_QDOC +/ 1948 , T* dummy = null 1949 /+ , typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined 1950 #endif +/ 1951 ) 1952 { 1953 /+ #ifdef QT_NO_QOBJECT 1954 QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName; 1955 #else +/ 1956 /+ QT_PREPEND_NAMESPACE(QByteArray) +/QByteArray normalizedTypeName = QMetaObject.normalizedType(typeName); 1957 /+ #endif +/ 1958 return qRegisterNormalizedMetaType!(T)(normalizedTypeName, cast(T*)(dummy), defined__1); 1959 } 1960 1961 /+ #ifndef QT_NO_DATASTREAM 1962 template <typename T> 1963 void qRegisterMetaTypeStreamOperators(const char *typeName 1964 #ifndef Q_CLANG_QDOC 1965 , T * /* dummy */ = nullptr 1966 #endif 1967 ) 1968 { 1969 qRegisterMetaType<T>(typeName); 1970 QMetaType::registerStreamOperators(typeName, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save, 1971 QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load); 1972 } 1973 #endif +/ // QT_NO_DATASTREAM 1974 1975 pragma(inline, true) int qMetaTypeId(T)() 1976 { 1977 /+ /+ Q_STATIC_ASSERT_X(QMetaTypeId2<T>::Defined, "Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system") +/static assert(cast(bool)(QMetaTypeId2!(T).Defined),"Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system"); 1978 return QMetaTypeId2!(T).qt_metatype_id();+/ 1979 1980 import std.traits; 1981 1982 static if(is(T == void)) return QMetaType.Type.Void; 1983 else static if(is(T == bool)) return QMetaType.Type.Bool; 1984 else static if(is(T == int)) return QMetaType.Type.Int; 1985 else static if(is(T == uint)) return QMetaType.Type.UInt; 1986 // else static if(is(T == qlonglong)) return QMetaType.Type.LongLong; 1987 // else static if(is(T == qulonglong)) return QMetaType.Type.ULongLong; 1988 else static if(is(T == double)) return QMetaType.Type.Double; 1989 // else static if(is(T == long)) return QMetaType.Type.Long; 1990 else static if(is(T == short)) return QMetaType.Type.Short; 1991 else static if(is(T == char)) return QMetaType.Type.Char; 1992 // else static if(is(T == ulong)) return QMetaType.Type.ULong; 1993 else static if(is(T == ushort)) return QMetaType.Type.UShort; 1994 else static if(is(T == ubyte)) return QMetaType.Type.UChar; 1995 else static if(is(T == float)) return QMetaType.Type.Float; 1996 else static if(is(T == byte)) return QMetaType.Type.SChar; 1997 else static if(is(T == typeof(null))) return QMetaType.Type.Nullptr; 1998 // else static if(is(T == QCborSimpleType)) return QMetaType.Type.QCborSimpleType; 1999 else static if(is(T == void*)) return QMetaType.Type.VoidStar; 2000 else static if(is(T == QObject)) return QMetaType.Type.QObjectStar; 2001 else static if(getUDAs!(T, QMetaType.Type).length) 2002 { 2003 static assert(getUDAs!(T, QMetaType.Type).length == 1); 2004 return getUDAs!(T, QMetaType.Type)[0]; 2005 } 2006 else static assert(false, "qMetaTypeId not implemented for " ~ T.stringof); 2007 } 2008 2009 pragma(inline, true) int qRegisterMetaType(T)() 2010 { 2011 return qMetaTypeId!(T)(); 2012 } 2013 2014 /+ #if QT_DEPRECATED_SINCE(5, 1) && !defined(Q_CLANG_QDOC) +/ 2015 // There used to be a T *dummy = 0 argument in Qt 4.0 to support MSVC6 2016 /+ QT_DEPRECATED +/ pragma(inline, true) int qMetaTypeId(T)(T* ) 2017 { return qMetaTypeId!(T)(); } 2018 /+ #ifndef Q_CC_SUN +/ 2019 /+ QT_DEPRECATED +/ pragma(inline, true) int qRegisterMetaType(T)(T* ) 2020 { return qRegisterMetaType!(T)(); } 2021 /+ #endif +/ 2022 /+ #endif 2023 2024 #ifndef QT_NO_QOBJECT 2025 template <typename T> 2026 struct QMetaTypeIdQObject<T*, QMetaType::PointerToQObject> 2027 { 2028 enum { 2029 Defined = 1 2030 }; 2031 2032 static int qt_metatype_id() 2033 { 2034 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); 2035 if (const int id = metatype_id.loadAcquire()) 2036 return id; 2037 const char * const cName = T::staticMetaObject.className(); 2038 QByteArray typeName; 2039 typeName.reserve(int(strlen(cName)) + 1); 2040 typeName.append(cName).append('*'); 2041 const int newId = qRegisterNormalizedMetaType<T*>( 2042 typeName, 2043 reinterpret_cast<T**>(quintptr(-1))); 2044 metatype_id.storeRelease(newId); 2045 return newId; 2046 } 2047 }; 2048 2049 template <typename T> 2050 struct QMetaTypeIdQObject<T, QMetaType::IsGadget> 2051 { 2052 enum { 2053 Defined = std::is_default_constructible<T>::value 2054 }; 2055 2056 static int qt_metatype_id() 2057 { 2058 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); 2059 if (const int id = metatype_id.loadAcquire()) 2060 return id; 2061 const char * const cName = T::staticMetaObject.className(); 2062 const int newId = qRegisterNormalizedMetaType<T>( 2063 cName, 2064 reinterpret_cast<T*>(quintptr(-1))); 2065 metatype_id.storeRelease(newId); 2066 return newId; 2067 } 2068 }; 2069 2070 template <typename T> 2071 struct QMetaTypeIdQObject<T*, QMetaType::PointerToGadget> 2072 { 2073 enum { 2074 Defined = 1 2075 }; 2076 2077 static int qt_metatype_id() 2078 { 2079 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); 2080 if (const int id = metatype_id.loadAcquire()) 2081 return id; 2082 const char * const cName = T::staticMetaObject.className(); 2083 QByteArray typeName; 2084 typeName.reserve(int(strlen(cName)) + 1); 2085 typeName.append(cName).append('*'); 2086 const int newId = qRegisterNormalizedMetaType<T*>( 2087 typeName, 2088 reinterpret_cast<T**>(quintptr(-1))); 2089 metatype_id.storeRelease(newId); 2090 return newId; 2091 } 2092 }; 2093 2094 template <typename T> 2095 struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration> 2096 { 2097 enum { 2098 Defined = 1 2099 }; 2100 2101 static int qt_metatype_id() 2102 { 2103 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); 2104 if (const int id = metatype_id.loadAcquire()) 2105 return id; 2106 const char *eName = qt_getEnumName(T()); 2107 const char *cName = qt_getEnumMetaObject(T())->className(); 2108 QByteArray typeName; 2109 typeName.reserve(int(strlen(cName) + 2 + strlen(eName))); 2110 typeName.append(cName).append("::").append(eName); 2111 const int newId = qRegisterNormalizedMetaType<T>( 2112 typeName, 2113 reinterpret_cast<T*>(quintptr(-1))); 2114 metatype_id.storeRelease(newId); 2115 return newId; 2116 } 2117 }; 2118 #endif 2119 2120 #ifndef QT_NO_DATASTREAM 2121 template <typename T> 2122 inline int qRegisterMetaTypeStreamOperators() 2123 { 2124 int id = qMetaTypeId<T>(); 2125 QMetaType::registerStreamOperators(id, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save, 2126 QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load); 2127 return id; 2128 } 2129 #endif 2130 2131 #define Q_DECLARE_OPAQUE_POINTER(POINTER) \ 2132 QT_BEGIN_NAMESPACE namespace QtPrivate { \ 2133 template <> \ 2134 struct IsPointerToTypeDerivedFromQObject<POINTER > \ 2135 { \ 2136 enum { Value = false }; \ 2137 }; \ 2138 } QT_END_NAMESPACE \ 2139 /**/ 2140 2141 #ifndef Q_MOC_RUN 2142 #define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE) 2143 #define Q_DECLARE_METATYPE_IMPL(TYPE) \ 2144 QT_BEGIN_NAMESPACE \ 2145 template <> \ 2146 struct QMetaTypeId< TYPE > \ 2147 { \ 2148 enum { Defined = 1 }; \ 2149 static int qt_metatype_id() \ 2150 { \ 2151 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ 2152 if (const int id = metatype_id.loadAcquire()) \ 2153 return id; \ 2154 const int newId = qRegisterMetaType< TYPE >(#TYPE, \ 2155 reinterpret_cast< TYPE *>(quintptr(-1))); \ 2156 metatype_id.storeRelease(newId); \ 2157 return newId; \ 2158 } \ 2159 }; \ 2160 QT_END_NAMESPACE 2161 #endif // Q_MOC_RUN 2162 2163 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \ 2164 QT_BEGIN_NAMESPACE \ 2165 template<> struct QMetaTypeId2<NAME> \ 2166 { \ 2167 enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID }; \ 2168 static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return METATYPEID; } \ 2169 }; \ 2170 QT_END_NAMESPACE 2171 2172 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \ 2173 class Name; 2174 2175 2176 QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER) +/ 2177 extern(C++, class) struct QMatrix4x4; 2178 extern(C++, class) struct QQuaternion; 2179 /+ QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER) 2180 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER) 2181 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER +/ 2182 2183 alias QVariantList = QList!(QVariant); 2184 /+ typedef QMap<QString, QVariant> QVariantMap; 2185 typedef QHash<QString, QVariant> QVariantHash; 2186 #ifdef Q_CLANG_QDOC 2187 class QByteArrayList; 2188 #else 2189 #endif 2190 2191 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \ 2192 QT_BEGIN_NAMESPACE \ 2193 template <typename T> \ 2194 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \ 2195 { \ 2196 enum { \ 2197 Defined = QMetaTypeId2<T>::Defined \ 2198 }; \ 2199 static int qt_metatype_id() \ 2200 { \ 2201 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ 2202 if (const int id = metatype_id.loadRelaxed()) \ 2203 return id; \ 2204 const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \ 2205 Q_ASSERT(tName); \ 2206 const int tNameLen = int(qstrlen(tName)); \ 2207 QByteArray typeName; \ 2208 typeName.reserve(int(sizeof(#SINGLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + 1); \ 2209 typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \ 2210 .append('<').append(tName, tNameLen); \ 2211 if (typeName.endsWith('>')) \ 2212 typeName.append(' '); \ 2213 typeName.append('>'); \ 2214 const int newId = qRegisterNormalizedMetaType< SINGLE_ARG_TEMPLATE<T> >( \ 2215 typeName, \ 2216 reinterpret_cast< SINGLE_ARG_TEMPLATE<T> *>(quintptr(-1))); \ 2217 metatype_id.storeRelease(newId); \ 2218 return newId; \ 2219 } \ 2220 }; \ 2221 namespace QtPrivate { \ 2222 template<typename T> \ 2223 struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \ 2224 { \ 2225 enum { Value = true }; \ 2226 }; \ 2227 } \ 2228 QT_END_NAMESPACE 2229 2230 #define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \ 2231 QT_BEGIN_NAMESPACE \ 2232 template<typename T, typename U> \ 2233 struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \ 2234 { \ 2235 enum { \ 2236 Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \ 2237 }; \ 2238 static int qt_metatype_id() \ 2239 { \ 2240 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ 2241 if (const int id = metatype_id.loadAcquire()) \ 2242 return id; \ 2243 const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \ 2244 const char *uName = QMetaType::typeName(qMetaTypeId<U>()); \ 2245 Q_ASSERT(tName); \ 2246 Q_ASSERT(uName); \ 2247 const int tNameLen = int(qstrlen(tName)); \ 2248 const int uNameLen = int(qstrlen(uName)); \ 2249 QByteArray typeName; \ 2250 typeName.reserve(int(sizeof(#DOUBLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \ 2251 typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \ 2252 .append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \ 2253 if (typeName.endsWith('>')) \ 2254 typeName.append(' '); \ 2255 typeName.append('>'); \ 2256 const int newId = qRegisterNormalizedMetaType< DOUBLE_ARG_TEMPLATE<T, U> >(\ 2257 typeName, \ 2258 reinterpret_cast< DOUBLE_ARG_TEMPLATE<T, U> *>(quintptr(-1))); \ 2259 metatype_id.storeRelease(newId); \ 2260 return newId; \ 2261 } \ 2262 }; \ 2263 QT_END_NAMESPACE 2264 2265 namespace QtPrivate { 2266 2267 template<typename T, bool /* isSharedPointerToQObjectDerived */ = false> 2268 struct SharedPointerMetaTypeIdHelper 2269 { 2270 enum { 2271 Defined = 0 2272 }; 2273 static int qt_metatype_id() 2274 { 2275 return -1; 2276 } 2277 }; 2278 2279 } 2280 2281 #define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \ 2282 QT_BEGIN_NAMESPACE \ 2283 namespace QtPrivate { \ 2284 template<typename T> \ 2285 struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \ 2286 { \ 2287 enum { \ 2288 Defined = 1 \ 2289 }; \ 2290 static int qt_metatype_id() \ 2291 { \ 2292 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ 2293 if (const int id = metatype_id.loadAcquire()) \ 2294 return id; \ 2295 const char * const cName = T::staticMetaObject.className(); \ 2296 QByteArray typeName; \ 2297 typeName.reserve(int(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1)); \ 2298 typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \ 2299 .append('<').append(cName).append('>'); \ 2300 const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >( \ 2301 typeName, \ 2302 reinterpret_cast< SMART_POINTER<T> *>(quintptr(-1))); \ 2303 metatype_id.storeRelease(newId); \ 2304 return newId; \ 2305 } \ 2306 }; \ 2307 template<typename T> \ 2308 struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \ 2309 typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type> \ 2310 { \ 2311 static bool registerConverter(int id) \ 2312 { \ 2313 const int toId = QMetaType::QObjectStar; \ 2314 if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { \ 2315 QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \ 2316 static const QtPrivate::ConverterFunctor<SMART_POINTER<T>, \ 2317 QObject*, \ 2318 QSmartPointerConvertFunctor<SMART_POINTER<T> > > f(o); \ 2319 return QMetaType::registerConverterFunction(&f, id, toId); \ 2320 } \ 2321 return true; \ 2322 } \ 2323 }; \ 2324 } \ 2325 template <typename T> \ 2326 struct QMetaTypeId< SMART_POINTER<T> > \ 2327 : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \ 2328 QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \ 2329 { \ 2330 };\ 2331 QT_END_NAMESPACE 2332 2333 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \ 2334 QT_BEGIN_NAMESPACE \ 2335 template <class T> class TEMPLATENAME; \ 2336 QT_END_NAMESPACE \ 2337 Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME) 2338 2339 2340 2341 QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER) 2342 #undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER 2343 2344 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE Q_DECLARE_METATYPE_TEMPLATE_1ARG 2345 2346 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector) 2347 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list) 2348 2349 #define Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \ 2350 QT_BEGIN_NAMESPACE \ 2351 template <class T1, class T2> CPPTYPE TEMPLATENAME; \ 2352 QT_END_NAMESPACE \ 2353 2354 QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER) 2355 2356 #undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER 2357 2358 #define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \ 2359 QT_BEGIN_NAMESPACE \ 2360 namespace QtPrivate { \ 2361 template<typename T, typename U> \ 2362 struct IsAssociativeContainer<TEMPLATENAME<T, U> > \ 2363 { \ 2364 enum { Value = true }; \ 2365 }; \ 2366 } \ 2367 QT_END_NAMESPACE \ 2368 Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME) 2369 2370 2371 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash) 2372 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap) 2373 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map) 2374 Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair) 2375 Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair) 2376 2377 #define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \ 2378 Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME) 2379 2380 2381 2382 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER) 2383 2384 #undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER 2385 2386 inline void *QMetaType::create(const void *copy) const 2387 { 2388 // ### TODO Qt6 remove the extension 2389 return createExtended(copy); 2390 } 2391 2392 2393 2394 QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE) 2395 2396 Q_DECLARE_METATYPE(QtMetaTypePrivate::QSequentialIterableImpl) 2397 Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl) 2398 Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl) 2399 2400 2401 template <typename T> 2402 inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter(int id) 2403 { 2404 const int toId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>(); 2405 if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { 2406 QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o; 2407 static const QtPrivate::ConverterFunctor<T, 2408 QtMetaTypePrivate::QPairVariantInterfaceImpl, 2409 QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> > f(o); 2410 return QMetaType::registerConverterFunction(&f, id, toId); 2411 } 2412 return true; 2413 } 2414 2415 namespace QtPrivate { 2416 template<typename T> 2417 struct ValueTypeIsMetaType<T, true> 2418 { 2419 static bool registerConverter(int id) 2420 { 2421 const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>(); 2422 if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { 2423 QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o; 2424 static const QtPrivate::ConverterFunctor<T, 2425 QtMetaTypePrivate::QSequentialIterableImpl, 2426 QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o); 2427 return QMetaType::registerConverterFunction(&f, id, toId); 2428 } 2429 return true; 2430 } 2431 }; 2432 2433 template<typename T> 2434 struct AssociativeValueTypeIsMetaType<T, true> 2435 { 2436 static bool registerConverter(int id) 2437 { 2438 const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>(); 2439 if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { 2440 QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o; 2441 static const QtPrivate::ConverterFunctor<T, 2442 QtMetaTypePrivate::QAssociativeIterableImpl, 2443 QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o); 2444 return QMetaType::registerConverterFunction(&f, id, toId); 2445 } 2446 return true; 2447 } 2448 }; 2449 } +/ 2450