52qsizetype qCalculateBlockSize(qsizetype elementCount, qsizetype elementSize, qsizetype headerSize)
noexcept
54 Q_ASSERT(elementSize);
57 if (Q_UNLIKELY(qMulOverflow(size_t(elementSize), size_t(elementCount), &bytes)) ||
58 Q_UNLIKELY(qAddOverflow(bytes, size_t(headerSize), &bytes)))
60 if (Q_UNLIKELY(qsizetype(bytes) < 0))
63 return qsizetype(bytes);
87 CalculateGrowingBlockSizeResult result = {
88 qsizetype(-1), qsizetype(-1)
91 qsizetype bytes = qCalculateBlockSize(elementCount, elementSize, headerSize);
95 size_t morebytes =
static_cast<size_t>(qNextPowerOfTwo(quint64(bytes)));
96 if (Q_UNLIKELY(qsizetype(morebytes) < 0)) {
100 bytes += (morebytes - bytes) / 2;
102 bytes = qsizetype(morebytes);
105 result.elementCount = (bytes - headerSize) / elementSize;
106 result.size = result.elementCount * elementSize + headerSize;
119calculateBlockSize(qsizetype capacity, qsizetype objectSize, qsizetype headerSize, QArrayData::AllocationOption option)
124 constexpr qsizetype FooterSize = qMax(
sizeof(QString::value_type),
sizeof(QByteArray::value_type));
125 if (objectSize <= FooterSize)
126 headerSize += FooterSize;
130 if (option == QArrayData::Grow) {
131 return qCalculateGrowingBlockSize(capacity, objectSize, headerSize);
133 return { qCalculateBlockSize(capacity, objectSize, headerSize), capacity };
158 QArrayData::AllocationOption option)
noexcept
163 qsizetype headerSize =
sizeof(AlignedQArrayData);
164 const qsizetype headerAlignment =
alignof(AlignedQArrayData);
166 if (alignment > headerAlignment) {
171 headerSize += alignment - headerAlignment;
173 Q_ASSERT(headerSize > 0);
175 auto blockSize = calculateBlockSize(capacity, objectSize, headerSize, option);
176 capacity = blockSize.elementCount;
177 qsizetype allocSize = blockSize.size;
178 if (Q_UNLIKELY(allocSize < 0))
181 QArrayData *header = allocateData(allocSize);
182 void *data =
nullptr;
185 data = QTypedArrayData<
void>::dataStart(header, alignment);
186 header->alloc = qsizetype(capacity);
189 return { data, header };
193void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype alignment,
194 qsizetype capacity, AllocationOption option)
noexcept
198 Q_ASSERT(alignment >= qsizetype(
alignof(QArrayData))
199 && !(alignment & (alignment - 1)));
201 auto r = allocateHelper(objectSize, alignment, capacity, option);
226QArrayData::reallocateUnaligned(QArrayData *data,
void *dataPointer,
227 qsizetype objectSize, qsizetype capacity, AllocationOption option)
noexcept
229 Q_ASSERT(!data || !data->isShared());
231 const qsizetype headerSize =
sizeof(AlignedQArrayData);
232 auto r = calculateBlockSize(capacity, objectSize, headerSize, option);
233 qsizetype allocSize = r.size;
234 capacity = r.elementCount;
235 if (Q_UNLIKELY(allocSize < 0))
238 const qptrdiff offset = dataPointer
239 ?
reinterpret_cast<
char *>(dataPointer) -
reinterpret_cast<
char *>(data)
241 Q_ASSERT(offset > 0);
242 Q_ASSERT(offset <= allocSize);
244 QArrayData *header =
static_cast<QArrayData *>(::realloc(data, size_t(allocSize)));
246 header->alloc = capacity;
247 dataPointer =
reinterpret_cast<
char *>(header) + offset;
249 dataPointer =
nullptr;
251 return {header, dataPointer};