diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 65ebc296d4..724edca947 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -115,7 +115,8 @@ public: ~QArrayDataPointer() { if (!d->ref.deref()) { - (*this)->destroyAll(); + if (d->isMutable()) + (*this)->destroyAll(); Data::deallocate(d); } } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index dea777d652..437c8e25ed 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -84,6 +84,7 @@ private slots: void arrayOps2(); void setSharable_data(); void setSharable(); + void fromRawData_data(); void fromRawData(); void literals(); void variadicLiterals(); @@ -1421,53 +1422,106 @@ void tst_QArrayData::setSharable() QVERIFY(array->ref.isSharable()); } -void tst_QArrayData::fromRawData() +struct ResetOnDtor { - static const int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + ResetOnDtor() + : value_() + { + } + + ResetOnDtor(int value) + : value_(value) + { + } + + ~ResetOnDtor() + { + value_ = 0; + } + + int value_; +}; + +bool operator==(const ResetOnDtor &lhs, const ResetOnDtor &rhs) +{ + return lhs.value_ == rhs.value_; +} + +template +void fromRawData_impl() +{ + static const T array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; { // Default: Immutable, sharable - SimpleVector raw = SimpleVector::fromRawData(array, + SimpleVector raw = SimpleVector::fromRawData(array, sizeof(array)/sizeof(array[0]), QArrayData::Default); QCOMPARE(raw.size(), size_t(11)); - QCOMPARE((const int *)raw.constBegin(), array); - QCOMPARE((const int *)raw.constEnd(), (const int *)(array + sizeof(array)/sizeof(array[0]))); + QCOMPARE((const T *)raw.constBegin(), array); + QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0]))); QVERIFY(!raw.isShared()); - QVERIFY(SimpleVector(raw).isSharedWith(raw)); + QVERIFY(SimpleVector(raw).isSharedWith(raw)); QVERIFY(!raw.isShared()); // Detach - QCOMPARE(raw.back(), 11); - QVERIFY((const int *)raw.constBegin() != array); + QCOMPARE(raw.back(), T(11)); + QVERIFY((const T *)raw.constBegin() != array); } { // Immutable, unsharable - SimpleVector raw = SimpleVector::fromRawData(array, + SimpleVector raw = SimpleVector::fromRawData(array, sizeof(array)/sizeof(array[0]), QArrayData::Unsharable); QCOMPARE(raw.size(), size_t(11)); - QCOMPARE((const int *)raw.constBegin(), array); - QCOMPARE((const int *)raw.constEnd(), (const int *)(array + sizeof(array)/sizeof(array[0]))); + QCOMPARE((const T *)raw.constBegin(), array); + QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0]))); - SimpleVector copy(raw); + SimpleVector copy(raw); QVERIFY(!copy.isSharedWith(raw)); QVERIFY(!raw.isShared()); QCOMPARE(copy.size(), size_t(11)); - for (size_t i = 0; i < 11; ++i) + for (size_t i = 0; i < 11; ++i) { QCOMPARE(const_(copy)[i], const_(raw)[i]); + QCOMPARE(const_(copy)[i], T(i + 1)); + } QCOMPARE(raw.size(), size_t(11)); - QCOMPARE((const int *)raw.constBegin(), array); - QCOMPARE((const int *)raw.constEnd(), (const int *)(array + sizeof(array)/sizeof(array[0]))); + QCOMPARE((const T *)raw.constBegin(), array); + QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0]))); // Detach - QCOMPARE(raw.back(), 11); - QVERIFY((const int *)raw.constBegin() != array); + QCOMPARE(raw.back(), T(11)); + QVERIFY((const T *)raw.constBegin() != array); + } +} + +void tst_QArrayData::fromRawData_data() +{ + QTest::addColumn("type"); + + QTest::newRow("int") << 0; + QTest::newRow("ResetOnDtor") << 1; +} +void tst_QArrayData::fromRawData() +{ + QFETCH(int, type); + + switch (type) + { + case 0: + fromRawData_impl(); + break; + case 1: + fromRawData_impl(); + break; + + default: + QFAIL("Unexpected type data"); } }