summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2012-06-08 17:35:50 +0200
committerQt by Nokia <qt-info@nokia.com>2012-07-03 01:55:39 +0200
commitdeb8d178fe06e3f626f0e7152ac69504094a52a0 (patch)
tree91ded3353deedfdbe5ddc0023857e41672801229
parent037238022f3a91a5619709b2c7cf4b38cd4d294b (diff)
Add erase operation to QArrayDataOps
Change-Id: I37d3ac465f5beddb5038e22e9cda32acb16c78fc Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qarraydataops.h63
-rw-r--r--tests/auto/corelib/tools/qarraydata/simplevector.h26
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp53
3 files changed, 142 insertions, 0 deletions
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index 088dd2bdee..e4da051742 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -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>
diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h
index f708fc12d1..c2568cf29c 100644
--- a/tests/auto/corelib/tools/qarraydata/simplevector.h
+++ b/tests/auto/corelib/tools/qarraydata/simplevector.h
@@ -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);
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index 9ab01d37ef..d3cc92080d 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -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>)