summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-06-11 18:45:02 +0200
committerLars Knoll <lars.knoll@qt.io>2019-12-08 10:29:01 +0100
commita3aa2fcfa72ab69bdbded26dcd43e37b35796a17 (patch)
tree3c8bdce81299261ffc381bebcae2e7c1312971c9 /src/corelib/tools
parentb6aa133cf556c962e666b8facc9ade9fab0dedbd (diff)
Introduce the Mutable flag and move QArrayDataPointer::needsDetach
The Mutable flag now contains the information on whether the data this QArrayData points to is mutable. This decouples the mutability / immutability setting from the allocation and from the type of data, opening the way for mutable raw or foreign data. There are still plenty of places in the source code that check the size of the allocation when it actually wants d->isMutable(). Fixing this will require reviewing all the code, so is left for later. The needsDetach() function is moved to QArrayData and de-constified. It returns true when a reallocation is necessary if the data is to be modified. Change-Id: I17e2bc5a3f6ef1f3eba8a205acd9852b95524f57 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qarraydata.cpp3
-rw-r--r--src/corelib/tools/qarraydata.h12
-rw-r--r--src/corelib/tools/qarraydatapointer.h7
-rw-r--r--src/corelib/tools/qvector.h3
4 files changed, 16 insertions, 9 deletions
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index bc48619349..3123d7467f 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -222,7 +222,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
return nullptr;
size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
- options |= ArrayOption(AllocatedDataType);
+ options |= AllocatedDataType | Mutable;
QArrayData *header = allocateData(allocSize, options);
if (header) {
quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)
@@ -252,6 +252,7 @@ QArrayData *QArrayData::reallocateUnaligned(QArrayData *data, size_t objectSize,
options |= ArrayOption(AllocatedDataType);
size_t headerSize = sizeof(QArrayData);
size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
+ options |= AllocatedDataType | Mutable;
QArrayData *header = reallocateData(data, allocSize, options);
if (header)
header->alloc = capacity;
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index babccc6017..8c21fd55c8 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -56,6 +56,7 @@ struct Q_CORE_EXPORT QArrayData
CapacityReserved = 0x0010, //!< the capacity was reserved by the user, try to keep it
GrowsForward = 0x0020, //!< allocate with eyes towards growing through append()
GrowsBackwards = 0x0040, //!< allocate with eyes towards growing through prepend()
+ Mutable = 0x0080, //!< the data can be changed; doesn't say anything about the header
/// this option is used by the Q_ARRAY_LITERAL and similar macros
StaticDataFlags = RawDataType,
@@ -102,7 +103,16 @@ struct Q_CORE_EXPORT QArrayData
// follow COW principles.
bool isMutable() const
{
- return flags & AllocatedDataType;
+ return flags & Mutable;
+ }
+
+ // Returns true if a detach is necessary before modifying the data
+ // This method is intentionally not const: if you want to know whether
+ // detaching is necessary, you should be in a non-const function already
+ bool needsDetach()
+ {
+ // ### optimize me -- this currently requires 3 conditionals!
+ return !isMutable() || ref.isShared();
}
size_t detachCapacity(size_t newSize) const
diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h
index ffeaff5862..b7236d485a 100644
--- a/src/corelib/tools/qarraydatapointer.h
+++ b/src/corelib/tools/qarraydatapointer.h
@@ -126,11 +126,6 @@ public:
return d;
}
- bool needsDetach() const
- {
- return (!d->isMutable() || d->ref.isShared());
- }
-
void swap(QArrayDataPointer &other) noexcept
{
qSwap(d, other.d);
@@ -144,7 +139,7 @@ public:
bool detach()
{
- if (needsDetach()) {
+ if (d->needsDetach()) {
Data *copy = clone(d->detachFlags());
QArrayDataPointer old(d);
d = copy;
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 9ef2ace471..a596beedcf 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -390,10 +390,11 @@ inline QVector<T>::QVector(const QVector<T> &v)
template <typename T>
void QVector<T>::detach()
{
+ // ### check whether this is still required
if (d->ref.isStatic())
return;
- if (!isDetached())
+ if (d->needsDetach())
realloc(d->allocatedCapacity(), d->detachFlags());
Q_ASSERT(isDetached());
}