File indexing completed on 2026-01-07 10:16:05
0001
0002
0003
0004 #ifndef QALLOC_H
0005 #define QALLOC_H
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <QtCore/qtconfigmacros.h>
0019 #include <QtCore/qtcoreexports.h>
0020 #include <QtCore/qnumeric.h>
0021 #include <QtCore/qtypeinfo.h>
0022
0023 #include <cstddef>
0024
0025 QT_BEGIN_NAMESPACE
0026
0027 namespace QtPrivate {
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION
0039 size_t expectedAllocSize(size_t allocSize, size_t alignment) noexcept;
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 inline size_t fittedAllocSize(size_t headerSize, size_t *capacity,
0051 size_t elementSize, size_t unusedCapacity, size_t alignment) noexcept
0052 {
0053 size_t totalCapacity = 0;
0054 if (Q_UNLIKELY(qAddOverflow(*capacity, unusedCapacity, &totalCapacity)))
0055 return 0;
0056
0057 size_t payloadSize = 0;
0058 if (Q_UNLIKELY(qMulOverflow(totalCapacity, elementSize, &payloadSize)))
0059 return 0;
0060
0061 size_t allocSize = 0;
0062 if (Q_UNLIKELY(qAddOverflow(headerSize, payloadSize, &allocSize)))
0063 return 0;
0064
0065 if (size_t fittedSize = expectedAllocSize(allocSize, alignment); fittedSize != 0) {
0066
0067
0068 *capacity = (fittedSize - headerSize) / elementSize - unusedCapacity;
0069 size_t newTotalCapacity = *capacity + unusedCapacity;
0070 size_t newPayloadSize = newTotalCapacity * elementSize;
0071 return headerSize + newPayloadSize;
0072 }
0073
0074 return allocSize;
0075 }
0076
0077 #ifdef Q_CC_GNU
0078 __attribute__((malloc))
0079 #endif
0080 inline void *fittedMalloc(size_t headerSize, size_t *capacity,
0081 size_t elementSize, size_t unusedCapacity) noexcept
0082 {
0083 size_t allocSize = fittedAllocSize(headerSize, capacity,
0084 elementSize, unusedCapacity, alignof(std::max_align_t));
0085 if (Q_LIKELY(allocSize != 0))
0086 return malloc(allocSize);
0087 else
0088 return nullptr;
0089 }
0090 inline void *fittedMalloc(size_t headerSize, qsizetype *capacity,
0091 size_t elementSize, size_t unusedCapacity = 0) noexcept
0092 {
0093 size_t uCapacity = size_t(*capacity);
0094 void *ptr = fittedMalloc(headerSize, &uCapacity, elementSize, unusedCapacity);
0095 *capacity = qsizetype(uCapacity);
0096 return ptr;
0097 }
0098
0099 inline void *fittedRealloc(void *ptr, size_t headerSize, size_t *capacity,
0100 size_t elementSize, size_t unusedCapacity) noexcept
0101 {
0102 size_t newCapacity = *capacity;
0103 size_t allocSize = fittedAllocSize(headerSize, &newCapacity,
0104 elementSize, unusedCapacity, alignof(std::max_align_t));
0105 if (Q_LIKELY(allocSize != 0)) {
0106 void *newPtr = realloc(ptr, allocSize);
0107 if (newPtr)
0108 *capacity = newCapacity;
0109 return newPtr;
0110 } else {
0111 return nullptr;
0112 }
0113 }
0114 inline void *fittedRealloc(void *ptr, size_t headerSize, qsizetype *capacity,
0115 size_t elementSize, size_t unusedCapacity = 0) noexcept
0116 {
0117 size_t uCapacity = size_t(*capacity);
0118 ptr = fittedRealloc(ptr, headerSize, &uCapacity, elementSize, unusedCapacity);
0119 *capacity = qsizetype(uCapacity);
0120 return ptr;
0121 }
0122
0123 Q_CORE_EXPORT void sizedFree(void *ptr, size_t allocSize) noexcept;
0124 inline void sizedFree(void *ptr, size_t capacity, size_t elementSize) noexcept
0125 {
0126 sizedFree(ptr, capacity * elementSize);
0127 }
0128
0129 }
0130
0131 QT_END_NAMESPACE
0132
0133 #endif