tests/auto/qvarlengtharray/tst_qvarlengtharray.cpp
changeset 30 5dc02b23752f
parent 29 b72c6db6890b
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    61     void append();
    61     void append();
    62     void removeLast();
    62     void removeLast();
    63     void oldTests();
    63     void oldTests();
    64     void task214223();
    64     void task214223();
    65     void QTBUG6718_resize();
    65     void QTBUG6718_resize();
    66     void QTBUG10978_realloc();
       
    67 };
    66 };
    68 
    67 
    69 int fooCtor = 0;
    68 int fooCtor = 0;
    70 int fooDtor = 0;
    69 int fooDtor = 0;
    71 
    70 
   132 	QVERIFY(sa[10] == 0xff);
   131 	QVERIFY(sa[10] == 0xff);
   133 	sa.resize(512);
   132 	sa.resize(512);
   134 	QVERIFY(sa.data() == &sa[0]);
   133 	QVERIFY(sa.data() == &sa[0]);
   135 	QVERIFY(sa[0] == 0xfee);
   134 	QVERIFY(sa[0] == 0xfee);
   136 	QVERIFY(sa[10] == 0xff);
   135 	QVERIFY(sa[10] == 0xff);
       
   136         QVERIFY(sa.at(0) == 0xfee);
       
   137         QVERIFY(sa.at(10) == 0xff);
       
   138         QVERIFY(sa.value(0) == 0xfee);
       
   139         QVERIFY(sa.value(10) == 0xff);
       
   140         QVERIFY(sa.value(1000) == 0);
       
   141         QVERIFY(sa.value(1000, 12) == 12);
   137 	QVERIFY(sa.size() == 512);
   142 	QVERIFY(sa.size() == 512);
   138 	sa.reserve(1024);
   143 	sa.reserve(1024);
   139 	QVERIFY(sa.capacity() == 1024);
   144 	QVERIFY(sa.capacity() == 1024);
   140 	QVERIFY(sa.size() == 512);
   145 	QVERIFY(sa.size() == 512);
   141     }
   146     }
   167         QCOMPARE(sa.size(), 10);
   172         QCOMPARE(sa.size(), 10);
   168         sa.append(arr, 2);
   173         sa.append(arr, 2);
   169         QCOMPARE(sa.size(), 12);
   174         QCOMPARE(sa.size(), 12);
   170         QCOMPARE(sa[10], QString("hello"));
   175         QCOMPARE(sa[10], QString("hello"));
   171         QCOMPARE(sa[11], QString("world"));
   176         QCOMPARE(sa[11], QString("world"));
       
   177         QCOMPARE(sa.at(10), QString("hello"));
       
   178         QCOMPARE(sa.at(11), QString("world"));
       
   179         QCOMPARE(sa.value(10), QString("hello"));
       
   180         QCOMPARE(sa.value(11), QString("world"));
       
   181         QCOMPARE(sa.value(10000), QString());
       
   182         QCOMPARE(sa.value(1212112, QString("none")), QString("none"));
       
   183         QCOMPARE(sa.value(-12, QString("neg")), QString("neg"));
   172 
   184 
   173         sa.append(arr, 1);
   185         sa.append(arr, 1);
   174         QCOMPARE(sa.size(), 13);
   186         QCOMPARE(sa.size(), 13);
   175         QCOMPARE(sa[12], QString("hello"));
   187         QCOMPARE(sa[12], QString("hello"));
   176 
   188 
   290         QCOMPARE(values[1].size(), 20);
   302         QCOMPARE(values[1].size(), 20);
   291         QCOMPARE(values.size(), 2);
   303         QCOMPARE(values.size(), 2);
   292     }
   304     }
   293 }
   305 }
   294 
   306 
   295 struct MyBase
       
   296 {
       
   297     MyBase()
       
   298         : data(this)
       
   299         , isCopy(false)
       
   300     {
       
   301         ++liveCount;
       
   302     }
       
   303 
       
   304     MyBase(MyBase const &)
       
   305         : data(this)
       
   306         , isCopy(true)
       
   307     {
       
   308         ++copyCount;
       
   309         ++liveCount;
       
   310     }
       
   311 
       
   312     MyBase & operator=(MyBase const &)
       
   313     {
       
   314         if (!isCopy) {
       
   315             isCopy = true;
       
   316             ++copyCount;
       
   317         } else {
       
   318             ++errorCount;
       
   319         }
       
   320 
       
   321         return *this;
       
   322     }
       
   323 
       
   324     ~MyBase()
       
   325     {
       
   326         if (isCopy) {
       
   327             if (!copyCount)
       
   328                 ++errorCount;
       
   329             else
       
   330                 --copyCount;
       
   331         }
       
   332 
       
   333         if (!liveCount)
       
   334             ++errorCount;
       
   335         else
       
   336             --liveCount;
       
   337     }
       
   338 
       
   339     bool hasMoved() const
       
   340     {
       
   341         return this != data;
       
   342     }
       
   343 
       
   344 protected:
       
   345     MyBase const * const data;
       
   346     bool isCopy;
       
   347 
       
   348 public:
       
   349     static int errorCount;
       
   350     static int liveCount;
       
   351     static int copyCount;
       
   352 };
       
   353 
       
   354 int MyBase::errorCount = 0;
       
   355 int MyBase::liveCount = 0;
       
   356 int MyBase::copyCount = 0;
       
   357 
       
   358 struct MyPrimitive
       
   359     : MyBase
       
   360 {
       
   361     MyPrimitive()
       
   362     {
       
   363         ++errorCount;
       
   364     }
       
   365 
       
   366     ~MyPrimitive()
       
   367     {
       
   368         ++errorCount;
       
   369     }
       
   370 
       
   371     MyPrimitive(MyPrimitive const &other)
       
   372         : MyBase(other)
       
   373     {
       
   374         ++errorCount;
       
   375     }
       
   376 };
       
   377 
       
   378 struct MyMovable
       
   379     : MyBase
       
   380 {
       
   381 };
       
   382 
       
   383 struct MyComplex
       
   384     : MyBase
       
   385 {
       
   386 };
       
   387 
       
   388 QT_BEGIN_NAMESPACE
       
   389 
       
   390 Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE);
       
   391 Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE);
       
   392 Q_DECLARE_TYPEINFO(MyComplex, Q_COMPLEX_TYPE);
       
   393 
       
   394 QT_END_NAMESPACE
       
   395 
       
   396 bool QTBUG10978_proceed = true;
       
   397 
       
   398 template <class T, int PreAlloc>
       
   399 int countMoved(QVarLengthArray<T, PreAlloc> const &c)
       
   400 {
       
   401     int result = 0;
       
   402     for (int i = 0; i < c.size(); ++i)
       
   403         if (c[i].hasMoved())
       
   404             ++result;
       
   405 
       
   406     return result;
       
   407 }
       
   408 
       
   409 template <class T>
       
   410 void QTBUG10978_test()
       
   411 {
       
   412     QTBUG10978_proceed = false;
       
   413 
       
   414     typedef QVarLengthArray<T, 16> Container;
       
   415     enum {
       
   416         isStatic = QTypeInfo<T>::isStatic,
       
   417         isComplex = QTypeInfo<T>::isComplex,
       
   418 
       
   419         isPrimitive = !isComplex && !isStatic,
       
   420         isMovable = !isStatic
       
   421     };
       
   422 
       
   423     // Constructors
       
   424     Container a;
       
   425     QCOMPARE( MyBase::liveCount, 0 );
       
   426     QCOMPARE( MyBase::copyCount, 0 );
       
   427 
       
   428     QVERIFY( a.capacity() >= 16 );
       
   429     QCOMPARE( a.size(), 0 );
       
   430 
       
   431     Container b_real(8);
       
   432     Container const &b = b_real;
       
   433     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 8 );
       
   434     QCOMPARE( MyBase::copyCount, 0 );
       
   435 
       
   436     QVERIFY( b.capacity() >= 16 );
       
   437     QCOMPARE( b.size(), 8 );
       
   438 
       
   439     // Assignment
       
   440     a = b;
       
   441     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 16 );
       
   442     QCOMPARE( MyBase::copyCount, isComplex ? 8 : 0 );
       
   443     QVERIFY( a.capacity() >= 16 );
       
   444     QCOMPARE( a.size(), 8 );
       
   445 
       
   446     QVERIFY( b.capacity() >= 16 );
       
   447     QCOMPARE( b.size(), 8 );
       
   448 
       
   449     // append
       
   450     a.append(b.data(), b.size());
       
   451     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 24 );
       
   452     QCOMPARE( MyBase::copyCount, isComplex ? 16 : 0 );
       
   453 
       
   454     QVERIFY( a.capacity() >= 16 );
       
   455     QCOMPARE( a.size(), 16 );
       
   456 
       
   457     QVERIFY( b.capacity() >= 16 );
       
   458     QCOMPARE( b.size(), 8 );
       
   459 
       
   460     // removeLast
       
   461     a.removeLast();
       
   462     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 23 );
       
   463     QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 );
       
   464 
       
   465     QVERIFY( a.capacity() >= 16 );
       
   466     QCOMPARE( a.size(), 15 );
       
   467 
       
   468     QVERIFY( b.capacity() >= 16 );
       
   469     QCOMPARE( b.size(), 8 );
       
   470 
       
   471     // Movable types
       
   472     const int capacity = a.capacity();
       
   473     if (!isPrimitive)
       
   474         QCOMPARE( countMoved(a), 0 );
       
   475 
       
   476     // Reserve, no re-allocation
       
   477     a.reserve(capacity);
       
   478     if (!isPrimitive)
       
   479         QCOMPARE( countMoved(a), 0 );
       
   480     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 23 );
       
   481     QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 );
       
   482 
       
   483     QCOMPARE( a.capacity(), capacity );
       
   484     QCOMPARE( a.size(), 15 );
       
   485 
       
   486     QVERIFY( b.capacity() >= 16 );
       
   487     QCOMPARE( b.size(), 8 );
       
   488 
       
   489     // Reserve, force re-allocation
       
   490     a.reserve(capacity * 2);
       
   491     if (!isPrimitive)
       
   492         QCOMPARE( countMoved(a), isMovable ? 15 : 0 );
       
   493     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 23 );
       
   494     QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 );
       
   495 
       
   496     QVERIFY( a.capacity() >= capacity * 2 );
       
   497     QCOMPARE( a.size(), 15 );
       
   498 
       
   499     QVERIFY( b.capacity() >= 16 );
       
   500     QCOMPARE( b.size(), 8 );
       
   501 
       
   502     // resize, grow
       
   503     a.resize(40);
       
   504     if (!isPrimitive)
       
   505         QCOMPARE( countMoved(a), isMovable ? 15 : 0 );
       
   506     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 48 );
       
   507     QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 );
       
   508 
       
   509     QVERIFY( a.capacity() >= a.size() );
       
   510     QCOMPARE( a.size(), 40 );
       
   511 
       
   512     QVERIFY( b.capacity() >= 16 );
       
   513     QCOMPARE( b.size(), 8 );
       
   514 
       
   515     // Copy constructor, allocate
       
   516     {
       
   517         Container c(a);
       
   518         if (!isPrimitive)
       
   519             QCOMPARE( countMoved(c), 0 );
       
   520         QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 88 );
       
   521         QCOMPARE( MyBase::copyCount, isComplex ? 55 : 0 );
       
   522 
       
   523         QVERIFY( a.capacity() >= a.size() );
       
   524         QCOMPARE( a.size(), 40 );
       
   525 
       
   526         QVERIFY( b.capacity() >= 16 );
       
   527         QCOMPARE( b.size(), 8 );
       
   528 
       
   529         QVERIFY( c.capacity() >= 40 );
       
   530         QCOMPARE( c.size(), 40 );
       
   531     }
       
   532 
       
   533     // resize, shrink
       
   534     a.resize(10);
       
   535     if (!isPrimitive)
       
   536         QCOMPARE( countMoved(a), isMovable ? 10 : 0 );
       
   537     QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 18 );
       
   538     QCOMPARE( MyBase::copyCount, isComplex ? 10 : 0 );
       
   539 
       
   540     QVERIFY( a.capacity() >= a.size() );
       
   541     QCOMPARE( a.size(), 10 );
       
   542 
       
   543     QVERIFY( b.capacity() >= 16 );
       
   544     QCOMPARE( b.size(), 8 );
       
   545 
       
   546     // Copy constructor, don't allocate
       
   547     {
       
   548         Container c(a);
       
   549         if (!isPrimitive)
       
   550             QCOMPARE( countMoved(c), 0 );
       
   551         QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 28 );
       
   552         QCOMPARE( MyBase::copyCount, isComplex ? 20 : 0 );
       
   553 
       
   554         QVERIFY( a.capacity() >= a.size() );
       
   555         QCOMPARE( a.size(), 10 );
       
   556 
       
   557         QVERIFY( b.capacity() >= 16 );
       
   558         QCOMPARE( b.size(), 8 );
       
   559 
       
   560         QVERIFY( c.capacity() >= 16 );
       
   561         QCOMPARE( c.size(), 10 );
       
   562     }
       
   563 
       
   564     a.clear();
       
   565     QCOMPARE( a.size(), 0 );
       
   566 
       
   567     b_real.clear();
       
   568     QCOMPARE( b.size(), 0 );
       
   569 
       
   570     QCOMPARE(MyBase::errorCount, 0);
       
   571     QCOMPARE(MyBase::liveCount, 0);
       
   572 
       
   573     // All done
       
   574     QTBUG10978_proceed = true;
       
   575 }
       
   576 
       
   577 void tst_QVarLengthArray::QTBUG10978_realloc()
       
   578 {
       
   579     QTBUG10978_test<MyBase>();
       
   580     QVERIFY(QTBUG10978_proceed);
       
   581 
       
   582     QTBUG10978_test<MyPrimitive>();
       
   583     QVERIFY(QTBUG10978_proceed);
       
   584 
       
   585     QTBUG10978_test<MyMovable>();
       
   586     QVERIFY(QTBUG10978_proceed);
       
   587 
       
   588     QTBUG10978_test<MyComplex>();
       
   589     QVERIFY(QTBUG10978_proceed);
       
   590 }
       
   591 
       
   592 QTEST_APPLESS_MAIN(tst_QVarLengthArray)
   307 QTEST_APPLESS_MAIN(tst_QVarLengthArray)
   593 #include "tst_qvarlengtharray.moc"
   308 #include "tst_qvarlengtharray.moc"