Adding detach to QArrayDataPointer

Detaching operations added to SimpleVector

Change-Id: I5f549582cf579569f08cb8d53a6d12fe32b862e6
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
João Abecasis 2011-11-24 17:22:37 +01:00 committed by Qt by Nokia
parent b29338e805
commit 51048e1f31
3 changed files with 80 additions and 6 deletions

View File

@ -121,7 +121,31 @@ public:
d = Data::sharedEmpty();
}
bool detach()
{
if (d->ref.isShared()) {
Data *copy = clone();
QArrayDataPointer old(d);
d = copy;
return true;
}
return false;
}
private:
Data *clone() const Q_REQUIRED_RESULT
{
QArrayDataPointer copy(Data::allocate(d->alloc ? d->alloc : d->size,
d->capacityReserved));
if (d->size)
copy->copyAppend(d->begin(), d->end());
Data *result = copy.d;
copy.d = Data::sharedNull();
return result;
}
Data *d;
};

View File

@ -93,15 +93,35 @@ public:
size_t size() const { return d->size; }
size_t capacity() const { return d->alloc; }
iterator begin() { detach(); return d->begin(); }
iterator end() { detach(); return d->end(); }
const_iterator begin() const { return d->begin(); }
const_iterator end() const { return d->end(); }
const_iterator constBegin() const { return begin(); }
const_iterator constEnd() const { return end(); }
T &operator[](size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; }
T &at(size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; }
const T &operator[](size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; }
const T &at(size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; }
T &front()
{
Q_ASSERT(!isEmpty());
detach();
return *begin();
}
T &back()
{
Q_ASSERT(!isEmpty());
detach();
return *(end() - 1);
}
const T &front() const
{
Q_ASSERT(!isEmpty());
@ -231,6 +251,11 @@ public:
d.clear();
}
void detach()
{
d.detach();
}
private:
QArrayDataPointer<T> d;
};

View File

@ -81,6 +81,8 @@ private slots:
void arrayOps();
};
template <class T> const T &const_(const T &t) { return t; }
void tst_QArrayData::referenceCounting()
{
{
@ -320,13 +322,36 @@ void tst_QArrayData::simpleVector()
QVERIFY(v6 >= v1);
QVERIFY(!(v1 >= v6));
QCOMPARE(v6.front(), 0);
QCOMPARE(v6.back(), 6);
{
SimpleVector<int> temp(v6);
for (size_t i = 0; i < v6.size(); ++i) {
QCOMPARE(v6[i], int(i));
QCOMPARE(v6.at(i), int(i));
QCOMPARE(&v6[i], &v6.at(i));
QCOMPARE(const_(v6).front(), 0);
QCOMPARE(const_(v6).back(), 6);
QVERIFY(temp.isShared());
QVERIFY(temp.isSharedWith(v6));
QCOMPARE(temp.front(), 0);
QCOMPARE(temp.back(), 6);
// Detached
QVERIFY(!temp.isShared());
const int *const tempBegin = temp.begin();
for (size_t i = 0; i < v6.size(); ++i) {
QCOMPARE(const_(v6)[i], int(i));
QCOMPARE(const_(v6).at(i), int(i));
QCOMPARE(&const_(v6)[i], &const_(v6).at(i));
QCOMPARE(const_(v8)[i], const_(v6)[i]);
QCOMPARE(temp[i], int(i));
QCOMPARE(temp.at(i), int(i));
QCOMPARE(&temp[i], &temp.at(i));
}
// A single detach should do
QCOMPARE(temp.begin(), tempBegin);
}
{