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(©, t); // t might be a reference to an object in the array 284 /+ QT_TRY +/ { 285 /+ QT_CATCH(...) +/scope(failure) { 286 node_destruct(©); 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(©, t); // t might be a reference to an object in the array 324 /+ QT_TRY +/ { 325 /+ QT_CATCH(...) +/scope(failure) { 326 node_destruct(©); 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(©, t); // t might be a reference to an object in the array 362 /+ QT_TRY +/ { 363 /+ QT_CATCH(...) +/scope(failure) { 364 node_destruct(©); 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