Introduce QArrayDataOps::truncate
This enables a truncating resize() to be implemented. It is similar to destroyAll(), but updates the size() as it goes, so it is safe to use outside a container's destructor (and doesn't necessarily destroy all elements). The appendInitialize test was repurposed and now doubles as an additional test for QArrayDataOps as well as exercising SimpleVector's resize(). Change-Id: Iee94a685c9ea436c6af5b1b77486734a38c49ca1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
8c413f3eff
commit
15e3ae6b9d
@ -89,6 +89,14 @@ struct QPodArrayOps
|
|||||||
this->size += n;
|
this->size += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void truncate(size_t newSize)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(newSize < size_t(this->size));
|
||||||
|
|
||||||
|
this->size = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
void destroyAll() // Call from destructors, ONLY!
|
void destroyAll() // Call from destructors, ONLY!
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->ref.atomic.load() == 0);
|
Q_ASSERT(this->ref.atomic.load() == 0);
|
||||||
@ -153,6 +161,17 @@ struct QGenericArrayOps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void truncate(size_t newSize)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(newSize < size_t(this->size));
|
||||||
|
|
||||||
|
const T *const b = this->begin();
|
||||||
|
do {
|
||||||
|
(b + --this->size)->~T();
|
||||||
|
} while (uint(this->size) != newSize);
|
||||||
|
}
|
||||||
|
|
||||||
void destroyAll() // Call from destructors, ONLY
|
void destroyAll() // Call from destructors, ONLY
|
||||||
{
|
{
|
||||||
// As this is to be called only from destructor, it doesn't need to be
|
// As this is to be called only from destructor, it doesn't need to be
|
||||||
@ -239,6 +258,7 @@ struct QMovableArrayOps
|
|||||||
{
|
{
|
||||||
// using QGenericArrayOps<T>::appendInitialize;
|
// using QGenericArrayOps<T>::appendInitialize;
|
||||||
// using QGenericArrayOps<T>::copyAppend;
|
// using QGenericArrayOps<T>::copyAppend;
|
||||||
|
// using QGenericArrayOps<T>::truncate;
|
||||||
// using QGenericArrayOps<T>::destroyAll;
|
// using QGenericArrayOps<T>::destroyAll;
|
||||||
|
|
||||||
void insert(T *where, const T *b, const T *e)
|
void insert(T *where, const T *b, const T *e)
|
||||||
|
@ -170,6 +170,36 @@ public:
|
|||||||
detached.swap(*this);
|
detached.swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resize(size_t newSize)
|
||||||
|
{
|
||||||
|
if (size() == newSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d->ref.isShared() || newSize > capacity()) {
|
||||||
|
SimpleVector detached(Data::allocate(
|
||||||
|
d->detachCapacity(newSize), d->detachFlags()));
|
||||||
|
if (newSize) {
|
||||||
|
if (newSize < size()) {
|
||||||
|
const T *const begin = constBegin();
|
||||||
|
detached.d->copyAppend(begin, begin + newSize);
|
||||||
|
} else {
|
||||||
|
if (size()) {
|
||||||
|
const T *const begin = constBegin();
|
||||||
|
detached.d->copyAppend(begin, begin + size());
|
||||||
|
}
|
||||||
|
detached.d->appendInitialize(newSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
detached.swap(*this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSize > size())
|
||||||
|
d->appendInitialize(newSize);
|
||||||
|
else
|
||||||
|
d->truncate(newSize);
|
||||||
|
}
|
||||||
|
|
||||||
void prepend(const_iterator first, const_iterator last)
|
void prepend(const_iterator first, const_iterator last)
|
||||||
{
|
{
|
||||||
if (!d->size) {
|
if (!d->size) {
|
||||||
|
@ -81,7 +81,7 @@ private slots:
|
|||||||
void typedData();
|
void typedData();
|
||||||
void gccBug43247();
|
void gccBug43247();
|
||||||
void arrayOps();
|
void arrayOps();
|
||||||
void appendInitialize();
|
void arrayOps2();
|
||||||
void setSharable_data();
|
void setSharable_data();
|
||||||
void setSharable();
|
void setSharable();
|
||||||
void fromRawData();
|
void fromRawData();
|
||||||
@ -1115,7 +1115,7 @@ void tst_QArrayData::arrayOps()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QArrayData::appendInitialize()
|
void tst_QArrayData::arrayOps2()
|
||||||
{
|
{
|
||||||
CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker)
|
CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker)
|
||||||
|
|
||||||
@ -1137,6 +1137,69 @@ void tst_QArrayData::appendInitialize()
|
|||||||
QCOMPARE(vo[i].id, i);
|
QCOMPARE(vo[i].id, i);
|
||||||
QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed));
|
QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// appendInitialize, again
|
||||||
|
|
||||||
|
// These will detach
|
||||||
|
vi.resize(10);
|
||||||
|
vs.resize(10);
|
||||||
|
vo.resize(10);
|
||||||
|
|
||||||
|
QCOMPARE(vi.size(), size_t(10));
|
||||||
|
QCOMPARE(vs.size(), size_t(10));
|
||||||
|
QCOMPARE(vo.size(), size_t(10));
|
||||||
|
|
||||||
|
QCOMPARE(CountedObject::liveCount, size_t(10));
|
||||||
|
for (size_t i = 0; i < 5; ++i) {
|
||||||
|
QCOMPARE(vi[i], 0);
|
||||||
|
QVERIFY(vs[i].isNull());
|
||||||
|
|
||||||
|
QCOMPARE(vo[i].id, i);
|
||||||
|
QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed
|
||||||
|
| CountedObject::CopyConstructed);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 5; i < 10; ++i) {
|
||||||
|
QCOMPARE(vi[i], 0);
|
||||||
|
QVERIFY(vs[i].isNull());
|
||||||
|
|
||||||
|
QCOMPARE(vo[i].id, i + 5);
|
||||||
|
QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// truncate
|
||||||
|
QVERIFY(!vi.isShared());
|
||||||
|
QVERIFY(!vs.isShared());
|
||||||
|
QVERIFY(!vo.isShared());
|
||||||
|
|
||||||
|
// These shouldn't detach
|
||||||
|
vi.resize(7);
|
||||||
|
vs.resize(7);
|
||||||
|
vo.resize(7);
|
||||||
|
|
||||||
|
QCOMPARE(vi.size(), size_t(7));
|
||||||
|
QCOMPARE(vs.size(), size_t(7));
|
||||||
|
QCOMPARE(vo.size(), size_t(7));
|
||||||
|
|
||||||
|
QCOMPARE(CountedObject::liveCount, size_t(7));
|
||||||
|
for (size_t i = 0; i < 5; ++i) {
|
||||||
|
QCOMPARE(vi[i], 0);
|
||||||
|
QVERIFY(vs[i].isNull());
|
||||||
|
|
||||||
|
QCOMPARE(vo[i].id, i);
|
||||||
|
QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed
|
||||||
|
| CountedObject::CopyConstructed);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 5; i < 7; ++i) {
|
||||||
|
QCOMPARE(vi[i], 0);
|
||||||
|
QVERIFY(vs[i].isNull());
|
||||||
|
|
||||||
|
QCOMPARE(vo[i].id, i + 5);
|
||||||
|
QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QArrayDataPointer<int>)
|
Q_DECLARE_METATYPE(QArrayDataPointer<int>)
|
||||||
|
Loading…
Reference in New Issue
Block a user