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.list;
15 extern(C++):
16 
17 import qt.config;
18 import qt.core.global;
19 import qt.core.refcount;
20 import qt.core.vector;
21 import qt.core.typeinfo;
22 import qt.helpers;
23 
24 /+ #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
25 #endif
26 
27 #ifdef Q_CC_MSVC
28 #pragma warning( push )
29 #pragma warning( disable : 4127 ) // "conditional expression is constant"
30 #endif
31 
32 
33 
34 template <typename T> class QVector;
35 template <typename T> class QSet; +/
36 
37 struct QListSpecialMethods(T)
38 {
39 protected:
40     /+ ~QListSpecialMethods() = default; +/
41 }
42 /+ template <> struct QListSpecialMethods<QByteArray>;
43 template <> struct QListSpecialMethods<QString>; +/
44 
45 struct /+ Q_CORE_EXPORT +/ QListData {
46     // tags for tag-dispatching of QList implementations,
47     // based on QList's three different memory layouts:
48     struct NotArrayCompatibleLayout {}
49     struct NotIndirectLayout {}
50     struct ArrayCompatibleLayout {
51         NotIndirectLayout base0;
52         alias base0 this;
53 }                           // data laid out like a C array
54     struct InlineWithPaddingLayout {
55         NotArrayCompatibleLayout base0;
56         alias base0 this;
57         NotIndirectLayout base1;
58 } // data laid out like a C array with padding
59     struct IndirectLayout {
60         NotArrayCompatibleLayout base0;
61         alias base0 this;
62 }                    // data allocated on the heap
63 
64     struct Data {
65         /+ QtPrivate:: +/qt.core.refcount.RefCount ref_;
66         int alloc; int begin; int end;
67         void*[1] array;
68     }
69     enum { DataHeaderSize = Data.sizeof - (void*).sizeof }
70 
71     Data* detach(int alloc);
72     Data* detach_grow(int* i, int n);
73     void realloc(int alloc);
74     void realloc_grow(int growth);
75     pragma(inline, true) void dispose() { dispose(d); }
76     static void dispose(Data* d);
77     mixin(mangleWindows("?shared_null@QListData@@2UData@1@B", exportOnWindows ~ q{
78     extern static __gshared Data shared_null;
79     }));
80     Data* d;
81     void** erase(void** xi);
82     void** append(int n);
83     void** append();
84     void** append(ref const(QListData) l);
85     void** prepend();
86     void** insert(int i);
87     void remove(int i);
88     void remove(int i, int n);
89     void move(int from, int to);
90     pragma(inline, true) int size() const/+ noexcept+/ { return int(d.end - d.begin); }   // q6sizetype
91     pragma(inline, true) bool isEmpty() const/+ noexcept+/ { return d.end  == d.begin; }
92     pragma(inline, true) void** at(int i) const/+ noexcept+/ { return cast(void**)(d.array.ptr + d.begin + i); }
93     pragma(inline, true) void** begin() const/+ noexcept+/ { return cast(void**)(d.array.ptr + d.begin); }
94     pragma(inline, true) void** end() const/+ noexcept+/ { return cast(void**)(d.array.ptr + d.end); }
95 }
96 
97 extern(C++, "QtPrivate") {
98 //    int indexOf(V, U)(ref const(QList!(V)) list, ref const(U) u, int from);
99 //    int lastIndexOf(V, U)(ref const(QList!(V)) list, ref const(U) u, int from);
100 }
101 
102 extern(C++, class) struct QList(T)
103 /+ #ifndef Q_QDOC +/
104 
105 /+ #endif +/
106 {
107     /+public QListSpecialMethods!(T) base0;
108     alias base0 this;+/
109 public:
110     /+ struct MemoryLayout
111         : std::conditional<
112             // must stay isStatic until ### Qt 6 for BC reasons (don't use !isRelocatable)!
113             QTypeInfo<T>::isStatic || QTypeInfo<T>::isLarge,
114             QListData::IndirectLayout,
115             typename std::conditional<
116                 sizeof(T) == sizeof(void*),
117                 QListData::ArrayCompatibleLayout,
118                 QListData::InlineWithPaddingLayout
119              >::type>::type {}; +/
120 private:
121     /+ template <typename V, typename U> +/ /+ friend int QtPrivate::indexOf(const QList<V> &list, const U &u, int from); +/
122     /+ template <typename V, typename U> +/ /+ friend int QtPrivate::lastIndexOf(const QList<V> &list, const U &u, int from); +/
123     struct Node { void* v;
124         ref T t()
125         {
126             static if(QTypeInfo!T.isLarge || QTypeInfo!T.isStatic)
127                 return *reinterpret_cast!(T*)(v);
128             else
129                 return *reinterpret_cast!(T*)(&this);
130         }
131     }
132 
133     version(Windows)
134         union { QListData.Data * d; QListData p; }
135     else
136         union { QListData.Data * d = &QListData.shared_null; QListData p; }
137 
138 
139 public:
140     version(Windows)
141     {
142         @disable this();
143         pragma(inline, true) void rawConstructor()/+ noexcept+/
144         {
145             this.d = const_cast!(QListData.Data*)(&QListData.shared_null);
146         }
147         static typeof(this) create()
148         {
149             typeof(this) r = typeof(this).init;
150             r.rawConstructor();
151             return r;
152         }
153     }
154     else
155     {
156         static typeof(this) create()
157         {
158             return typeof(this).init;
159         }
160     }
161 
162     this(this)
163     {
164         if (!d.ref_.ref_()) {
165             auto orig = p;
166             p.detach(d.alloc);
167 
168             /+ QT_TRY +/ {
169                  /+ QT_CATCH(...) +/scope(failure) {
170                     QListData.dispose(d);
171                 }
172                 node_copy(reinterpret_cast!(Node*)(p.begin()),
173                         reinterpret_cast!(Node*)(p.end()),
174                         reinterpret_cast!(Node*)(orig.begin()));
175             }
176         }
177     }
178     ~this()
179     {
180         if (!d.ref_.deref())
181             dealloc(d);
182     }
183     /+pragma(inline, true) ref QList!(T) operator =(ref const(QList!(T)) l)
184     {
185         if (d != l.d) {
186             QList<T> tmp(l);
187             tmp.swap(this);
188         }
189         return this;
190     }+/
191     /+ inline QList(QList<T> &&other) noexcept
192         : d(other.d) { other.d = const_cast<QListData::Data *>(&QListData::shared_null); } +/
193     /+ inline QList &operator=(QList<T> &&other) noexcept
194     { QList moved(std::move(other)); swap(moved); return *this; } +/
195     /+ inline void swap(QList<T> &other) noexcept { qSwap(d, other.d); } +/
196     /+ inline QList(std::initializer_list<T> args)
197         : QList(args.begin(), args.end()) {} +/
198     /+ template <typename InputIterator, QtPrivate::IfIsInputIterator<InputIterator> = true> +/
199     /+ QList(InputIterator first, InputIterator last); +/
200     /+bool operator ==(ref const(QList!(T)) l) const
201     {
202         if (d == l.d)
203             return true;
204         if (p.size() != l.p.size())
205             return false;
206         return this.op_eq_impl(l, MemoryLayout());
207     }+/
208     /+pragma(inline, true) bool operator !=(ref const(QList!(T)) l) const { return !(this == l); }+/
209 
210     pragma(inline, true) int size() const/+ noexcept+/ { return p.size(); }
211 
212     pragma(inline, true) void detach() { if (d.ref_.isShared()) detach_helper(); }
213 
214     pragma(inline, true) void detachShared()
215     {
216         // The "this->" qualification is needed for GCCE.
217         if (d.ref_.isShared() && this.d != &QListData.shared_null)
218             detach_helper();
219     }
220 
221     pragma(inline, true) bool isDetached() const { return !d.ref_.isShared(); }
222     version(QT_NO_UNSHARABLE_CONTAINERS){}else
223     {
224         pragma(inline, true) void setSharable(bool sharable)
225         {
226             if (sharable == d.ref_.isSharable())
227                 return;
228             if (!sharable)
229                 detach();
230             if (d != &QListData.shared_null)
231                 d.ref_.setSharable(sharable);
232         }
233     }
234     pragma(inline, true) bool isSharedWith(ref const(QList!(T)) other) const/+ noexcept+/ { return d == other.d; }
235 
236     pragma(inline, true) bool isEmpty() const/+ noexcept+/ { return p.isEmpty(); }
237 
238     void clear()
239     {
240         this = QList!(T).create();
241     }
242 
243     pragma(inline, true) ref const(T) at(int i) const
244     { (mixin(Q_ASSERT_X(q{i >= 0 && i < p.size()},q{ "QList<T>::at"},q{ "index out of range"})));
245      return reinterpret_cast!(Node*)(p.at(i)).t(); }
246     pragma(inline, true) ref const(T) opIndex(int i) const
247     { (mixin(Q_ASSERT_X(q{i >= 0 && i < p.size()},q{ "QList<T>::operator[]"},q{ "index out of range"})));
248      return reinterpret_cast!(Node*)(p.at(i)).t(); }
249     pragma(inline, true) ref T opIndex()(int i)
250     { (mixin(Q_ASSERT_X(q{i >= 0 && i < p.size()},q{ "QList<T>::operator[]"},/*what*/q{ "index out of range"})));
251       detach(); return reinterpret_cast!(Node*)(p.at(i)).t(); }
252 
253     void reserve(int alloc)
254     {
255         if (d.alloc < alloc) {
256             if (d.ref_.isShared())
257                 detach_helper(alloc);
258             else
259                 p.realloc(alloc);
260         }
261     }
262     void append()(ref const(T) t)
263     {
264         if (d.ref_.isShared()) {
265             Node* n = detach_helper_grow(int.max, 1);
266             /+ QT_TRY +/ {
267                  /+ QT_CATCH(...) +/scope(failure) {
268                     --d.end;
269                 }
270                 node_construct(n, t);
271             }
272         } else {
273             if (QTypeInfo!(T).isLarge || QTypeInfo!(T).isStatic) {
274                 Node* n = reinterpret_cast!(Node*)(p.append());
275                 /+ QT_TRY +/ {
276                      /+ QT_CATCH(...) +/scope(failure) {
277                         --d.end;
278                     }
279                     node_construct(n, t);
280                 }
281             } else {
282                 Node* n; Node copy;
283                 node_construct(&copy, t); // t might be a reference to an object in the array
284                 /+ QT_TRY +/ {
285                      /+ QT_CATCH(...) +/scope(failure) {
286                         node_destruct(&copy);
287                     }
288                     n = reinterpret_cast!(Node*)(p.append());
289                 }
290                 *n = copy;
291             }
292         }
293     }
294     void append()(const(T) t)
295     {
296         append(t);
297     }
298     /+pragma(inline, true) void append(ref const(QList!(T)) t)
299     {
300         this += t;
301     }+/
302     pragma(inline, true) void prepend()(ref const(T) t)
303     {
304         if (d.ref_.isShared()) {
305             Node* n = detach_helper_grow(0, 1);
306             /+ QT_TRY +/ {
307                  /+ QT_CATCH(...) +/scope(failure) {
308                     ++d.begin;
309                 }
310                 node_construct(n, t);
311             }
312         } else {
313             if (QTypeInfo!(T).isLarge || QTypeInfo!(T).isStatic) {
314                 Node* n = reinterpret_cast!(Node*)(p.prepend());
315                 /+ QT_TRY +/ {
316                      /+ QT_CATCH(...) +/scope(failure) {
317                         ++d.begin;
318                     }
319                     node_construct(n, t);
320                 }
321             } else {
322                 Node* n; Node copy;
323                 node_construct(&copy, t); // t might be a reference to an object in the array
324                 /+ QT_TRY +/ {
325                      /+ QT_CATCH(...) +/scope(failure) {
326                         node_destruct(&copy);
327                     }
328                     n = reinterpret_cast!(Node*)(p.prepend());
329                 }
330                 *n = copy;
331             }
332         }
333     }
334     pragma(inline, true) void insert()(int i, ref const(T) t)
335     {
336     /+ #if !QT_DEPRECATED_SINCE(5, 15)
337         Q_ASSERT_X(i >= 0 && i <= p.size(), "QList<T>::insert", "index out of range");
338     #elif !defined(QT_NO_DEBUG)
339         if (i < 0 || i > p.size())
340             qWarning("QList::insert(): Index out of range.");
341     #endif +/
342         if (d.ref_.isShared()) {
343             Node* n = detach_helper_grow(i, 1);
344             /+ QT_TRY +/ {
345                  /+ QT_CATCH(...) +/scope(failure) {
346                     p.remove(i);
347                 }
348                 node_construct(n, t);
349             }
350         } else {
351             if (QTypeInfo!(T).isLarge || QTypeInfo!(T).isStatic) {
352                 Node* n = reinterpret_cast!(Node*)(p.insert(i));
353                 /+ QT_TRY +/ {
354                      /+ QT_CATCH(...) +/scope(failure) {
355                         p.remove(i);
356                     }
357                     node_construct(n, t);
358                 }
359             } else {
360                 Node* n; Node copy;
361                 node_construct(&copy, t); // t might be a reference to an object in the array
362                 /+ QT_TRY +/ {
363                      /+ QT_CATCH(...) +/scope(failure) {
364                         node_destruct(&copy);
365                     }
366                     n = reinterpret_cast!(Node*)(p.insert(i));
367                 }
368                 *n = copy;
369             }
370         }
371     }
372     pragma(inline, true) void replace()(int i, ref const(T) t)
373     {
374         (mixin(Q_ASSERT_X(q{i >= 0 && i < p.size()},q{ "QList<T>::replace"},q{ "index out of range"})));
375         detach();
376         reinterpret_cast!(Node*)(p.at(i)).t() = *cast(T*)&t;
377     }
378     pragma(inline, true) void removeAt(int i)
379     {
380     /+ #if !QT_DEPRECATED_SINCE(5, 15) +/
381         (mixin(Q_ASSERT_X(q{i >= 0 && i < p.size()}, q{"QList<T>::removeAt"}, q{"index out of range"})));
382     /+ #endif +/
383         if (i < 0 || i >= p.size()) {
384     /+ #if !defined(QT_NO_DEBUG)
385             qWarning("QList::removeAt(): Index out of range.");
386     #endif +/
387             return;
388         }
389         detach();
390         node_destruct(reinterpret_cast!(Node*)(p.at(i))); p.remove(i);
391     }
392 /+    int removeAll(ref const(T) _t)
393     {
394         int index = indexOf(_t);
395         if (index == -1)
396             return 0;
397 
398         const(T) t = _t;
399         detach();
400 
401         Node* i = reinterpret_cast!(Node*)(p.at(index));
402         Node* e = reinterpret_cast!(Node*)(p.end());
403         Node* n = i;
404         node_destruct(i);
405         while (++i != e) {
406             if (i.t() == t)
407                 node_destruct(i);
408             else
409                 *n++ = *i;
410         }
411 
412         int removedCount = cast(int)(e - n);
413         d.end -= removedCount;
414         return removedCount;
415     }+/
416     /+bool removeOne(ref const(T) _t)
417     {
418         int index = indexOf(_t);
419         if (index != -1) {
420             removeAt(index);
421             return true;
422         }
423         return false;
424     }+/
425     pragma(inline, true) T takeAt()(int i)
426     { (mixin(Q_ASSERT_X(q{i >= 0 && i < p.size()},q{ "QList<T>::take"},q{ "index out of range"})));
427      detach();
428      Node* n = reinterpret_cast!(Node*)(p.at(i));
429      T t = /+ std:: +//*move*/(n.t()); node_destruct(n);
430      p.remove(i); return t; }
431     pragma(inline, true) T takeFirst()()
432     { T t = /+ std:: +//*move*/(first()); removeFirst(); return t; }
433     pragma(inline, true) T takeLast()
434     { T t = /+ std:: +//*move*/(last()); removeLast(); return t; }
435     pragma(inline, true) void move()(int from, int to)
436     {
437         (mixin(Q_ASSERT_X(q{from >= 0 && from < p.size() && to >= 0 && to < p.size()},q{
438                    "QList<T>::move"},q{ "index out of range"})));
439         detach();
440         p.move(from, to);
441     }
442 /+    pragma(inline, true) void swapItemsAt(int i, int j)
443     {
444         (mixin(Q_ASSERT_X(q{i >= 0 && i < p.size() && j >= 0 && j < p.size()},q{
445                     "QList<T>::swap"},q{ "index out of range"})));
446         detach();
447         qSwap(d.array[d.begin + i], d.array[d.begin + j]);
448     }
449 +/
450 /+ #if QT_DEPRECATED_SINCE(5, 13) && QT_VERSION < QT_VERSION_CHECK(6,0,0) +/
451     /+ QT_DEPRECATED_VERSION_X_5_13("Use QList<T>::swapItemsAt()")
452     void swap(int i, int j) { swapItemsAt(i, j); } +/
453 /+ #endif +/
454     int indexOf(ref const(T) t, int from = 0) const
455     {
456         return /+ QtPrivate:: +/.indexOf!(T, T)(this, t, from);
457     }
458     int lastIndexOf(ref const(T) t, int from = -1) const
459     {
460         import qt.core.stringalgorithms;
461 
462         return /+ QtPrivate:: +/.lastIndexOf!(T, T)(this, t, from);
463     }
464 /+    bool contains(ref const(T) t) const
465     {
466         return contains_impl(t, MemoryLayout());
467     }
468     int count(ref const(T) t) const
469     {
470         return this.count_impl(t, MemoryLayout());
471     }
472 +/
473 
474     /+
475     extern(C++, class) struct const_iterator;
476     +/
477 
478     extern(C++, class) struct iterator {
479     public:
480         Node* i = null;
481 //        alias iterator_category = /+ std:: +/random_access_iterator_tag;
482         // ### Qt6: use int
483         alias difference_type = qptrdiff;
484         alias value_type = T;
485         alias pointer = T*;
486         /+ typedef T &reference; +/
487 
488         //@disable this();
489         /+pragma(inline, true) this()/+ noexcept+/
490         {
491             this.i = null;
492         }+/
493         pragma(inline, true) this(Node* n)/+ noexcept+/
494         {
495             this.i = n;
496         }
497 /+ #if QT_VERSION < QT_VERSION_CHECK(6,0,0) +/
498         // can't remove it in Qt 5, since doing so would make the type trivial,
499         // which changes the way it's passed to functions by value.
500         //@disable this(this);
501         pragma(inline, true) this(ref const(iterator) o)/+ noexcept+/
502         {
503             this.i = cast(Node*)o.i;
504         }
505         /+pragma(inline, true) ref iterator operator =(ref const(iterator) o)/+ noexcept+/
506         { i = o.i; return this; }+/
507 /+ #endif +/
508         pragma(inline, true) ref T opUnary(string op)() const if(op == "*") { return (cast(Node*)i).t(); }
509         /+pragma(inline, true) T* operator ->() const { return &i.t(); }+/
510         pragma(inline, true) ref T opIndex(difference_type j) const { return (cast(Node*)i).t(); }
511         /+pragma(inline, true) bool operator ==(ref const(iterator) o) const/+ noexcept+/ { return i == o.i; }+/
512         /+pragma(inline, true) bool operator !=(ref const(iterator) o) const/+ noexcept+/ { return i != o.i; }+/
513         /+pragma(inline, true) bool operator <(ref const(iterator) other) const/+ noexcept+/ { return i < other.i; }+/
514         /+pragma(inline, true) bool operator <=(ref const(iterator) other) const/+ noexcept+/ { return i <= other.i; }+/
515         /+pragma(inline, true) bool operator >(ref const(iterator) other) const/+ noexcept+/ { return i > other.i; }+/
516         /+pragma(inline, true) bool operator >=(ref const(iterator) other) const/+ noexcept+/ { return i >= other.i; }+/
517 /+ #ifndef QT_STRICT_ITERATORS +/
518         /+pragma(inline, true) bool operator ==(ref const(const_iterator) o) const/+ noexcept+/
519             { return i == o.i; }+/
520         /+pragma(inline, true) bool operator !=(ref const(const_iterator) o) const/+ noexcept+/
521             { return i != o.i; }+/
522         /+pragma(inline, true) bool operator <(ref const(const_iterator) other) const/+ noexcept+/
523             { return i < other.i; }+/
524         /+pragma(inline, true) bool operator <=(ref const(const_iterator) other) const/+ noexcept+/
525             { return i <= other.i; }+/
526         /+pragma(inline, true) bool operator >(ref const(const_iterator) other) const/+ noexcept+/
527             { return i > other.i; }+/
528         /+pragma(inline, true) bool operator >=(ref const(const_iterator) other) const/+ noexcept+/
529             { return i >= other.i; }+/
530 /+ #endif +/
531         pragma(inline, true) ref iterator opUnary(string op)() if(op == "++") { ++i; return this; }
532         /+pragma(inline, true) iterator operator ++(int) { Node* n = i; ++i; return cast(iterator)(n); }+/
533         pragma(inline, true) ref iterator opUnary(string op)() if(op == "--") { i--; return this; }
534         /+pragma(inline, true) iterator operator --(int) { Node* n = i; i--; return cast(iterator)(n); }+/
535         pragma(inline, true) ref iterator opOpAssign(string op)(difference_type j) if(op == "+") { i+=j; return this; }
536         pragma(inline, true) ref iterator opOpAssign(string op)(difference_type j) if(op == "-") { i-=j; return this; }
537         pragma(inline, true) iterator opBinary(string op)(difference_type j) const if(op == "+") { return iterator(cast(Node*)(i+j)); }
538         pragma(inline, true) iterator opBinary(string op)(difference_type j) const if(op == "-") { return iterator(cast(Node*)(i-j)); }
539         /+ friend inline iterator operator+(difference_type j, iterator k) { return k + j; } +/
540         pragma(inline, true) int opBinary(string op)(iterator j) const if(op == "-") { return cast(int)(i - j.i); }
541     }
542     /+ friend class iterator; +/
543 
544     extern(C++, class) struct const_iterator {
545     public:
546         Node* i = null;
547 //        alias iterator_category = /+ std:: +/random_access_iterator_tag;
548         // ### Qt6: use int
549         alias difference_type = qptrdiff;
550         alias value_type = T;
551         alias pointer = const(T)*;
552         /+ typedef const T &reference; +/
553 
554         //@disable this();
555         /+pragma(inline, true) this()/+ noexcept+/
556         {
557             this.i = null;
558         }+/
559         pragma(inline, true) this(Node* n)/+ noexcept+/
560         {
561             this.i = n;
562         }
563 /+ #if QT_VERSION < QT_VERSION_CHECK(6,0,0) +/
564         // can't remove it in Qt 5, since doing so would make the type trivial,
565         // which changes the way it's passed to functions by value.
566         //@disable this(this);
567         pragma(inline, true) this(ref const(const_iterator) o)/+ noexcept+/
568         {
569             this.i = cast(Node*)o.i;
570         }
571         /+pragma(inline, true) ref const_iterator operator =(ref const(const_iterator) o)/+ noexcept+/
572         { i = o.i; return this; }+/
573 /+ #endif
574 #ifdef QT_STRICT_ITERATORS
575         inline explicit const_iterator(const iterator &o) noexcept : i(o.i) {}
576 #else +/
577         pragma(inline, true) this(ref const(iterator) o)/+ noexcept+/
578         {
579             this.i = cast(Node*)o.i;
580         }
581         pragma(inline, true) this(const(iterator) o)/+ noexcept+/
582         {
583             this.i = cast(Node*)o.i;
584         }
585 /+ #endif +/
586         pragma(inline, true) ref const(T) opUnary(string op)() const if(op == "*") { return i.t(); }
587         /+pragma(inline, true) const(T)* operator ->() const { return &i.t(); }+/
588         pragma(inline, true) ref const(T) opIndex(difference_type j) const { return (cast(Node*)i)[j].t(); }
589         /+pragma(inline, true) bool operator ==(ref const(const_iterator) o) const/+ noexcept+/ { return i == o.i; }+/
590         /+pragma(inline, true) bool operator !=(ref const(const_iterator) o) const/+ noexcept+/ { return i != o.i; }+/
591         /+pragma(inline, true) bool operator <(ref const(const_iterator) other) const/+ noexcept+/ { return i < other.i; }+/
592         /+pragma(inline, true) bool operator <=(ref const(const_iterator) other) const/+ noexcept+/ { return i <= other.i; }+/
593         /+pragma(inline, true) bool operator >(ref const(const_iterator) other) const/+ noexcept+/ { return i > other.i; }+/
594         /+pragma(inline, true) bool operator >=(ref const(const_iterator) other) const/+ noexcept+/ { return i >= other.i; }+/
595         pragma(inline, true) ref const_iterator opUnary(string op)() if(op == "++") { ++i; return this; }
596         /+pragma(inline, true) const_iterator operator ++(int) { Node* n = i; ++i; return cast(const_iterator)(n); }+/
597         pragma(inline, true) ref const_iterator opUnary(string op)() if(op == "--") { i--; return this; }
598         /+pragma(inline, true) const_iterator operator --(int) { Node* n = i; i--; return cast(const_iterator)(n); }+/
599         pragma(inline, true) ref const_iterator opOpAssign(string op)(difference_type j) if(op == "+") { i+=j; return this; }
600         pragma(inline, true) ref const_iterator opOpAssign(string op)(difference_type j) if(op == "-") { i-=j; return this; }
601         pragma(inline, true) const_iterator opBinary(string op)(difference_type j) const if(op == "+") { return const_iterator(i+j); }
602         pragma(inline, true) const_iterator opBinary(string op)(difference_type j) const if(op == "-") { return const_iterator(i-j); }
603         /+ friend inline const_iterator operator+(difference_type j, const_iterator k) { return k + j; } +/
604         pragma(inline, true) int opBinary(string op)(const_iterator j) const if(op == "-") { return cast(int)(i - j.i); }
605     }
606     /+ friend class const_iterator; +/
607 
608     // stl style
609     /+ typedef std::reverse_iterator<iterator> reverse_iterator; +/
610     /+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; +/
611     pragma(inline, true) iterator begin() { detach(); return iterator(reinterpret_cast!(Node*)(p.begin())); }
612     pragma(inline, true) const_iterator begin() const/+ noexcept+/ { return const_iterator(reinterpret_cast!(Node*)(p.begin())); }
613     pragma(inline, true) const_iterator cbegin() const/+ noexcept+/ { return const_iterator(reinterpret_cast!(Node*)(p.begin())); }
614     pragma(inline, true) const_iterator constBegin() const/+ noexcept+/ { return const_iterator(reinterpret_cast!(Node*)(p.begin())); }
615     pragma(inline, true) iterator end() { detach(); return iterator(reinterpret_cast!(Node*)(p.end())); }
616     pragma(inline, true) const_iterator end() const/+ noexcept+/ { return const_iterator(reinterpret_cast!(Node*)(p.end())); }
617     pragma(inline, true) const_iterator cend() const/+ noexcept+/ { return const_iterator(reinterpret_cast!(Node*)(p.end())); }
618     pragma(inline, true) const_iterator constEnd() const/+ noexcept+/ { return const_iterator(reinterpret_cast!(Node*)(p.end())); }
619     /+ reverse_iterator rbegin() { return reverse_iterator(end()); } +/
620     /+ reverse_iterator rend() { return reverse_iterator(begin()); } +/
621     /+ const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } +/
622     /+ const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } +/
623     /+ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } +/
624     /+ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } +/
625 
626     auto opSlice()const
627     {
628         struct R
629         {
630             iterator i;
631             iterator end;
632             ref T front()
633             {
634                 return *i;
635             }
636             bool empty()
637             {
638                 return i == end;
639             }
640             void popFront()
641             {
642                 ++i;
643             }
644         }
645         auto this_ = cast(QList*)&this;
646         return R(this_.begin(), this_.end());
647     }
648 
649     pragma(inline, true) iterator insert()(iterator before, ref const(T) t)
650     {
651         (mixin(Q_ASSERT_X(q{QList.isValidIterator(before)},q{ "QList::insert"},q{ "The specified iterator argument 'before' is invalid"})));
652 
653         int iBefore = cast(int)(before.i - reinterpret_cast!(Node*)(p.begin()));
654         Node* n = null;
655         if (d.ref_.isShared())
656             n = detach_helper_grow(iBefore, 1);
657         else
658             n = reinterpret_cast!(Node*)(p.insert(iBefore));
659         /+ QT_TRY +/ {
660              /+ QT_CATCH(...) +/scope(failure) {
661                 p.remove(iBefore);
662             }
663             node_construct(n, t);
664         }
665         return cast(iterator)(n);
666     }
667     pragma(inline, true) iterator erase(iterator it)
668     /+/+ typename QList<T>::iterator +/pragma(inline, true) iterator erase(iterator it)+/
669     {
670         (mixin(Q_ASSERT_X(q{QList!T.isValidIterator(it)},q{ "QList::erase"},q{ "The specified iterator argument 'it' is invalid"})));
671         if (d.ref_.isShared()) {
672             int offset = cast(int)(it.i - reinterpret_cast!(Node*)(p.begin()));
673             it = begin(); // implies detach()
674             it += offset;
675         }
676         node_destruct(it.i);
677         return iterator(reinterpret_cast!(Node*)(p.erase(reinterpret_cast!(void**)(it.i))));
678     }
679     iterator erase(iterator afirst, iterator alast)
680     /+/+ typename QList<T>::iterator +/iterator erase(/+ typename QList<T>::iterator +/ iterator afirst,
681                                                                      /+ typename QList<T>::iterator +/ iterator alast)+/
682     {
683         (mixin(Q_ASSERT_X(q{QList.isValidIterator(afirst)},q{ "QList::erase"},q{ "The specified iterator argument 'afirst' is invalid"})));
684         (mixin(Q_ASSERT_X(q{QList.isValidIterator(alast)},q{ "QList::erase"},q{ "The specified iterator argument 'alast' is invalid"})));
685 
686         if (d.ref_.isShared()) {
687             // ### A block is erased and a detach is needed. We should shrink and only copy relevant items.
688             int offsetfirst = cast(int)(afirst.i - reinterpret_cast!(Node*)(p.begin()));
689             int offsetlast = cast(int)(alast.i - reinterpret_cast!(Node*)(p.begin()));
690             afirst = begin(); // implies detach()
691             alast = afirst;
692             afirst += offsetfirst;
693             alast += offsetlast;
694         }
695 
696         for (Node *n = afirst.i; n < alast.i; ++n)
697             node_destruct(n);
698         int idx = cast(int)(afirst - begin());
699         p.remove(idx, alast - afirst);
700         return begin() + idx;
701     }
702 
703     // more Qt
704     alias Iterator = iterator;
705     alias ConstIterator = const_iterator;
706     pragma(inline, true) int count() const { return p.size(); }
707     pragma(inline, true) int length() const { return p.size(); } // Same as count()
708     pragma(inline, true) ref T first() { (mixin(Q_ASSERT(q{!QList.isEmpty()}))); return *begin(); }
709     pragma(inline, true) ref const(T) constFirst() const { return first(); }
710     pragma(inline, true) ref const(T) first() const { (mixin(Q_ASSERT(q{!QList.isEmpty()}))); return at(0); }
711     ref T last() { (mixin(Q_ASSERT(q{!QList.isEmpty()}))); return *(--end()); }
712     ref const(T) last() const { (mixin(Q_ASSERT(q{!QList.isEmpty()}))); return at(count() - 1); }
713     pragma(inline, true) ref const(T) constLast() const { return last(); }
714     pragma(inline, true) void removeFirst() { (mixin(Q_ASSERT(q{!QList.isEmpty()}))); erase(begin()); }
715     pragma(inline, true) void removeLast() { (mixin(Q_ASSERT(q{!QList.isEmpty()}))); erase(--end()); }
716     pragma(inline, true) bool startsWith(ref const(T) t) const { return !isEmpty() && first() == t; }
717     pragma(inline, true) bool endsWith(ref const(T) t) const { return !isEmpty() && last() == t; }
718 /+    QList!(T) mid(int pos, int alength = -1) const
719     {
720 //        using namespace QtPrivate;
721         switch (QContainerImplHelper.mid(size(), &pos, &alength)) {
722         case QContainerImplHelper.Null:
723         case QContainerImplHelper.Empty:
724             return QList!(T)();
725         case QContainerImplHelper.Full:
726             return this;
727         case QContainerImplHelper.Subset:
728             break;default:
729 
730         }
731 
732         QList!T cpy;
733         if (alength <= 0)
734             return cpy;
735         cpy.reserve(alength);
736         cpy.d.end = alength;
737         /+ QT_TRY +/ {
738              /+ QT_CATCH(...) +/scope(failure) {
739                 // restore the old end
740                 cpy.d.end = 0;
741             }
742             cpy.node_copy(reinterpret_cast!(Node*)(cpy.p.begin()),
743                           reinterpret_cast!(Node*)(cpy.p.end()),
744                           reinterpret_cast!(Node*)(p.begin() + pos));
745         }
746         return cpy;
747     }
748 +/
749 
750     T value()(int i) const
751     {
752         if (i < 0 || i >= p.size()) {
753             return T();
754         }
755         return reinterpret_cast!(Node*)(p.at(i)).t();
756     }
757 /+    T value(int i, ref const(T) defaultValue) const
758     {
759         return ((i < 0 || i >= p.size()) ? defaultValue : reinterpret_cast!(Node*)(p.at(i)).t());
760     }+/
761 
762     // stl compatibility
763     pragma(inline, true) void push_back()(ref const(T) t) { append(t); }
764     pragma(inline, true) void push_front()(ref const(T) t) { prepend(t); }
765     pragma(inline, true) ref T front() { return first(); }
766     pragma(inline, true) ref const(T) front() const { return first(); }
767     pragma(inline, true) ref T back() { return last(); }
768     pragma(inline, true) ref const(T) back() const { return last(); }
769     pragma(inline, true) void pop_front() { removeFirst(); }
770     pragma(inline, true) void pop_back() { removeLast(); }
771     pragma(inline, true) bool empty() const { return isEmpty(); }
772     alias size_type = int;
773     alias value_type = T;
774     alias pointer = value_type*;
775     alias const_pointer = const(value_type)*;
776     /+ typedef value_type &reference; +/
777     /+ typedef const value_type &const_reference; +/
778     // ### Qt6: use int
779     alias difference_type = qptrdiff;
780 
781     // comfort
782     extern(D) ref QList!(T) opOpAssign(string op)(ref const(QList!(T)) l) if(op == "~")
783     {
784         if (!l.isEmpty()) {
785             if (d == &QListData.shared_null) {
786                 this = l;
787             } else {
788                 Node* n = (d.ref_.isShared())
789                           ? detach_helper_grow(int.max, l.size())
790                           : reinterpret_cast!(Node*)(p.append(l.p));
791                 /+ QT_TRY +/ {
792                      /+ QT_CATCH(...) +/scope(failure) {
793                         // restore the old end
794                         d.end -= int(reinterpret_cast!(Node*)(p.end()) - n);
795                     }
796                     node_copy(n, reinterpret_cast!(Node*)(p.end()),
797                               reinterpret_cast!(Node*)(l.p.begin()));
798                 }
799             }
800         }
801         return this;
802     }
803     extern(D) pragma(inline, true) QList!(T) opBinary(string op)(ref const(QList!(T)) l) const if(op == "~")
804     { QList n = this; n ~= l; return n; }
805     extern(D) pragma(inline, true) ref QList!(T) opOpAssign(string op)(ref const(T) t) if(op == "~")
806     { append(t); return this; }
807     /+pragma(inline, true) ref QList!(T) operator << (ref const(T) t)
808     { append(t); return this; }+/
809     /+pragma(inline, true) ref QList!(T) operator <<(ref const(QList!(T)) l)
810     { this += l; return this; }+/
811 
812     extern(D) void opOpAssign(string op, T2)(ref const T2 t) if(op == "~" && !is(const(T2) == const(T)))
813     {
814         auto tmp = T(t);
815         append(tmp);
816     }
817     extern(D) void opOpAssign(string op)(const T t) if(op == "~")
818     {
819         append(t);
820     }
821 
822 /+    static QList!(T) fromVector(ref const(QVector!(T)) vector)
823     {
824         return vector.toList();
825     }
826     QVector!(T) toVector() const
827     {
828         return QVector!(T)(begin(), end());
829     }+/
830 
831 /+ #if QT_DEPRECATED_SINCE(5, 14) && QT_VERSION < QT_VERSION_CHECK(6,0,0) +/
832     /+ QT_DEPRECATED_VERSION_X_5_14("Use QList<T>(set.begin(), set.end()) instead.")
833     static QList<T> fromSet(const QSet<T> &set); +/
834     /+ QT_DEPRECATED_VERSION_X_5_14("Use QSet<T>(list.begin(), list.end()) instead.")
835     QSet<T> toSet() const; +/
836 
837     /+ QT_DEPRECATED_VERSION_X_5_14("Use QList<T>(list.begin(), list.end()) instead.")
838     static inline QList<T> fromStdList(const std::list<T> &list)
839     { return QList<T>(list.begin(), list.end()); } +/
840     /+ QT_DEPRECATED_VERSION_X_5_14("Use std::list<T>(list.begin(), list.end()) instead.")
841     inline std::list<T> toStdList() const
842     { return std::list<T>(begin(), end()); } +/
843 /+ #endif +/
844 
845 private:
846     Node* detach_helper_grow(int i, int c)
847     /+/+ typename QList<T>::Node +/Node* detach_helper_grow(int i, int c)+/
848     {
849         Node* n = reinterpret_cast!(Node*)(p.begin());
850         QListData.Data *x = p.detach_grow(&i, c);
851         /+ QT_TRY +/ {
852              /+ QT_CATCH(...) +/scope(failure) {
853                 p.dispose();
854                 d = x;
855             }
856             node_copy(reinterpret_cast!(Node*)(p.begin()),
857                       reinterpret_cast!(Node*)(p.begin() + i), n);
858         }
859         /+ QT_TRY +/ {
860              /+ QT_CATCH(...) +/scope(failure) {
861                 node_destruct(reinterpret_cast!(Node*)(p.begin()),
862                               reinterpret_cast!(Node*)(p.begin() + i));
863                 p.dispose();
864                 d = x;
865             }
866             node_copy(reinterpret_cast!(Node*)(p.begin() + i + c),
867                       reinterpret_cast!(Node*)(p.end()), n + i);
868         }
869 
870         if (!x.ref_.deref())
871             dealloc(x);
872 
873         return reinterpret_cast!(Node*)(p.begin() + i);
874     }
875     void detach_helper(int alloc)
876     {
877         Node* n = reinterpret_cast!(Node*)(p.begin());
878         QListData.Data *x = p.detach(alloc);
879         /+ QT_TRY +/ {
880              /+ QT_CATCH(...) +/scope(failure) {
881                 p.dispose();
882                 d = x;
883             }
884             node_copy(reinterpret_cast!(Node*)(p.begin()), reinterpret_cast!(Node*)(p.end()), n);
885         }
886 
887         if (!x.ref_.deref())
888             dealloc(x);
889     }
890     void detach_helper()
891     {
892         detach_helper(d.alloc);
893     }
894     void dealloc(QListData.Data* data)
895     {
896         node_destruct(reinterpret_cast!(Node*)(data.array.ptr + data.begin),
897                       reinterpret_cast!(Node*)(data.array.ptr + data.end));
898         QListData.dispose(data);
899     }
900 
901     pragma(inline, true) void node_construct()(Node* n, ref const(T) t)
902     {
903         import core.lifetime;
904         import core.stdcpp.new_;
905 
906         static if (QTypeInfo!(T).isLarge || QTypeInfo!(T).isStatic)
907         {
908             n.v = cpp_new!T;
909             *cast(T*)n.v = *cast(T*)&t;
910         }
911         else static if (QTypeInfo!(T).isComplex)
912         {
913             static if(__traits(hasMember, T, "rawConstructor"))
914                 (*cast(T*)n).rawConstructor();
915             else
916                 emplace!T(cast(T*)n);
917             *cast(T*)n = *cast(T*)&t;
918         }
919     /+ #if (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__IBMCPP__)) && !defined(__OPTIMIZE__) +/
920         // This violates pointer aliasing rules, but it is known to be safe (and silent)
921         // in unoptimized GCC builds (-fno-strict-aliasing). The other compilers which
922         // set the same define are assumed to be safe.
923         else *reinterpret_cast!(T*)(n) = *cast(T*)&t;
924     /+ #else
925         // This is always safe, but penaltizes unoptimized builds a lot.
926         else ::memcpy(n, static_cast<const void *>(&t), sizeof(T));
927     #endif +/
928     }
929     pragma(inline, true) void node_destruct(Node* n)
930     {
931         import core.stdcpp.new_;
932 
933         static if (QTypeInfo!(T).isLarge || QTypeInfo!(T).isStatic) cpp_delete(reinterpret_cast!(T*)(n.v));
934         else if (QTypeInfo!(T).isComplex) destroy!false(*reinterpret_cast!(T*)(n));
935     }
936     pragma(inline, true) void node_copy(Node* from, Node* to, Node* src)
937     {
938         import core.lifetime;
939         import core.stdc.string;
940         import core.stdcpp.new_;
941 
942         Node* current = from;
943         static if (QTypeInfo!(T).isLarge || QTypeInfo!(T).isStatic) {
944             /+ QT_TRY +/ {
945                  /+ QT_CATCH(...) +/scope(failure) {
946                     while (current-- != from)
947                         cpp_delete(reinterpret_cast!(T*)(current.v));
948                 }
949                 while(current != to) {
950                     current.v = cpp_new!T(*reinterpret_cast!(T*)(src.v));
951                     ++current;
952                     ++src;
953                 }
954             }
955 
956         } else if (QTypeInfo!(T).isComplex) {
957             /+ QT_TRY +/ {
958                  /+ QT_CATCH(...) +/scope(failure) {
959                     while (current-- != from)
960                         destroy!false(*reinterpret_cast!(T*)(current));
961                 }
962                 while(current != to) {
963                     emplace!T(cast(T*)current, *reinterpret_cast!(T*)(src));
964                     ++current;
965                     ++src;
966                 }
967             }
968         } else {
969             if (src != from && to - from > 0)
970                 memcpy(from, src, (to - from) * Node.sizeof);
971         }
972     }
973     pragma(inline, true) void node_destruct(Node* from, Node* to)
974     {
975         import core.stdcpp.new_;
976 
977         static if (QTypeInfo!(T).isLarge || QTypeInfo!(T).isStatic)
978             while(from != to) {
979                 --to;
980                 cpp_delete(reinterpret_cast!(T*)(to.v));
981             }
982         else if (QTypeInfo!(T).isComplex)
983             while (from != to) {
984                 --to;
985                 destroy!false(*reinterpret_cast!(T*)(to));
986             }
987     }
988 
989     bool isValidIterator(ref const(iterator) i) const/+ noexcept+/
990     {
991         return !(i.i < cbegin().i) && !(end().i < i.i);
992     }
993 
994 private:
995     pragma(inline, true) bool op_eq_impl(ref const(QList) l, QListData.NotArrayCompatibleLayout) const
996     {
997         Node* i = reinterpret_cast!(Node*)(p.begin());
998         Node* e = reinterpret_cast!(Node*)(p.end());
999         Node* li = reinterpret_cast!(Node*)(l.p.begin());
1000         for (; i != e; ++i, ++li) {
1001             if (!(i.t() == li.t()))
1002                 return false;
1003         }
1004         return true;
1005     }
1006 /+    pragma(inline, true) bool op_eq_impl(ref const(QList) l, QListData.ArrayCompatibleLayout) const
1007     {
1008         const(T)* lb = reinterpret_cast!(const(T)*)(l.p.begin());
1009         const(T)* b  = reinterpret_cast!(const(T)*)(p.begin());
1010         const(T)* e  = reinterpret_cast!(const(T)*)(p.end());
1011         return /+ std:: +/equal(b, e, mixin(QT_MAKE_CHECKED_ARRAY_ITERATOR(q{lb},q{ l.p.size()})));
1012     }+/
1013     pragma(inline, true) bool contains_impl(ref const(T) t, QListData.NotArrayCompatibleLayout) const
1014     {
1015         Node* e = reinterpret_cast!(Node*)(p.end());
1016         Node* i = reinterpret_cast!(Node*)(p.begin());
1017         for (; i != e; ++i)
1018             if (i.t() == t)
1019                 return true;
1020         return false;
1021     }
1022 /+    pragma(inline, true) bool contains_impl(ref const(T) t, QListData.ArrayCompatibleLayout) const
1023     {
1024         const(T)* b = reinterpret_cast!(const(T)*)(p.begin());
1025         const(T)* e = reinterpret_cast!(const(T)*)(p.end());
1026         return /+ std:: +/find(b, e, t) != e;
1027     }+/
1028     pragma(inline, true) int count_impl(ref const(T) t, QListData.NotArrayCompatibleLayout) const
1029     {
1030         int c = 0;
1031         Node* e = reinterpret_cast!(Node*)(p.end());
1032         Node* i = reinterpret_cast!(Node*)(p.begin());
1033         for (; i != e; ++i)
1034             if (i.t() == t)
1035                 ++c;
1036         return c;
1037     }
1038 /+    pragma(inline, true) int count_impl(ref const(T) t, QListData.ArrayCompatibleLayout) const
1039     {
1040         return int(/+ std:: +/count(reinterpret_cast!(const(T)*)(p.begin()),
1041                               reinterpret_cast!(const(T)*)(p.end()),
1042                               t));
1043     }
1044 +/
1045 }
1046 
1047 /+ #if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
1048 template <typename InputIterator,
1049           typename ValueType = typename std::iterator_traits<InputIterator>::value_type,
1050           QtPrivate::IfIsInputIterator<InputIterator> = true>
1051 QList(InputIterator, InputIterator) -> QList<ValueType>;
1052 #endif
1053 
1054 #if defined(Q_CC_BOR)
1055 template <typename T>
1056 T &QList<T>::Node::t()
1057 { return QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic ? *(T*)v:*(T*)this; }
1058 #endif +/
1059 
1060 
1061 extern(C++, "QtPrivate")
1062 {
1063 int indexOf(T, U)(ref const(QList!(T)) list, ref const(U) u, int from)
1064 {
1065     /+ typename QList<T>::Node +/// self alias: alias Node = QList.Node;
1066 
1067     if (from < 0)
1068         from = qMax(from + list.p.size(), 0);
1069     if (from < list.p.size()) {
1070         QList!T.Node* n = reinterpret_cast!(QList!T.Node*)(list.p.at(from -1));
1071         QList!T.Node* e = reinterpret_cast!(QList!T.Node*)(list.p.end());
1072         while (++n != e)
1073             if (n.t() == u)
1074                 return cast(int)(n - reinterpret_cast!(QList!T.Node*)(list.p.begin()));
1075     }
1076     return -1;
1077 }
1078 }
1079 
1080 extern(C++, "QtPrivate")
1081 {
1082 int lastIndexOf(T, U)(ref const(QList!(T)) list, ref const(U) u, int from)
1083 {
1084     /+ typename QList<T>::Node +/// self alias: alias Node = QList.Node;
1085 
1086     if (from < 0)
1087         from += list.p.size();
1088     else if (from >= list.p.size())
1089         from = list.p.size()-1;
1090     if (from >= 0) {
1091         QList!T.Node* b = reinterpret_cast!(QList!T.Node*)(list.p.begin());
1092         QList!T.Node* n = reinterpret_cast!(QList!T.Node*)(list.p.at(from + 1));
1093         while (n-- != b) {
1094             if (n.t() == u)
1095                 return cast(int)(n - b);
1096         }
1097     }
1098     return -1;
1099 }
1100 }
1101 
1102 /+ Q_DECLARE_SEQUENTIAL_ITERATOR(List)
1103 Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List)
1104 
1105 template <typename T>
1106 uint qHash(const QList<T> &key, uint seed = 0)
1107     noexcept(noexcept(qHashRange(key.cbegin(), key.cend(), seed)))
1108 {
1109     return qHashRange(key.cbegin(), key.cend(), seed);
1110 } +/
1111 
1112 /+bool operator <(T)(ref const(QList!(T)) lhs, ref const(QList!(T)) rhs)
1113     /+ noexcept(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(),
1114                                                                rhs.begin(), rhs.end()))) +/
1115 {
1116     return /+ std:: +/lexicographical_compare(lhs.begin(), lhs.end(),
1117                                         rhs.begin(), rhs.end());
1118 }+/
1119 
1120 /+pragma(inline, true) bool operator >(T)(ref const(QList!(T)) lhs, ref const(QList!(T)) rhs)
1121     /+ noexcept(noexcept(lhs < rhs)) +/
1122 {
1123     return rhs < lhs;
1124 }+/
1125 
1126 /+pragma(inline, true) bool operator <=(T)(ref const(QList!(T)) lhs, ref const(QList!(T)) rhs)
1127     /+ noexcept(noexcept(lhs < rhs)) +/
1128 {
1129     return !(lhs > rhs);
1130 }+/
1131 
1132 /+pragma(inline, true) bool operator >=(T)(ref const(QList!(T)) lhs, ref const(QList!(T)) rhs)
1133     /+ noexcept(noexcept(lhs < rhs)) +/
1134 {
1135     return !(lhs < rhs);
1136 }+/
1137 
1138 
1139 /+ #ifdef Q_CC_MSVC
1140 #pragma warning( pop )
1141 #endif +/
1142