Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qarraydata.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2019 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QARRAYDATA_H
6#define QARRAYDATA_H
7
8#include <QtCore/qpair.h>
9#include <QtCore/qatomic.h>
10#include <QtCore/qflags.h>
11#include <QtCore/qcontainerfwd.h>
12#include <string.h>
13
15
16#if __has_cpp_attribute(gnu::malloc)
17# define Q_DECL_MALLOCLIKE [[nodiscard, gnu::malloc]]
18#else
19# define Q_DECL_MALLOCLIKE [[nodiscard]]
20#endif
21
22template <class T> struct QTypedArrayData;
23
25{
30
35
40 Q_DECLARE_FLAGS(ArrayOptions, ArrayOption)
41
43 ArrayOptions flags;
45
47 {
48 return alloc;
49 }
50
52 {
53 return alloc;
54 }
55
57 bool ref() noexcept
58 {
59 ref_.ref();
60 return true;
61 }
62
64 bool deref() noexcept
65 {
66 return ref_.deref();
67 }
68
69 bool isShared() const noexcept
70 {
71 return ref_.loadRelaxed() != 1;
72 }
73
74 // Returns true if a detach is necessary before modifying the data
75 // This method is intentionally not const: if you want to know whether
76 // detaching is necessary, you should be in a non-const function already
77 bool needsDetach() noexcept
78 {
79 return ref_.loadRelaxed() > 1;
80 }
81
82 qsizetype detachCapacity(qsizetype newSize) const noexcept
83 {
86 return newSize;
87 }
88
90 static Q_CORE_EXPORT void *allocate(QArrayData **pdata, qsizetype objectSize, qsizetype alignment,
93 static Q_CORE_EXPORT void *allocate1(QArrayData **pdata, qsizetype capacity,
96 static Q_CORE_EXPORT void *allocate2(QArrayData **pdata, qsizetype capacity,
98
99 [[nodiscard]] static Q_CORE_EXPORT std::pair<QArrayData *, void *> reallocateUnaligned(QArrayData *data, void *dataPointer,
100 qsizetype objectSize, qsizetype newCapacity, AllocationOption option) noexcept;
101 static Q_CORE_EXPORT void deallocate(QArrayData *data, qsizetype objectSize,
102 qsizetype alignment) noexcept;
103};
104
105Q_DECLARE_OPERATORS_FOR_FLAGS(QArrayData::ArrayOptions)
106
107namespace QtPrivate {
108// QArrayData with strictest alignment requirements supported by malloc()
109#if defined(Q_PROCESSOR_X86_32) && defined(Q_CC_GNU)
110// GCC's definition is incorrect since GCC 8 (commit r240248 in SVN; commit
111// 63012d9a57edc950c5f30242d1e19318b5708060 in Git). This is applied to all
112// GCC-like compilers in case they decide to follow GCC's lead in being wrong.
113constexpr size_t MaxPrimitiveAlignment = 2 * sizeof(void *);
114#else
115constexpr size_t MaxPrimitiveAlignment = alignof(std::max_align_t);
116#endif
117
118struct alignas(MaxPrimitiveAlignment) AlignedQArrayData : QArrayData
119{
120};
121}
122
123template <class T>
125 : QArrayData
126{
128
129 [[nodiscard]] static std::pair<QTypedArrayData *, T *> allocate(qsizetype capacity, AllocationOption option = QArrayData::KeepSize)
130 {
131 static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
132 QArrayData *d;
133 void *result;
134 if constexpr (sizeof(T) == 1) {
135 // necessarily, alignof(T) == 1
136 result = allocate1(&d, capacity, option);
137 } else if constexpr (sizeof(T) == 2) {
138 // alignof(T) may be 1, but that makes no difference
139 result = allocate2(&d, capacity, option);
140 } else {
141 result = QArrayData::allocate(&d, sizeof(T), alignof(AlignmentDummy), capacity, option);
142 }
143#if __has_builtin(__builtin_assume_aligned)
144 // and yet we do offer results that have stricter alignment
145 result = __builtin_assume_aligned(result, Q_ALIGNOF(AlignmentDummy));
146#endif
147 return {static_cast<QTypedArrayData *>(d), static_cast<T *>(result)};
148 }
149
150 static std::pair<QTypedArrayData *, T *>
152 {
153 static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
154 std::pair<QArrayData *, void *> pair =
155 QArrayData::reallocateUnaligned(data, dataPointer, sizeof(T), capacity, option);
156 return {static_cast<QTypedArrayData *>(pair.first), static_cast<T *>(pair.second)};
157 }
158
159 static void deallocate(QArrayData *data) noexcept
160 {
161 static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
162 QArrayData::deallocate(data, sizeof(T), alignof(AlignmentDummy));
163 }
164
166 {
167 // Alignment is a power of two
168 Q_ASSERT(alignment >= qsizetype(alignof(QArrayData)) && !(alignment & (alignment - 1)));
169 void *start = reinterpret_cast<void *>(
170 (quintptr(data) + sizeof(QArrayData) + alignment - 1) & ~(alignment - 1));
171 return static_cast<T *>(start);
172 }
173
174 constexpr static qsizetype max_size() noexcept
175 {
176 // -1 to deal with the pointer one-past-the-end
177 return (QtPrivate::MaxAllocSize - sizeof(QtPrivate::AlignedQArrayData) - 1) / sizeof(T);
178 }
179};
180
181namespace QtPrivate {
182struct Q_CORE_EXPORT QContainerImplHelper
183{
184 enum CutResult { Null, Empty, Full, Subset };
185 static constexpr CutResult mid(qsizetype originalLength, qsizetype *_position, qsizetype *_length)
186 {
187 qsizetype &position = *_position;
188 qsizetype &length = *_length;
189 if (position > originalLength) {
190 position = 0;
191 length = 0;
192 return Null;
193 }
194
195 if (position < 0) {
196 if (length < 0 || length + position >= originalLength) {
197 position = 0;
198 length = originalLength;
199 return Full;
200 }
201 if (length + position <= 0) {
202 position = length = 0;
203 return Null;
204 }
205 length += position;
206 position = 0;
207 } else if (size_t(length) > size_t(originalLength - position)) {
208 length = originalLength - position;
209 }
210
211 if (position == 0 && length == originalLength)
212 return Full;
213
214 return length > 0 ? Subset : Empty;
215 }
216};
217}
218
219#undef Q_DECL_MALLOCLIKE
220
222
223#endif // include guard
bool ref() noexcept
bool deref() noexcept
T loadRelaxed() const noexcept
uint alignment
Combined button and popup list for selecting options.
\macro QT_NO_KEYWORDS >
constexpr qsizetype MaxAllocSize
constexpr size_t MaxPrimitiveAlignment
Definition qarraydata.h:115
#define Q_DECL_MALLOCLIKE
Definition qarraydata.h:19
#define Q_ALIGNOF(x)
static QString header(const QString &name)
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition qflags.h:194
NSUInteger capacity
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLbitfield flags
GLuint start
GLuint64EXT * result
[6]
GLuint GLenum option
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
size_t quintptr
Definition qtypes.h:167
ptrdiff_t qsizetype
Definition qtypes.h:165
qsizetype detachCapacity(qsizetype newSize) const noexcept
Definition qarraydata.h:82
@ CapacityReserved
the capacity was reserved by the user, try to keep it
Definition qarraydata.h:38
@ ArrayOptionDefault
Definition qarraydata.h:37
bool deref() noexcept
Returns false if deallocation is necessary.
Definition qarraydata.h:64
static Q_CORE_EXPORT std::pair< QArrayData *, void * > reallocateUnaligned(QArrayData *data, void *dataPointer, qsizetype objectSize, qsizetype newCapacity, AllocationOption option) noexcept
bool isShared() const noexcept
Definition qarraydata.h:69
qsizetype alloc
Definition qarraydata.h:44
qsizetype constAllocatedCapacity() const noexcept
Definition qarraydata.h:51
static Q_DECL_MALLOCLIKE Q_CORE_EXPORT void * allocate(QArrayData **pdata, qsizetype objectSize, qsizetype alignment, qsizetype capacity, AllocationOption option=QArrayData::KeepSize) noexcept
static Q_CORE_EXPORT void deallocate(QArrayData *data, qsizetype objectSize, qsizetype alignment) noexcept
bool needsDetach() noexcept
Definition qarraydata.h:77
static Q_DECL_MALLOCLIKE Q_CORE_EXPORT void * allocate2(QArrayData **pdata, qsizetype capacity, AllocationOption option=QArrayData::KeepSize) noexcept
qsizetype allocatedCapacity() noexcept
Definition qarraydata.h:46
@ GrowsAtBeginning
Definition qarraydata.h:33
bool ref() noexcept
Returns true if sharing took place.
Definition qarraydata.h:57
QBasicAtomicInt ref_
Definition qarraydata.h:42
static Q_DECL_MALLOCLIKE Q_CORE_EXPORT void * allocate1(QArrayData **pdata, qsizetype capacity, AllocationOption option=QArrayData::KeepSize) noexcept
static std::pair< QTypedArrayData *, T * > reallocateUnaligned(QTypedArrayData *data, T *dataPointer, qsizetype capacity, AllocationOption option)
Definition qarraydata.h:151
static std::pair< QTypedArrayData *, T * > allocate(qsizetype capacity, AllocationOption option=QArrayData::KeepSize)
Definition qarraydata.h:129
static constexpr qsizetype max_size() noexcept
Definition qarraydata.h:174
static void deallocate(QArrayData *data) noexcept
Definition qarraydata.h:159
static T * dataStart(QArrayData *data, qsizetype alignment) noexcept
Definition qarraydata.h:165
static constexpr CutResult mid(qsizetype originalLength, qsizetype *_position, qsizetype *_length)
Definition qarraydata.h:185