| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the test suite of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
| 21 | ** included in the packaging of this file. Please review the following | 
| 22 | ** information to ensure the GNU General Public License requirements will | 
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 24 | ** | 
| 25 | ** $QT_END_LICENSE$ | 
| 26 | ** | 
| 27 | ****************************************************************************/ | 
| 28 |  | 
| 29 | #include <QtTest/QtTest> | 
| 30 | #include <QAtomicInt> | 
| 31 | #include <QThread> | 
| 32 | #include <QSemaphore> | 
| 33 | #include <qvector.h> | 
| 34 |  | 
| 35 | struct Movable { | 
| 36 |     Movable(char input = 'j') | 
| 37 |         : i(input) | 
| 38 |         , that(this) | 
| 39 |         , state(Constructed) | 
| 40 |     { | 
| 41 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 42 |     } | 
| 43 |     Movable(const Movable &other) | 
| 44 |         : i(other.i) | 
| 45 |         , that(this) | 
| 46 |         , state(Constructed) | 
| 47 |     { | 
| 48 |         check(state1: other.state, state2: Constructed); | 
| 49 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 50 |     } | 
| 51 |     Movable(Movable &&other) | 
| 52 |         : i(other.i) | 
| 53 |         , that(other.that) | 
| 54 |         , state(Constructed) | 
| 55 |     { | 
| 56 |         check(state1: other.state, state2: Constructed); | 
| 57 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 58 |         other.that = nullptr; | 
| 59 |     } | 
| 60 |  | 
| 61 |     ~Movable() | 
| 62 |     { | 
| 63 |         check(state1: state, state2: Constructed); | 
| 64 |         i = 0; | 
| 65 |         counter.fetchAndAddRelaxed(valueToAdd: -1); | 
| 66 |         state = Destructed; | 
| 67 |     } | 
| 68 |  | 
| 69 |     bool operator ==(const Movable &other) const | 
| 70 |     { | 
| 71 |         check(state1: state, state2: Constructed); | 
| 72 |         check(state1: other.state, state2: Constructed); | 
| 73 |         return i == other.i; | 
| 74 |     } | 
| 75 |  | 
| 76 |     Movable &operator=(const Movable &other) | 
| 77 |     { | 
| 78 |         check(state1: state, state2: Constructed); | 
| 79 |         check(state1: other.state, state2: Constructed); | 
| 80 |         i = other.i; | 
| 81 |         that = this; | 
| 82 |         return *this; | 
| 83 |     } | 
| 84 |     Movable &operator=(Movable &&other) | 
| 85 |     { | 
| 86 |         check(state1: state, state2: Constructed); | 
| 87 |         check(state1: other.state, state2: Constructed); | 
| 88 |         i = other.i; | 
| 89 |         that = other.that; | 
| 90 |         other.that = nullptr; | 
| 91 |         return *this; | 
| 92 |     } | 
| 93 |     bool wasConstructedAt(const Movable *other) const | 
| 94 |     { | 
| 95 |         return that == other; | 
| 96 |     } | 
| 97 |     char i; | 
| 98 |     static QAtomicInt counter; | 
| 99 | private: | 
| 100 |     Movable *that;       // used to check if an instance was moved | 
| 101 |  | 
| 102 |     enum State { Constructed = 106, Destructed = 110 }; | 
| 103 |     State state; | 
| 104 |  | 
| 105 |     static void check(const State state1, const State state2) | 
| 106 |     { | 
| 107 |         QCOMPARE(state1, state2); | 
| 108 |     } | 
| 109 | }; | 
| 110 |  | 
| 111 | inline uint qHash(const Movable &key, uint seed = 0) { return qHash(key: key.i, seed); } | 
| 112 |  | 
| 113 | QAtomicInt Movable::counter = 0; | 
| 114 | QT_BEGIN_NAMESPACE | 
| 115 | Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); | 
| 116 | QT_END_NAMESPACE | 
| 117 | Q_DECLARE_METATYPE(Movable); | 
| 118 |  | 
| 119 | struct Custom { | 
| 120 |     Custom(char input = 'j') | 
| 121 |         : i(input) | 
| 122 |         , that(this) | 
| 123 |         , state(Constructed) | 
| 124 |     { | 
| 125 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 126 |     } | 
| 127 |     Custom(const Custom &other) | 
| 128 |         : that(this) | 
| 129 |         , state(Constructed) | 
| 130 |     { | 
| 131 |         check(c: &other); | 
| 132 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 133 |         this->i = other.i; | 
| 134 |     } | 
| 135 |     ~Custom() | 
| 136 |     { | 
| 137 |         check(c: this); | 
| 138 |         i = 0; | 
| 139 |         counter.fetchAndAddRelaxed(valueToAdd: -1); | 
| 140 |         state = Destructed; | 
| 141 |     } | 
| 142 |  | 
| 143 |     bool operator ==(const Custom &other) const | 
| 144 |     { | 
| 145 |         check(c: &other); | 
| 146 |         check(c: this); | 
| 147 |         return i == other.i; | 
| 148 |     } | 
| 149 |  | 
| 150 |     bool operator<(const Custom &other) const | 
| 151 |     { | 
| 152 |         check(c: &other); | 
| 153 |         check(c: this); | 
| 154 |         return i < other.i; | 
| 155 |     } | 
| 156 |  | 
| 157 |     Custom &operator=(const Custom &other) | 
| 158 |     { | 
| 159 |         check(c: &other); | 
| 160 |         check(c: this); | 
| 161 |         i = other.i; | 
| 162 |         return *this; | 
| 163 |     } | 
| 164 |     static QAtomicInt counter; | 
| 165 |  | 
| 166 |     char i;             // used to identify orgin of an instance | 
| 167 | private: | 
| 168 |     Custom *that;       // used to check if an instance was moved | 
| 169 |  | 
| 170 |     enum State { Constructed = 106, Destructed = 110 }; | 
| 171 |     State state; | 
| 172 |  | 
| 173 |     static void check(const Custom *c) | 
| 174 |     { | 
| 175 |         // check if c object has been moved | 
| 176 |         QCOMPARE(c, c->that); | 
| 177 |         QCOMPARE(c->state, Constructed); | 
| 178 |     } | 
| 179 | }; | 
| 180 | QAtomicInt Custom::counter = 0; | 
| 181 |  | 
| 182 | inline uint qHash(const Custom &key, uint seed = 0) { return qHash(key: key.i, seed); } | 
| 183 |  | 
| 184 | Q_DECLARE_METATYPE(Custom); | 
| 185 |  | 
| 186 | // Similar to Custom but not default-constructible and has move constructor and assignment | 
| 187 | struct NonDefaultConstructible { | 
| 188 |     NonDefaultConstructible() = delete; | 
| 189 |     NonDefaultConstructible(char input) | 
| 190 |         : i(input) | 
| 191 |         , that(this) | 
| 192 |         , state(Constructed) | 
| 193 |     { | 
| 194 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 195 |     } | 
| 196 |     NonDefaultConstructible(const NonDefaultConstructible &other) | 
| 197 |         : i(other.i) | 
| 198 |         , that(this) | 
| 199 |         , state(Constructed) | 
| 200 |     { | 
| 201 |         check(c: &other); | 
| 202 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 203 |     } | 
| 204 |     NonDefaultConstructible(NonDefaultConstructible &&other) | 
| 205 |         : i(other.i) | 
| 206 |         , that(this) | 
| 207 |         , state(Constructed) | 
| 208 |     { | 
| 209 |         check(c: &other); | 
| 210 |         other.state = MovedFrom; | 
| 211 |         counter.fetchAndAddRelaxed(valueToAdd: 1); | 
| 212 |     } | 
| 213 |     ~NonDefaultConstructible() | 
| 214 |     { | 
| 215 |         check(c: this, movedOk: true); | 
| 216 |         i = 0; | 
| 217 |         counter.fetchAndAddRelaxed(valueToAdd: -1); | 
| 218 |         state = Destructed; | 
| 219 |     } | 
| 220 |  | 
| 221 |     bool operator==(const NonDefaultConstructible &other) const | 
| 222 |     { | 
| 223 |         check(c: &other); | 
| 224 |         check(c: this); | 
| 225 |         return i == other.i; | 
| 226 |     } | 
| 227 |  | 
| 228 |     bool operator<(const NonDefaultConstructible &other) const | 
| 229 |     { | 
| 230 |         check(c: &other); | 
| 231 |         check(c: this); | 
| 232 |         return i < other.i; | 
| 233 |     } | 
| 234 |  | 
| 235 |     NonDefaultConstructible &operator=(const NonDefaultConstructible &other) | 
| 236 |     { | 
| 237 |         check(c: &other); | 
| 238 |         check(c: this, movedOk: true); | 
| 239 |         i = other.i; | 
| 240 |         state = Constructed; | 
| 241 |         return *this; | 
| 242 |     } | 
| 243 |  | 
| 244 |     NonDefaultConstructible &operator=(NonDefaultConstructible &&other) | 
| 245 |     { | 
| 246 |         check(c: &other); | 
| 247 |         check(c: this, movedOk: true); | 
| 248 |         i = other.i; | 
| 249 |         state = Constructed; | 
| 250 |         other.state = MovedFrom; | 
| 251 |         return *this; | 
| 252 |     } | 
| 253 |     static QAtomicInt counter; | 
| 254 |  | 
| 255 |     char i; // used to identify origin of an instance | 
| 256 | private: | 
| 257 |     NonDefaultConstructible *that; // used to catch copying using mem{cpy,move}() | 
| 258 |  | 
| 259 |     enum State { Constructed = 106, Destructed = 110, MovedFrom = 120 }; | 
| 260 |     State state; | 
| 261 |  | 
| 262 |     static void check(const NonDefaultConstructible *c, bool movedOk = false) | 
| 263 |     { | 
| 264 |         // check if c object has been moved incorrectly | 
| 265 |         QCOMPARE(c, c->that); | 
| 266 |         if (!movedOk || c->state != MovedFrom) | 
| 267 |             QCOMPARE(c->state, Constructed); | 
| 268 |     } | 
| 269 | }; | 
| 270 | QAtomicInt NonDefaultConstructible::counter = 0; | 
| 271 |  | 
| 272 | inline uint qHash(const NonDefaultConstructible &key, uint seed = 0) { return qHash(key: key.i, seed); } | 
| 273 |  | 
| 274 | // tests depends on the fact that: | 
| 275 | Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic); | 
| 276 | Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex); | 
| 277 | Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic); | 
| 278 | Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex); | 
| 279 | Q_STATIC_ASSERT(QTypeInfo<Custom>::isStatic); | 
| 280 | Q_STATIC_ASSERT(QTypeInfo<Custom>::isComplex); | 
| 281 | Q_STATIC_ASSERT(QTypeInfo<NonDefaultConstructible>::isStatic); | 
| 282 | Q_STATIC_ASSERT(QTypeInfo<NonDefaultConstructible>::isComplex); | 
| 283 |  | 
| 284 |  | 
| 285 | class tst_QVector : public QObject | 
| 286 | { | 
| 287 |     Q_OBJECT | 
| 288 | private slots: | 
| 289 |     void constructors_empty() const; | 
| 290 |     void constructors_emptyReserveZero() const; | 
| 291 |     void constructors_emptyReserve() const; | 
| 292 |     void constructors_reserveAndInitialize() const; | 
| 293 |     void copyConstructorInt() const; | 
| 294 |     void copyConstructorMovable() const; | 
| 295 |     void copyConstructorCustom() const; | 
| 296 |     void assignmentInt() const; | 
| 297 |     void assignmentMovable() const; | 
| 298 |     void assignmentCustom() const; | 
| 299 |     void assignFromInitializerListInt() const; | 
| 300 |     void assignFromInitializerListMovable() const; | 
| 301 |     void assignFromInitializerListCustom() const; | 
| 302 |     void addInt() const; | 
| 303 |     void addMovable() const; | 
| 304 |     void addCustom() const; | 
| 305 |     void appendInt() const; | 
| 306 |     void appendMovable() const; | 
| 307 |     void appendCustom() const; | 
| 308 |     void appendRvalue() const; | 
| 309 |     void at() const; | 
| 310 |     void capacityInt() const; | 
| 311 |     void capacityMovable() const; | 
| 312 |     void capacityCustom() const; | 
| 313 |     void clearInt() const; | 
| 314 |     void clearMovable() const; | 
| 315 |     void clearCustom() const; | 
| 316 |     void constData() const; | 
| 317 |     void constFirst() const; | 
| 318 |     void constLast() const; | 
| 319 |     void contains() const; | 
| 320 |     void countInt() const; | 
| 321 |     void countMovable() const; | 
| 322 |     void countCustom() const; | 
| 323 |     void cpp17ctad() const; | 
| 324 |     void data() const; | 
| 325 |     void emptyInt() const; | 
| 326 |     void emptyMovable() const; | 
| 327 |     void emptyCustom() const; | 
| 328 |     void endsWith() const; | 
| 329 |     void eraseEmptyInt() const; | 
| 330 |     void eraseEmptyMovable() const; | 
| 331 |     void eraseEmptyCustom() const; | 
| 332 |     void eraseEmptyReservedInt() const; | 
| 333 |     void eraseEmptyReservedMovable() const; | 
| 334 |     void eraseEmptyReservedCustom() const; | 
| 335 |     void eraseInt() const; | 
| 336 |     void eraseIntShared() const; | 
| 337 |     void eraseMovable() const; | 
| 338 |     void eraseMovableShared() const; | 
| 339 |     void eraseCustom() const; | 
| 340 |     void eraseCustomShared() const; | 
| 341 |     void eraseReservedInt() const; | 
| 342 |     void eraseReservedMovable() const; | 
| 343 |     void eraseReservedCustom() const; | 
| 344 |     void fillInt() const; | 
| 345 |     void fillMovable() const; | 
| 346 |     void fillCustom() const; | 
| 347 |     void fillDetaches() const; | 
| 348 |     void first() const; | 
| 349 |     void fromListInt() const; | 
| 350 |     void fromListMovable() const; | 
| 351 |     void fromListCustom() const; | 
| 352 |     void indexOf() const; | 
| 353 |     void insertInt() const; | 
| 354 |     void insertMovable() const; | 
| 355 |     void insertCustom() const; | 
| 356 |     void insertNonDefaultConstructible() const; | 
| 357 |     void isEmpty() const; | 
| 358 |     void last() const; | 
| 359 |     void lastIndexOf() const; | 
| 360 |     void mid() const; | 
| 361 |     void moveInt() const; | 
| 362 |     void moveMovable() const; | 
| 363 |     void moveCustom() const; | 
| 364 |     void prependInt() const; | 
| 365 |     void prependMovable() const; | 
| 366 |     void prependCustom() const; | 
| 367 |     void prependNonDefaultConstructible() const; | 
| 368 |     void qhashInt() const { qhash<int>(); } | 
| 369 |     void qhashMovable() const { qhash<Movable>(); } | 
| 370 |     void qhashCustom() const { qhash<Custom>(); } | 
| 371 |     void removeAllWithAlias() const; | 
| 372 |     void removeInt() const; | 
| 373 |     void removeMovable() const; | 
| 374 |     void removeCustom() const; | 
| 375 |     void removeFirstLast() const; | 
| 376 |     void resizePOD_data() const; | 
| 377 |     void resizePOD() const; | 
| 378 |     void resizeComplexMovable_data() const; | 
| 379 |     void resizeComplexMovable() const; | 
| 380 |     void resizeComplex_data() const; | 
| 381 |     void resizeComplex() const; | 
| 382 |     void resizeCtorAndDtor() const; | 
| 383 |     void reverseIterators() const; | 
| 384 |     void sizeInt() const; | 
| 385 |     void sizeMovable() const; | 
| 386 |     void sizeCustom() const; | 
| 387 |     void startsWith() const; | 
| 388 |     void swapInt() const; | 
| 389 |     void swapMovable() const; | 
| 390 |     void swapCustom() const; | 
| 391 |     void toList() const; | 
| 392 | #if QT_VERSION < QT_VERSION_CHECK(6,0,0) | 
| 393 |     void fromStdVector() const; | 
| 394 |     void toStdVector() const; | 
| 395 | #endif | 
| 396 |     void value() const; | 
| 397 |  | 
| 398 |     void testOperators() const; | 
| 399 |  | 
| 400 |     void reserve(); | 
| 401 |     void reserveZero(); | 
| 402 |     void reallocAfterCopy_data(); | 
| 403 |     void reallocAfterCopy(); | 
| 404 |     void initializeListInt(); | 
| 405 |     void initializeListMovable(); | 
| 406 |     void initializeListCustom(); | 
| 407 |  | 
| 408 |     void const_shared_null(); | 
| 409 | #if 1 | 
| 410 |     // ### Qt6 remove this section | 
| 411 |     void setSharableInt_data(); | 
| 412 |     void setSharableInt(); | 
| 413 |     void setSharableMovable_data(); | 
| 414 |     void setSharableMovable(); | 
| 415 |     void setSharableCustom_data(); | 
| 416 |     void setSharableCustom(); | 
| 417 | #endif | 
| 418 |  | 
| 419 |     void detachInt() const; | 
| 420 |     void detachMovable() const; | 
| 421 |     void detachCustom() const; | 
| 422 |     void detachThreadSafetyInt() const; | 
| 423 |     void detachThreadSafetyMovable() const; | 
| 424 |     void detachThreadSafetyCustom() const; | 
| 425 |  | 
| 426 |     void insertMove() const; | 
| 427 |  | 
| 428 |     void swapItemsAt() const; | 
| 429 |  | 
| 430 | private: | 
| 431 |     template<typename T> void copyConstructor() const; | 
| 432 |     template<typename T> void add() const; | 
| 433 |     template<typename T> void append() const; | 
| 434 |     template<typename T> void assignFromInitializerList() const; | 
| 435 |     template<typename T> void capacity() const; | 
| 436 |     template<typename T> void clear() const; | 
| 437 |     template<typename T> void count() const; | 
| 438 |     template<typename T> void empty() const; | 
| 439 |     template<typename T> void eraseEmpty() const; | 
| 440 |     template<typename T> void eraseEmptyReserved() const; | 
| 441 |     template<typename T> void erase(bool shared) const; | 
| 442 |     template<typename T> void eraseReserved() const; | 
| 443 |     template<typename T> void fill() const; | 
| 444 |     template<typename T> void fromList() const; | 
| 445 |     template<typename T> void insert() const; | 
| 446 |     template<typename T> void qhash() const; | 
| 447 |     template<typename T> void move() const; | 
| 448 |     template<typename T> void prepend() const; | 
| 449 |     template<typename T> void remove() const; | 
| 450 |     template<typename T> void size() const; | 
| 451 |     template<typename T> void swap() const; | 
| 452 |     template<typename T> void initializeList(); | 
| 453 |     template<typename T> void setSharable_data() const; | 
| 454 |     template<typename T> void setSharable() const; | 
| 455 |     template<typename T> void detach() const; | 
| 456 |     template<typename T> void detachThreadSafety() const; | 
| 457 | }; | 
| 458 |  | 
| 459 |  | 
| 460 | template<typename T> struct SimpleValue | 
| 461 | { | 
| 462 |     static T at(int index) | 
| 463 |     { | 
| 464 |         return Values[index % MaxIndex]; | 
| 465 |     } | 
| 466 |  | 
| 467 |     static QVector<T> vector(int size) | 
| 468 |     { | 
| 469 |         QVector<T> ret; | 
| 470 |         for (int i = 0; i < size; i++) | 
| 471 |             ret.append(at(index: i)); | 
| 472 |         return ret; | 
| 473 |     } | 
| 474 |  | 
| 475 |     static const uint MaxIndex = 6; | 
| 476 |     static const T Values[MaxIndex]; | 
| 477 | }; | 
| 478 |  | 
| 479 | template<> | 
| 480 | const int SimpleValue<int>::Values[] = { 110, 105, 101, 114, 111, 98 }; | 
| 481 | template<> | 
| 482 | const Movable SimpleValue<Movable>::Values[] = { 110, 105, 101, 114, 111, 98 }; | 
| 483 | template<> | 
| 484 | const Custom SimpleValue<Custom>::Values[] = { 110, 105, 101, 114, 111, 98 }; | 
| 485 | template<> | 
| 486 | const NonDefaultConstructible SimpleValue<NonDefaultConstructible>::Values[] = | 
| 487 |     { 110, 105, 101, 114, 111, 98 }; | 
| 488 |  | 
| 489 |  | 
| 490 | // Make some macros for the tests to use in order to be slightly more readable... | 
| 491 | #define T_FOO SimpleValue<T>::at(0) | 
| 492 | #define T_BAR SimpleValue<T>::at(1) | 
| 493 | #define T_BAZ SimpleValue<T>::at(2) | 
| 494 | #define T_CAT SimpleValue<T>::at(3) | 
| 495 | #define T_DOG SimpleValue<T>::at(4) | 
| 496 | #define T_BLAH SimpleValue<T>::at(5) | 
| 497 |  | 
| 498 | void tst_QVector::constructors_empty() const | 
| 499 | { | 
| 500 |     QVector<int> emptyInt; | 
| 501 |     QVector<Movable> emptyMovable; | 
| 502 |     QVector<Custom> emptyCustom; | 
| 503 | } | 
| 504 |  | 
| 505 | void tst_QVector::constructors_emptyReserveZero() const | 
| 506 | { | 
| 507 |     QVector<int> emptyInt(0); | 
| 508 |     QVector<Movable> emptyMovable(0); | 
| 509 |     QVector<Custom> emptyCustom(0); | 
| 510 | } | 
| 511 |  | 
| 512 | void tst_QVector::constructors_emptyReserve() const | 
| 513 | { | 
| 514 |     // pre-reserve capacity | 
| 515 |     QVector<int> myInt(5); | 
| 516 |     QVERIFY(myInt.capacity() == 5); | 
| 517 |     QVector<Movable> myMovable(5); | 
| 518 |     QVERIFY(myMovable.capacity() == 5); | 
| 519 |     QVector<Custom> myCustom(4); | 
| 520 |     QVERIFY(myCustom.capacity() == 4); | 
| 521 | } | 
| 522 |  | 
| 523 | void tst_QVector::constructors_reserveAndInitialize() const | 
| 524 | { | 
| 525 |     // default-initialise items | 
| 526 |  | 
| 527 |     QVector<int> myInt(5, 42); | 
| 528 |     QVERIFY(myInt.capacity() == 5); | 
| 529 |     foreach (int meaningoflife, myInt) { | 
| 530 |         QCOMPARE(meaningoflife, 42); | 
| 531 |     } | 
| 532 |  | 
| 533 |     QVector<QString> myString(5, QString::fromLatin1(str: "c++" )); | 
| 534 |     QVERIFY(myString.capacity() == 5); | 
| 535 |     // make sure all items are initialised ok | 
| 536 |     foreach (QString meaningoflife, myString) { | 
| 537 |         QCOMPARE(meaningoflife, QString::fromLatin1("c++" )); | 
| 538 |     } | 
| 539 |  | 
| 540 |     QVector<Custom> myCustom(5, Custom('n')); | 
| 541 |     QVERIFY(myCustom.capacity() == 5); | 
| 542 |     // make sure all items are initialised ok | 
| 543 |     foreach (Custom meaningoflife, myCustom) { | 
| 544 |         QCOMPARE(meaningoflife.i, 'n'); | 
| 545 |     } | 
| 546 | } | 
| 547 |  | 
| 548 | template<typename T> | 
| 549 | void tst_QVector::copyConstructor() const | 
| 550 | { | 
| 551 |     T value1(SimpleValue<T>::at(0)); | 
| 552 |     T value2(SimpleValue<T>::at(1)); | 
| 553 |     T value3(SimpleValue<T>::at(2)); | 
| 554 |     T value4(SimpleValue<T>::at(3)); | 
| 555 |     { | 
| 556 |         QVector<T> v1; | 
| 557 |         QVector<T> v2(v1); | 
| 558 |         QCOMPARE(v1, v2); | 
| 559 |     } | 
| 560 |     { | 
| 561 |         QVector<T> v1; | 
| 562 |         v1 << value1 << value2 << value3 << value4; | 
| 563 |         QVector<T> v2(v1); | 
| 564 |         QCOMPARE(v1, v2); | 
| 565 |     } | 
| 566 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 567 |     // ### Qt6 remove this section | 
| 568 |     { | 
| 569 |         QVector<T> v1; | 
| 570 |         v1.setSharable(false); | 
| 571 |         QVector<T> v2(v1); | 
| 572 |         QVERIFY(!v1.isSharedWith(v2)); | 
| 573 |         QCOMPARE(v1, v2); | 
| 574 |     } | 
| 575 |     { | 
| 576 |         QVector<T> v1; | 
| 577 |         v1 << value1 << value2 << value3 << value4; | 
| 578 |         v1.setSharable(false); | 
| 579 |         QVector<T> v2(v1); | 
| 580 |         QVERIFY(!v1.isSharedWith(v2)); | 
| 581 |         QCOMPARE(v1, v2); | 
| 582 |     } | 
| 583 | #endif | 
| 584 | } | 
| 585 |  | 
| 586 | void tst_QVector::copyConstructorInt() const | 
| 587 | { | 
| 588 |     copyConstructor<int>(); | 
| 589 | } | 
| 590 |  | 
| 591 | void tst_QVector::copyConstructorMovable() const | 
| 592 | { | 
| 593 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 594 |     copyConstructor<Movable>(); | 
| 595 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 596 | } | 
| 597 |  | 
| 598 | void tst_QVector::copyConstructorCustom() const | 
| 599 | { | 
| 600 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 601 |     copyConstructor<Custom>(); | 
| 602 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 603 | } | 
| 604 |  | 
| 605 | template <class T> | 
| 606 | static inline void testAssignment() | 
| 607 | { | 
| 608 |     QVector<T> v1(5); | 
| 609 |     QCOMPARE(v1.size(), 5); | 
| 610 |     QVERIFY(v1.isDetached()); | 
| 611 |  | 
| 612 |     QVector<T> v2(7); | 
| 613 |     QCOMPARE(v2.size(), 7); | 
| 614 |     QVERIFY(v2.isDetached()); | 
| 615 |  | 
| 616 |     QVERIFY(!v1.isSharedWith(v2)); | 
| 617 |  | 
| 618 |     v1 = v2; | 
| 619 |  | 
| 620 |     QVERIFY(!v1.isDetached()); | 
| 621 |     QVERIFY(!v2.isDetached()); | 
| 622 |     QVERIFY(v1.isSharedWith(v2)); | 
| 623 |  | 
| 624 |     const void *const data1 = v1.constData(); | 
| 625 |     const void *const data2 = v2.constData(); | 
| 626 |  | 
| 627 |     QCOMPARE(data1, data2); | 
| 628 |  | 
| 629 |     v1.clear(); | 
| 630 |  | 
| 631 |     QVERIFY(v2.isDetached()); | 
| 632 |     QVERIFY(!v1.isSharedWith(v2)); | 
| 633 |     QCOMPARE((void *)v2.constData(), data2); | 
| 634 | } | 
| 635 |  | 
| 636 | void tst_QVector::assignmentInt() const | 
| 637 | { | 
| 638 |     testAssignment<int>(); | 
| 639 | } | 
| 640 |  | 
| 641 | void tst_QVector::assignmentMovable() const | 
| 642 | { | 
| 643 |     testAssignment<Movable>(); | 
| 644 | } | 
| 645 |  | 
| 646 | void tst_QVector::assignmentCustom() const | 
| 647 | { | 
| 648 |     testAssignment<Custom>(); | 
| 649 | } | 
| 650 |  | 
| 651 | template<typename T> | 
| 652 | void tst_QVector::assignFromInitializerList() const | 
| 653 | { | 
| 654 |     T val1(SimpleValue<T>::at(1)); | 
| 655 |     T val2(SimpleValue<T>::at(2)); | 
| 656 |     T val3(SimpleValue<T>::at(3)); | 
| 657 |  | 
| 658 |     QVector<T> v1 = {val1, val2, val3}; | 
| 659 |     QCOMPARE(v1, QVector<T>() << val1 << val2 << val3); | 
| 660 |     QCOMPARE(v1, (QVector<T> {val1, val2, val3})); | 
| 661 |  | 
| 662 |     v1 = {}; | 
| 663 |     QCOMPARE(v1.size(), 0); | 
| 664 | } | 
| 665 |  | 
| 666 | void tst_QVector::assignFromInitializerListInt() const | 
| 667 | { | 
| 668 |     assignFromInitializerList<int>(); | 
| 669 | } | 
| 670 |  | 
| 671 | void tst_QVector::assignFromInitializerListMovable() const | 
| 672 | { | 
| 673 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 674 |     assignFromInitializerList<Movable>(); | 
| 675 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 676 | } | 
| 677 |  | 
| 678 | void tst_QVector::assignFromInitializerListCustom() const | 
| 679 | { | 
| 680 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 681 |     assignFromInitializerList<Custom>(); | 
| 682 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 683 | } | 
| 684 |  | 
| 685 | template<typename T> | 
| 686 | void tst_QVector::add() const | 
| 687 | { | 
| 688 |     { | 
| 689 |         QVector<T> empty1; | 
| 690 |         QVector<T> empty2; | 
| 691 |         QVERIFY((empty1 + empty2).isEmpty()); | 
| 692 |         empty1 += empty2; | 
| 693 |         QVERIFY(empty1.isEmpty()); | 
| 694 |         QVERIFY(empty2.isEmpty()); | 
| 695 |     } | 
| 696 |     { | 
| 697 |         QVector<T> v(12); | 
| 698 |         QVector<T> empty; | 
| 699 |         QCOMPARE((v + empty), v); | 
| 700 |         v += empty; | 
| 701 |         QVERIFY(!v.isEmpty()); | 
| 702 |         QCOMPARE(v.size(), 12); | 
| 703 |         QVERIFY(empty.isEmpty()); | 
| 704 |     } | 
| 705 |     { | 
| 706 |         QVector<T> v1(12); | 
| 707 |         QVector<T> v2; | 
| 708 |         v2 += v1; | 
| 709 |         QVERIFY(!v1.isEmpty()); | 
| 710 |         QCOMPARE(v1.size(), 12); | 
| 711 |         QVERIFY(!v2.isEmpty()); | 
| 712 |         QCOMPARE(v2.size(), 12); | 
| 713 |     } | 
| 714 | } | 
| 715 |  | 
| 716 | void tst_QVector::addInt() const | 
| 717 | { | 
| 718 |     add<int>(); | 
| 719 | } | 
| 720 |  | 
| 721 | void tst_QVector::addMovable() const | 
| 722 | { | 
| 723 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 724 |     add<Movable>(); | 
| 725 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 726 | } | 
| 727 |  | 
| 728 | void tst_QVector::addCustom() const | 
| 729 | { | 
| 730 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 731 |     add<Custom>(); | 
| 732 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 733 | } | 
| 734 |  | 
| 735 | template<typename T> | 
| 736 | void tst_QVector::append() const | 
| 737 | { | 
| 738 |     { | 
| 739 |         QVector<T> myvec; | 
| 740 |         myvec.append(SimpleValue<T>::at(0)); | 
| 741 |         QVERIFY(myvec.size() == 1); | 
| 742 |         myvec.append(SimpleValue<T>::at(1)); | 
| 743 |         QVERIFY(myvec.size() == 2); | 
| 744 |         myvec.append(SimpleValue<T>::at(2)); | 
| 745 |         QVERIFY(myvec.size() == 3); | 
| 746 |  | 
| 747 |         QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(0) | 
| 748 |                                      << SimpleValue<T>::at(1) | 
| 749 |                                      << SimpleValue<T>::at(2)); | 
| 750 |     } | 
| 751 |     { | 
| 752 |         QVector<T> v(2); | 
| 753 |         v.append(SimpleValue<T>::at(0)); | 
| 754 |         QVERIFY(v.size() == 3); | 
| 755 |         QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0)); | 
| 756 |     } | 
| 757 |     { | 
| 758 |         QVector<T> v(2); | 
| 759 |         v.reserve(12); | 
| 760 |         v.append(SimpleValue<T>::at(0)); | 
| 761 |         QVERIFY(v.size() == 3); | 
| 762 |         QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0)); | 
| 763 |     } | 
| 764 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 765 |     // ### Qt6 remove this section | 
| 766 |     { | 
| 767 |         QVector<T> v(2); | 
| 768 |         v.reserve(12); | 
| 769 |         v.setSharable(false); | 
| 770 |         v.append(SimpleValue<T>::at(0)); | 
| 771 |         QVERIFY(v.size() == 3); | 
| 772 |         QCOMPARE(v.last(), SimpleValue<T>::at(0)); | 
| 773 |     } | 
| 774 | #endif | 
| 775 |     { | 
| 776 |         QVector<int> v; | 
| 777 |         v << 1 << 2 << 3; | 
| 778 |         QVector<int> x; | 
| 779 |         x << 4 << 5 << 6; | 
| 780 |         v.append(l: x); | 
| 781 |  | 
| 782 |         QVector<int> combined; | 
| 783 |         combined << 1 << 2 << 3 << 4 << 5 << 6; | 
| 784 |  | 
| 785 |         QCOMPARE(v, combined); | 
| 786 |     } | 
| 787 | } | 
| 788 |  | 
| 789 | void tst_QVector::appendInt() const | 
| 790 | { | 
| 791 |     append<int>(); | 
| 792 | } | 
| 793 |  | 
| 794 | void tst_QVector::appendMovable() const | 
| 795 | { | 
| 796 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 797 |     append<Movable>(); | 
| 798 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 799 | } | 
| 800 |  | 
| 801 | void tst_QVector::appendCustom() const | 
| 802 | { | 
| 803 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 804 |     append<Custom>(); | 
| 805 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 806 | } | 
| 807 |  | 
| 808 | void tst_QVector::appendRvalue() const | 
| 809 | { | 
| 810 |     QVector<QString> v; | 
| 811 |     v.append(t: "hello" ); | 
| 812 |     QString world = "world" ; | 
| 813 |     v.append(t: std::move(world)); | 
| 814 |     QVERIFY(world.isEmpty()); | 
| 815 |     QCOMPARE(v.front(), QString("hello" )); | 
| 816 |     QCOMPARE(v.back(),  QString("world" )); | 
| 817 | } | 
| 818 |  | 
| 819 | void tst_QVector::at() const | 
| 820 | { | 
| 821 |     QVector<QString> myvec; | 
| 822 |     myvec << "foo"  << "bar"  << "baz" ; | 
| 823 |  | 
| 824 |     QVERIFY(myvec.size() == 3); | 
| 825 |     QCOMPARE(myvec.at(0), QLatin1String("foo" )); | 
| 826 |     QCOMPARE(myvec.at(1), QLatin1String("bar" )); | 
| 827 |     QCOMPARE(myvec.at(2), QLatin1String("baz" )); | 
| 828 |  | 
| 829 |     // append an item | 
| 830 |     myvec << "hello" ; | 
| 831 |     QVERIFY(myvec.size() == 4); | 
| 832 |     QCOMPARE(myvec.at(0), QLatin1String("foo" )); | 
| 833 |     QCOMPARE(myvec.at(1), QLatin1String("bar" )); | 
| 834 |     QCOMPARE(myvec.at(2), QLatin1String("baz" )); | 
| 835 |     QCOMPARE(myvec.at(3), QLatin1String("hello" )); | 
| 836 |  | 
| 837 |     // remove an item | 
| 838 |     myvec.remove(i: 1); | 
| 839 |     QVERIFY(myvec.size() == 3); | 
| 840 |     QCOMPARE(myvec.at(0), QLatin1String("foo" )); | 
| 841 |     QCOMPARE(myvec.at(1), QLatin1String("baz" )); | 
| 842 |     QCOMPARE(myvec.at(2), QLatin1String("hello" )); | 
| 843 | } | 
| 844 |  | 
| 845 | template<typename T> | 
| 846 | void tst_QVector::capacity() const | 
| 847 | { | 
| 848 |     QVector<T> myvec; | 
| 849 |  | 
| 850 |     // TODO: is this guaranteed? seems a safe assumption, but I suppose preallocation of a | 
| 851 |     // few items isn't an entirely unforseeable possibility. | 
| 852 |     QVERIFY(myvec.capacity() == 0); | 
| 853 |  | 
| 854 |     // test it gets a size | 
| 855 |     myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2); | 
| 856 |     QVERIFY(myvec.capacity() >= 3); | 
| 857 |  | 
| 858 |     // make sure it grows ok | 
| 859 |     myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2); | 
| 860 |     QVERIFY(myvec.capacity() >= 6); | 
| 861 |     // let's try squeeze a bit | 
| 862 |     myvec.remove(3); | 
| 863 |     myvec.remove(3); | 
| 864 |     myvec.remove(3); | 
| 865 |     // TODO: is this a safe assumption? presumably it won't release memory until shrink(), but can we asser that is true? | 
| 866 |     QVERIFY(myvec.capacity() >= 6); | 
| 867 |     myvec.squeeze(); | 
| 868 |     QVERIFY(myvec.capacity() >= 3); | 
| 869 |  | 
| 870 |     myvec.remove(0); | 
| 871 |     myvec.remove(0); | 
| 872 |     myvec.remove(0); | 
| 873 |     // TODO: as above note | 
| 874 |     QVERIFY(myvec.capacity() >= 3); | 
| 875 |     myvec.squeeze(); | 
| 876 |     QVERIFY(myvec.capacity() == 0); | 
| 877 | } | 
| 878 |  | 
| 879 | void tst_QVector::capacityInt() const | 
| 880 | { | 
| 881 |     capacity<int>(); | 
| 882 | } | 
| 883 |  | 
| 884 | void tst_QVector::capacityMovable() const | 
| 885 | { | 
| 886 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 887 |     capacity<Movable>(); | 
| 888 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 889 | } | 
| 890 |  | 
| 891 | void tst_QVector::capacityCustom() const | 
| 892 | { | 
| 893 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 894 |     capacity<Custom>(); | 
| 895 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 896 | } | 
| 897 |  | 
| 898 | template<typename T> | 
| 899 | void tst_QVector::clear() const | 
| 900 | { | 
| 901 |     QVector<T> myvec; | 
| 902 |     myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2); | 
| 903 |  | 
| 904 |     const auto oldCapacity = myvec.capacity(); | 
| 905 |     QCOMPARE(myvec.size(), 3); | 
| 906 |     myvec.clear(); | 
| 907 |     QCOMPARE(myvec.size(), 0); | 
| 908 |     QCOMPARE(myvec.capacity(), oldCapacity); | 
| 909 | } | 
| 910 |  | 
| 911 | void tst_QVector::clearInt() const | 
| 912 | { | 
| 913 |     clear<int>(); | 
| 914 | } | 
| 915 |  | 
| 916 | void tst_QVector::clearMovable() const | 
| 917 | { | 
| 918 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 919 |     clear<Movable>(); | 
| 920 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 921 | } | 
| 922 |  | 
| 923 | void tst_QVector::clearCustom() const | 
| 924 | { | 
| 925 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 926 |     clear<Custom>(); | 
| 927 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 928 | } | 
| 929 |  | 
| 930 | void tst_QVector::constData() const | 
| 931 | { | 
| 932 |     int arr[] = { 42, 43, 44 }; | 
| 933 |     QVector<int> myvec; | 
| 934 |     myvec << 42 << 43 << 44; | 
| 935 |  | 
| 936 |     QVERIFY(memcmp(myvec.constData(), reinterpret_cast<const int *>(&arr), sizeof(int) * 3) == 0); | 
| 937 | } | 
| 938 |  | 
| 939 | void tst_QVector::contains() const | 
| 940 | { | 
| 941 |     QVector<QString> myvec; | 
| 942 |     myvec << "aaa"  << "bbb"  << "ccc" ; | 
| 943 |  | 
| 944 |     QVERIFY(myvec.contains(QLatin1String("aaa" ))); | 
| 945 |     QVERIFY(myvec.contains(QLatin1String("bbb" ))); | 
| 946 |     QVERIFY(myvec.contains(QLatin1String("ccc" ))); | 
| 947 |     QVERIFY(!myvec.contains(QLatin1String("I don't exist" ))); | 
| 948 |  | 
| 949 |     // add it and make sure it does :) | 
| 950 |     myvec.append(t: QLatin1String("I don't exist" )); | 
| 951 |     QVERIFY(myvec.contains(QLatin1String("I don't exist" ))); | 
| 952 | } | 
| 953 |  | 
| 954 | template<typename T> | 
| 955 | void tst_QVector::count() const | 
| 956 | { | 
| 957 |     // total size | 
| 958 |     { | 
| 959 |         // zero size | 
| 960 |         QVector<T> myvec; | 
| 961 |         QVERIFY(myvec.count() == 0); | 
| 962 |  | 
| 963 |         // grow | 
| 964 |         myvec.append(SimpleValue<T>::at(0)); | 
| 965 |         QVERIFY(myvec.count() == 1); | 
| 966 |         myvec.append(SimpleValue<T>::at(1)); | 
| 967 |         QVERIFY(myvec.count() == 2); | 
| 968 |  | 
| 969 |         // shrink | 
| 970 |         myvec.remove(0); | 
| 971 |         QVERIFY(myvec.count() == 1); | 
| 972 |         myvec.remove(0); | 
| 973 |         QVERIFY(myvec.count() == 0); | 
| 974 |     } | 
| 975 |  | 
| 976 |     // count of items | 
| 977 |     { | 
| 978 |         QVector<T> myvec; | 
| 979 |         myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2); | 
| 980 |  | 
| 981 |         // initial tests | 
| 982 |         QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1); | 
| 983 |         QVERIFY(myvec.count(SimpleValue<T>::at(3)) == 0); | 
| 984 |  | 
| 985 |         // grow | 
| 986 |         myvec.append(SimpleValue<T>::at(0)); | 
| 987 |         QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 2); | 
| 988 |  | 
| 989 |         // shrink | 
| 990 |         myvec.remove(0); | 
| 991 |         QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1); | 
| 992 |     } | 
| 993 | } | 
| 994 |  | 
| 995 | void tst_QVector::countInt() const | 
| 996 | { | 
| 997 |     count<int>(); | 
| 998 | } | 
| 999 |  | 
| 1000 | void tst_QVector::countMovable() const | 
| 1001 | { | 
| 1002 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1003 |     count<Movable>(); | 
| 1004 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1005 | } | 
| 1006 |  | 
| 1007 | void tst_QVector::countCustom() const | 
| 1008 | { | 
| 1009 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1010 |     count<Custom>(); | 
| 1011 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1012 | } | 
| 1013 |  | 
| 1014 | void tst_QVector::cpp17ctad() const | 
| 1015 | { | 
| 1016 | #ifdef __cpp_deduction_guides | 
| 1017 | #define QVERIFY_IS_VECTOR_OF(obj, Type) \ | 
| 1018 |     QVERIFY2((std::is_same<decltype(obj), QVector<Type>>::value), \ | 
| 1019 |              QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>())) | 
| 1020 | #define CHECK(Type, One, Two, Three) \ | 
| 1021 |     do { \ | 
| 1022 |         const Type v[] = {One, Two, Three}; \ | 
| 1023 |         QVector v1 = {One, Two, Three}; \ | 
| 1024 |         QVERIFY_IS_VECTOR_OF(v1, Type); \ | 
| 1025 |         QVector v2(v1.begin(), v1.end()); \ | 
| 1026 |         QVERIFY_IS_VECTOR_OF(v2, Type); \ | 
| 1027 |         QVector v3(std::begin(v), std::end(v)); \ | 
| 1028 |         QVERIFY_IS_VECTOR_OF(v3, Type); \ | 
| 1029 |     } while (false) \ | 
| 1030 |     /*end*/ | 
| 1031 |     CHECK(int, 1, 2, 3); | 
| 1032 |     CHECK(double, 1.0, 2.0, 3.0); | 
| 1033 |     CHECK(QString, QStringLiteral("one" ), QStringLiteral("two" ), QStringLiteral("three" )); | 
| 1034 | #undef QVERIFY_IS_VECTOR_OF | 
| 1035 | #undef CHECK | 
| 1036 | #else | 
| 1037 |     QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler." ); | 
| 1038 | #endif | 
| 1039 | } | 
| 1040 |  | 
| 1041 | void tst_QVector::data() const | 
| 1042 | { | 
| 1043 |     QVector<int> myvec; | 
| 1044 |     myvec << 42 << 43 << 44; | 
| 1045 |  | 
| 1046 |     // make sure it starts off ok | 
| 1047 |     QCOMPARE(*(myvec.data() + 1), 43); | 
| 1048 |  | 
| 1049 |     // alter it | 
| 1050 |     *(myvec.data() + 1) = 69; | 
| 1051 |  | 
| 1052 |     // check it altered | 
| 1053 |     QCOMPARE(*(myvec.data() + 1), 69); | 
| 1054 |  | 
| 1055 |     int arr[] = { 42, 69, 44 }; | 
| 1056 |     QVERIFY(memcmp(myvec.data(), reinterpret_cast<int *>(&arr), sizeof(int) * 3) == 0); | 
| 1057 | } | 
| 1058 |  | 
| 1059 | template<typename T> | 
| 1060 | void tst_QVector::empty() const | 
| 1061 | { | 
| 1062 |     QVector<T> myvec; | 
| 1063 |  | 
| 1064 |     // starts empty | 
| 1065 |     QVERIFY(myvec.empty()); | 
| 1066 |  | 
| 1067 |     // not empty | 
| 1068 |     myvec.append(SimpleValue<T>::at(2)); | 
| 1069 |     QVERIFY(!myvec.empty()); | 
| 1070 |  | 
| 1071 |     // empty again | 
| 1072 |     myvec.remove(0); | 
| 1073 |     QVERIFY(myvec.empty()); | 
| 1074 | } | 
| 1075 |  | 
| 1076 | void tst_QVector::emptyInt() const | 
| 1077 | { | 
| 1078 |     empty<int>(); | 
| 1079 | } | 
| 1080 |  | 
| 1081 | void tst_QVector::emptyMovable() const | 
| 1082 | { | 
| 1083 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1084 |     empty<Movable>(); | 
| 1085 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1086 | } | 
| 1087 |  | 
| 1088 | void tst_QVector::emptyCustom() const | 
| 1089 | { | 
| 1090 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1091 |     empty<Custom>(); | 
| 1092 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1093 | } | 
| 1094 |  | 
| 1095 | void tst_QVector::endsWith() const | 
| 1096 | { | 
| 1097 |     QVector<int> myvec; | 
| 1098 |  | 
| 1099 |     // empty vector | 
| 1100 |     QVERIFY(!myvec.endsWith(1)); | 
| 1101 |  | 
| 1102 |     // add the one, should work | 
| 1103 |     myvec.append(t: 1); | 
| 1104 |     QVERIFY(myvec.endsWith(1)); | 
| 1105 |  | 
| 1106 |     // add something else, fails now | 
| 1107 |     myvec.append(t: 3); | 
| 1108 |     QVERIFY(!myvec.endsWith(1)); | 
| 1109 |  | 
| 1110 |     // remove it again :) | 
| 1111 |     myvec.remove(i: 1); | 
| 1112 |     QVERIFY(myvec.endsWith(1)); | 
| 1113 | } | 
| 1114 |  | 
| 1115 | template<typename T> | 
| 1116 | void tst_QVector::eraseEmpty() const | 
| 1117 | { | 
| 1118 |     { | 
| 1119 |         QVector<T> v; | 
| 1120 |         v.erase(v.begin(), v.end()); | 
| 1121 |         QCOMPARE(v.size(), 0); | 
| 1122 |     } | 
| 1123 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 1124 |     // ### Qt6 remove this section | 
| 1125 |     { | 
| 1126 |         QVector<T> v; | 
| 1127 |         v.setSharable(false); | 
| 1128 |         v.erase(v.begin(), v.end()); | 
| 1129 |         QCOMPARE(v.size(), 0); | 
| 1130 |     } | 
| 1131 | #endif | 
| 1132 | } | 
| 1133 |  | 
| 1134 | void tst_QVector::eraseEmptyInt() const | 
| 1135 | { | 
| 1136 |     eraseEmpty<int>(); | 
| 1137 | } | 
| 1138 |  | 
| 1139 | void tst_QVector::eraseEmptyMovable() const | 
| 1140 | { | 
| 1141 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1142 |     eraseEmpty<Movable>(); | 
| 1143 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1144 | } | 
| 1145 |  | 
| 1146 | void tst_QVector::eraseEmptyCustom() const | 
| 1147 | { | 
| 1148 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1149 |     eraseEmpty<Custom>(); | 
| 1150 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1151 | } | 
| 1152 |  | 
| 1153 | template<typename T> | 
| 1154 | void tst_QVector::eraseEmptyReserved() const | 
| 1155 | { | 
| 1156 |     { | 
| 1157 |         QVector<T> v; | 
| 1158 |         v.reserve(10); | 
| 1159 |         v.erase(v.begin(), v.end()); | 
| 1160 |         QCOMPARE(v.size(), 0); | 
| 1161 |     } | 
| 1162 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 1163 |     // ### Qt6 remove this section | 
| 1164 |     { | 
| 1165 |         QVector<T> v; | 
| 1166 |         v.reserve(10); | 
| 1167 |         v.setSharable(false); | 
| 1168 |         v.erase(v.begin(), v.end()); | 
| 1169 |         QCOMPARE(v.size(), 0); | 
| 1170 |     } | 
| 1171 | #endif | 
| 1172 | } | 
| 1173 |  | 
| 1174 | void tst_QVector::eraseEmptyReservedInt() const | 
| 1175 | { | 
| 1176 |     eraseEmptyReserved<int>(); | 
| 1177 | } | 
| 1178 |  | 
| 1179 | void tst_QVector::eraseEmptyReservedMovable() const | 
| 1180 | { | 
| 1181 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1182 |     eraseEmptyReserved<Movable>(); | 
| 1183 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1184 | } | 
| 1185 |  | 
| 1186 | void tst_QVector::eraseEmptyReservedCustom() const | 
| 1187 | { | 
| 1188 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1189 |     eraseEmptyReserved<Custom>(); | 
| 1190 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1191 | } | 
| 1192 |  | 
| 1193 | template<typename T> | 
| 1194 | struct SharedVectorChecker | 
| 1195 | { | 
| 1196 |     SharedVectorChecker(const QVector<T> &original, bool doCopyVector) | 
| 1197 |         : originalSize(-1), | 
| 1198 |           copy(0) | 
| 1199 |     { | 
| 1200 |         if (doCopyVector) { | 
| 1201 |             originalSize = original.size(); | 
| 1202 |             copy = new QVector<T>(original); | 
| 1203 |             // this is unlikely to fail, but if the check in the destructor fails it's good to know that | 
| 1204 |             // we were still alright here. | 
| 1205 |             QCOMPARE(originalSize, copy->size()); | 
| 1206 |         } | 
| 1207 |     } | 
| 1208 |  | 
| 1209 |     ~SharedVectorChecker() | 
| 1210 |     { | 
| 1211 |         if (copy) | 
| 1212 |             QCOMPARE(copy->size(), originalSize); | 
| 1213 |         delete copy; | 
| 1214 |     } | 
| 1215 |  | 
| 1216 |     int originalSize; | 
| 1217 |     QVector<T> *copy; | 
| 1218 | }; | 
| 1219 |  | 
| 1220 | template<typename T> | 
| 1221 | void tst_QVector::erase(bool shared) const | 
| 1222 | { | 
| 1223 |     // note: remove() is actually more efficient, and more dangerous, because it uses the non-detaching | 
| 1224 |     // begin() / end() internally. you can also use constBegin() and constEnd() with erase(), but only | 
| 1225 |     // using reinterpret_cast... because both iterator types are really just pointers. | 
| 1226 |     // so we use a mix of erase() and remove() to cover more cases. | 
| 1227 |     { | 
| 1228 |         QVector<T> v = SimpleValue<T>::vector(12); | 
| 1229 |         SharedVectorChecker<T> svc(v, shared); | 
| 1230 |         v.erase(v.begin()); | 
| 1231 |         QCOMPARE(v.size(), 11); | 
| 1232 |         for (int i = 0; i < 11; i++) | 
| 1233 |             QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1)); | 
| 1234 |         v.erase(v.begin(), v.end()); | 
| 1235 |         QCOMPARE(v.size(), 0); | 
| 1236 |         if (shared) | 
| 1237 |             QCOMPARE(SimpleValue<T>::vector(12), *svc.copy); | 
| 1238 |     } | 
| 1239 |     { | 
| 1240 |         QVector<T> v = SimpleValue<T>::vector(12); | 
| 1241 |         SharedVectorChecker<T> svc(v, shared); | 
| 1242 |         v.remove(1); | 
| 1243 |         QCOMPARE(v.size(), 11); | 
| 1244 |         QCOMPARE(v.at(0), SimpleValue<T>::at(0)); | 
| 1245 |         for (int i = 1; i < 11; i++) | 
| 1246 |             QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1)); | 
| 1247 |         v.erase(v.begin() + 1, v.end()); | 
| 1248 |         QCOMPARE(v.size(), 1); | 
| 1249 |         QCOMPARE(v.at(0), SimpleValue<T>::at(0)); | 
| 1250 |         if (shared) | 
| 1251 |             QCOMPARE(SimpleValue<T>::vector(12), *svc.copy); | 
| 1252 |     } | 
| 1253 |     { | 
| 1254 |         QVector<T> v = SimpleValue<T>::vector(12); | 
| 1255 |         SharedVectorChecker<T> svc(v, shared); | 
| 1256 |         v.erase(v.begin(), v.end() - 1); | 
| 1257 |         QCOMPARE(v.size(), 1); | 
| 1258 |         QCOMPARE(v.at(0), SimpleValue<T>::at(11)); | 
| 1259 |         if (shared) | 
| 1260 |             QCOMPARE(SimpleValue<T>::vector(12), *svc.copy); | 
| 1261 |     } | 
| 1262 |     { | 
| 1263 |         QVector<T> v = SimpleValue<T>::vector(12); | 
| 1264 |         SharedVectorChecker<T> svc(v, shared); | 
| 1265 |         v.remove(5); | 
| 1266 |         QCOMPARE(v.size(), 11); | 
| 1267 |         for (int i = 0; i < 5; i++) | 
| 1268 |             QCOMPARE(v.at(i), SimpleValue<T>::at(i)); | 
| 1269 |         for (int i = 5; i < 11; i++) | 
| 1270 |             QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1)); | 
| 1271 |         v.erase(v.begin() + 1, v.end() - 1); | 
| 1272 |         QCOMPARE(v.at(0), SimpleValue<T>::at(0)); | 
| 1273 |         QCOMPARE(v.at(1), SimpleValue<T>::at(11)); | 
| 1274 |         QCOMPARE(v.size(), 2); | 
| 1275 |         if (shared) | 
| 1276 |             QCOMPARE(SimpleValue<T>::vector(12), *svc.copy); | 
| 1277 |     } | 
| 1278 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 1279 |     // ### Qt6 remove this section | 
| 1280 |     { | 
| 1281 |         QVector<T> v = SimpleValue<T>::vector(10); | 
| 1282 |         SharedVectorChecker<T> svc(v, shared); | 
| 1283 |         v.setSharable(false); | 
| 1284 |         SharedVectorChecker<T> svc2(v, shared); | 
| 1285 |         v.erase(v.begin() + 3); | 
| 1286 |         QCOMPARE(v.size(), 9); | 
| 1287 |         v.erase(v.begin(), v.end() - 1); | 
| 1288 |         QCOMPARE(v.size(), 1); | 
| 1289 |         if (shared) | 
| 1290 |             QCOMPARE(SimpleValue<T>::vector(10), *svc.copy); | 
| 1291 |     } | 
| 1292 | #endif | 
| 1293 | } | 
| 1294 |  | 
| 1295 | void tst_QVector::eraseInt() const | 
| 1296 | { | 
| 1297 |     erase<int>(shared: false); | 
| 1298 | } | 
| 1299 |  | 
| 1300 | void tst_QVector::eraseIntShared() const | 
| 1301 | { | 
| 1302 |     erase<int>(shared: true); | 
| 1303 | } | 
| 1304 |  | 
| 1305 | void tst_QVector::eraseMovable() const | 
| 1306 | { | 
| 1307 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1308 |     erase<Movable>(shared: false); | 
| 1309 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1310 | } | 
| 1311 |  | 
| 1312 | void tst_QVector::eraseMovableShared() const | 
| 1313 | { | 
| 1314 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1315 |     erase<Movable>(shared: true); | 
| 1316 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1317 | } | 
| 1318 |  | 
| 1319 | void tst_QVector::eraseCustom() const | 
| 1320 | { | 
| 1321 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1322 |     erase<Custom>(shared: false); | 
| 1323 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1324 | } | 
| 1325 |  | 
| 1326 | void tst_QVector::eraseCustomShared() const | 
| 1327 | { | 
| 1328 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1329 |     erase<Custom>(shared: true); | 
| 1330 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1331 | } | 
| 1332 |  | 
| 1333 | template<typename T> void tst_QVector::eraseReserved() const | 
| 1334 | { | 
| 1335 |     { | 
| 1336 |         QVector<T> v(12); | 
| 1337 |         v.reserve(16); | 
| 1338 |         v.erase(v.begin()); | 
| 1339 |         QCOMPARE(v.size(), 11); | 
| 1340 |         v.erase(v.begin(), v.end()); | 
| 1341 |         QCOMPARE(v.size(), 0); | 
| 1342 |     } | 
| 1343 |     { | 
| 1344 |         QVector<T> v(12); | 
| 1345 |         v.reserve(16); | 
| 1346 |         v.erase(v.begin() + 1); | 
| 1347 |         QCOMPARE(v.size(), 11); | 
| 1348 |         v.erase(v.begin() + 1, v.end()); | 
| 1349 |         QCOMPARE(v.size(), 1); | 
| 1350 |     } | 
| 1351 |     { | 
| 1352 |         QVector<T> v(12); | 
| 1353 |         v.reserve(16); | 
| 1354 |         v.erase(v.begin(), v.end() - 1); | 
| 1355 |         QCOMPARE(v.size(), 1); | 
| 1356 |     } | 
| 1357 |     { | 
| 1358 |         QVector<T> v(12); | 
| 1359 |         v.reserve(16); | 
| 1360 |         v.erase(v.begin() + 5); | 
| 1361 |         QCOMPARE(v.size(), 11); | 
| 1362 |         v.erase(v.begin() + 1, v.end() - 1); | 
| 1363 |         QCOMPARE(v.size(), 2); | 
| 1364 |     } | 
| 1365 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 1366 |     // ### Qt6 remove this section | 
| 1367 |     { | 
| 1368 |         QVector<T> v(10); | 
| 1369 |         v.reserve(16); | 
| 1370 |         v.setSharable(false); | 
| 1371 |         v.erase(v.begin() + 3); | 
| 1372 |         QCOMPARE(v.size(), 9); | 
| 1373 |         v.erase(v.begin(), v.end() - 1); | 
| 1374 |         QCOMPARE(v.size(), 1); | 
| 1375 |     } | 
| 1376 | #endif | 
| 1377 | } | 
| 1378 |  | 
| 1379 | void tst_QVector::eraseReservedInt() const | 
| 1380 | { | 
| 1381 |     eraseReserved<int>(); | 
| 1382 | } | 
| 1383 |  | 
| 1384 | void tst_QVector::eraseReservedMovable() const | 
| 1385 | { | 
| 1386 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1387 |     eraseReserved<Movable>(); | 
| 1388 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1389 | } | 
| 1390 |  | 
| 1391 | void tst_QVector::eraseReservedCustom() const | 
| 1392 | { | 
| 1393 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1394 |     eraseReserved<Custom>(); | 
| 1395 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1396 | } | 
| 1397 |  | 
| 1398 | template<typename T> | 
| 1399 | void tst_QVector::fill() const | 
| 1400 | { | 
| 1401 |     QVector<T> myvec; | 
| 1402 |  | 
| 1403 |     // resize | 
| 1404 |     myvec.resize(5); | 
| 1405 |     myvec.fill(SimpleValue<T>::at(1)); | 
| 1406 |     QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(1) << SimpleValue<T>::at(1) | 
| 1407 |                                  << SimpleValue<T>::at(1) << SimpleValue<T>::at(1) | 
| 1408 |                                  << SimpleValue<T>::at(1)); | 
| 1409 |  | 
| 1410 |     // make sure it can resize itself too | 
| 1411 |     myvec.fill(SimpleValue<T>::at(2), 10); | 
| 1412 |     QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(2) << SimpleValue<T>::at(2) | 
| 1413 |                                  << SimpleValue<T>::at(2) << SimpleValue<T>::at(2) | 
| 1414 |                                  << SimpleValue<T>::at(2) << SimpleValue<T>::at(2) | 
| 1415 |                                  << SimpleValue<T>::at(2) << SimpleValue<T>::at(2) | 
| 1416 |                                  << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)); | 
| 1417 | } | 
| 1418 |  | 
| 1419 | void tst_QVector::fillInt() const | 
| 1420 | { | 
| 1421 |     fill<int>(); | 
| 1422 | } | 
| 1423 |  | 
| 1424 | void tst_QVector::fillMovable() const | 
| 1425 | { | 
| 1426 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1427 |     fill<Movable>(); | 
| 1428 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1429 | } | 
| 1430 |  | 
| 1431 | void tst_QVector::fillCustom() const | 
| 1432 | { | 
| 1433 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1434 |     fill<Custom>(); | 
| 1435 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1436 | } | 
| 1437 |  | 
| 1438 | void tst_QVector::fillDetaches() const | 
| 1439 | { | 
| 1440 |     QVector<int> test = { 1, 2, 3 }; | 
| 1441 |     QVector<int> copy = test; | 
| 1442 |     copy.fill(from: 42); | 
| 1443 |  | 
| 1444 |     QCOMPARE(test, QVector<int>({1, 2, 3})); | 
| 1445 |     QCOMPARE(copy, QVector<int>({42, 42, 42})); | 
| 1446 | } | 
| 1447 |  | 
| 1448 | void tst_QVector::first() const | 
| 1449 | { | 
| 1450 |     QVector<int> myvec; | 
| 1451 |     myvec << 69 << 42 << 3; | 
| 1452 |  | 
| 1453 |     // test it starts ok | 
| 1454 |     QCOMPARE(myvec.first(), 69); | 
| 1455 |     QCOMPARE(myvec.constFirst(), 69); | 
| 1456 |  | 
| 1457 |     // test removal changes | 
| 1458 |     myvec.remove(i: 0); | 
| 1459 |     QCOMPARE(myvec.first(), 42); | 
| 1460 |     QCOMPARE(myvec.constFirst(), 42); | 
| 1461 |  | 
| 1462 |     // test prepend changes | 
| 1463 |     myvec.prepend(t: 23); | 
| 1464 |     QCOMPARE(myvec.first(), 23); | 
| 1465 |     QCOMPARE(myvec.constFirst(), 23); | 
| 1466 | } | 
| 1467 |  | 
| 1468 | void tst_QVector::constFirst() const | 
| 1469 | { | 
| 1470 |     QVector<int> myvec; | 
| 1471 |     myvec << 69 << 42 << 3; | 
| 1472 |  | 
| 1473 |     // test it starts ok | 
| 1474 |     QCOMPARE(myvec.constFirst(), 69); | 
| 1475 |     QVERIFY(myvec.isDetached()); | 
| 1476 |  | 
| 1477 |     QVector<int> myvecCopy = myvec; | 
| 1478 |     QVERIFY(!myvec.isDetached()); | 
| 1479 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1480 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1481 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1482 |  | 
| 1483 |     QCOMPARE(myvec.constFirst(), 69); | 
| 1484 |     QCOMPARE(myvecCopy.constFirst(), 69); | 
| 1485 |  | 
| 1486 |     QVERIFY(!myvec.isDetached()); | 
| 1487 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1488 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1489 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1490 |  | 
| 1491 |     // test removal changes | 
| 1492 |     myvec.remove(i: 0); | 
| 1493 |     QVERIFY(myvec.isDetached()); | 
| 1494 |     QVERIFY(!myvec.isSharedWith(myvecCopy)); | 
| 1495 |     QCOMPARE(myvec.constFirst(), 42); | 
| 1496 |     QCOMPARE(myvecCopy.constFirst(), 69); | 
| 1497 |  | 
| 1498 |     myvecCopy = myvec; | 
| 1499 |     QVERIFY(!myvec.isDetached()); | 
| 1500 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1501 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1502 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1503 |  | 
| 1504 |     QCOMPARE(myvec.constFirst(), 42); | 
| 1505 |     QCOMPARE(myvecCopy.constFirst(), 42); | 
| 1506 |  | 
| 1507 |     QVERIFY(!myvec.isDetached()); | 
| 1508 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1509 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1510 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1511 |  | 
| 1512 |     // test prepend changes | 
| 1513 |     myvec.prepend(t: 23); | 
| 1514 |     QVERIFY(myvec.isDetached()); | 
| 1515 |     QVERIFY(!myvec.isSharedWith(myvecCopy)); | 
| 1516 |     QCOMPARE(myvec.constFirst(), 23); | 
| 1517 |     QCOMPARE(myvecCopy.constFirst(), 42); | 
| 1518 |  | 
| 1519 |     myvecCopy = myvec; | 
| 1520 |     QVERIFY(!myvec.isDetached()); | 
| 1521 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1522 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1523 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1524 |  | 
| 1525 |     QCOMPARE(myvec.constFirst(), 23); | 
| 1526 |     QCOMPARE(myvecCopy.constFirst(), 23); | 
| 1527 |  | 
| 1528 |     QVERIFY(!myvec.isDetached()); | 
| 1529 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1530 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1531 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1532 | } | 
| 1533 |  | 
| 1534 |  | 
| 1535 | template<typename T> | 
| 1536 | void tst_QVector::fromList() const | 
| 1537 | { | 
| 1538 |     QList<T> list; | 
| 1539 |     list << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3); | 
| 1540 |  | 
| 1541 |     QVector<T> myvec; | 
| 1542 |     myvec = QVector<T>::fromList(list); | 
| 1543 |  | 
| 1544 |     // test it worked ok | 
| 1545 |     QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3)); | 
| 1546 |     QCOMPARE(list, QList<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3)); | 
| 1547 | } | 
| 1548 |  | 
| 1549 | void tst_QVector::fromListInt() const | 
| 1550 | { | 
| 1551 |     fromList<int>(); | 
| 1552 | } | 
| 1553 |  | 
| 1554 | void tst_QVector::fromListMovable() const | 
| 1555 | { | 
| 1556 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1557 |     fromList<Movable>(); | 
| 1558 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1559 | } | 
| 1560 |  | 
| 1561 | void tst_QVector::fromListCustom() const | 
| 1562 | { | 
| 1563 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1564 |     fromList<Custom>(); | 
| 1565 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1566 | } | 
| 1567 |  | 
| 1568 | #if QT_VERSION < QT_VERSION_CHECK(6,0,0) | 
| 1569 | void tst_QVector::fromStdVector() const | 
| 1570 | { | 
| 1571 |     // stl = :( | 
| 1572 |     std::vector<QString> svec; | 
| 1573 |     svec.push_back(x: QLatin1String("aaa" )); | 
| 1574 |     svec.push_back(x: QLatin1String("bbb" )); | 
| 1575 |     svec.push_back(x: QLatin1String("ninjas" )); | 
| 1576 |     svec.push_back(x: QLatin1String("pirates" )); | 
| 1577 |     QVector<QString> myvec = QVector<QString>::fromStdVector(vector: svec); | 
| 1578 |  | 
| 1579 |     // test it converts ok | 
| 1580 |     QCOMPARE(myvec, QVector<QString>() << "aaa"  << "bbb"  << "ninjas"  << "pirates" ); | 
| 1581 | } | 
| 1582 | #endif | 
| 1583 |  | 
| 1584 | void tst_QVector::indexOf() const | 
| 1585 | { | 
| 1586 |     QVector<QString> myvec; | 
| 1587 |     myvec << "A"  << "B"  << "C"  << "B"  << "A" ; | 
| 1588 |  | 
| 1589 |     QVERIFY(myvec.indexOf("B" ) == 1); | 
| 1590 |     QVERIFY(myvec.indexOf("B" , 1) == 1); | 
| 1591 |     QVERIFY(myvec.indexOf("B" , 2) == 3); | 
| 1592 |     QVERIFY(myvec.indexOf("X" ) == -1); | 
| 1593 |     QVERIFY(myvec.indexOf("X" , 2) == -1); | 
| 1594 |  | 
| 1595 |     // add an X | 
| 1596 |     myvec << "X" ; | 
| 1597 |     QVERIFY(myvec.indexOf("X" ) == 5); | 
| 1598 |     QVERIFY(myvec.indexOf("X" , 5) == 5); | 
| 1599 |     QVERIFY(myvec.indexOf("X" , 6) == -1); | 
| 1600 |  | 
| 1601 |     // remove first A | 
| 1602 |     myvec.remove(i: 0); | 
| 1603 |     QVERIFY(myvec.indexOf("A" ) == 3); | 
| 1604 |     QVERIFY(myvec.indexOf("A" , 3) == 3); | 
| 1605 |     QVERIFY(myvec.indexOf("A" , 4) == -1); | 
| 1606 | } | 
| 1607 |  | 
| 1608 | template <typename T> | 
| 1609 | void tst_QVector::insert() const | 
| 1610 | { | 
| 1611 |     QVector<T> myvec; | 
| 1612 |     const T | 
| 1613 |         tA = SimpleValue<T>::at(0), | 
| 1614 |         tB = SimpleValue<T>::at(1), | 
| 1615 |         tC = SimpleValue<T>::at(2), | 
| 1616 |         tX = SimpleValue<T>::at(3), | 
| 1617 |         tZ = SimpleValue<T>::at(4), | 
| 1618 |         tT = SimpleValue<T>::at(5), | 
| 1619 |         ti = SimpleValue<T>::at(6); | 
| 1620 |     myvec << tA << tB << tC; | 
| 1621 |     QVector<T> myvec2 = myvec; | 
| 1622 |  | 
| 1623 |     // first position | 
| 1624 |     QCOMPARE(myvec.at(0), tA); | 
| 1625 |     myvec.insert(0, tX); | 
| 1626 |     QCOMPARE(myvec.at(0), tX); | 
| 1627 |     QCOMPARE(myvec.at(1), tA); | 
| 1628 |  | 
| 1629 |     QCOMPARE(myvec2.at(0), tA); | 
| 1630 |     myvec2.insert(myvec2.begin(), tX); | 
| 1631 |     QCOMPARE(myvec2.at(0), tX); | 
| 1632 |     QCOMPARE(myvec2.at(1), tA); | 
| 1633 |  | 
| 1634 |     // middle | 
| 1635 |     myvec.insert(1, tZ); | 
| 1636 |     QCOMPARE(myvec.at(0), tX); | 
| 1637 |     QCOMPARE(myvec.at(1), tZ); | 
| 1638 |     QCOMPARE(myvec.at(2), tA); | 
| 1639 |  | 
| 1640 |     myvec2.insert(myvec2.begin() + 1, tZ); | 
| 1641 |     QCOMPARE(myvec2.at(0), tX); | 
| 1642 |     QCOMPARE(myvec2.at(1), tZ); | 
| 1643 |     QCOMPARE(myvec2.at(2), tA); | 
| 1644 |  | 
| 1645 |     // end | 
| 1646 |     myvec.insert(5, tT); | 
| 1647 |     QCOMPARE(myvec.at(5), tT); | 
| 1648 |     QCOMPARE(myvec.at(4), tC); | 
| 1649 |  | 
| 1650 |     myvec2.insert(myvec2.end(), tT); | 
| 1651 |     QCOMPARE(myvec2.at(5), tT); | 
| 1652 |     QCOMPARE(myvec2.at(4), tC); | 
| 1653 |  | 
| 1654 |     // insert a lot of garbage in the middle | 
| 1655 |     myvec.insert(2, 2, ti); | 
| 1656 |     QCOMPARE(myvec, QVector<T>() << tX << tZ << ti << ti | 
| 1657 |              << tA << tB << tC << tT); | 
| 1658 |  | 
| 1659 |     myvec2.insert(myvec2.begin() + 2, 2, ti); | 
| 1660 |     QCOMPARE(myvec2, myvec); | 
| 1661 |  | 
| 1662 |     // insert from references to the same container: | 
| 1663 |     myvec.insert(0, 1, myvec[5]);   // inserts tB | 
| 1664 |     myvec2.insert(0, 1, myvec2[5]); // inserts tB | 
| 1665 |     QCOMPARE(myvec, QVector<T>() << tB << tX << tZ << ti << ti | 
| 1666 |              << tA << tB << tC << tT); | 
| 1667 |     QCOMPARE(myvec2, myvec); | 
| 1668 |  | 
| 1669 |     myvec.insert(0, 1, const_cast<const QVector<T>&>(myvec)[0]);   // inserts tB | 
| 1670 |     myvec2.insert(0, 1, const_cast<const QVector<T>&>(myvec2)[0]); // inserts tB | 
| 1671 |     QCOMPARE(myvec, QVector<T>() << tB << tB << tX << tZ << ti << ti | 
| 1672 |              << tA << tB << tC << tT); | 
| 1673 |     QCOMPARE(myvec2, myvec); | 
| 1674 | } | 
| 1675 |  | 
| 1676 | void tst_QVector::insertInt() const | 
| 1677 | { | 
| 1678 |     insert<int>(); | 
| 1679 | } | 
| 1680 |  | 
| 1681 | void tst_QVector::insertMovable() const | 
| 1682 | { | 
| 1683 |     insert<Movable>(); | 
| 1684 | } | 
| 1685 |  | 
| 1686 | void tst_QVector::insertCustom() const | 
| 1687 | { | 
| 1688 |     insert<Custom>(); | 
| 1689 | } | 
| 1690 |  | 
| 1691 | void tst_QVector::insertNonDefaultConstructible() const | 
| 1692 | { | 
| 1693 |     insert<NonDefaultConstructible>(); | 
| 1694 | } | 
| 1695 |  | 
| 1696 | void tst_QVector::isEmpty() const | 
| 1697 | { | 
| 1698 |     QVector<QString> myvec; | 
| 1699 |  | 
| 1700 |     // starts ok | 
| 1701 |     QVERIFY(myvec.isEmpty()); | 
| 1702 |  | 
| 1703 |     // not empty now | 
| 1704 |     myvec.append(t: QLatin1String("hello there" )); | 
| 1705 |     QVERIFY(!myvec.isEmpty()); | 
| 1706 |  | 
| 1707 |     // empty again | 
| 1708 |     myvec.remove(i: 0); | 
| 1709 |     QVERIFY(myvec.isEmpty()); | 
| 1710 | } | 
| 1711 |  | 
| 1712 | void tst_QVector::last() const | 
| 1713 | { | 
| 1714 |     QVector<QString> myvec; | 
| 1715 |     myvec << "A"  << "B"  << "C" ; | 
| 1716 |  | 
| 1717 |     // test starts ok | 
| 1718 |     QCOMPARE(myvec.last(), QLatin1String("C" )); | 
| 1719 |     QCOMPARE(myvec.constLast(), QLatin1String("C" )); | 
| 1720 |  | 
| 1721 |     // test it changes ok | 
| 1722 |     myvec.append(t: QLatin1String("X" )); | 
| 1723 |     QCOMPARE(myvec.last(), QLatin1String("X" )); | 
| 1724 |     QCOMPARE(myvec.constLast(), QLatin1String("X" )); | 
| 1725 |  | 
| 1726 |     // and remove again | 
| 1727 |     myvec.remove(i: 3); | 
| 1728 |     QCOMPARE(myvec.last(), QLatin1String("C" )); | 
| 1729 |     QCOMPARE(myvec.constLast(), QLatin1String("C" )); | 
| 1730 | } | 
| 1731 |  | 
| 1732 | void tst_QVector::constLast() const | 
| 1733 | { | 
| 1734 |     QVector<int> myvec; | 
| 1735 |     myvec << 69 << 42 << 3; | 
| 1736 |  | 
| 1737 |     // test it starts ok | 
| 1738 |     QCOMPARE(myvec.constLast(), 3); | 
| 1739 |     QVERIFY(myvec.isDetached()); | 
| 1740 |  | 
| 1741 |     QVector<int> myvecCopy = myvec; | 
| 1742 |     QVERIFY(!myvec.isDetached()); | 
| 1743 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1744 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1745 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1746 |  | 
| 1747 |     QCOMPARE(myvec.constLast(), 3); | 
| 1748 |     QCOMPARE(myvecCopy.constLast(), 3); | 
| 1749 |  | 
| 1750 |     QVERIFY(!myvec.isDetached()); | 
| 1751 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1752 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1753 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1754 |  | 
| 1755 |     // test removal changes | 
| 1756 |     myvec.removeLast(); | 
| 1757 |     QVERIFY(myvec.isDetached()); | 
| 1758 |     QVERIFY(!myvec.isSharedWith(myvecCopy)); | 
| 1759 |     QCOMPARE(myvec.constLast(), 42); | 
| 1760 |     QCOMPARE(myvecCopy.constLast(), 3); | 
| 1761 |  | 
| 1762 |     myvecCopy = myvec; | 
| 1763 |     QVERIFY(!myvec.isDetached()); | 
| 1764 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1765 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1766 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1767 |  | 
| 1768 |     QCOMPARE(myvec.constLast(), 42); | 
| 1769 |     QCOMPARE(myvecCopy.constLast(), 42); | 
| 1770 |  | 
| 1771 |     QVERIFY(!myvec.isDetached()); | 
| 1772 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1773 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1774 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1775 |  | 
| 1776 |     // test prepend changes | 
| 1777 |     myvec.append(t: 23); | 
| 1778 |     QVERIFY(myvec.isDetached()); | 
| 1779 |     QVERIFY(!myvec.isSharedWith(myvecCopy)); | 
| 1780 |     QCOMPARE(myvec.constLast(), 23); | 
| 1781 |     QCOMPARE(myvecCopy.constLast(), 42); | 
| 1782 |  | 
| 1783 |     myvecCopy = myvec; | 
| 1784 |     QVERIFY(!myvec.isDetached()); | 
| 1785 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1786 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1787 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1788 |  | 
| 1789 |     QCOMPARE(myvec.constLast(), 23); | 
| 1790 |     QCOMPARE(myvecCopy.constLast(), 23); | 
| 1791 |  | 
| 1792 |     QVERIFY(!myvec.isDetached()); | 
| 1793 |     QVERIFY(!myvecCopy.isDetached()); | 
| 1794 |     QVERIFY(myvec.isSharedWith(myvecCopy)); | 
| 1795 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1796 | } | 
| 1797 |  | 
| 1798 | void tst_QVector::lastIndexOf() const | 
| 1799 | { | 
| 1800 |     QVector<QString> myvec; | 
| 1801 |     myvec << "A"  << "B"  << "C"  << "B"  << "A" ; | 
| 1802 |  | 
| 1803 |     QVERIFY(myvec.lastIndexOf("B" ) == 3); | 
| 1804 |     QVERIFY(myvec.lastIndexOf("B" , 2) == 1); | 
| 1805 |     QVERIFY(myvec.lastIndexOf("X" ) == -1); | 
| 1806 |     QVERIFY(myvec.lastIndexOf("X" , 2) == -1); | 
| 1807 |  | 
| 1808 |     // add an X | 
| 1809 |     myvec << "X" ; | 
| 1810 |     QVERIFY(myvec.lastIndexOf("X" ) == 5); | 
| 1811 |     QVERIFY(myvec.lastIndexOf("X" , 5) == 5); | 
| 1812 |     QVERIFY(myvec.lastIndexOf("X" , 3) == -1); | 
| 1813 |  | 
| 1814 |     // remove first A | 
| 1815 |     myvec.remove(i: 0); | 
| 1816 |     QVERIFY(myvec.lastIndexOf("A" ) == 3); | 
| 1817 |     QVERIFY(myvec.lastIndexOf("A" , 3) == 3); | 
| 1818 |     QVERIFY(myvec.lastIndexOf("A" , 2) == -1); | 
| 1819 | } | 
| 1820 |  | 
| 1821 | void tst_QVector::mid() const | 
| 1822 | { | 
| 1823 |     QVector<QString> list; | 
| 1824 |     list << "foo"  << "bar"  << "baz"  << "bak"  << "buck"  << "hello"  << "kitty" ; | 
| 1825 |  | 
| 1826 |     QCOMPARE(list.mid(3, 3), QVector<QString>() << "bak"  << "buck"  << "hello" ); | 
| 1827 |     QCOMPARE(list.mid(6, 10), QVector<QString>() << "kitty" ); | 
| 1828 |     QCOMPARE(list.mid(-1, 20), list); | 
| 1829 |     QCOMPARE(list.mid(4), QVector<QString>() << "buck"  << "hello"  << "kitty" ); | 
| 1830 | } | 
| 1831 |  | 
| 1832 | template <typename T> | 
| 1833 | void tst_QVector::qhash() const | 
| 1834 | { | 
| 1835 |     QVector<T> l1, l2; | 
| 1836 |     QCOMPARE(qHash(l1), qHash(l2)); | 
| 1837 |     l1 << SimpleValue<T>::at(0); | 
| 1838 |     l2 << SimpleValue<T>::at(0); | 
| 1839 |     QCOMPARE(qHash(l1), qHash(l2)); | 
| 1840 | } | 
| 1841 |  | 
| 1842 | template <typename T> | 
| 1843 | void tst_QVector::move() const | 
| 1844 | { | 
| 1845 |     QVector<T> list; | 
| 1846 |     list << T_FOO << T_BAR << T_BAZ; | 
| 1847 |  | 
| 1848 |     // move an item | 
| 1849 |     list.move(0, list.count() - 1); | 
| 1850 |     QCOMPARE(list, QVector<T>() << T_BAR << T_BAZ << T_FOO); | 
| 1851 |  | 
| 1852 |     // move it back | 
| 1853 |     list.move(list.count() - 1, 0); | 
| 1854 |     QCOMPARE(list, QVector<T>() << T_FOO << T_BAR << T_BAZ); | 
| 1855 |  | 
| 1856 |     // move an item in the middle | 
| 1857 |     list.move(1, 0); | 
| 1858 |     QCOMPARE(list, QVector<T>() << T_BAR << T_FOO << T_BAZ); | 
| 1859 | } | 
| 1860 |  | 
| 1861 | void tst_QVector::moveInt() const | 
| 1862 | { | 
| 1863 |     move<int>(); | 
| 1864 | } | 
| 1865 |  | 
| 1866 | void tst_QVector::moveMovable() const | 
| 1867 | { | 
| 1868 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1869 |     move<Movable>(); | 
| 1870 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1871 | } | 
| 1872 |  | 
| 1873 | void tst_QVector::moveCustom() const | 
| 1874 | { | 
| 1875 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1876 |     move<Custom>(); | 
| 1877 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1878 | } | 
| 1879 |  | 
| 1880 | template<typename T> | 
| 1881 | void tst_QVector::prepend() const | 
| 1882 | { | 
| 1883 |     QVector<T> myvec; | 
| 1884 |     T val1 = SimpleValue<T>::at(0); | 
| 1885 |     T val2 = SimpleValue<T>::at(1); | 
| 1886 |     T val3 = SimpleValue<T>::at(2); | 
| 1887 |     T val4 = SimpleValue<T>::at(3); | 
| 1888 |     T val5 = SimpleValue<T>::at(4); | 
| 1889 |     myvec << val1 << val2 << val3; | 
| 1890 |  | 
| 1891 |     // starts ok | 
| 1892 |     QVERIFY(myvec.size() == 3); | 
| 1893 |     QCOMPARE(myvec.at(0), val1); | 
| 1894 |  | 
| 1895 |     // add something | 
| 1896 |     myvec.prepend(val4); | 
| 1897 |     QCOMPARE(myvec.at(0), val4); | 
| 1898 |     QCOMPARE(myvec.at(1), val1); | 
| 1899 |     QVERIFY(myvec.size() == 4); | 
| 1900 |  | 
| 1901 |     // something else | 
| 1902 |     myvec.prepend(val5); | 
| 1903 |     QCOMPARE(myvec.at(0), val5); | 
| 1904 |     QCOMPARE(myvec.at(1), val4); | 
| 1905 |     QCOMPARE(myvec.at(2), val1); | 
| 1906 |     QVERIFY(myvec.size() == 5); | 
| 1907 |  | 
| 1908 |     // clear and prepend to an empty vector | 
| 1909 |     myvec.clear(); | 
| 1910 |     QVERIFY(myvec.size() == 0); | 
| 1911 |     myvec.prepend(val5); | 
| 1912 |     QVERIFY(myvec.size() == 1); | 
| 1913 |     QCOMPARE(myvec.at(0), val5); | 
| 1914 | } | 
| 1915 |  | 
| 1916 | void tst_QVector::prependInt() const | 
| 1917 | { | 
| 1918 |     prepend<int>(); | 
| 1919 | } | 
| 1920 |  | 
| 1921 | void tst_QVector::prependMovable() const | 
| 1922 | { | 
| 1923 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1924 |     prepend<Movable>(); | 
| 1925 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1926 | } | 
| 1927 |  | 
| 1928 | void tst_QVector::prependCustom() const | 
| 1929 | { | 
| 1930 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 1931 |     prepend<Custom>(); | 
| 1932 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 1933 | } | 
| 1934 |  | 
| 1935 | void tst_QVector::prependNonDefaultConstructible() const | 
| 1936 | { | 
| 1937 |     const int instancesCount = NonDefaultConstructible::counter.loadAcquire(); | 
| 1938 |     prepend<NonDefaultConstructible>(); | 
| 1939 |     QCOMPARE(instancesCount, NonDefaultConstructible::counter.loadAcquire()); | 
| 1940 | } | 
| 1941 |  | 
| 1942 | void tst_QVector::removeAllWithAlias() const | 
| 1943 | { | 
| 1944 |     QVector<QString> strings; | 
| 1945 |     strings << "One"  << "Two"  << "Three"  << "One"  /* must be distinct, but equal */; | 
| 1946 |     QCOMPARE(strings.removeAll(strings.front()), 2); // will trigger asan/ubsan | 
| 1947 | } | 
| 1948 |  | 
| 1949 | template<typename T> | 
| 1950 | void tst_QVector::remove() const | 
| 1951 | { | 
| 1952 |     QVector<T> myvec; | 
| 1953 |     T val1 = SimpleValue<T>::at(1); | 
| 1954 |     T val2 = SimpleValue<T>::at(2); | 
| 1955 |     T val3 = SimpleValue<T>::at(3); | 
| 1956 |     T val4 = SimpleValue<T>::at(4); | 
| 1957 |     myvec << val1 << val2 << val3; | 
| 1958 |     myvec << val1 << val2 << val3; | 
| 1959 |     myvec << val1 << val2 << val3; | 
| 1960 |     // remove middle | 
| 1961 |     myvec.remove(1); | 
| 1962 |     QCOMPARE(myvec, QVector<T>() << val1 << val3  << val1 << val2 << val3  << val1 << val2 << val3); | 
| 1963 |  | 
| 1964 |     // removeOne() | 
| 1965 |     QVERIFY(!myvec.removeOne(val4)); | 
| 1966 |     QVERIFY(myvec.removeOne(val2)); | 
| 1967 |     QCOMPARE(myvec, QVector<T>() << val1 << val3  << val1 << val3  << val1 << val2 << val3); | 
| 1968 |  | 
| 1969 |     QVector<T> myvecCopy = myvec; | 
| 1970 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1971 |     // removeAll() | 
| 1972 |     QCOMPARE(myvec.removeAll(val4), 0); | 
| 1973 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1974 |     QCOMPARE(myvec.removeAll(val1), 3); | 
| 1975 |     QVERIFY(!myvecCopy.isSharedWith(myvec)); | 
| 1976 |     QCOMPARE(myvec, QVector<T>() << val3  << val3  << val2 << val3); | 
| 1977 |     myvecCopy = myvec; | 
| 1978 |     QVERIFY(myvecCopy.isSharedWith(myvec)); | 
| 1979 |     QCOMPARE(myvec.removeAll(val2), 1); | 
| 1980 |     QVERIFY(!myvecCopy.isSharedWith(myvec)); | 
| 1981 |     QCOMPARE(myvec, QVector<T>() << val3  << val3  << val3); | 
| 1982 |  | 
| 1983 |     // remove rest | 
| 1984 |     myvec.remove(0, 3); | 
| 1985 |     QCOMPARE(myvec, QVector<T>()); | 
| 1986 | } | 
| 1987 |  | 
| 1988 | void tst_QVector::removeInt() const | 
| 1989 | { | 
| 1990 |     remove<int>(); | 
| 1991 | } | 
| 1992 |  | 
| 1993 | void tst_QVector::removeMovable() const | 
| 1994 | { | 
| 1995 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 1996 |     remove<Movable>(); | 
| 1997 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 1998 | } | 
| 1999 |  | 
| 2000 | void tst_QVector::removeCustom() const | 
| 2001 | { | 
| 2002 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 2003 |     remove<Custom>(); | 
| 2004 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 2005 | } | 
| 2006 |  | 
| 2007 | struct RemoveLastTestClass | 
| 2008 | { | 
| 2009 |     RemoveLastTestClass() { other = 0; deleted = false; } | 
| 2010 |     RemoveLastTestClass *other; | 
| 2011 |     bool deleted; | 
| 2012 |     ~RemoveLastTestClass() | 
| 2013 |     { | 
| 2014 |         deleted = true; | 
| 2015 |         if (other) | 
| 2016 |             other->other = 0; | 
| 2017 |     } | 
| 2018 | }; | 
| 2019 |  | 
| 2020 | void tst_QVector::removeFirstLast() const | 
| 2021 | { | 
| 2022 |     // pop_pack - pop_front | 
| 2023 |     QVector<int> t, t2; | 
| 2024 |     t.append(t: 1); | 
| 2025 |     t.append(t: 2); | 
| 2026 |     t.append(t: 3); | 
| 2027 |     t.append(t: 4); | 
| 2028 |     t2 = t; | 
| 2029 |     t.pop_front(); | 
| 2030 |     QCOMPARE(t.size(), 3); | 
| 2031 |     QCOMPARE(t.at(0), 2); | 
| 2032 |     t.pop_back(); | 
| 2033 |     QCOMPARE(t.size(), 2); | 
| 2034 |     QCOMPARE(t.at(0), 2); | 
| 2035 |     QCOMPARE(t.at(1), 3); | 
| 2036 |  | 
| 2037 |     // takefirst - takeLast | 
| 2038 |     int n1 = t2.takeLast(); | 
| 2039 |     QCOMPARE(t2.size(), 3); | 
| 2040 |     QCOMPARE(n1, 4); | 
| 2041 |     QCOMPARE(t2.at(0), 1); | 
| 2042 |     QCOMPARE(t2.at(2), 3); | 
| 2043 |     n1 = t2.takeFirst(); | 
| 2044 |     QCOMPARE(t2.size(), 2); | 
| 2045 |     QCOMPARE(n1, 1); | 
| 2046 |     QCOMPARE(t2.at(0), 2); | 
| 2047 |     QCOMPARE(t2.at(1), 3); | 
| 2048 |  | 
| 2049 |     // remove first | 
| 2050 |     QVector<int> x, y; | 
| 2051 |     x.append(t: 1); | 
| 2052 |     x.append(t: 2); | 
| 2053 |     y = x; | 
| 2054 |     x.removeFirst(); | 
| 2055 |     QCOMPARE(x.size(), 1); | 
| 2056 |     QCOMPARE(y.size(), 2); | 
| 2057 |     QCOMPARE(x.at(0), 2); | 
| 2058 |  | 
| 2059 |     // remove Last | 
| 2060 |     QVector<RemoveLastTestClass> v; | 
| 2061 |     v.resize(asize: 2); | 
| 2062 |     v[0].other = &(v[1]); | 
| 2063 |     v[1].other = &(v[0]); | 
| 2064 |     // Check dtor - complex type | 
| 2065 |     QVERIFY(v.at(0).other != 0); | 
| 2066 |     v.removeLast(); | 
| 2067 |     QVERIFY(v.at(0).other == 0); | 
| 2068 |     QCOMPARE(v.at(0).deleted, false); | 
| 2069 |     // check iterator | 
| 2070 |     int count = 0; | 
| 2071 |     for (QVector<RemoveLastTestClass>::const_iterator i = v.constBegin(); i != v.constEnd(); ++i) { | 
| 2072 |         ++count; | 
| 2073 |         QVERIFY(i->other == 0); | 
| 2074 |         QCOMPARE(i->deleted, false); | 
| 2075 |     } | 
| 2076 |     // Check size | 
| 2077 |     QCOMPARE(count, 1); | 
| 2078 |     QCOMPARE(v.size(), 1); | 
| 2079 |     v.removeLast(); | 
| 2080 |     QCOMPARE(v.size(), 0); | 
| 2081 |     // Check if we do correct realloc | 
| 2082 |     QVector<int> v2, v3; | 
| 2083 |     v2.append(t: 1); | 
| 2084 |     v2.append(t: 2); | 
| 2085 |     v3 = v2; // shared | 
| 2086 |     v2.removeLast(); | 
| 2087 |     QCOMPARE(v2.size(), 1); | 
| 2088 |     QCOMPARE(v3.size(), 2); | 
| 2089 |     QCOMPARE(v2.at(0), 1); | 
| 2090 |     QCOMPARE(v3.at(0), 1); | 
| 2091 |     QCOMPARE(v3.at(1), 2); | 
| 2092 |  | 
| 2093 |     // Remove last with shared | 
| 2094 |     QVector<int> z1, z2; | 
| 2095 |     z1.append(t: 9); | 
| 2096 |     z2 = z1; | 
| 2097 |     z1.removeLast(); | 
| 2098 |     QCOMPARE(z1.size(), 0); | 
| 2099 |     QCOMPARE(z2.size(), 1); | 
| 2100 |     QCOMPARE(z2.at(0), 9); | 
| 2101 | } | 
| 2102 |  | 
| 2103 |  | 
| 2104 | void tst_QVector::resizePOD_data() const | 
| 2105 | { | 
| 2106 |     QTest::addColumn<QVector<int> >(name: "vector" ); | 
| 2107 |     QTest::addColumn<int>(name: "size" ); | 
| 2108 |  | 
| 2109 |     QVERIFY(!QTypeInfo<int>::isComplex); | 
| 2110 |     QVERIFY(!QTypeInfo<int>::isStatic); | 
| 2111 |  | 
| 2112 |     QVector<int> null; | 
| 2113 |     QVector<int> empty(0, 5); | 
| 2114 |     QVector<int> emptyReserved; | 
| 2115 |     QVector<int> nonEmpty; | 
| 2116 |     QVector<int> nonEmptyReserved; | 
| 2117 |  | 
| 2118 |     emptyReserved.reserve(asize: 10); | 
| 2119 |     nonEmptyReserved.reserve(asize: 15); | 
| 2120 |     nonEmpty << 0 << 1 << 2 << 3 << 4; | 
| 2121 |     nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6; | 
| 2122 |     QVERIFY(emptyReserved.capacity() >= 10); | 
| 2123 |     QVERIFY(nonEmptyReserved.capacity() >= 15); | 
| 2124 |  | 
| 2125 |     QTest::newRow(dataTag: "null" ) << null << 10; | 
| 2126 |     QTest::newRow(dataTag: "empty" ) << empty << 10; | 
| 2127 |     QTest::newRow(dataTag: "emptyReserved" ) << emptyReserved << 10; | 
| 2128 |     QTest::newRow(dataTag: "nonEmpty" ) << nonEmpty << 10; | 
| 2129 |     QTest::newRow(dataTag: "nonEmptyReserved" ) << nonEmptyReserved << 10; | 
| 2130 |  | 
| 2131 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 2132 |     // ### Qt6 remove this section | 
| 2133 |     QVector<int> nullNotShared; | 
| 2134 |     QVector<int> emptyNotShared(0, 5); | 
| 2135 |     QVector<int> emptyReservedNotShared; | 
| 2136 |     QVector<int> nonEmptyNotShared; | 
| 2137 |     QVector<int> nonEmptyReservedNotShared; | 
| 2138 |  | 
| 2139 |     emptyReservedNotShared.reserve(asize: 10); | 
| 2140 |     nonEmptyReservedNotShared.reserve(asize: 15); | 
| 2141 |     nonEmptyNotShared << 0 << 1 << 2 << 3 << 4; | 
| 2142 |     nonEmptyReservedNotShared << 0 << 1 << 2 << 3 << 4 << 5 << 6; | 
| 2143 |     QVERIFY(emptyReservedNotShared.capacity() >= 10); | 
| 2144 |     QVERIFY(nonEmptyReservedNotShared.capacity() >= 15); | 
| 2145 |  | 
| 2146 |     emptyNotShared.setSharable(false); | 
| 2147 |     emptyReservedNotShared.setSharable(false); | 
| 2148 |     nonEmptyNotShared.setSharable(false); | 
| 2149 |     nonEmptyReservedNotShared.setSharable(false); | 
| 2150 |  | 
| 2151 |     QTest::newRow(dataTag: "nullNotShared" ) << nullNotShared << 10; | 
| 2152 |     QTest::newRow(dataTag: "emptyNotShared" ) << emptyNotShared << 10; | 
| 2153 |     QTest::newRow(dataTag: "emptyReservedNotShared" ) << emptyReservedNotShared << 10; | 
| 2154 |     QTest::newRow(dataTag: "nonEmptyNotShared" ) << nonEmptyNotShared << 10; | 
| 2155 |     QTest::newRow(dataTag: "nonEmptyReservedNotShared" ) << nonEmptyReservedNotShared << 10; | 
| 2156 | #endif | 
| 2157 | } | 
| 2158 |  | 
| 2159 | void tst_QVector::resizePOD() const | 
| 2160 | { | 
| 2161 |     QFETCH(QVector<int>, vector); | 
| 2162 |     QFETCH(int, size); | 
| 2163 |  | 
| 2164 |     const int oldSize = vector.size(); | 
| 2165 |  | 
| 2166 |     vector.resize(asize: size); | 
| 2167 |     QCOMPARE(vector.size(), size); | 
| 2168 |     QVERIFY(vector.capacity() >= size); | 
| 2169 |     for (int i = oldSize; i < size; ++i) | 
| 2170 |         QVERIFY(vector[i] == 0); // check initialization | 
| 2171 |  | 
| 2172 |     const int capacity = vector.capacity(); | 
| 2173 |  | 
| 2174 |     vector.clear(); | 
| 2175 |     QCOMPARE(vector.size(), 0); | 
| 2176 |     QVERIFY(vector.capacity() <= capacity); | 
| 2177 | } | 
| 2178 |  | 
| 2179 | void tst_QVector::resizeComplexMovable_data() const | 
| 2180 | { | 
| 2181 |     QTest::addColumn<QVector<Movable> >(name: "vector" ); | 
| 2182 |     QTest::addColumn<int>(name: "size" ); | 
| 2183 |  | 
| 2184 |     QVERIFY(QTypeInfo<Movable>::isComplex); | 
| 2185 |     QVERIFY(!QTypeInfo<Movable>::isStatic); | 
| 2186 |  | 
| 2187 |     QVector<Movable> null; | 
| 2188 |     QVector<Movable> empty(0, 'Q'); | 
| 2189 |     QVector<Movable> emptyReserved; | 
| 2190 |     QVector<Movable> nonEmpty; | 
| 2191 |     QVector<Movable> nonEmptyReserved; | 
| 2192 |  | 
| 2193 |     emptyReserved.reserve(asize: 10); | 
| 2194 |     nonEmptyReserved.reserve(asize: 15); | 
| 2195 |     nonEmpty << '0' << '1' << '2' << '3' << '4'; | 
| 2196 |     nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6'; | 
| 2197 |     QVERIFY(emptyReserved.capacity() >= 10); | 
| 2198 |     QVERIFY(nonEmptyReserved.capacity() >= 15); | 
| 2199 |  | 
| 2200 |     QTest::newRow(dataTag: "null" ) << null << 10; | 
| 2201 |     QTest::newRow(dataTag: "empty" ) << empty << 10; | 
| 2202 |     QTest::newRow(dataTag: "emptyReserved" ) << emptyReserved << 10; | 
| 2203 |     QTest::newRow(dataTag: "nonEmpty" ) << nonEmpty << 10; | 
| 2204 |     QTest::newRow(dataTag: "nonEmptyReserved" ) << nonEmptyReserved << 10; | 
| 2205 |  | 
| 2206 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 2207 |     // ### Qt6 remove this section | 
| 2208 |     QVector<Movable> nullNotShared; | 
| 2209 |     QVector<Movable> emptyNotShared(0, 'Q'); | 
| 2210 |     QVector<Movable> emptyReservedNotShared; | 
| 2211 |     QVector<Movable> nonEmptyNotShared; | 
| 2212 |     QVector<Movable> nonEmptyReservedNotShared; | 
| 2213 |  | 
| 2214 |     emptyReservedNotShared.reserve(asize: 10); | 
| 2215 |     nonEmptyReservedNotShared.reserve(asize: 15); | 
| 2216 |     nonEmptyNotShared << '0' << '1' << '2' << '3' << '4'; | 
| 2217 |     nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6'; | 
| 2218 |     QVERIFY(emptyReservedNotShared.capacity() >= 10); | 
| 2219 |     QVERIFY(nonEmptyReservedNotShared.capacity() >= 15); | 
| 2220 |  | 
| 2221 |     emptyNotShared.setSharable(false); | 
| 2222 |     emptyReservedNotShared.setSharable(false); | 
| 2223 |     nonEmptyNotShared.setSharable(false); | 
| 2224 |     nonEmptyReservedNotShared.setSharable(false); | 
| 2225 |  | 
| 2226 |     QTest::newRow(dataTag: "nullNotShared" ) << nullNotShared << 10; | 
| 2227 |     QTest::newRow(dataTag: "emptyNotShared" ) << emptyNotShared << 10; | 
| 2228 |     QTest::newRow(dataTag: "emptyReservedNotShared" ) << emptyReservedNotShared << 10; | 
| 2229 |     QTest::newRow(dataTag: "nonEmptyNotShared" ) << nonEmptyNotShared << 10; | 
| 2230 |     QTest::newRow(dataTag: "nonEmptyReservedNotShared" ) << nonEmptyReservedNotShared << 10; | 
| 2231 | #endif | 
| 2232 | } | 
| 2233 |  | 
| 2234 | void tst_QVector::resizeComplexMovable() const | 
| 2235 | { | 
| 2236 |     const int items = Movable::counter.loadAcquire(); | 
| 2237 |     { | 
| 2238 |         QFETCH(QVector<Movable>, vector); | 
| 2239 |         QFETCH(int, size); | 
| 2240 |  | 
| 2241 |         const int oldSize = vector.size(); | 
| 2242 |  | 
| 2243 |         vector.resize(asize: size); | 
| 2244 |         QCOMPARE(vector.size(), size); | 
| 2245 |         QVERIFY(vector.capacity() >= size); | 
| 2246 |         for (int i = oldSize; i < size; ++i) | 
| 2247 |             QVERIFY(vector[i] == 'j'); // check initialization | 
| 2248 |  | 
| 2249 |         const int capacity = vector.capacity(); | 
| 2250 |  | 
| 2251 |         vector.resize(asize: 0); | 
| 2252 |         QCOMPARE(vector.size(), 0); | 
| 2253 |         QVERIFY(vector.capacity() <= capacity); | 
| 2254 |     } | 
| 2255 |     QCOMPARE(items, Movable::counter.loadAcquire()); | 
| 2256 | } | 
| 2257 |  | 
| 2258 | void tst_QVector::resizeComplex_data() const | 
| 2259 | { | 
| 2260 |     QTest::addColumn<QVector<Custom> >(name: "vector" ); | 
| 2261 |     QTest::addColumn<int>(name: "size" ); | 
| 2262 |  | 
| 2263 |     QVERIFY(QTypeInfo<Custom>::isComplex); | 
| 2264 |     QVERIFY(QTypeInfo<Custom>::isStatic); | 
| 2265 |  | 
| 2266 |     QVector<Custom> null; | 
| 2267 |     QVector<Custom> empty(0, '0'); | 
| 2268 |     QVector<Custom> emptyReserved; | 
| 2269 |     QVector<Custom> nonEmpty; | 
| 2270 |     QVector<Custom> nonEmptyReserved; | 
| 2271 |  | 
| 2272 |     emptyReserved.reserve(asize: 10); | 
| 2273 |     nonEmptyReserved.reserve(asize: 15); | 
| 2274 |     nonEmpty << '0' << '1' << '2' << '3' << '4'; | 
| 2275 |     nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6'; | 
| 2276 |     QVERIFY(emptyReserved.capacity() >= 10); | 
| 2277 |     QVERIFY(nonEmptyReserved.capacity() >= 15); | 
| 2278 |  | 
| 2279 |     QTest::newRow(dataTag: "null" ) << null << 10; | 
| 2280 |     QTest::newRow(dataTag: "empty" ) << empty << 10; | 
| 2281 |     QTest::newRow(dataTag: "emptyReserved" ) << emptyReserved << 10; | 
| 2282 |     QTest::newRow(dataTag: "nonEmpty" ) << nonEmpty << 10; | 
| 2283 |     QTest::newRow(dataTag: "nonEmptyReserved" ) << nonEmptyReserved << 10; | 
| 2284 |  | 
| 2285 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 2286 |     // ### Qt6 remove this section | 
| 2287 |     QVector<Custom> nullNotShared; | 
| 2288 |     QVector<Custom> emptyNotShared(0, '0'); | 
| 2289 |     QVector<Custom> emptyReservedNotShared; | 
| 2290 |     QVector<Custom> nonEmptyNotShared; | 
| 2291 |     QVector<Custom> nonEmptyReservedNotShared; | 
| 2292 |  | 
| 2293 |     emptyReservedNotShared.reserve(asize: 10); | 
| 2294 |     nonEmptyReservedNotShared.reserve(asize: 15); | 
| 2295 |     nonEmptyNotShared << '0' << '1' << '2' << '3' << '4'; | 
| 2296 |     nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6'; | 
| 2297 |     QVERIFY(emptyReservedNotShared.capacity() >= 10); | 
| 2298 |     QVERIFY(nonEmptyReservedNotShared.capacity() >= 15); | 
| 2299 |  | 
| 2300 |     emptyNotShared.setSharable(false); | 
| 2301 |     emptyReservedNotShared.setSharable(false); | 
| 2302 |     nonEmptyNotShared.setSharable(false); | 
| 2303 |     nonEmptyReservedNotShared.setSharable(false); | 
| 2304 |  | 
| 2305 |     QTest::newRow(dataTag: "nullNotShared" ) << nullNotShared << 10; | 
| 2306 |     QTest::newRow(dataTag: "emptyNotShared" ) << emptyNotShared << 10; | 
| 2307 |     QTest::newRow(dataTag: "emptyReservedNotShared" ) << emptyReservedNotShared << 10; | 
| 2308 |     QTest::newRow(dataTag: "nonEmptyNotShared" ) << nonEmptyNotShared << 10; | 
| 2309 |     QTest::newRow(dataTag: "nonEmptyReservedNotShared" ) << nonEmptyReservedNotShared << 10; | 
| 2310 | #endif | 
| 2311 | } | 
| 2312 |  | 
| 2313 | void tst_QVector::resizeComplex() const | 
| 2314 | { | 
| 2315 |     const int items = Custom::counter.loadAcquire(); | 
| 2316 |     { | 
| 2317 |         QFETCH(QVector<Custom>, vector); | 
| 2318 |         QFETCH(int, size); | 
| 2319 |  | 
| 2320 |         int oldSize = vector.size(); | 
| 2321 |         vector.resize(asize: size); | 
| 2322 |         QCOMPARE(vector.size(), size); | 
| 2323 |         QVERIFY(vector.capacity() >= size); | 
| 2324 |         for (int i = oldSize; i < size; ++i) | 
| 2325 |             QVERIFY(vector[i].i == 'j'); // check default initialization | 
| 2326 |  | 
| 2327 |         const int capacity = vector.capacity(); | 
| 2328 |  | 
| 2329 |         vector.resize(asize: 0); | 
| 2330 |         QCOMPARE(vector.size(), 0); | 
| 2331 |         QVERIFY(vector.isEmpty()); | 
| 2332 |         QVERIFY(vector.capacity() <= capacity); | 
| 2333 |     } | 
| 2334 |     QCOMPARE(Custom::counter.loadAcquire(), items); | 
| 2335 | } | 
| 2336 |  | 
| 2337 | void tst_QVector::resizeCtorAndDtor() const | 
| 2338 | { | 
| 2339 |     const int items = Custom::counter.loadAcquire(); | 
| 2340 |     { | 
| 2341 |         QVector<Custom> null; | 
| 2342 |         QVector<Custom> empty(0, '0'); | 
| 2343 |         QVector<Custom> emptyReserved; | 
| 2344 |         QVector<Custom> nonEmpty; | 
| 2345 |         QVector<Custom> nonEmptyReserved; | 
| 2346 |  | 
| 2347 |         emptyReserved.reserve(asize: 10); | 
| 2348 |         nonEmptyReserved.reserve(asize: 15); | 
| 2349 |         nonEmpty << '0' << '1' << '2' << '3' << '4'; | 
| 2350 |         nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6'; | 
| 2351 |         QVERIFY(emptyReserved.capacity() >= 10); | 
| 2352 |         QVERIFY(nonEmptyReserved.capacity() >= 15); | 
| 2353 |  | 
| 2354 |         // start playing with vectors | 
| 2355 |         null.resize(asize: 21); | 
| 2356 |         nonEmpty.resize(asize: 2); | 
| 2357 |         emptyReserved.resize(asize: 0); | 
| 2358 |         nonEmpty.resize(asize: 0); | 
| 2359 |         nonEmptyReserved.resize(asize: 2); | 
| 2360 |     } | 
| 2361 |     QCOMPARE(Custom::counter.loadAcquire(), items); | 
| 2362 | } | 
| 2363 |  | 
| 2364 | void tst_QVector::reverseIterators() const | 
| 2365 | { | 
| 2366 |     QVector<int> v; | 
| 2367 |     v << 1 << 2 << 3 << 4; | 
| 2368 |     QVector<int> vr = v; | 
| 2369 |     std::reverse(first: vr.begin(), last: vr.end()); | 
| 2370 |     const QVector<int> &cvr = vr; | 
| 2371 |     QVERIFY(std::equal(v.begin(), v.end(), vr.rbegin())); | 
| 2372 |     QVERIFY(std::equal(v.begin(), v.end(), vr.crbegin())); | 
| 2373 |     QVERIFY(std::equal(v.begin(), v.end(), cvr.rbegin())); | 
| 2374 |     QVERIFY(std::equal(vr.rbegin(), vr.rend(), v.begin())); | 
| 2375 |     QVERIFY(std::equal(vr.crbegin(), vr.crend(), v.begin())); | 
| 2376 |     QVERIFY(std::equal(cvr.rbegin(), cvr.rend(), v.begin())); | 
| 2377 | } | 
| 2378 |  | 
| 2379 | template<typename T> | 
| 2380 | void tst_QVector::size() const | 
| 2381 | { | 
| 2382 |     // zero size | 
| 2383 |     QVector<T> myvec; | 
| 2384 |     QVERIFY(myvec.size() == 0); | 
| 2385 |  | 
| 2386 |     // grow | 
| 2387 |     myvec.append(SimpleValue<T>::at(0)); | 
| 2388 |     QVERIFY(myvec.size() == 1); | 
| 2389 |     myvec.append(SimpleValue<T>::at(1)); | 
| 2390 |     QVERIFY(myvec.size() == 2); | 
| 2391 |  | 
| 2392 |     // shrink | 
| 2393 |     myvec.remove(0); | 
| 2394 |     QVERIFY(myvec.size() == 1); | 
| 2395 |     myvec.remove(0); | 
| 2396 |     QVERIFY(myvec.size() == 0); | 
| 2397 | } | 
| 2398 |  | 
| 2399 | void tst_QVector::sizeInt() const | 
| 2400 | { | 
| 2401 |     size<int>(); | 
| 2402 | } | 
| 2403 |  | 
| 2404 | void tst_QVector::sizeMovable() const | 
| 2405 | { | 
| 2406 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 2407 |     size<Movable>(); | 
| 2408 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 2409 | } | 
| 2410 |  | 
| 2411 | void tst_QVector::sizeCustom() const | 
| 2412 | { | 
| 2413 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 2414 |     size<Custom>(); | 
| 2415 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 2416 | } | 
| 2417 |  | 
| 2418 | // ::squeeze() is tested in ::capacity(). | 
| 2419 |  | 
| 2420 | void tst_QVector::startsWith() const | 
| 2421 | { | 
| 2422 |     QVector<int> myvec; | 
| 2423 |  | 
| 2424 |     // empty vector | 
| 2425 |     QVERIFY(!myvec.startsWith(1)); | 
| 2426 |  | 
| 2427 |     // add the one, should work | 
| 2428 |     myvec.prepend(t: 1); | 
| 2429 |     QVERIFY(myvec.startsWith(1)); | 
| 2430 |  | 
| 2431 |     // add something else, fails now | 
| 2432 |     myvec.prepend(t: 3); | 
| 2433 |     QVERIFY(!myvec.startsWith(1)); | 
| 2434 |  | 
| 2435 |     // remove it again :) | 
| 2436 |     myvec.remove(i: 0); | 
| 2437 |     QVERIFY(myvec.startsWith(1)); | 
| 2438 | } | 
| 2439 |  | 
| 2440 | template<typename T> | 
| 2441 | void tst_QVector::swap() const | 
| 2442 | { | 
| 2443 |     QVector<T> v1, v2; | 
| 2444 |     T val1 = SimpleValue<T>::at(0); | 
| 2445 |     T val2 = SimpleValue<T>::at(1); | 
| 2446 |     T val3 = SimpleValue<T>::at(2); | 
| 2447 |     T val4 = SimpleValue<T>::at(3); | 
| 2448 |     T val5 = SimpleValue<T>::at(4); | 
| 2449 |     T val6 = SimpleValue<T>::at(5); | 
| 2450 |     v1 << val1 << val2 << val3; | 
| 2451 |     v2 << val4 << val5 << val6; | 
| 2452 |  | 
| 2453 |     v1.swap(v2); | 
| 2454 |     QCOMPARE(v1,QVector<T>() << val4 << val5 << val6); | 
| 2455 |     QCOMPARE(v2,QVector<T>() << val1 << val2 << val3); | 
| 2456 | } | 
| 2457 |  | 
| 2458 | void tst_QVector::swapInt() const | 
| 2459 | { | 
| 2460 |     swap<int>(); | 
| 2461 | } | 
| 2462 |  | 
| 2463 | void tst_QVector::swapMovable() const | 
| 2464 | { | 
| 2465 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 2466 |     swap<Movable>(); | 
| 2467 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 2468 | } | 
| 2469 |  | 
| 2470 | void tst_QVector::swapCustom() const | 
| 2471 | { | 
| 2472 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 2473 |     swap<Custom>(); | 
| 2474 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 2475 | } | 
| 2476 |  | 
| 2477 | void tst_QVector::toList() const | 
| 2478 | { | 
| 2479 |     QVector<QString> myvec; | 
| 2480 |     myvec << "A"  << "B"  << "C" ; | 
| 2481 |  | 
| 2482 |     // make sure it converts and doesn't modify the original vector | 
| 2483 |     QCOMPARE(myvec.toList(), QList<QString>() << "A"  << "B"  << "C" ); | 
| 2484 |     QCOMPARE(myvec, QVector<QString>() << "A"  << "B"  << "C" ); | 
| 2485 | } | 
| 2486 |  | 
| 2487 | #if QT_VERSION < QT_VERSION_CHECK(6,0,0) | 
| 2488 | void tst_QVector::toStdVector() const | 
| 2489 | { | 
| 2490 |     QVector<QString> myvec; | 
| 2491 |     myvec << "A"  << "B"  << "C" ; | 
| 2492 |  | 
| 2493 |     std::vector<QString> svec = myvec.toStdVector(); | 
| 2494 |     QCOMPARE(svec.at(0), QLatin1String("A" )); | 
| 2495 |     QCOMPARE(svec.at(1), QLatin1String("B" )); | 
| 2496 |     QCOMPARE(svec.at(2), QLatin1String("C" )); | 
| 2497 |  | 
| 2498 |     QCOMPARE(myvec, QVector<QString>() << "A"  << "B"  << "C" ); | 
| 2499 | } | 
| 2500 | #endif | 
| 2501 |  | 
| 2502 | void tst_QVector::value() const | 
| 2503 | { | 
| 2504 |     QVector<QString> myvec; | 
| 2505 |     myvec << "A"  << "B"  << "C" ; | 
| 2506 |  | 
| 2507 |     // valid calls | 
| 2508 |     QCOMPARE(myvec.value(0), QLatin1String("A" )); | 
| 2509 |     QCOMPARE(myvec.value(1), QLatin1String("B" )); | 
| 2510 |     QCOMPARE(myvec.value(2), QLatin1String("C" )); | 
| 2511 |  | 
| 2512 |     // default calls | 
| 2513 |     QCOMPARE(myvec.value(-1), QString()); | 
| 2514 |     QCOMPARE(myvec.value(3), QString()); | 
| 2515 |  | 
| 2516 |     // test calls with a provided default, valid calls | 
| 2517 |     QCOMPARE(myvec.value(0, QLatin1String("default" )), QLatin1String("A" )); | 
| 2518 |     QCOMPARE(myvec.value(1, QLatin1String("default" )), QLatin1String("B" )); | 
| 2519 |     QCOMPARE(myvec.value(2, QLatin1String("default" )), QLatin1String("C" )); | 
| 2520 |  | 
| 2521 |     // test calls with a provided default that will return the default | 
| 2522 |     QCOMPARE(myvec.value(-1, QLatin1String("default" )), QLatin1String("default" )); | 
| 2523 |     QCOMPARE(myvec.value(3, QLatin1String("default" )), QLatin1String("default" )); | 
| 2524 | } | 
| 2525 |  | 
| 2526 | void tst_QVector::testOperators() const | 
| 2527 | { | 
| 2528 |     QVector<QString> myvec; | 
| 2529 |     myvec << "A"  << "B"  << "C" ; | 
| 2530 |     QVector<QString> myvectwo; | 
| 2531 |     myvectwo << "D"  << "E"  << "F" ; | 
| 2532 |     QVector<QString> combined; | 
| 2533 |     combined << "A"  << "B"  << "C"  << "D"  << "E"  << "F" ; | 
| 2534 |  | 
| 2535 |     // != | 
| 2536 |     QVERIFY(myvec != myvectwo); | 
| 2537 |  | 
| 2538 |     // + | 
| 2539 |     QCOMPARE(myvec + myvectwo, combined); | 
| 2540 |     QCOMPARE(myvec, QVector<QString>() << "A"  << "B"  << "C" ); | 
| 2541 |     QCOMPARE(myvectwo, QVector<QString>() << "D"  << "E"  << "F" ); | 
| 2542 |  | 
| 2543 |     // += | 
| 2544 |     myvec += myvectwo; | 
| 2545 |     QCOMPARE(myvec, combined); | 
| 2546 |  | 
| 2547 |     // == | 
| 2548 |     QVERIFY(myvec == combined); | 
| 2549 |  | 
| 2550 |     // <, >, <=, >= | 
| 2551 |     QVERIFY(!(myvec <  combined)); | 
| 2552 |     QVERIFY(!(myvec >  combined)); | 
| 2553 |     QVERIFY(  myvec <= combined); | 
| 2554 |     QVERIFY(  myvec >= combined); | 
| 2555 |     combined.push_back(t: "G" ); | 
| 2556 |     QVERIFY(  myvec <  combined); | 
| 2557 |     QVERIFY(!(myvec >  combined)); | 
| 2558 |     QVERIFY(  myvec <= combined); | 
| 2559 |     QVERIFY(!(myvec >= combined)); | 
| 2560 |     QVERIFY(combined >  myvec); | 
| 2561 |     QVERIFY(combined >= myvec); | 
| 2562 |  | 
| 2563 |     // [] | 
| 2564 |     QCOMPARE(myvec[0], QLatin1String("A" )); | 
| 2565 |     QCOMPARE(myvec[1], QLatin1String("B" )); | 
| 2566 |     QCOMPARE(myvec[2], QLatin1String("C" )); | 
| 2567 |     QCOMPARE(myvec[3], QLatin1String("D" )); | 
| 2568 |     QCOMPARE(myvec[4], QLatin1String("E" )); | 
| 2569 |     QCOMPARE(myvec[5], QLatin1String("F" )); | 
| 2570 | } | 
| 2571 |  | 
| 2572 |  | 
| 2573 | int fooCtor; | 
| 2574 | int fooDtor; | 
| 2575 |  | 
| 2576 | struct Foo | 
| 2577 | { | 
| 2578 |     int *p; | 
| 2579 |  | 
| 2580 |     Foo() { p = new int; ++fooCtor; } | 
| 2581 |     Foo(const Foo &other) { Q_UNUSED(other); p = new int; ++fooCtor; } | 
| 2582 |  | 
| 2583 |     void operator=(const Foo & /* other */) { } | 
| 2584 |  | 
| 2585 |     ~Foo() { delete p; ++fooDtor; } | 
| 2586 | }; | 
| 2587 |  | 
| 2588 | void tst_QVector::reserve() | 
| 2589 | { | 
| 2590 |     fooCtor = 0; | 
| 2591 |     fooDtor = 0; | 
| 2592 |     { | 
| 2593 |         QVector<Foo> a; | 
| 2594 |         a.resize(asize: 2); | 
| 2595 |         QCOMPARE(fooCtor, 2); | 
| 2596 |         QVector<Foo> b(a); | 
| 2597 |         b.reserve(asize: 1); | 
| 2598 |         QCOMPARE(b.size(), a.size()); | 
| 2599 |         QCOMPARE(fooDtor, 0); | 
| 2600 |     } | 
| 2601 |     QCOMPARE(fooCtor, fooDtor); | 
| 2602 | } | 
| 2603 |  | 
| 2604 | // This is a regression test for QTBUG-51758 | 
| 2605 | void tst_QVector::reserveZero() | 
| 2606 | { | 
| 2607 |     QVector<int> vec; | 
| 2608 |     vec.detach(); | 
| 2609 |     vec.reserve(asize: 0); // should not crash | 
| 2610 |     QCOMPARE(vec.size(), 0); | 
| 2611 |     QCOMPARE(vec.capacity(), 0); | 
| 2612 |     vec.squeeze(); | 
| 2613 |     QCOMPARE(vec.size(), 0); | 
| 2614 |     QCOMPARE(vec.capacity(), 0); | 
| 2615 |     vec.reserve(asize: -1); | 
| 2616 |     QCOMPARE(vec.size(), 0); | 
| 2617 |     QCOMPARE(vec.capacity(), 0); | 
| 2618 |     vec.append(t: 42); | 
| 2619 |     QCOMPARE(vec.size(), 1); | 
| 2620 |     QVERIFY(vec.capacity() >= 1); | 
| 2621 | } | 
| 2622 |  | 
| 2623 | // This is a regression test for QTBUG-11763, where memory would be reallocated | 
| 2624 | // soon after copying a QVector. | 
| 2625 | void tst_QVector::reallocAfterCopy_data() | 
| 2626 | { | 
| 2627 |     QTest::addColumn<int>(name: "capacity" ); | 
| 2628 |     QTest::addColumn<int>(name: "fill_size" ); | 
| 2629 |     QTest::addColumn<int>(name: "func_id" ); | 
| 2630 |     QTest::addColumn<int>(name: "result1" ); | 
| 2631 |     QTest::addColumn<int>(name: "result2" ); | 
| 2632 |     QTest::addColumn<int>(name: "result3" ); | 
| 2633 |     QTest::addColumn<int>(name: "result4" ); | 
| 2634 |  | 
| 2635 |     int result1, result2, result3, result4; | 
| 2636 |     int fill_size; | 
| 2637 |     for (int i = 70; i <= 100; i += 10) { | 
| 2638 |         const QByteArray prefix = "reallocAfterCopy:"  + QByteArray::number(i) + ','; | 
| 2639 |         fill_size = i - 20; | 
| 2640 |         for (int j = 0; j <= 3; j++) { | 
| 2641 |             if (j == 0) { // append | 
| 2642 |                 result1 = i; | 
| 2643 |                 result2 = i; | 
| 2644 |                 result3 = i - 19; | 
| 2645 |                 result4 = i - 20; | 
| 2646 |             } else if (j == 1) { // insert(0) | 
| 2647 |                 result1 = i; | 
| 2648 |                 result2 = i; | 
| 2649 |                 result3 = i - 19; | 
| 2650 |                 result4 = i - 20; | 
| 2651 |             } else if (j == 2) { // insert(20) | 
| 2652 |                 result1 = i; | 
| 2653 |                 result2 = i; | 
| 2654 |                 result3 = i - 19; | 
| 2655 |                 result4 = i - 20; | 
| 2656 |             } else if (j == 3) { // insert(0, 10) | 
| 2657 |                 result1 = i; | 
| 2658 |                 result2 = i; | 
| 2659 |                 result3 = i - 10; | 
| 2660 |                 result4 = i - 20; | 
| 2661 |             } | 
| 2662 |             QTest::newRow(dataTag: (prefix + QByteArray::number(j)).constData()) | 
| 2663 |                     << i << fill_size << j << result1 << result2 << result3 << result4; | 
| 2664 |         } | 
| 2665 |     } | 
| 2666 | } | 
| 2667 |  | 
| 2668 | void tst_QVector::reallocAfterCopy() | 
| 2669 | { | 
| 2670 |     QFETCH(int, capacity); | 
| 2671 |     QFETCH(int, fill_size); | 
| 2672 |     QFETCH(int, func_id); | 
| 2673 |     QFETCH(int, result1); | 
| 2674 |     QFETCH(int, result2); | 
| 2675 |     QFETCH(int, result3); | 
| 2676 |     QFETCH(int, result4); | 
| 2677 |  | 
| 2678 |     QVector<qreal> v1; | 
| 2679 |     QVector<qreal> v2; | 
| 2680 |  | 
| 2681 |     v1.reserve(asize: capacity); | 
| 2682 |     v1.resize(asize: 0); | 
| 2683 |     v1.fill(from: qreal(1.0), asize: fill_size); | 
| 2684 |  | 
| 2685 |     v2 = v1; | 
| 2686 |  | 
| 2687 |     // no need to test begin() and end(), there is a detach() in them | 
| 2688 |     if (func_id == 0) { | 
| 2689 |         v1.append(t: qreal(1.0)); //push_back is same as append | 
| 2690 |     } else if (func_id == 1) { | 
| 2691 |         v1.insert(i: 0, t: qreal(1.0)); //push_front is same as prepend, insert(0) | 
| 2692 |     } else if (func_id == 2) { | 
| 2693 |         v1.insert(i: 20, t: qreal(1.0)); | 
| 2694 |     } else if (func_id == 3) { | 
| 2695 |         v1.insert(i: 0, n: 10, t: qreal(1.0)); | 
| 2696 |     } | 
| 2697 |  | 
| 2698 |     QCOMPARE(v1.capacity(), result1); | 
| 2699 |     QCOMPARE(v2.capacity(), result2); | 
| 2700 |     QCOMPARE(v1.size(), result3); | 
| 2701 |     QCOMPARE(v2.size(), result4); | 
| 2702 | } | 
| 2703 |  | 
| 2704 | template<typename T> | 
| 2705 | void tst_QVector::initializeList() | 
| 2706 | { | 
| 2707 |     T val1(SimpleValue<T>::at(1)); | 
| 2708 |     T val2(SimpleValue<T>::at(2)); | 
| 2709 |     T val3(SimpleValue<T>::at(3)); | 
| 2710 |     T val4(SimpleValue<T>::at(4)); | 
| 2711 |  | 
| 2712 |     QVector<T> v1 {val1, val2, val3}; | 
| 2713 |     QCOMPARE(v1, QVector<T>() << val1 << val2 << val3); | 
| 2714 |     QCOMPARE(v1, (QVector<T> {val1, val2, val3})); | 
| 2715 |  | 
| 2716 |     QVector<QVector<T>> v2{ v1, {val4}, QVector<T>(), {val1, val2, val3} }; | 
| 2717 |     QVector<QVector<T>> v3; | 
| 2718 |     v3 << v1 << (QVector<T>() << val4) << QVector<T>() << v1; | 
| 2719 |     QCOMPARE(v3, v2); | 
| 2720 |  | 
| 2721 |     QVector<T> v4({}); | 
| 2722 |     QCOMPARE(v4.size(), 0); | 
| 2723 | } | 
| 2724 |  | 
| 2725 | void tst_QVector::initializeListInt() | 
| 2726 | { | 
| 2727 |     initializeList<int>(); | 
| 2728 | } | 
| 2729 |  | 
| 2730 | void tst_QVector::initializeListMovable() | 
| 2731 | { | 
| 2732 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 2733 |     initializeList<Movable>(); | 
| 2734 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 2735 | } | 
| 2736 |  | 
| 2737 | void tst_QVector::initializeListCustom() | 
| 2738 | { | 
| 2739 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 2740 |     initializeList<Custom>(); | 
| 2741 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 2742 | } | 
| 2743 |  | 
| 2744 | void tst_QVector::const_shared_null() | 
| 2745 | { | 
| 2746 |     QVector<int> v2; | 
| 2747 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 2748 |     // ### Qt6 remove this section | 
| 2749 |     QVector<int> v1; | 
| 2750 |     v1.setSharable(false); | 
| 2751 |     QVERIFY(v1.isDetached()); | 
| 2752 |  | 
| 2753 |     v2.setSharable(true); | 
| 2754 | #endif | 
| 2755 |     QVERIFY(!v2.isDetached()); | 
| 2756 | } | 
| 2757 |  | 
| 2758 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) | 
| 2759 | // ### Qt6 remove this section | 
| 2760 | template<typename T> | 
| 2761 | void tst_QVector::setSharable_data() const | 
| 2762 | { | 
| 2763 |     QTest::addColumn<QVector<T> >("vector" ); | 
| 2764 |     QTest::addColumn<int>(name: "size" ); | 
| 2765 |     QTest::addColumn<int>(name: "capacity" ); | 
| 2766 |     QTest::addColumn<bool>(name: "isCapacityReserved" ); | 
| 2767 |  | 
| 2768 |     QVector<T> null; | 
| 2769 |     QVector<T> empty(0, SimpleValue<T>::at(1)); | 
| 2770 |     QVector<T> emptyReserved; | 
| 2771 |     QVector<T> nonEmpty; | 
| 2772 |     QVector<T> nonEmptyReserved; | 
| 2773 |  | 
| 2774 |     emptyReserved.reserve(10); | 
| 2775 |     nonEmptyReserved.reserve(15); | 
| 2776 |  | 
| 2777 |     nonEmpty << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4); | 
| 2778 |     nonEmptyReserved << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4) << SimpleValue<T>::at(5) << SimpleValue<T>::at(6); | 
| 2779 |  | 
| 2780 |     QVERIFY(emptyReserved.capacity() >= 10); | 
| 2781 |     QVERIFY(nonEmptyReserved.capacity() >= 15); | 
| 2782 |  | 
| 2783 |     QTest::newRow(dataTag: "null" ) << null << 0 << 0 << false; | 
| 2784 |     QTest::newRow(dataTag: "empty" ) << empty << 0 << 0 << false; | 
| 2785 |     QTest::newRow(dataTag: "empty, Reserved" ) << emptyReserved << 0 << 10 << true; | 
| 2786 |     QTest::newRow(dataTag: "non-empty" ) << nonEmpty << 5 << 0 << false; | 
| 2787 |     QTest::newRow(dataTag: "non-empty, Reserved" ) << nonEmptyReserved << 7 << 15 << true; | 
| 2788 | } | 
| 2789 |  | 
| 2790 | template<typename T> | 
| 2791 | void tst_QVector::setSharable() const | 
| 2792 | { | 
| 2793 |     QFETCH(QVector<T>, vector); | 
| 2794 |     QFETCH(int, size); | 
| 2795 |     QFETCH(int, capacity); | 
| 2796 |     QFETCH(bool, isCapacityReserved); | 
| 2797 |  | 
| 2798 |     QVERIFY(!vector.isDetached()); // Shared with QTest | 
| 2799 |  | 
| 2800 |     vector.setSharable(true); | 
| 2801 |  | 
| 2802 |     QCOMPARE(vector.size(), size); | 
| 2803 |     if (isCapacityReserved) | 
| 2804 |         QVERIFY2(vector.capacity() >= capacity, | 
| 2805 |                 qPrintable(QString("Capacity is %1, expected at least %2." ) | 
| 2806 |                     .arg(vector.capacity()) | 
| 2807 |                     .arg(capacity))); | 
| 2808 |  | 
| 2809 |     { | 
| 2810 |         QVector<T> copy(vector); | 
| 2811 |  | 
| 2812 |         QVERIFY(!copy.isDetached()); | 
| 2813 |         QVERIFY(copy.isSharedWith(vector)); | 
| 2814 |     } | 
| 2815 |  | 
| 2816 |     vector.setSharable(false); | 
| 2817 |     QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<T>())); | 
| 2818 |  | 
| 2819 |     { | 
| 2820 |         QVector<T> copy(vector); | 
| 2821 |  | 
| 2822 |         QVERIFY(copy.isDetached() || copy.isEmpty() || copy.isSharedWith(QVector<T>())); | 
| 2823 |         QCOMPARE(copy.size(), size); | 
| 2824 |         if (isCapacityReserved) | 
| 2825 |             QVERIFY2(copy.capacity() >= capacity, | 
| 2826 |                     qPrintable(QString("Capacity is %1, expected at least %2." ) | 
| 2827 |                         .arg(copy.capacity()) | 
| 2828 |                         .arg(capacity))); | 
| 2829 |         QCOMPARE(copy, vector); | 
| 2830 |     } | 
| 2831 |  | 
| 2832 |     vector.setSharable(true); | 
| 2833 |  | 
| 2834 |     { | 
| 2835 |         QVector<T> copy(vector); | 
| 2836 |  | 
| 2837 |         QVERIFY(!copy.isDetached()); | 
| 2838 |         QVERIFY(copy.isSharedWith(vector)); | 
| 2839 |     } | 
| 2840 |  | 
| 2841 |     for (int i = 0; i < vector.size(); ++i) | 
| 2842 |         QCOMPARE(vector[i], SimpleValue<T>::at(i)); | 
| 2843 |  | 
| 2844 |     QCOMPARE(vector.size(), size); | 
| 2845 |     if (isCapacityReserved) | 
| 2846 |         QVERIFY2(vector.capacity() >= capacity, | 
| 2847 |                 qPrintable(QString("Capacity is %1, expected at least %2." ) | 
| 2848 |                     .arg(vector.capacity()) | 
| 2849 |                     .arg(capacity))); | 
| 2850 | } | 
| 2851 | #else | 
| 2852 | template<typename T> void tst_QVector::setSharable_data() const | 
| 2853 | { | 
| 2854 | } | 
| 2855 |  | 
| 2856 | template<typename T> void tst_QVector::setSharable() const | 
| 2857 | { | 
| 2858 | } | 
| 2859 | #endif | 
| 2860 |  | 
| 2861 | void tst_QVector::setSharableInt_data() | 
| 2862 | { | 
| 2863 |     setSharable_data<int>(); | 
| 2864 | } | 
| 2865 |  | 
| 2866 | void tst_QVector::setSharableMovable_data() | 
| 2867 | { | 
| 2868 |     setSharable_data<Movable>(); | 
| 2869 | } | 
| 2870 |  | 
| 2871 | void tst_QVector::setSharableCustom_data() | 
| 2872 | { | 
| 2873 |     setSharable_data<Custom>(); | 
| 2874 | } | 
| 2875 |  | 
| 2876 | void tst_QVector::setSharableInt() | 
| 2877 | { | 
| 2878 |     setSharable<int>(); | 
| 2879 | } | 
| 2880 |  | 
| 2881 | void tst_QVector::setSharableMovable() | 
| 2882 | { | 
| 2883 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 2884 |     setSharable<Movable>(); | 
| 2885 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 2886 | } | 
| 2887 |  | 
| 2888 | void tst_QVector::setSharableCustom() | 
| 2889 | { | 
| 2890 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 2891 |     setSharable<Custom>(); | 
| 2892 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 2893 | } | 
| 2894 |  | 
| 2895 | template<typename T> | 
| 2896 | void tst_QVector::detach() const | 
| 2897 | { | 
| 2898 |     { | 
| 2899 |         // detach an empty vector | 
| 2900 |         QVector<T> v; | 
| 2901 |         v.detach(); | 
| 2902 |         QVERIFY(v.isDetached()); | 
| 2903 |         QCOMPARE(v.size(), 0); | 
| 2904 |         QCOMPARE(v.capacity(), 0); | 
| 2905 |     } | 
| 2906 |     { | 
| 2907 |         // detach an empty referenced vector | 
| 2908 |         QVector<T> v; | 
| 2909 |         QVector<T> ref(v); | 
| 2910 |         QVERIFY(!v.isDetached()); | 
| 2911 |         v.detach(); | 
| 2912 |         QVERIFY(v.isDetached()); | 
| 2913 |         QCOMPARE(v.size(), 0); | 
| 2914 |         QCOMPARE(v.capacity(), 0); | 
| 2915 |     } | 
| 2916 |     { | 
| 2917 |         // detach a not empty referenced vector | 
| 2918 |         QVector<T> v(31); | 
| 2919 |         QVector<T> ref(v); | 
| 2920 |         QVERIFY(!v.isDetached()); | 
| 2921 |         v.detach(); | 
| 2922 |         QVERIFY(v.isDetached()); | 
| 2923 |         QCOMPARE(v.size(), 31); | 
| 2924 |         QCOMPARE(v.capacity(), 31); | 
| 2925 |     } | 
| 2926 |     { | 
| 2927 |         // detach a not empty vector | 
| 2928 |         QVector<T> v(31); | 
| 2929 |         QVERIFY(v.isDetached()); | 
| 2930 |         v.detach(); // detaching a detached vector | 
| 2931 |         QVERIFY(v.isDetached()); | 
| 2932 |         QCOMPARE(v.size(), 31); | 
| 2933 |         QCOMPARE(v.capacity(), 31); | 
| 2934 |     } | 
| 2935 |     { | 
| 2936 |         // detach a not empty vector with preallocated space | 
| 2937 |         QVector<T> v(3); | 
| 2938 |         v.reserve(8); | 
| 2939 |         QVector<T> ref(v); | 
| 2940 |         QVERIFY(!v.isDetached()); | 
| 2941 |         v.detach(); | 
| 2942 |         QVERIFY(v.isDetached()); | 
| 2943 |         QCOMPARE(v.size(), 3); | 
| 2944 |         QCOMPARE(v.capacity(), 8); | 
| 2945 |     } | 
| 2946 |     { | 
| 2947 |         // detach a not empty vector with preallocated space | 
| 2948 |         QVector<T> v(3); | 
| 2949 |         v.reserve(8); | 
| 2950 |         QVERIFY(v.isDetached()); | 
| 2951 |         v.detach(); // detaching a detached vector | 
| 2952 |         QVERIFY(v.isDetached()); | 
| 2953 |         QCOMPARE(v.size(), 3); | 
| 2954 |         QCOMPARE(v.capacity(), 8); | 
| 2955 |     } | 
| 2956 |     { | 
| 2957 |         // detach a not empty, initialized vector | 
| 2958 |         QVector<T> v(7, SimpleValue<T>::at(1)); | 
| 2959 |         QVector<T> ref(v); | 
| 2960 |         QVERIFY(!v.isDetached()); | 
| 2961 |         v.detach(); | 
| 2962 |         QVERIFY(v.isDetached()); | 
| 2963 |         QCOMPARE(v.size(), 7); | 
| 2964 |         for (int i = 0; i < v.size(); ++i) | 
| 2965 |             QCOMPARE(v[i], SimpleValue<T>::at(1)); | 
| 2966 |     } | 
| 2967 |     { | 
| 2968 |         // detach a not empty, initialized vector | 
| 2969 |         QVector<T> v(7, SimpleValue<T>::at(2)); | 
| 2970 |         QVERIFY(v.isDetached()); | 
| 2971 |         v.detach(); // detaching a detached vector | 
| 2972 |         QVERIFY(v.isDetached()); | 
| 2973 |         QCOMPARE(v.size(), 7); | 
| 2974 |         for (int i = 0; i < v.size(); ++i) | 
| 2975 |             QCOMPARE(v[i], SimpleValue<T>::at(2)); | 
| 2976 |     } | 
| 2977 |     { | 
| 2978 |         // detach a not empty, initialized vector with preallocated space | 
| 2979 |         QVector<T> v(7, SimpleValue<T>::at(3)); | 
| 2980 |         v.reserve(31); | 
| 2981 |         QVector<T> ref(v); | 
| 2982 |         QVERIFY(!v.isDetached()); | 
| 2983 |         v.detach(); | 
| 2984 |         QVERIFY(v.isDetached()); | 
| 2985 |         QCOMPARE(v.size(), 7); | 
| 2986 |         QCOMPARE(v.capacity(), 31); | 
| 2987 |         for (int i = 0; i < v.size(); ++i) | 
| 2988 |             QCOMPARE(v[i], SimpleValue<T>::at(3)); | 
| 2989 |     } | 
| 2990 | } | 
| 2991 |  | 
| 2992 | void tst_QVector::detachInt() const | 
| 2993 | { | 
| 2994 |     detach<int>(); | 
| 2995 | } | 
| 2996 |  | 
| 2997 | void tst_QVector::detachMovable() const | 
| 2998 | { | 
| 2999 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 3000 |     detach<Movable>(); | 
| 3001 |     QCOMPARE(instancesCount, Movable::counter.loadAcquire()); | 
| 3002 | } | 
| 3003 |  | 
| 3004 | void tst_QVector::detachCustom() const | 
| 3005 | { | 
| 3006 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 3007 |     detach<Custom>(); | 
| 3008 |     QCOMPARE(instancesCount, Custom::counter.loadAcquire()); | 
| 3009 | } | 
| 3010 |  | 
| 3011 | static QAtomicPointer<QVector<int> > detachThreadSafetyDataInt; | 
| 3012 | static QAtomicPointer<QVector<Movable> > detachThreadSafetyDataMovable; | 
| 3013 | static QAtomicPointer<QVector<Custom> > detachThreadSafetyDataCustom; | 
| 3014 |  | 
| 3015 | template<typename T> QAtomicPointer<QVector<T> > *detachThreadSafetyData(); | 
| 3016 | template<> QAtomicPointer<QVector<int> > *detachThreadSafetyData() { return &detachThreadSafetyDataInt; } | 
| 3017 | template<> QAtomicPointer<QVector<Movable> > *detachThreadSafetyData() { return &detachThreadSafetyDataMovable; } | 
| 3018 | template<> QAtomicPointer<QVector<Custom> > *detachThreadSafetyData() { return &detachThreadSafetyDataCustom; } | 
| 3019 |  | 
| 3020 | static QSemaphore detachThreadSafetyLock; | 
| 3021 |  | 
| 3022 | template<typename T> | 
| 3023 | void tst_QVector::detachThreadSafety() const | 
| 3024 | { | 
| 3025 |     delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(new QVector<T>(SimpleValue<T>::vector(400))); | 
| 3026 |  | 
| 3027 |     static const uint threadsCount = 5; | 
| 3028 |  | 
| 3029 |     struct : QThread { | 
| 3030 |         void run() override | 
| 3031 |         { | 
| 3032 |             QVector<T> copy(*detachThreadSafetyData<T>()->loadRelaxed()); | 
| 3033 |             QVERIFY(!copy.isDetached()); | 
| 3034 |             detachThreadSafetyLock.release(); | 
| 3035 |             detachThreadSafetyLock.acquire(n: 100); | 
| 3036 |             copy.detach(); | 
| 3037 |         } | 
| 3038 |     } threads[threadsCount]; | 
| 3039 |  | 
| 3040 |     for (uint i = 0; i < threadsCount; ++i) | 
| 3041 |         threads[i].start(); | 
| 3042 |     QThread::yieldCurrentThread(); | 
| 3043 |     detachThreadSafetyLock.acquire(n: threadsCount); | 
| 3044 |  | 
| 3045 |     // destroy static original data | 
| 3046 |     delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(0); | 
| 3047 |  | 
| 3048 |     QVERIFY(threadsCount < 100); | 
| 3049 |     detachThreadSafetyLock.release(n: threadsCount * 100); | 
| 3050 |     QThread::yieldCurrentThread(); | 
| 3051 |  | 
| 3052 |     for (uint i = 0; i < threadsCount; ++i) | 
| 3053 |         threads[i].wait(); | 
| 3054 | } | 
| 3055 |  | 
| 3056 | void tst_QVector::detachThreadSafetyInt() const | 
| 3057 | { | 
| 3058 |     for (uint i = 0; i < 128; ++i) | 
| 3059 |         detachThreadSafety<int>(); | 
| 3060 | } | 
| 3061 |  | 
| 3062 | void tst_QVector::detachThreadSafetyMovable() const | 
| 3063 | { | 
| 3064 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 3065 |     for (uint i = 0; i < 128; ++i) { | 
| 3066 |         detachThreadSafety<Movable>(); | 
| 3067 |         QCOMPARE(Movable::counter.loadAcquire(), instancesCount); | 
| 3068 |     } | 
| 3069 | } | 
| 3070 |  | 
| 3071 | void tst_QVector::detachThreadSafetyCustom() const | 
| 3072 | { | 
| 3073 |     const int instancesCount = Custom::counter.loadAcquire(); | 
| 3074 |     for (uint i = 0; i < 128; ++i) { | 
| 3075 |         detachThreadSafety<Custom>(); | 
| 3076 |         QCOMPARE(Custom::counter.loadAcquire(), instancesCount); | 
| 3077 |     } | 
| 3078 | } | 
| 3079 |  | 
| 3080 | void tst_QVector::insertMove() const | 
| 3081 | { | 
| 3082 |     const int instancesCount = Movable::counter.loadAcquire(); | 
| 3083 |     { | 
| 3084 |         QVector<Movable> vec; | 
| 3085 |         vec.reserve(asize: 7); | 
| 3086 |         Movable m0; | 
| 3087 |         Movable m1; | 
| 3088 |         Movable m2; | 
| 3089 |         Movable m3; | 
| 3090 |         Movable m4; | 
| 3091 |         Movable m5; | 
| 3092 |         Movable m6; | 
| 3093 |  | 
| 3094 |         vec.append(t: std::move(m3)); | 
| 3095 |         QVERIFY(m3.wasConstructedAt(nullptr)); | 
| 3096 |         QVERIFY(vec.at(0).wasConstructedAt(&m3)); | 
| 3097 |         vec.push_back(t: std::move(m4)); | 
| 3098 |         QVERIFY(m4.wasConstructedAt(nullptr)); | 
| 3099 |         QVERIFY(vec.at(0).wasConstructedAt(&m3)); | 
| 3100 |         QVERIFY(vec.at(1).wasConstructedAt(&m4)); | 
| 3101 |         vec.prepend(t: std::move(m1)); | 
| 3102 |         QVERIFY(m1.wasConstructedAt(nullptr)); | 
| 3103 |         QVERIFY(vec.at(0).wasConstructedAt(&m1)); | 
| 3104 |         QVERIFY(vec.at(1).wasConstructedAt(&m3)); | 
| 3105 |         QVERIFY(vec.at(2).wasConstructedAt(&m4)); | 
| 3106 |         vec.insert(i: 1, t: std::move(m2)); | 
| 3107 |         QVERIFY(m2.wasConstructedAt(nullptr)); | 
| 3108 |         QVERIFY(vec.at(0).wasConstructedAt(&m1)); | 
| 3109 |         QVERIFY(vec.at(1).wasConstructedAt(&m2)); | 
| 3110 |         QVERIFY(vec.at(2).wasConstructedAt(&m3)); | 
| 3111 |         QVERIFY(vec.at(3).wasConstructedAt(&m4)); | 
| 3112 |         vec += std::move(m5); | 
| 3113 |         QVERIFY(m5.wasConstructedAt(nullptr)); | 
| 3114 |         QVERIFY(vec.at(0).wasConstructedAt(&m1)); | 
| 3115 |         QVERIFY(vec.at(1).wasConstructedAt(&m2)); | 
| 3116 |         QVERIFY(vec.at(2).wasConstructedAt(&m3)); | 
| 3117 |         QVERIFY(vec.at(3).wasConstructedAt(&m4)); | 
| 3118 |         QVERIFY(vec.at(4).wasConstructedAt(&m5)); | 
| 3119 |         vec << std::move(m6); | 
| 3120 |         QVERIFY(m6.wasConstructedAt(nullptr)); | 
| 3121 |         QVERIFY(vec.at(0).wasConstructedAt(&m1)); | 
| 3122 |         QVERIFY(vec.at(1).wasConstructedAt(&m2)); | 
| 3123 |         QVERIFY(vec.at(2).wasConstructedAt(&m3)); | 
| 3124 |         QVERIFY(vec.at(3).wasConstructedAt(&m4)); | 
| 3125 |         QVERIFY(vec.at(4).wasConstructedAt(&m5)); | 
| 3126 |         QVERIFY(vec.at(5).wasConstructedAt(&m6)); | 
| 3127 |         vec.push_front(t: std::move(m0)); | 
| 3128 |         QVERIFY(m0.wasConstructedAt(nullptr)); | 
| 3129 |         QVERIFY(vec.at(0).wasConstructedAt(&m0)); | 
| 3130 |         QVERIFY(vec.at(1).wasConstructedAt(&m1)); | 
| 3131 |         QVERIFY(vec.at(2).wasConstructedAt(&m2)); | 
| 3132 |         QVERIFY(vec.at(3).wasConstructedAt(&m3)); | 
| 3133 |         QVERIFY(vec.at(4).wasConstructedAt(&m4)); | 
| 3134 |         QVERIFY(vec.at(5).wasConstructedAt(&m5)); | 
| 3135 |         QVERIFY(vec.at(6).wasConstructedAt(&m6)); | 
| 3136 |  | 
| 3137 |         QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 14); | 
| 3138 |     } | 
| 3139 |     QCOMPARE(Movable::counter.loadAcquire(), instancesCount); | 
| 3140 | } | 
| 3141 |  | 
| 3142 | void tst_QVector::swapItemsAt() const | 
| 3143 | { | 
| 3144 |     QVector<int> v; | 
| 3145 |     v << 0 << 1 << 2 << 3; | 
| 3146 |  | 
| 3147 |     v.swapItemsAt(i: 0, j: 2); | 
| 3148 |     QCOMPARE(v.at(0), 2); | 
| 3149 |     QCOMPARE(v.at(2), 0); | 
| 3150 |  | 
| 3151 |     auto copy = v; | 
| 3152 |     copy.swapItemsAt(i: 0, j: 2); | 
| 3153 |     QCOMPARE(v.at(0), 2); | 
| 3154 |     QCOMPARE(v.at(2), 0); | 
| 3155 |     QCOMPARE(copy.at(0), 0); | 
| 3156 |     QCOMPARE(copy.at(2), 2); | 
| 3157 | } | 
| 3158 |  | 
| 3159 | QTEST_MAIN(tst_QVector) | 
| 3160 | #include "tst_qvector.moc" | 
| 3161 |  |