summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qarraydata.cpp8
-rw-r--r--src/corelib/tools/qarraydata.h37
-rw-r--r--src/corelib/tools/qarraydatapointer.h12
-rw-r--r--tests/auto/corelib/tools/qarraydata/simplevector.h12
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp42
5 files changed, 78 insertions, 33 deletions
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 150f23cc12..efed984aef 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -49,7 +49,7 @@ static const QArrayData qt_array_empty = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0
static const QArrayData qt_array_unsharable_empty = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 };
QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
- size_t capacity, bool reserve, bool sharable)
+ size_t capacity, AllocateOptions options)
{
// Alignment is a power of two
Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData)
@@ -57,7 +57,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
// Don't allocate empty headers
if (!capacity)
- return sharable
+ return !(options & Unsharable)
? const_cast<QArrayData *>(&qt_array_empty)
: const_cast<QArrayData *>(&qt_array_unsharable_empty);
@@ -73,10 +73,10 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)
& ~(alignment - 1);
- header->ref.atomic.store(sharable ? 1 : 0);
+ header->ref.atomic.store(bool(!(options & Unsharable)));
header->size = 0;
header->alloc = capacity;
- header->capacityReserved = reserve;
+ header->capacityReserved = bool(options & CapacityReserved);
header->offset = data - quintptr(header);
}
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index 2486bebafa..8eb543ee51 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -73,14 +73,43 @@ struct Q_CORE_EXPORT QArrayData
return reinterpret_cast<const char *>(this) + offset;
}
+ enum AllocateOption {
+ CapacityReserved = 0x1,
+ Unsharable = 0x2,
+
+ Default = 0
+ };
+
+ Q_DECLARE_FLAGS(AllocateOptions, AllocateOption)
+
+ AllocateOptions detachFlags() const
+ {
+ AllocateOptions result;
+ if (!ref.isSharable())
+ result |= Unsharable;
+ if (capacityReserved)
+ result |= CapacityReserved;
+ return result;
+ }
+
+ AllocateOptions cloneFlags() const
+ {
+ AllocateOptions result;
+ if (capacityReserved)
+ result |= CapacityReserved;
+ return result;
+ }
+
static QArrayData *allocate(size_t objectSize, size_t alignment,
- size_t capacity, bool reserve, bool sharable) Q_REQUIRED_RESULT;
+ size_t capacity, AllocateOptions options = Default) Q_REQUIRED_RESULT;
static void deallocate(QArrayData *data, size_t objectSize,
size_t alignment);
static const QArrayData shared_null;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QArrayData::AllocateOptions)
+
template <class T>
struct QTypedArrayData
: QArrayData
@@ -98,11 +127,11 @@ struct QTypedArrayData
class AlignmentDummy { QArrayData header; T data; };
- static QTypedArrayData *allocate(size_t capacity, bool reserve = false,
- bool sharable = true) Q_REQUIRED_RESULT
+ static QTypedArrayData *allocate(size_t capacity,
+ AllocateOptions options = Default) Q_REQUIRED_RESULT
{
return static_cast<QTypedArrayData *>(QArrayData::allocate(sizeof(T),
- Q_ALIGNOF(AlignmentDummy), capacity, reserve, sharable));
+ Q_ALIGNOF(AlignmentDummy), capacity, options));
}
static void deallocate(QArrayData *data)
diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h
index c03e2ef849..1dc02daa63 100644
--- a/src/corelib/tools/qarraydatapointer.h
+++ b/src/corelib/tools/qarraydatapointer.h
@@ -66,7 +66,7 @@ public:
QArrayDataPointer(const QArrayDataPointer &other)
: d(other.d->ref.ref()
? other.d
- : other.clone())
+ : other.clone(other.d->cloneFlags()))
{
}
@@ -115,7 +115,9 @@ public:
void setSharable(bool sharable)
{
if (d->alloc == 0 && d->size == 0) {
- d = Data::allocate(0, false, sharable);
+ d = Data::allocate(0, sharable
+ ? QArrayData::Default
+ : QArrayData::Unsharable);
return;
}
@@ -137,7 +139,7 @@ public:
bool detach()
{
if (d->ref.isShared()) {
- Data *copy = clone();
+ Data *copy = clone(d->detachFlags());
QArrayDataPointer old(d);
d = copy;
return true;
@@ -147,10 +149,10 @@ public:
}
private:
- Data *clone() const Q_REQUIRED_RESULT
+ Data *clone(QArrayData::AllocateOptions options) const Q_REQUIRED_RESULT
{
QArrayDataPointer copy(Data::allocate(d->alloc ? d->alloc : d->size,
- d->capacityReserved));
+ options));
if (d->size)
copy->copyAppend(d->begin(), d->end());
diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h
index 9ab28a9ddd..4f02df1c40 100644
--- a/tests/auto/corelib/tools/qarraydata/simplevector.h
+++ b/tests/auto/corelib/tools/qarraydata/simplevector.h
@@ -140,7 +140,8 @@ public:
|| (n
&& !d->capacityReserved
&& (d->ref != 1 || (d->capacityReserved = 1, false)))) {
- SimpleVector detached(Data::allocate(n, true));
+ SimpleVector detached(Data::allocate(n,
+ d->detachFlags() | Data::CapacityReserved));
detached.d->copyAppend(constBegin(), constEnd());
detached.swap(*this);
}
@@ -160,7 +161,8 @@ public:
if (d->ref != 1
|| capacity() - size() < size_t(last - first)) {
SimpleVector detached(Data::allocate(
- qMax(capacity(), size() + (last - first)), d->capacityReserved));
+ qMax(capacity(), size() + (last - first)),
+ d->detachFlags()));
detached.d->copyAppend(first, last);
detached.d->copyAppend(begin, begin + d->size);
@@ -180,7 +182,8 @@ public:
if (d->ref != 1
|| capacity() - size() < size_t(last - first)) {
SimpleVector detached(Data::allocate(
- qMax(capacity(), size() + (last - first)), d->capacityReserved));
+ qMax(capacity(), size() + (last - first)),
+ d->detachFlags()));
if (d->size) {
const T *const begin = constBegin();
@@ -219,7 +222,8 @@ public:
if (d->ref != 1
|| capacity() - size() < size_t(last - first)) {
SimpleVector detached(Data::allocate(
- qMax(capacity(), size() + (last - first)), d->capacityReserved));
+ qMax(capacity(), size() + (last - first)),
+ d->detachFlags()));
if (position)
detached.d->copyAppend(begin, where);
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index 47d5e2a32b..2df4131f4a 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -153,7 +153,7 @@ void tst_QArrayData::referenceCounting()
void tst_QArrayData::sharedNullEmpty()
{
QArrayData *null = const_cast<QArrayData *>(&QArrayData::shared_null);
- QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0, false, true);
+ QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0);
QVERIFY(null->ref.isStatic());
QVERIFY(null->ref.isSharable());
@@ -473,11 +473,13 @@ struct Deallocator
};
Q_DECLARE_METATYPE(const QArrayData *)
+Q_DECLARE_METATYPE(QArrayData::AllocateOptions)
void tst_QArrayData::allocate_data()
{
QTest::addColumn<size_t>("objectSize");
QTest::addColumn<size_t>("alignment");
+ QTest::addColumn<QArrayData::AllocateOptions>("allocateOptions");
QTest::addColumn<bool>("isCapacityReserved");
QTest::addColumn<bool>("isSharable");
QTest::addColumn<const QArrayData *>("commonEmpty");
@@ -492,22 +494,25 @@ void tst_QArrayData::allocate_data()
{ "void *", sizeof(void *), Q_ALIGNOF(void *) }
};
- QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, false, true);
- QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, false, false);
+ QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0);
+ QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable);
QVERIFY(shared_empty);
QVERIFY(unsharable_empty);
struct {
char const *description;
+ QArrayData::AllocateOptions allocateOptions;
bool isCapacityReserved;
bool isSharable;
const QArrayData *commonEmpty;
} options[] = {
- { "Default", false, true, shared_empty },
- { "Reserved", true, true, shared_empty },
- { "Reserved | Unsharable", true, false, unsharable_empty },
- { "Unsharable", false, false, unsharable_empty },
+ { "Default", QArrayData::Default, false, true, shared_empty },
+ { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty },
+ { "Reserved | Unsharable",
+ QArrayData::CapacityReserved | QArrayData::Unsharable, true, false,
+ unsharable_empty },
+ { "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty },
};
for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
@@ -517,14 +522,15 @@ void tst_QArrayData::allocate_data()
+ QLatin1String(": ")
+ QLatin1String(options[j].description)))
<< types[i].objectSize << types[i].alignment
- << options[j].isCapacityReserved << options[j].isSharable
- << options[j].commonEmpty;
+ << options[j].allocateOptions << options[j].isCapacityReserved
+ << options[j].isSharable << options[j].commonEmpty;
}
void tst_QArrayData::allocate()
{
QFETCH(size_t, objectSize);
QFETCH(size_t, alignment);
+ QFETCH(QArrayData::AllocateOptions, allocateOptions);
QFETCH(bool, isCapacityReserved);
QFETCH(bool, isSharable);
QFETCH(const QArrayData *, commonEmpty);
@@ -535,14 +541,14 @@ void tst_QArrayData::allocate()
// Shared Empty
QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0,
- isCapacityReserved, isSharable), commonEmpty);
+ QArrayData::AllocateOptions(allocateOptions)), commonEmpty);
Deallocator keeper(objectSize, minAlignment);
keeper.headers.reserve(1024);
for (int capacity = 1; capacity <= 1024; capacity <<= 1) {
QArrayData *data = QArrayData::allocate(objectSize, minAlignment,
- capacity, isCapacityReserved, isSharable);
+ capacity, QArrayData::AllocateOptions(allocateOptions));
keeper.headers.append(data);
QCOMPARE(data->size, 0);
@@ -584,7 +590,7 @@ void tst_QArrayData::alignment()
for (int i = 0; i < 100; ++i) {
QArrayData *data = QArrayData::allocate(sizeof(Unaligned),
- minAlignment, 8, false, true);
+ minAlignment, 8, QArrayData::Default);
keeper.headers.append(data);
QVERIFY(data);
@@ -952,10 +958,14 @@ void tst_QArrayData::setSharable_data()
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
};
- QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5, true, true));
- QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(10, false, true));
- QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15, true, true));
- QArrayDataPointer<int> staticArray(static_cast<QTypedArrayData<int> *>(&staticArrayData.header));
+ QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5,
+ QArrayData::CapacityReserved));
+ QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(10,
+ QArrayData::Default));
+ QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15,
+ QArrayData::CapacityReserved));
+ QArrayDataPointer<int> staticArray(
+ static_cast<QTypedArrayData<int> *>(&staticArrayData.header));
nonEmpty->copyAppend(5, 1);
nonEmptyReserved->copyAppend(7, 2);