Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmllistcompositor_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
5#ifndef QQMLLISTCOMPOSITOR_P_H
6#define QQMLLISTCOMPOSITOR_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/qglobal.h>
20#include <QtCore/qvector.h>
21
22#include <private/qqmlchangeset_p.h>
23
24#include <QtCore/qdebug.h>
25
27
29{
30public:
31 enum { MinimumGroupCount = 3, MaximumGroupCount = 11 };
32
33 enum Group
34 {
35 Cache = 0,
36 Default = 1,
37 Persisted = 2
38 };
39
40 enum Flag
41 {
42 CacheFlag = 1 << Cache,
43 DefaultFlag = 1 << Default,
44 PersistedFlag = 1 << Persisted,
45 PrependFlag = 0x10000000,
46 AppendFlag = 0x20000000,
47 UnresolvedFlag = 0x40000000,
48 MovedFlag = 0x80000000,
49 GroupMask = ~(PrependFlag | AppendFlag | UnresolvedFlag | MovedFlag | CacheFlag)
50 };
51
52 class Range
53 {
54 public:
55 Range() : next(this), previous(this) {}
56 Range(Range *next, void *list, int index, int count, uint flags)
57 : next(next), previous(next->previous), list(list), index(index), count(count), flags(flags) {
58 next->previous = this; previous->next = this; }
59
60 Range *next;
61 Range *previous;
62 void *list = nullptr;
63 int index = 0;
64 int count = 0;
65 uint flags = 0;
66
67 inline int start() const { return index; }
68 inline int end() const { return index + count; }
69
70 inline int groups() const { return flags & GroupMask; }
71
72 inline bool inGroup() const { return flags & GroupMask; }
73 inline bool inCache() const { return flags & CacheFlag; }
74 inline bool inGroup(int group) const { return flags & (1 << group); }
75 inline bool isUnresolved() const { return flags & UnresolvedFlag; }
76
77 inline bool prepend() const { return flags & PrependFlag; }
78 inline bool append() const { return flags & AppendFlag; }
79 };
80
81 class Q_AUTOTEST_EXPORT iterator
82 {
83 public:
84 inline iterator() = default;
85 inline iterator(Range *range, int offset, Group group, int groupCount);
86
87 bool operator ==(const iterator &it) const { return range == it.range && offset == it.offset; }
88 bool operator !=(const iterator &it) const { return range != it.range || offset != it.offset; }
89
90 bool operator ==(Group group) const { return range->flags & (1 << group); }
91 bool operator !=(Group group) const { return !(range->flags & (1 << group)); }
92
93 Range *&operator *() { return range; }
94 Range * const &operator *() const { return range; }
95 Range *operator ->() { return range; }
96 const Range *operator ->() const { return range; }
97
98 iterator &operator +=(int difference);
99
100 template<typename T> T *list() const { return static_cast<T *>(range->list); }
101 int modelIndex() const { return range->index + offset; }
102
103 void incrementIndexes(int difference) { incrementIndexes(difference, range->flags); }
104 void decrementIndexes(int difference) { decrementIndexes(difference, range->flags); }
105
106 inline void incrementIndexes(int difference, uint flags);
107 inline void decrementIndexes(int difference, uint flags);
108
109 void setGroup(Group g) { group = g; groupFlag = 1 << g; }
110
111 Range *range = nullptr;
112 int offset = 0;
113 Group group = Default;
114 int groupFlag = 0;
115 int groupCount = 0;
116 int index[MaximumGroupCount] = { 0 };
117
118 int cacheIndex() const {
119 return index[Cache];
120 }
121
122 void setCacheIndex(int cacheIndex) {
123 index[Cache] = cacheIndex;
124 }
125 };
126
127 class Q_AUTOTEST_EXPORT insert_iterator : public iterator
128 {
129 public:
130 inline insert_iterator() {}
131 inline insert_iterator(const iterator &it) : iterator(it) {}
132 inline insert_iterator(Range *, int, Group, int);
133
134 insert_iterator &operator +=(int difference);
135 };
136
137 struct Change
138 {
139 inline Change() = default;
140 inline Change(const iterator &it, int count, uint flags, int moveId = -1);
141 int count = 0;
142 uint flags = 0;
143 int moveId = 0;
144 int index[MaximumGroupCount] = { 0 };
145
146 int cacheIndex() const {
147 return index[Cache];
148 }
149
150 void setCacheIndex(int cacheIndex) {
151 index[Cache] = cacheIndex;
152 }
153
154 inline bool isMove() const { return moveId >= 0; }
155 inline bool inCache() const { return flags & CacheFlag; }
156 inline bool inGroup() const { return flags & GroupMask; }
157 inline bool inGroup(int group) const { return flags & (CacheFlag << group); }
158
159 inline int groups() const { return flags & GroupMask; }
160 };
161
162 struct Insert : public Change
163 {
164 Insert() {}
165 Insert(const iterator &it, int count, uint flags, int moveId = -1)
166 : Change(it, count, flags, moveId) {}
167 };
168
169 struct Remove : public Change
170 {
171 Remove() {}
172 Remove(const iterator &it, int count, uint flags, int moveId = -1)
173 : Change(it, count, flags, moveId) {}
174 };
175
176 QQmlListCompositor();
177 ~QQmlListCompositor();
178
179 int defaultGroups() const { return m_defaultFlags & ~PrependFlag; }
180 void setDefaultGroups(int groups) { m_defaultFlags = groups | PrependFlag; }
181 void setDefaultGroup(Group group) { m_defaultFlags |= (1 << group); }
182 void clearDefaultGroup(Group group) { m_defaultFlags &= ~(1 << group); }
183 void setRemoveGroups(int groups) { m_removeFlags = PrependFlag | AppendFlag | groups; }
184 void setGroupCount(int count);
185
186 int count(Group group) const;
187 iterator find(Group group, int index);
188 iterator find(Group group, int index) const;
189 insert_iterator findInsertPosition(Group group, int index);
190
191 const iterator &end() { return m_end; }
192
193 void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
194 void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
195 iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
196
197 void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = nullptr);
198 void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = nullptr);
199 void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = nullptr) {
200 setFlags(fromGroup, from, count, fromGroup, flags, inserts); }
201 void setFlags(const iterator from, int count, uint flags, QVector<Insert> *inserts = nullptr) {
202 setFlags(from, count, from.group, flags, inserts); }
203
204 void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = nullptr);
205 void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = nullptr);
206 void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = nullptr) {
207 clearFlags(fromGroup, from, count, fromGroup, flags, removals); }
208 void clearFlags(const iterator &from, int count, uint flags, QVector<Remove> *removals = nullptr) {
209 clearFlags(from, count, from.group, flags, removals); }
210
211 bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count, Group group) const;
212
213 void move(
214 Group fromGroup,
215 int from,
216 Group toGroup,
217 int to,
218 int count,
219 Group group,
220 QVector<Remove> *removals = nullptr,
221 QVector<Insert> *inserts = nullptr);
222 void clear();
223
224 void listItemsInserted(void *list, int index, int count, QVector<Insert> *inserts);
225 void listItemsRemoved(void *list, int index, int count, QVector<Remove> *removals);
226 void listItemsMoved(void *list, int from, int to, int count, QVector<Remove> *removals, QVector<Insert> *inserts);
227 void listItemsChanged(void *list, int index, int count, QVector<Change> *changes);
228
229 void transition(
230 Group from,
231 Group to,
232 QVector<QQmlChangeSet::Change> *removes,
233 QVector<QQmlChangeSet::Change> *inserts);
234
235private:
236 Range m_ranges;
237 iterator m_end;
238 iterator m_cacheIt;
239 int m_groupCount;
240 int m_defaultFlags;
241 int m_removeFlags;
242 int m_moveId;
243
244 inline Range *insert(Range *before, void *list, int index, int count, uint flags);
245 inline Range *erase(Range *range);
246
247 struct MovedFlags
248 {
249 MovedFlags() {}
250 MovedFlags(int moveId, uint flags) : moveId(moveId), flags(flags) {}
251
252 int moveId;
253 uint flags;
254 };
255
256 void listItemsRemoved(
257 QVector<Remove> *translatedRemovals,
258 void *list,
259 QVector<QQmlChangeSet::Change> *removals,
260 QVector<QQmlChangeSet::Change> *insertions = nullptr,
261 QVector<MovedFlags> *movedFlags = nullptr);
262 void listItemsInserted(
263 QVector<Insert> *translatedInsertions,
264 void *list,
265 const QVector<QQmlChangeSet::Change> &insertions,
266 const QVector<MovedFlags> *movedFlags = nullptr);
267 void listItemsChanged(
268 QVector<Change> *translatedChanges,
269 void *list,
270 const QVector<QQmlChangeSet::Change> &changes);
271
272 friend Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor &list);
273};
274
275Q_DECLARE_TYPEINFO(QQmlListCompositor::Change, Q_PRIMITIVE_TYPE);
276Q_DECLARE_TYPEINFO(QQmlListCompositor::Remove, Q_PRIMITIVE_TYPE);
277Q_DECLARE_TYPEINFO(QQmlListCompositor::Insert, Q_PRIMITIVE_TYPE);
278
279QT_WARNING_PUSH
280// GCC isn't wrong, as groupCount is public in iterator, but we tried Q_ASSUME(),
281// right in front of the loops, and it didn't help, so we disable the warning:
282QT_WARNING_DISABLE_GCC("-Warray-bounds")
283inline QQmlListCompositor::iterator::iterator(
284 Range *range, int offset, Group group, int groupCount)
285 : range(range)
286 , offset(offset)
287 , group(group)
288 , groupFlag(1 << group)
289 , groupCount(groupCount)
290{
291 for (int i = 0; i < groupCount; ++i)
292 index[i] = 0;
293}
294
295inline void QQmlListCompositor::iterator::incrementIndexes(int difference, uint flags)
296{
297 for (int i = 0; i < groupCount; ++i) {
298 if (flags & (1 << i))
299 index[i] += difference;
300 }
301}
302
303inline void QQmlListCompositor::iterator::decrementIndexes(int difference, uint flags)
304{
305 for (int i = 0; i < groupCount; ++i) {
306 if (flags & (1 << i))
307 index[i] -= difference;
308 }
309}
310QT_WARNING_POP // -Warray-bounds
311
312inline QQmlListCompositor::insert_iterator::insert_iterator(
313 Range *range, int offset, Group group, int groupCount)
314 : iterator(range, offset, group, groupCount) {}
315
316inline QQmlListCompositor::Change::Change(const iterator &it, int count, uint flags, int moveId)
317 : count(count), flags(flags), moveId(moveId)
318{
319 for (int i = 0; i < MaximumGroupCount; ++i)
320 index[i] = it.index[i];
321}
322
323Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Group &group);
324Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Range &range);
325Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::iterator &it);
326Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Change &change);
327Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Remove &remove);
328Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Insert &insert);
329Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor &list);
330
331QT_END_NAMESPACE
332
333#endif
The QQmlListCompositor class provides a lookup table for filtered, or re-ordered list indexes.
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2568
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
#define QT_QML_VERIFY_LISTCOMPOSITOR
static QDebug qt_print_change(QDebug debug, const char *name, const QQmlListCompositor::Change &change)
static void qt_print_indexes(QDebug &debug, int count, const int *indexes)
#define QT_QML_TRACE_LISTCOMPOSITOR(args)