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