Add erase operation to QArrayDataOps
Change-Id: I37d3ac465f5beddb5038e22e9cda32acb16c78fc Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
037238022f
commit
deb8d178fe
@ -117,6 +117,16 @@ struct QPodArrayOps
|
||||
::memcpy(where, b, (e - b) * sizeof(T));
|
||||
this->size += (e - b);
|
||||
}
|
||||
|
||||
void erase(T *b, T *e)
|
||||
{
|
||||
Q_ASSERT(b < e);
|
||||
Q_ASSERT(b >= this->begin() && b < this->end());
|
||||
Q_ASSERT(e > this->begin() && e < this->end());
|
||||
|
||||
::memmove(b, e, (this->end() - e) * sizeof(T));
|
||||
this->size -= (e - b);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@ -250,6 +260,25 @@ struct QGenericArrayOps
|
||||
*writeIter = *e;
|
||||
}
|
||||
}
|
||||
|
||||
void erase(T *b, T *e)
|
||||
{
|
||||
Q_ASSERT(b < e);
|
||||
Q_ASSERT(b >= this->begin() && b < this->end());
|
||||
Q_ASSERT(e > this->begin() && e < this->end());
|
||||
|
||||
const T *const end = this->end();
|
||||
|
||||
do {
|
||||
*b = *e;
|
||||
++b, ++e;
|
||||
} while (e != end);
|
||||
|
||||
do {
|
||||
(--e)->~T();
|
||||
--this->size;
|
||||
} while (e != b);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@ -324,6 +353,40 @@ struct QMovableArrayOps
|
||||
displace.commit();
|
||||
this->size += (e - b);
|
||||
}
|
||||
|
||||
void erase(T *b, T *e)
|
||||
{
|
||||
Q_ASSERT(b < e);
|
||||
Q_ASSERT(b >= this->begin() && b < this->end());
|
||||
Q_ASSERT(e > this->begin() && e < this->end());
|
||||
|
||||
struct Mover
|
||||
{
|
||||
Mover(T *&start, const T *finish, int &sz)
|
||||
: destination(start)
|
||||
, source(start)
|
||||
, n(finish - start)
|
||||
, size(sz)
|
||||
{
|
||||
}
|
||||
|
||||
~Mover()
|
||||
{
|
||||
::memmove(destination, source, n * sizeof(T));
|
||||
size -= (source - destination);
|
||||
}
|
||||
|
||||
T *&destination;
|
||||
const T *const source;
|
||||
size_t n;
|
||||
int &size;
|
||||
} mover(e, this->end(), this->size);
|
||||
|
||||
do {
|
||||
// Exceptions or not, dtor called once per instance
|
||||
(--e)->~T();
|
||||
} while (e != b);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class = void>
|
||||
|
@ -302,6 +302,32 @@ public:
|
||||
d->insert(where, first, last);
|
||||
}
|
||||
|
||||
void erase(iterator first, iterator last)
|
||||
{
|
||||
if (first == last)
|
||||
return;
|
||||
|
||||
const T *const begin = d->begin();
|
||||
const T *const end = begin + d->size;
|
||||
|
||||
if (d.needsDetach()) {
|
||||
SimpleVector detached(Data::allocate(
|
||||
d->detachCapacity(size() - (last - first)),
|
||||
d->detachFlags()));
|
||||
if (first != begin)
|
||||
detached.d->copyAppend(begin, first);
|
||||
detached.d->copyAppend(last, end);
|
||||
detached.swap(*this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (last == end)
|
||||
d->truncate(end - first);
|
||||
else
|
||||
d->erase(first, last);
|
||||
}
|
||||
|
||||
void swap(SimpleVector &other)
|
||||
{
|
||||
qSwap(d, other.d);
|
||||
|
@ -1222,6 +1222,59 @@ void tst_QArrayData::arrayOps2()
|
||||
QCOMPARE(vo[i].id, i + 5);
|
||||
QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
vi.resize(10);
|
||||
vs.resize(10);
|
||||
vo.resize(10);
|
||||
|
||||
for (size_t i = 7; i < 10; ++i) {
|
||||
vi[i] = i;
|
||||
vs[i] = QString::number(i);
|
||||
|
||||
QCOMPARE(vo[i].id, i);
|
||||
QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed));
|
||||
}
|
||||
|
||||
QCOMPARE(CountedObject::liveCount, size_t(10));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// erase
|
||||
vi.erase(vi.begin() + 2, vi.begin() + 5);
|
||||
vs.erase(vs.begin() + 2, vs.begin() + 5);
|
||||
vo.erase(vo.begin() + 2, vo.begin() + 5);
|
||||
|
||||
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 < 2; ++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 = 2; i < 4; ++i) {
|
||||
QCOMPARE(vi[i], 0);
|
||||
QVERIFY(vs[i].isNull());
|
||||
|
||||
QCOMPARE(vo[i].id, i + 8);
|
||||
QCOMPARE(int(vo[i].flags), int(CountedObject::DefaultConstructed)
|
||||
| CountedObject::CopyAssigned);
|
||||
}
|
||||
|
||||
for (size_t i = 4; i < 7; ++i) {
|
||||
QCOMPARE(vi[i], int(i + 3));
|
||||
QCOMPARE(vs[i], QString::number(i + 3));
|
||||
|
||||
QCOMPARE(vo[i].id, i + 3);
|
||||
QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed
|
||||
| CountedObject::CopyAssigned);
|
||||
}
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QArrayDataPointer<int>)
|
||||
|
Loading…
Reference in New Issue
Block a user