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.variant; 15 extern(C++): 16 17 import core.stdc.config; 18 import qt.config; 19 import qt.core.abstractitemmodel; 20 import qt.core.atomic; 21 import qt.core.bitarray; 22 import qt.core.bytearray; 23 import qt.core.datetime; 24 import qt.core.easingcurve; 25 import qt.core.global; 26 import qt.core.hash; 27 import qt.core.list; 28 import qt.core.locale; 29 import qt.core.map; 30 import qt.core.metatype; 31 import qt.core.namespace; 32 import qt.core.object; 33 import qt.core.qchar; 34 import qt.core.regularexpression; 35 import qt.core.string; 36 import qt.core.stringlist; 37 import qt.core.typeinfo; 38 import qt.core.url; 39 import qt.core.uuid; 40 import qt.helpers; 41 version(QT_NO_DATASTREAM){}else 42 import qt.core.datastream; 43 version(QT_NO_GEOM_VARIANT){}else 44 { 45 import qt.core.line; 46 import qt.core.point; 47 import qt.core.rect; 48 import qt.core.size; 49 } 50 version(QT_NO_REGEXP){}else 51 import qt.core.regexp; 52 53 /+ #ifndef QT_BOOTSTRAPPED 54 #endif 55 56 #if __has_include(<variant>) && __cplusplus >= 201703L 57 #elif defined(Q_CLANG_QDOC) 58 namespace std { template<typename...> struct variant; } 59 #endif 60 61 62 63 class QBitArray; 64 class QDataStream; 65 class QDate; 66 class QDateTime; 67 #if QT_CONFIG(easingcurve) 68 class QEasingCurve; 69 #endif 70 class QLine; 71 class QLineF; 72 class QLocale; 73 class QMatrix; 74 class QTransform; 75 class QStringList; 76 class QTime; 77 class QPoint; 78 class QPointF; 79 class QSize; 80 class QSizeF; 81 class QRect; 82 class QRectF; 83 #ifndef QT_NO_REGEXP 84 class QRegExp; 85 #endif // QT_NO_REGEXP 86 #if QT_CONFIG(regularexpression) 87 class QRegularExpression; 88 #endif // QT_CONFIG(regularexpression) 89 class QTextFormat; 90 class QTextLength; 91 class QUrl; 92 class QVariant; 93 class QVariantComparisonHelper; +/ 94 95 version(QT_MOC) 96 { 97 pragma(inline, true) T qvariant_cast(T)(ref const(QVariant) ); 98 } 99 100 101 extern(C++, "QtPrivate") { 102 103 struct ObjectInvoker(Derived, Argument, ReturnType) 104 { 105 static ReturnType invoke(Argument a) 106 { 107 return Derived.object(a); 108 } 109 } 110 111 struct MetaTypeInvoker(Derived, Argument, ReturnType) 112 { 113 static ReturnType invoke(Argument a) 114 { 115 return Derived.metaType(a); 116 } 117 } 118 119 struct TreatAsQObjectBeforeMetaType(Derived, T, Argument, ReturnType, /+ bool +/ /+ = IsPointerToTypeDerivedFromQObject<T>::Value +/) 120 { 121 ObjectInvoker!(Derived, Argument, ReturnType) base0; 122 alias base0 this; 123 } 124 125 /+ template <typename Derived, typename T, typename Argument, typename ReturnType> 126 struct TreatAsQObjectBeforeMetaType<Derived, T, Argument, ReturnType, false> : MetaTypeInvoker<Derived, Argument, ReturnType> 127 { 128 }; 129 130 template<typename T> struct QVariantValueHelper; +/ 131 } 132 133 @(QMetaType.Type.QVariant) @Q_MOVABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QVariant 134 { 135 public: 136 enum Type { 137 Invalid = QMetaType.Type.UnknownType, 138 Bool = QMetaType.Type.Bool, 139 Int = QMetaType.Type.Int, 140 UInt = QMetaType.Type.UInt, 141 LongLong = QMetaType.Type.LongLong, 142 ULongLong = QMetaType.Type.ULongLong, 143 Double = QMetaType.Type.Double, 144 Char = QMetaType.Type.QChar, 145 Map = QMetaType.Type.QVariantMap, 146 List = QMetaType.Type.QVariantList, 147 String = QMetaType.Type.QString, 148 StringList = QMetaType.Type.QStringList, 149 ByteArray = QMetaType.Type.QByteArray, 150 BitArray = QMetaType.Type.QBitArray, 151 Date = QMetaType.Type.QDate, 152 Time = QMetaType.Type.QTime, 153 DateTime = QMetaType.Type.QDateTime, 154 Url = QMetaType.Type.QUrl, 155 Locale = QMetaType.Type.QLocale, 156 Rect = QMetaType.Type.QRect, 157 RectF = QMetaType.Type.QRectF, 158 Size = QMetaType.Type.QSize, 159 SizeF = QMetaType.Type.QSizeF, 160 Line = QMetaType.Type.QLine, 161 LineF = QMetaType.Type.QLineF, 162 Point = QMetaType.Type.QPoint, 163 PointF = QMetaType.Type.QPointF, 164 RegExp = QMetaType.Type.QRegExp, 165 RegularExpression = QMetaType.Type.QRegularExpression, 166 Hash = QMetaType.Type.QVariantHash, 167 /+ #if QT_CONFIG(easingcurve) +/ 168 EasingCurve = QMetaType.Type.QEasingCurve, 169 /+ #endif +/ 170 Uuid = QMetaType.Type.QUuid, 171 /+ #if QT_CONFIG(itemmodel) +/ 172 ModelIndex = QMetaType.Type.QModelIndex, 173 PersistentModelIndex = QMetaType.Type.QPersistentModelIndex, 174 /+ #endif +/ 175 LastCoreType = QMetaType.Type.LastCoreType, 176 177 Font = QMetaType.Type.QFont, 178 Pixmap = QMetaType.Type.QPixmap, 179 Brush = QMetaType.Type.QBrush, 180 Color = QMetaType.Type.QColor, 181 Palette = QMetaType.Type.QPalette, 182 Image = QMetaType.Type.QImage, 183 Polygon = QMetaType.Type.QPolygon, 184 Region = QMetaType.Type.QRegion, 185 Bitmap = QMetaType.Type.QBitmap, 186 Cursor = QMetaType.Type.QCursor, 187 KeySequence = QMetaType.Type.QKeySequence, 188 Pen = QMetaType.Type.QPen, 189 TextLength = QMetaType.Type.QTextLength, 190 TextFormat = QMetaType.Type.QTextFormat, 191 Matrix = QMetaType.Type.QMatrix, 192 Transform = QMetaType.Type.QTransform, 193 Matrix4x4 = QMetaType.Type.QMatrix4x4, 194 Vector2D = QMetaType.Type.QVector2D, 195 Vector3D = QMetaType.Type.QVector3D, 196 Vector4D = QMetaType.Type.QVector4D, 197 Quaternion = QMetaType.Type.QQuaternion, 198 PolygonF = QMetaType.Type.QPolygonF, 199 Icon = QMetaType.Type.QIcon, 200 LastGuiType = QMetaType.Type.LastGuiType, 201 202 SizePolicy = QMetaType.Type.QSizePolicy, 203 204 UserType = QMetaType.Type.User, 205 // LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type 206 } 207 208 /+this()/+ noexcept+/ 209 { 210 this.d = typeof(this.d)(); 211 }+/ 212 ~this(); 213 this(Type type); 214 this(int typeId, const(void)* copy); 215 this(int typeId, const(void)* copy, uint flags); 216 @disable this(this); 217 this(ref const(QVariant) other); 218 219 version(QT_NO_DATASTREAM){}else 220 { 221 this(ref QDataStream s); 222 } 223 224 this(int i); 225 this(uint ui); 226 this(qlonglong ll); 227 this(qulonglong ull); 228 this(bool b); 229 this(double d); 230 this(float f); 231 /+ #ifndef QT_NO_CAST_FROM_ASCII 232 QT_ASCII_CAST_WARN QVariant(const char *str); 233 #endif +/ 234 235 this(ref const(QByteArray) bytearray); 236 this(ref const(QBitArray) bitarray); 237 this(ref const(QString) string); 238 this(const(QString) string){ this(string); } 239 this(QLatin1String string); 240 this(ref const(QStringList) stringlist); 241 this(QChar qchar); 242 this(ref const(QDate) date); 243 this(ref const(QTime) time); 244 this(ref const(QDateTime) datetime); 245 this(ref const(QList!(QVariant)) list); 246 // this(ref const(QMap!(QString,QVariant)) map); 247 // this(ref const(QHash!(QString,QVariant)) hash); 248 version(QT_NO_GEOM_VARIANT){}else 249 { 250 this(ref const(QSize) size); 251 this(ref const(QSizeF) size); 252 this(ref const(QPoint) pt); 253 this(ref const(QPointF) pt); 254 this(ref const(QLine) line); 255 this(ref const(QLineF) line); 256 this(ref const(QRect) rect); 257 this(ref const(QRectF) rect); 258 } 259 this(ref const(QLocale) locale); 260 /+ #ifndef QT_NO_REGEXP +/ 261 version(QT_NO_REGEXP){}else 262 { 263 this(ref const(QRegExp) regExp); 264 } 265 /+ #endif // QT_NO_REGEXP 266 #if QT_CONFIG(regularexpression) +/ 267 this(ref const(QRegularExpression) re); 268 /+ #endif // QT_CONFIG(regularexpression) 269 #if QT_CONFIG(easingcurve) +/ 270 this(ref const(QEasingCurve) easing); 271 /+ #endif +/ 272 this(ref const(QUuid) uuid); 273 /+ #ifndef QT_BOOTSTRAPPED +/ 274 this(ref const(QUrl) url); 275 // this(ref const(QJsonValue) jsonValue); 276 // this(ref const(QJsonObject) jsonObject); 277 // this(ref const(QJsonArray) jsonArray); 278 // this(ref const(QJsonDocument) jsonDocument); 279 /+ #endif // QT_BOOTSTRAPPED 280 #if QT_CONFIG(itemmodel) +/ 281 this(ref const(QModelIndex) modelIndex); 282 this(ref const(QPersistentModelIndex) modelIndex); 283 /+ #endif +/ 284 285 /+ref QVariant operator =(ref const(QVariant) other);+/ 286 /+ inline QVariant(QVariant &&other) noexcept : d(other.d) 287 { other.d = Private(); } +/ 288 /+ inline QVariant &operator=(QVariant &&other) noexcept 289 { qSwap(d, other.d); return *this; } +/ 290 291 /+ inline void swap(QVariant &other) noexcept { qSwap(d, other.d); } +/ 292 293 Type type() const; 294 int userType() const; 295 const(char)* typeName() const; 296 297 bool canConvert(int targetTypeId) const; 298 bool convert(int targetTypeId); 299 300 pragma(inline, true) bool isValid() const { return d.type != Type.Invalid; } 301 bool isNull() const; 302 303 void clear(); 304 305 void detach(); 306 pragma(inline, true) bool isDetached() const 307 { return !d.is_shared || d.data.shared_.ref_.loadRelaxed() == 1; } 308 309 int toInt(bool* ok = null) const; 310 uint toUInt(bool* ok = null) const; 311 qlonglong toLongLong(bool* ok = null) const; 312 qulonglong toULongLong(bool* ok = null) const; 313 bool toBool() const; 314 double toDouble(bool* ok = null) const; 315 float toFloat(bool* ok = null) const; 316 qreal toReal(bool* ok = null) const; 317 QByteArray toByteArray() const; 318 QBitArray toBitArray() const; 319 QString toString() const; 320 QStringList toStringList() const; 321 QChar toChar() const; 322 QDate toDate() const; 323 QTime toTime() const; 324 QDateTime toDateTime() const; 325 QList!(QVariant) toList() const; 326 // QMap!(QString, QVariant) toMap() const; 327 // QHash!(QString, QVariant) toHash() const; 328 329 version(QT_NO_GEOM_VARIANT){}else 330 { 331 QPoint toPoint() const; 332 QPointF toPointF() const; 333 QRect toRect() const; 334 QSize toSize() const; 335 QSizeF toSizeF() const; 336 QLine toLine() const; 337 QLineF toLineF() const; 338 QRectF toRectF() const; 339 } 340 QLocale toLocale() const; 341 /+ #ifndef QT_NO_REGEXP +/ 342 version(QT_NO_REGEXP){}else 343 { 344 QRegExp toRegExp() const; 345 } 346 /+ #endif // QT_NO_REGEXP 347 #if QT_CONFIG(regularexpression) +/ 348 QRegularExpression toRegularExpression() const; 349 /+ #endif // QT_CONFIG(regularexpression) 350 #if QT_CONFIG(easingcurve) +/ 351 QEasingCurve toEasingCurve() const; 352 /+ #endif +/ 353 QUuid toUuid() const; 354 /+ #ifndef QT_BOOTSTRAPPED +/ 355 QUrl toUrl() const; 356 /+ QJsonValue toJsonValue() const; +/ 357 /+ QJsonObject toJsonObject() const; +/ 358 /+ QJsonArray toJsonArray() const; +/ 359 /+ QJsonDocument toJsonDocument() const; +/ 360 /+ #endif // QT_BOOTSTRAPPED 361 #if QT_CONFIG(itemmodel) +/ 362 QModelIndex toModelIndex() const; 363 QPersistentModelIndex toPersistentModelIndex() const; 364 /+ #endif 365 366 #ifndef QT_NO_DATASTREAM +/ 367 version(QT_NO_DATASTREAM){}else 368 { 369 void load(ref QDataStream ds); 370 void save(ref QDataStream ds) const; 371 } 372 /+ #endif +/ 373 static const(char)* typeToName(int typeId); 374 static Type nameToType(const(char)* name); 375 376 void* data(); 377 const(void)* constData() const; 378 pragma(inline, true) const(void)* data() const { return constData(); } 379 380 /+ template<typename T> +/ 381 /+ inline void setValue(const T &value); +/ 382 383 /+ template<typename T> +/ 384 /+ inline T value() const 385 { return qvariant_cast<T>(*this); } +/ 386 387 static QVariant fromValue(T)(ref const T value) 388 { 389 import std.traits; 390 return QVariant(qMetaTypeId!T(), &value, isPointer!T); 391 } 392 393 /+ #if (__has_include(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC) 394 template<typename... Types> 395 static inline QVariant fromStdVariant(const std::variant<Types...> &value) 396 { 397 if (value.valueless_by_exception()) 398 return QVariant(); 399 return std::visit([](const auto &arg) { return fromValue(arg); }, value); 400 } 401 #endif +/ 402 403 /+ template<typename T> +/ 404 /+ bool canConvert() const 405 { return canConvert(qMetaTypeId<T>()); } +/ 406 407 public: 408 struct PrivateShared 409 { 410 pragma(inline, true) this(void* v) 411 { 412 this.ptr = v; 413 this.ref_ = 1; 414 } 415 void* ptr; 416 QAtomicInt ref_; 417 } 418 struct Private 419 { 420 /+pragma(inline, true) this()/+ noexcept+/ 421 { 422 this.type = Type.Invalid; 423 this.is_shared = false; 424 this.is_null = true; 425 data.ptr = null; 426 }+/ 427 428 // Internal constructor for initialized variants. 429 /+ explicit +/ pragma(inline, true) this(uint variantType)/+ noexcept+/ 430 { 431 this.type = variantType; 432 this.is_shared = false; 433 this.is_null = false; 434 } 435 436 /+ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/ 437 @disable this(this); 438 this(ref const(Private) other)/+ noexcept+/ 439 { 440 this.data = *cast(Data*)&other.data; 441 this.type = other.type; 442 this.is_shared = other.is_shared; 443 this.is_null = other.is_null; 444 } 445 /+ Private &operator=(const Private &other) noexcept = default; +/ 446 /+ #endif +/ 447 union Data 448 { 449 QObject o = null; 450 char c; 451 uchar uc; 452 short s; 453 byte sc; 454 ushort us; 455 int i; 456 uint u; 457 cpp_long l; 458 cpp_ulong ul; 459 bool b; 460 double d; 461 float f; 462 qreal real_; 463 qlonglong ll; 464 qulonglong ull; 465 void* ptr; 466 PrivateShared* shared_; 467 }Data data; 468 /+ uint type : 30; +/ 469 uint bitfieldData_type = Type.Invalid | (uint(1) << 31); 470 final uint type() const 471 { 472 return (bitfieldData_type >> 0) & 0x3fffffff; 473 } 474 final uint type(uint value) 475 { 476 bitfieldData_type = (bitfieldData_type & ~0x3fffffff) | ((value & 0x3fffffff) << 0); 477 return value; 478 } 479 /+ uint is_shared : 1; +/ 480 final uint is_shared() const 481 { 482 return (bitfieldData_type >> 30) & 0x1; 483 } 484 final uint is_shared(uint value) 485 { 486 bitfieldData_type = (bitfieldData_type & ~0x40000000) | ((value & 0x1) << 30); 487 return value; 488 } 489 /+ uint is_null : 1; +/ 490 final uint is_null() const 491 { 492 return (bitfieldData_type >> 31) & 0x1; 493 } 494 final uint is_null(uint value) 495 { 496 bitfieldData_type = (bitfieldData_type & ~0x80000000) | ((value & 0x1) << 31); 497 return value; 498 } 499 } 500 public: 501 alias f_construct = ExternCPPFunc!(void function(Private* , const(void)* )); 502 alias f_clear = ExternCPPFunc!(void function(Private* )); 503 alias f_null = ExternCPPFunc!(bool function(const(Private)* )); 504 version(QT_NO_DATASTREAM){}else 505 { 506 alias f_load = ExternCPPFunc!(void function(Private* , ref QDataStream )); 507 alias f_save = ExternCPPFunc!(void function(const(Private)* , ref QDataStream )); 508 } 509 alias f_compare = ExternCPPFunc!(bool function(const(Private)* , const(Private)* )); 510 alias f_convert = ExternCPPFunc!(bool function(const(QVariant.Private)* d, int t, void* , bool* )); 511 alias f_canConvert = ExternCPPFunc!(bool function(const(QVariant.Private)* d, int t)); 512 /+ typedef void (*f_debugStream)(QDebug, const QVariant &); +/ 513 /+ struct Handler { 514 f_construct construct; 515 f_clear clear; 516 f_null isNull; 517 #ifndef QT_NO_DATASTREAM 518 f_load load; 519 f_save save; 520 #endif 521 f_compare compare; 522 f_convert convert; 523 f_canConvert canConvert; 524 f_debugStream debugStream; 525 }; +/ 526 527 /+pragma(inline, true) bool operator ==(ref const(QVariant) v) const 528 { return cmp(v); }+/ 529 /+pragma(inline, true) bool operator !=(ref const(QVariant) v) const 530 { return !cmp(v); }+/ 531 /+ #if QT_DEPRECATED_SINCE(5, 15) +/ 532 /+/+ QT_DEPRECATED +/ pragma(inline, true) bool operator <(ref const(QVariant) v) const 533 { return compare(v) < 0; }+/ 534 /+/+ QT_DEPRECATED +/ pragma(inline, true) bool operator <=(ref const(QVariant) v) const 535 { return compare(v) <= 0; }+/ 536 /+/+ QT_DEPRECATED +/ pragma(inline, true) bool operator >(ref const(QVariant) v) const 537 { return compare(v) > 0; }+/ 538 /+/+ QT_DEPRECATED +/ pragma(inline, true) bool operator >=(ref const(QVariant) v) const 539 { return compare(v) >= 0; }+/ 540 /+ #endif +/ 541 542 protected: 543 /+ friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &); +/ 544 /+ #ifndef QT_NO_DEBUG_STREAM 545 friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &); 546 #endif 547 // ### Qt6: FIXME: Remove the special Q_CC_MSVC handling, it was introduced to maintain BC for QTBUG-41810 . 548 #if !defined(Q_NO_TEMPLATE_FRIENDS) && !defined(Q_CC_MSVC) +/ 549 /*static if(!defined!"Q_NO_TEMPLATE_FRIENDS") 550 { 551 /+ template<typename T> +/ 552 /+ friend inline T qvariant_cast(const QVariant &); +/ 553 /+ template<typename T> +/ /+ friend struct QtPrivate::QVariantValueHelper; +/ 554 protected: 555 } 556 else 557 { 558 /+ #else +/ 559 public: 560 }*/ 561 public: 562 /+ #endif +/ 563 Private d; 564 /+ void create(int type, const void *copy); +/ 565 bool cmp(ref const(QVariant) other) const; 566 int compare(ref const(QVariant) other) const; 567 bool convert(const(int) t, void* ptr) const; // ### Qt6: drop const 568 569 private: 570 // force compile error, prevent QVariant(bool) to be called 571 pragma(inline, true) @disable this(void* ) /+ = delete +/; 572 // QVariant::Type is marked as \obsolete, but we don't want to 573 // provide a constructor from its intended replacement, 574 // QMetaType::Type, instead, because the idea behind these 575 // constructors is flawed in the first place. But we also don't 576 // want QVariant(QMetaType::String) to compile and falsely be an 577 // int variant, so delete this constructor: 578 @disable this(QMetaType.Type) /+ = delete +/; 579 580 // These constructors don't create QVariants of the type associcated 581 // with the enum, as expected, but they would create a QVariant of 582 // type int with the value of the enum value. 583 // Use QVariant v = QColor(Qt::red) instead of QVariant v = Qt::red for 584 // example. 585 @disable this(/+ Qt:: +/qt.core.namespace.GlobalColor) /+ = delete +/; 586 @disable this(/+ Qt:: +/qt.core.namespace.BrushStyle) /+ = delete +/; 587 @disable this(/+ Qt:: +/qt.core.namespace.PenStyle) /+ = delete +/; 588 @disable this(/+ Qt:: +/qt.core.namespace.CursorShape) /+ = delete +/; 589 /+ #ifdef QT_NO_CAST_FROM_ASCII +/ 590 // force compile error when implicit conversion is not wanted 591 pragma(inline, true) @disable this(const(char)* ) /+ = delete +/; 592 /+ #endif +/ 593 public: 594 alias DataPtr = Private; 595 pragma(inline, true) ref DataPtr data_ptr() return { return d; } 596 pragma(inline, true) ref const(DataPtr) data_ptr() const return { return d; } 597 } 598 599 /+ #if QT_DEPRECATED_SINCE(5, 14) +/ 600 /+ QT_DEPRECATED_X("Use QVariant::fromValue() instead.") +/ 601 pragma(inline, true) QVariant qVariantFromValue(T)(ref const(T) t) 602 { 603 return QVariant.fromValue(t); 604 } 605 606 /+ QT_DEPRECATED_X("Use QVariant::setValue() instead.") +/ 607 pragma(inline, true) void qVariantSetValue(T)(ref QVariant v, ref const(T) t) 608 { 609 v.setValue(t); 610 } 611 /+ #endif 612 613 template<> 614 #if __has_include(<variant>) && __cplusplus >= 201703L 615 template<> 616 inline QVariant QVariant::fromValue(const std::monostate &) 617 { 618 return QVariant(); 619 } 620 #endif 621 622 template<> 623 #ifndef QT_NO_DATASTREAM 624 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p); 625 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p); 626 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant::Type& p); 627 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p); 628 #endif 629 630 631 #ifdef Q_QDOC 632 inline bool operator==(const QVariant &v1, const QVariant &v2); 633 inline bool operator!=(const QVariant &v1, const QVariant &v2); 634 #else +/ 635 636 /* Helper class to add one more level of indirection to prevent 637 implicit casts. 638 */ 639 extern(C++, class) struct QVariantComparisonHelper 640 { 641 public: 642 pragma(inline, true) this(ref const(QVariant) var) 643 { 644 this.v = &var; 645 } 646 private: 647 /+ friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &); +/ 648 const(QVariant)* v; 649 } 650 651 /+pragma(inline, true) bool operator ==(ref const(QVariant) v1, ref const(QVariantComparisonHelper) v2) 652 { 653 return v1.cmp(*v2.v); 654 }+/ 655 656 /+pragma(inline, true) bool operator !=(ref const(QVariant) v1, ref const(QVariantComparisonHelper) v2) 657 { 658 return !operator==(v1, v2); 659 }+/ 660 /+ #endif 661 Q_DECLARE_SHARED(QVariant) +/ 662 663 /+extern(C++, class) struct /+ Q_CORE_EXPORT +/ QSequentialIterable 664 { 665 private: 666 /+ QtMetaTypePrivate:: +/QSequentialIterableImpl m_impl; 667 public: 668 struct /+ Q_CORE_EXPORT +/ const_iterator 669 { 670 private: 671 /+ QtMetaTypePrivate:: +/QSequentialIterableImpl m_impl; 672 QAtomicInt* ref_; 673 /+ friend class QSequentialIterable; +/ 674 /+ explicit +/this(ref const(QSequentialIterable) iter, QAtomicInt* ref_); 675 676 /+ explicit +/this(ref const(/+ QtMetaTypePrivate:: +/QSequentialIterableImpl) impl, QAtomicInt* ref_); 677 678 void begin(); 679 void end(); 680 public: 681 ~this(); 682 683 @disable this(this); 684 this(ref const(const_iterator) other); 685 686 /+ref const_iterator operator =(ref const(const_iterator) other);+/ 687 688 const(QVariant) opUnary(string op)() const if(op == "*"); 689 /+bool operator ==(ref const(const_iterator) o) const;+/ 690 /+bool operator !=(ref const(const_iterator) o) const;+/ 691 ref const_iterator opUnary(string op)() if(op == "++"); 692 /+const_iterator operator ++(int);+/ 693 ref const_iterator opUnary(string op)() if(op == "--"); 694 /+const_iterator operator --(int);+/ 695 ref const_iterator opOpAssign(string op)(int j) if(op == "+"); 696 ref const_iterator opOpAssign(string op)(int j) if(op == "-"); 697 const_iterator opBinary(string op)(int j) const if(op == "+"); 698 const_iterator opBinary(string op)(int j) const if(op == "-"); 699 /+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } +/ 700 } 701 702 /+ friend struct const_iterator; +/ 703 704 /+ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/ 705 /+ explicit +/this(/+ QtMetaTypePrivate:: +/QSequentialIterableImpl impl); 706 /+ #else 707 explicit QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl); 708 #endif +/ 709 710 const_iterator begin() const; 711 const_iterator end() const; 712 713 QVariant at(int idx) const; 714 int size() const; 715 716 bool canReverseIterate() const; 717 }+/ 718 719 /+extern(C++, class) struct /+ Q_CORE_EXPORT +/ QAssociativeIterable 720 { 721 private: 722 /+ QtMetaTypePrivate:: +/QAssociativeIterableImpl m_impl; 723 public: 724 struct /+ Q_CORE_EXPORT +/ const_iterator 725 { 726 private: 727 /+ QtMetaTypePrivate:: +/QAssociativeIterableImpl m_impl; 728 QAtomicInt* ref_; 729 /+ friend class QAssociativeIterable; +/ 730 /+ explicit +/this(ref const(QAssociativeIterable) iter, QAtomicInt* ref_); 731 732 /+ explicit +/this(ref const(/+ QtMetaTypePrivate:: +/QAssociativeIterableImpl) impl, QAtomicInt* ref_); 733 734 void begin(); 735 void end(); 736 /+ void find(const QVariant &key); +/ 737 public: 738 ~this(); 739 @disable this(this); 740 this(ref const(const_iterator) other); 741 742 /+ref const_iterator operator =(ref const(const_iterator) other);+/ 743 744 const(QVariant) key() const; 745 746 const(QVariant) value() const; 747 748 const(QVariant) opUnary(string op)() const if(op == "*"); 749 /+bool operator ==(ref const(const_iterator) o) const;+/ 750 /+bool operator !=(ref const(const_iterator) o) const;+/ 751 ref const_iterator opUnary(string op)() if(op == "++"); 752 /+const_iterator operator ++(int);+/ 753 ref const_iterator opUnary(string op)() if(op == "--"); 754 /+const_iterator operator --(int);+/ 755 ref const_iterator opOpAssign(string op)(int j) if(op == "+"); 756 ref const_iterator opOpAssign(string op)(int j) if(op == "-"); 757 const_iterator opBinary(string op)(int j) const if(op == "+"); 758 const_iterator opBinary(string op)(int j) const if(op == "-"); 759 /+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } +/ 760 } 761 762 /+ friend struct const_iterator; +/ 763 764 /+ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/ 765 /+ explicit +/this(/+ QtMetaTypePrivate:: +/QAssociativeIterableImpl impl); 766 /+ #else 767 explicit QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl); 768 #endif +/ 769 770 const_iterator begin() const; 771 const_iterator end() const; 772 /+ const_iterator find(const QVariant &key) const; +/ 773 774 QVariant value(ref const(QVariant) key) const; 775 776 int size() const; 777 }+/ 778 779 version(QT_MOC){}else 780 { 781 /+extern(C++, "QtPrivate") { 782 /+ template<typename T> 783 struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T> 784 { 785 static T metaType(const QVariant &v) 786 { 787 const int vid = qMetaTypeId<T>(); 788 if (vid == v.userType()) 789 return *reinterpret_cast<const T *>(v.constData()); 790 T t; 791 if (v.convert(vid, &t)) 792 return t; 793 return T(); 794 } 795 #ifndef QT_NO_QOBJECT 796 static T object(const QVariant &v) 797 { 798 return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject 799 ? v.d.data.o 800 : QVariantValueHelper::metaType(v)); 801 } 802 #endif 803 }; +/ 804 805 struct QVariantValueHelperInterface(T) 806 { 807 QVariantValueHelper!(T) base0; 808 alias base0 this; 809 } 810 811 /+ template<> 812 struct QVariantValueHelperInterface<QSequentialIterable> 813 { 814 static QSequentialIterable invoke(const QVariant &v) 815 { 816 const int typeId = v.userType(); 817 if (typeId == qMetaTypeId<QVariantList>()) { 818 return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QVariantList*>(v.constData()))); 819 } 820 if (typeId == qMetaTypeId<QStringList>()) { 821 return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QStringList*>(v.constData()))); 822 } 823 #ifndef QT_BOOTSTRAPPED 824 if (typeId == qMetaTypeId<QByteArrayList>()) { 825 return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QByteArrayList*>(v.constData()))); 826 } 827 #endif 828 return QSequentialIterable(qvariant_cast<QtMetaTypePrivate::QSequentialIterableImpl>(v)); 829 } 830 }; 831 template<> 832 struct QVariantValueHelperInterface<QAssociativeIterable> 833 { 834 static QAssociativeIterable invoke(const QVariant &v) 835 { 836 const int typeId = v.userType(); 837 if (typeId == qMetaTypeId<QVariantMap>()) { 838 return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantMap*>(v.constData()))); 839 } 840 if (typeId == qMetaTypeId<QVariantHash>()) { 841 return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData()))); 842 } 843 return QAssociativeIterable(qvariant_cast<QtMetaTypePrivate::QAssociativeIterableImpl>(v)); 844 } 845 }; 846 template<> 847 struct QVariantValueHelperInterface<QVariantList> 848 { 849 static QVariantList invoke(const QVariant &v) 850 { 851 const int typeId = v.userType(); 852 if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() || 853 (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantList>()))) { 854 QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v); 855 QVariantList l; 856 l.reserve(iter.size()); 857 for (QSequentialIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it) 858 l << *it; 859 return l; 860 } 861 return QVariantValueHelper<QVariantList>::invoke(v); 862 } 863 }; 864 template<> 865 struct QVariantValueHelperInterface<QVariantHash> 866 { 867 static QVariantHash invoke(const QVariant &v) 868 { 869 const int typeId = v.userType(); 870 if (typeId == qMetaTypeId<QVariantMap>() || ((QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantHash>()))) { 871 QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v); 872 QVariantHash l; 873 l.reserve(iter.size()); 874 for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it) 875 static_cast<QMultiHash<QString, QVariant> &>(l).insert(it.key().toString(), it.value()); 876 return l; 877 } 878 return QVariantValueHelper<QVariantHash>::invoke(v); 879 } 880 }; 881 template<> 882 struct QVariantValueHelperInterface<QVariantMap> 883 { 884 static QVariantMap invoke(const QVariant &v) 885 { 886 const int typeId = v.userType(); 887 if (typeId == qMetaTypeId<QVariantHash>() || (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantMap>()))) { 888 QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v); 889 QVariantMap l; 890 for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it) 891 static_cast<QMultiMap<QString, QVariant> &>(l).insert(it.key().toString(), it.value()); 892 return l; 893 } 894 return QVariantValueHelper<QVariantMap>::invoke(v); 895 } 896 }; 897 template<> 898 struct QVariantValueHelperInterface<QPair<QVariant, QVariant> > 899 { 900 static QPair<QVariant, QVariant> invoke(const QVariant &v) 901 { 902 const int typeId = v.userType(); 903 904 if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>()) && !(typeId == qMetaTypeId<QPair<QVariant, QVariant> >())) { 905 QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>(); 906 const QtMetaTypePrivate::VariantData d1 = pi.first(); 907 QVariant v1(d1.metaTypeId, d1.data, d1.flags); 908 if (d1.metaTypeId == qMetaTypeId<QVariant>()) 909 v1 = *reinterpret_cast<const QVariant*>(d1.data); 910 911 const QtMetaTypePrivate::VariantData d2 = pi.second(); 912 QVariant v2(d2.metaTypeId, d2.data, d2.flags); 913 if (d2.metaTypeId == qMetaTypeId<QVariant>()) 914 v2 = *reinterpret_cast<const QVariant*>(d2.data); 915 916 return QPair<QVariant, QVariant>(v1, v2); 917 } 918 return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v); 919 } 920 }; +/ 921 }+/ 922 923 pragma(inline, true) T qvariant_cast(T)(ref const(QVariant) v) 924 { 925 // TODO: special cases of qvariant_cast 926 static if(is(T == class)) 927 static assert(false); 928 else 929 { 930 const(int) vid = qMetaTypeId!(T)(); 931 if (vid == v.userType()) 932 return *reinterpret_cast!(T*)(v.constData()); 933 static if(__traits(hasMember, T, "rawConstructor")) 934 mixin("T t = T.init; t.rawConstructor();"); 935 else 936 mixin("T t;"); 937 if (v.convert(vid, &t)) 938 return t; 939 static if(__traits(hasMember, T, "rawConstructor")) 940 mixin("T r = T.init; r.rawConstructor(); return r;"); 941 else 942 mixin("return T();"); 943 } 944 } 945 pragma(inline, true) T qvariant_cast(T)(const(QVariant) v) 946 { 947 return qvariant_cast!T(v); 948 } 949 950 /+ #if QT_DEPRECATED_SINCE(5, 0) 951 template<typename T> 952 inline QT_DEPRECATED T qVariantValue(const QVariant &variant) 953 { return qvariant_cast<T>(variant); } 954 955 template<typename T> 956 inline QT_DEPRECATED bool qVariantCanConvert(const QVariant &variant) 957 { return variant.template canConvert<T>(); } 958 #endif +/ 959 960 } 961 962 /+ #ifndef QT_NO_DEBUG_STREAM 963 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &); 964 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type); 965 #endif +/ 966