Refine precoditions and logic of array operations
Updated insert() methods: * Refined Q_ASSERT() checks * Fixed implementation issues (some of which resulted in actual crashes) * Allowed to insert at the end. This is safe as far as I can tell and actually would allow to simplify considerable chunks of code (mainly, copyAppend versions to just return insert at the end) Updated tests accordingly Change-Id: I0ba33ae5034ce8d5ff95b753894e95d71ba00257 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
48911869cb
commit
5247af96e3
@ -145,7 +145,7 @@ public:
|
|||||||
{
|
{
|
||||||
Q_ASSERT(this->isMutable());
|
Q_ASSERT(this->isMutable());
|
||||||
Q_ASSERT(!this->isShared());
|
Q_ASSERT(!this->isShared());
|
||||||
Q_ASSERT(where >= this->begin() && where < this->end()); // Use copyAppend at end
|
Q_ASSERT(where >= this->begin() && where <= this->end());
|
||||||
Q_ASSERT(b <= e);
|
Q_ASSERT(b <= e);
|
||||||
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
||||||
Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size);
|
Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size);
|
||||||
@ -159,7 +159,7 @@ public:
|
|||||||
void insert(T *where, size_t n, parameter_type t)
|
void insert(T *where, size_t n, parameter_type t)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!this->isShared());
|
Q_ASSERT(!this->isShared());
|
||||||
Q_ASSERT(where >= this->begin() && where < this->end()); // Use copyAppend at end
|
Q_ASSERT(where >= this->begin() && where <= this->end());
|
||||||
Q_ASSERT(this->allocatedCapacity() - this->size >= n);
|
Q_ASSERT(this->allocatedCapacity() - this->size >= n);
|
||||||
|
|
||||||
::memmove(static_cast<void *>(where + n), static_cast<void *>(where),
|
::memmove(static_cast<void *>(where + n), static_cast<void *>(where),
|
||||||
@ -351,7 +351,7 @@ struct QGenericArrayOps
|
|||||||
{
|
{
|
||||||
Q_ASSERT(this->isMutable());
|
Q_ASSERT(this->isMutable());
|
||||||
Q_ASSERT(!this->isShared());
|
Q_ASSERT(!this->isShared());
|
||||||
Q_ASSERT(where >= this->begin() && where < this->end()); // Use copyAppend at end
|
Q_ASSERT(where >= this->begin() && where <= this->end());
|
||||||
Q_ASSERT(b <= e);
|
Q_ASSERT(b <= e);
|
||||||
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
||||||
Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size);
|
Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size);
|
||||||
@ -388,10 +388,10 @@ struct QGenericArrayOps
|
|||||||
} destroyer(writeIter);
|
} destroyer(writeIter);
|
||||||
|
|
||||||
// Construct new elements in array
|
// Construct new elements in array
|
||||||
do {
|
while (writeIter != step1End) {
|
||||||
--readIter, --writeIter;
|
--readIter, --writeIter;
|
||||||
new (writeIter) T(*readIter);
|
new (writeIter) T(*readIter);
|
||||||
} while (writeIter != step1End);
|
}
|
||||||
|
|
||||||
while (writeIter != end) {
|
while (writeIter != end) {
|
||||||
--e, --writeIter;
|
--e, --writeIter;
|
||||||
@ -450,10 +450,10 @@ struct QGenericArrayOps
|
|||||||
} destroyer(writeIter);
|
} destroyer(writeIter);
|
||||||
|
|
||||||
// Construct new elements in array
|
// Construct new elements in array
|
||||||
do {
|
while (writeIter != step1End) {
|
||||||
--readIter, --writeIter;
|
--readIter, --writeIter;
|
||||||
new (writeIter) T(*readIter);
|
new (writeIter) T(*readIter);
|
||||||
} while (writeIter != step1End);
|
}
|
||||||
|
|
||||||
while (writeIter != end) {
|
while (writeIter != end) {
|
||||||
--n, --writeIter;
|
--n, --writeIter;
|
||||||
@ -551,7 +551,7 @@ struct QMovableArrayOps
|
|||||||
{
|
{
|
||||||
Q_ASSERT(this->isMutable());
|
Q_ASSERT(this->isMutable());
|
||||||
Q_ASSERT(!this->isShared());
|
Q_ASSERT(!this->isShared());
|
||||||
Q_ASSERT(where >= this->begin() && where < this->end()); // Use copyAppend at end
|
Q_ASSERT(where >= this->begin() && where <= this->end());
|
||||||
Q_ASSERT(b <= e);
|
Q_ASSERT(b <= e);
|
||||||
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
||||||
Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size);
|
Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size);
|
||||||
|
@ -1373,10 +1373,10 @@ void tst_QArrayData::arrayOpsExtra()
|
|||||||
// empty ranges
|
// empty ranges
|
||||||
RUN_TEST_FUNC(testInsertRange, intData, 0, intArray.data(), intArray.data());
|
RUN_TEST_FUNC(testInsertRange, intData, 0, intArray.data(), intArray.data());
|
||||||
RUN_TEST_FUNC(testInsertRange, strData, 0, stringArray.data(), stringArray.data());
|
RUN_TEST_FUNC(testInsertRange, strData, 0, stringArray.data(), stringArray.data());
|
||||||
// RUN_TEST_FUNC(testInsertRange, objData, 0, objArray.data(), objArray.data()); // ### crashes
|
RUN_TEST_FUNC(testInsertRange, objData, 0, objArray.data(), objArray.data());
|
||||||
RUN_TEST_FUNC(testInsertValue, intData, 1, 0, int());
|
RUN_TEST_FUNC(testInsertValue, intData, 1, 0, int());
|
||||||
RUN_TEST_FUNC(testInsertValue, strData, 1, 0, QString());
|
RUN_TEST_FUNC(testInsertValue, strData, 1, 0, QString());
|
||||||
// RUN_TEST_FUNC(testInsertValue, objData, 1, 0, CountedObject()); // ### crashes
|
RUN_TEST_FUNC(testInsertValue, objData, 1, 0, CountedObject());
|
||||||
|
|
||||||
// insert at the beginning
|
// insert at the beginning
|
||||||
RUN_TEST_FUNC(testInsertRange, intData, 0, intArray.data(), intArray.data() + 1);
|
RUN_TEST_FUNC(testInsertRange, intData, 0, intArray.data(), intArray.data() + 1);
|
||||||
@ -1405,9 +1405,14 @@ void tst_QArrayData::arrayOpsExtra()
|
|||||||
RUN_TEST_FUNC(testInsertValue, strData, strData.size - 3, 3, QLatin1String("foo"));
|
RUN_TEST_FUNC(testInsertValue, strData, strData.size - 3, 3, QLatin1String("foo"));
|
||||||
RUN_TEST_FUNC(testInsertValue, objData, objData.size - 3, 3, CountedObject());
|
RUN_TEST_FUNC(testInsertValue, objData, objData.size - 3, 3, CountedObject());
|
||||||
|
|
||||||
// insert at the end (generic and movable operations allow it in value case)
|
// insert at the end
|
||||||
|
RUN_TEST_FUNC(testInsertRange, intData, intData.size, intArray.data(), intArray.data() + 3);
|
||||||
|
RUN_TEST_FUNC(testInsertRange, strData, strData.size, stringArray.data(),
|
||||||
|
stringArray.data() + 3);
|
||||||
|
RUN_TEST_FUNC(testInsertRange, objData, objData.size, objArray.data(), objArray.data() + 3);
|
||||||
|
RUN_TEST_FUNC(testInsertValue, intData, intData.size, 1, int(-42));
|
||||||
RUN_TEST_FUNC(testInsertValue, strData, strData.size, 1, QLatin1String("hello, world"));
|
RUN_TEST_FUNC(testInsertValue, strData, strData.size, 1, QLatin1String("hello, world"));
|
||||||
// RUN_TEST_FUNC(testInsertValue, objData, objData.size, 1, CountedObject()); // ### crashes
|
RUN_TEST_FUNC(testInsertValue, objData, objData.size, 1, CountedObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
// emplace
|
// emplace
|
||||||
|
Loading…
Reference in New Issue
Block a user