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
qfieldlist_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 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 QFIELDLIST_P_H
6#define QFIELDLIST_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/private/qglobal_p.h>
20#include <QtCore/qtaggedpointer.h>
21
22
23// QForwardFieldList is a super simple linked list that can only prepend
24template<class N, N *N::*nextMember, typename Tag = QtPrivate::TagInfo<N>>
26{
27public:
29 inline N *first() const;
30 inline N *takeFirst();
31
32 inline void prepend(N *);
33 template <typename OtherTag>
34 inline void copyAndClearPrepend(QForwardFieldList<N, nextMember, OtherTag> &);
35
36 inline bool isEmpty() const;
37 inline bool isOne() const;
38 inline bool isMany() const;
39
40 static inline N *next(N *v);
41
42 inline Tag tag() const;
43 inline void setTag(Tag t);
44private:
45 QTaggedPointer<N, Tag> _first;
46};
47
48// QFieldList is a simple linked list, that can append and prepend and also
49// maintains a count
50template<class N, N *N::*nextMember>
52{
53public:
54 inline QFieldList();
55 inline N *first() const;
56 inline N *takeFirst();
57
58 inline void append(N *);
59 inline void prepend(N *);
60
61 inline bool isEmpty() const;
62 inline bool isOne() const;
63 inline bool isMany() const;
64 inline int count() const;
65
66 inline void append(QFieldList<N, nextMember> &);
67 inline void prepend(QFieldList<N, nextMember> &);
68 inline void insertAfter(N *, QFieldList<N, nextMember> &);
69
70 inline void copyAndClear(QFieldList<N, nextMember> &);
71 template <typename Tag>
72 inline void copyAndClearAppend(QForwardFieldList<N, nextMember, Tag> &);
73 template <typename Tag>
74 inline void copyAndClearPrepend(QForwardFieldList<N, nextMember, Tag> &);
75
76 static inline N *next(N *v);
77
78 inline bool flag() const;
79 inline void setFlag();
80 inline void clearFlag();
81 inline void setFlagValue(bool);
82private:
83 N *_first;
84 N *_last;
85 quint32 _flag:1;
86 quint32 _count:31;
87};
88
89template<class N, N *N::*nextMember, typename Tag>
90QForwardFieldList<N, nextMember, Tag>::QForwardFieldList()
91{
92}
93
94template<class N, N *N::*nextMember, typename Tag>
95N *QForwardFieldList<N, nextMember, Tag>::first() const
96{
97 return _first.data();
98}
99
100template<class N, N *N::*nextMember, typename Tag>
101N *QForwardFieldList<N, nextMember, Tag>::takeFirst()
102{
103 N *value = _first.data();
104 if (value) {
105 _first = next(value);
106 value->*nextMember = nullptr;
107 }
108 return value;
109}
110
111template<class N, N *N::*nextMember, typename Tag>
112void QForwardFieldList<N, nextMember, Tag>::prepend(N *v)
113{
114 Q_ASSERT(v->*nextMember == nullptr);
115 v->*nextMember = _first.data();
116 _first = v;
117}
118
119template<class N, N *N::*nextMember, typename Tag>
120template <typename OtherTag>
121void QForwardFieldList<N, nextMember, Tag>::copyAndClearPrepend(QForwardFieldList<N, nextMember, OtherTag> &o)
122{
123 _first = nullptr;
124 while (N *n = o.takeFirst()) prepend(n);
125}
126
127template<class N, N *N::*nextMember, typename Tag>
128bool QForwardFieldList<N, nextMember, Tag>::isEmpty() const
129{
130 return _first.isNull();
131}
132
133template<class N, N *N::*nextMember, typename Tag>
134bool QForwardFieldList<N, nextMember, Tag>::isOne() const
135{
136 return _first.data() && _first->*nextMember == 0;
137}
138
139template<class N, N *N::*nextMember, typename Tag>
140bool QForwardFieldList<N, nextMember, Tag>::isMany() const
141{
142 return _first.data() && _first->*nextMember != 0;
143}
144
145template<class N, N *N::*nextMember, typename Tag>
146N *QForwardFieldList<N, nextMember, Tag>::next(N *v)
147{
148 Q_ASSERT(v);
149 return v->*nextMember;
150}
151
152template<class N, N *N::*nextMember, typename Tag>
153Tag QForwardFieldList<N, nextMember, Tag>::tag() const
154{
155 return _first.tag();
156}
157
158template<class N, N *N::*nextMember, typename Tag>
159void QForwardFieldList<N, nextMember, Tag>::setTag(Tag t)
160{
161 _first.setTag(t);
162}
163
164template<class N, N *N::*nextMember>
165QFieldList<N, nextMember>::QFieldList()
166: _first(nullptr), _last(nullptr), _flag(0), _count(0)
167{
168}
169
170template<class N, N *N::*nextMember>
171N *QFieldList<N, nextMember>::first() const
172{
173 return _first;
174}
175
176template<class N, N *N::*nextMember>
177N *QFieldList<N, nextMember>::takeFirst()
178{
179 N *value = _first;
180 if (value) {
181 _first = next(value);
182 if (_last == value) {
183 Q_ASSERT(_first == nullptr);
184 _last = nullptr;
185 }
186 value->*nextMember = nullptr;
187 --_count;
188 }
189 return value;
190}
191
192template<class N, N *N::*nextMember>
193void QFieldList<N, nextMember>::append(N *v)
194{
195 Q_ASSERT(v->*nextMember == nullptr);
196 if (isEmpty()) {
197 _first = v;
198 _last = v;
199 } else {
200 _last->*nextMember = v;
201 _last = v;
202 }
203 ++_count;
204}
205
206template<class N, N *N::*nextMember>
207void QFieldList<N, nextMember>::prepend(N *v)
208{
209 Q_ASSERT(v->*nextMember == nullptr);
210 if (isEmpty()) {
211 _first = v;
212 _last = v;
213 } else {
214 v->*nextMember = _first;
215 _first = v;
216 }
217 ++_count;
218}
219
220template<class N, N *N::*nextMember>
221bool QFieldList<N, nextMember>::isEmpty() const
222{
223 return _count == 0;
224}
225
226template<class N, N *N::*nextMember>
227bool QFieldList<N, nextMember>::isOne() const
228{
229 return _count == 1;
230}
231
232template<class N, N *N::*nextMember>
233bool QFieldList<N, nextMember>::isMany() const
234{
235 return _count > 1;
236}
237
238template<class N, N *N::*nextMember>
239int QFieldList<N, nextMember>::count() const
240{
241 return _count;
242}
243
244template<class N, N *N::*nextMember>
245N *QFieldList<N, nextMember>::next(N *v)
246{
247 Q_ASSERT(v);
248 return v->*nextMember;
249}
250
251template<class N, N *N::*nextMember>
252void QFieldList<N, nextMember>::append(QFieldList<N, nextMember> &o)
253{
254 if (!o.isEmpty()) {
255 if (isEmpty()) {
256 _first = o._first;
257 _last = o._last;
258 _count = o._count;
259 } else {
260 _last->*nextMember = o._first;
261 _last = o._last;
262 _count += o._count;
263 }
264 o._first = o._last = 0; o._count = 0;
265 }
266}
267
268template<class N, N *N::*nextMember>
269void QFieldList<N, nextMember>::prepend(QFieldList<N, nextMember> &o)
270{
271 if (!o.isEmpty()) {
272 if (isEmpty()) {
273 _first = o._first;
274 _last = o._last;
275 _count = o._count;
276 } else {
277 o._last->*nextMember = _first;
278 _first = o._first;
279 _count += o._count;
280 }
281 o._first = o._last = 0; o._count = 0;
282 }
283}
284
285template<class N, N *N::*nextMember>
286void QFieldList<N, nextMember>::insertAfter(N *after, QFieldList<N, nextMember> &o)
287{
288 if (after == 0) {
289 prepend(o);
290 } else if (after == _last) {
291 append(o);
292 } else if (!o.isEmpty()) {
293 if (isEmpty()) {
294 _first = o._first;
295 _last = o._last;
296 _count = o._count;
297 } else {
298 o._last->*nextMember = after->*nextMember;
299 after->*nextMember = o._first;
300 _count += o._count;
301 }
302 o._first = o._last = 0; o._count = 0;
303 }
304}
305
306template<class N, N *N::*nextMember>
307void QFieldList<N, nextMember>::copyAndClear(QFieldList<N, nextMember> &o)
308{
309 _first = o._first;
310 _last = o._last;
311 _count = o._count;
312 o._first = o._last = nullptr;
313 o._count = 0;
314}
315
316template<class N, N *N::*nextMember>
317template <typename Tag>
318void QFieldList<N, nextMember>::copyAndClearAppend(QForwardFieldList<N, nextMember, Tag> &o)
319{
320 _first = 0;
321 _last = 0;
322 _count = 0;
323 while (N *n = o.takeFirst()) append(n);
324}
325
326template<class N, N *N::*nextMember>
327template <typename Tag>
328void QFieldList<N, nextMember>::copyAndClearPrepend(QForwardFieldList<N, nextMember, Tag> &o)
329{
330 _first = nullptr;
331 _last = nullptr;
332 _count = 0;
333 while (N *n = o.takeFirst()) prepend(n);
334}
335
336template<class N, N *N::*nextMember>
337bool QFieldList<N, nextMember>::flag() const
338{
339 return _flag;
340}
341
342template<class N, N *N::*nextMember>
343void QFieldList<N, nextMember>::setFlag()
344{
345 _flag = true;
346}
347
348template<class N, N *N::*nextMember>
349void QFieldList<N, nextMember>::clearFlag()
350{
351 _flag = false;
352}
353
354template<class N, N *N::*nextMember>
355void QFieldList<N, nextMember>::setFlagValue(bool v)
356{
357 _flag = v;
358}
359
360#endif // QFIELDLIST_P_H
void clearFlag()
void setFlagValue(bool)
static N * next(N *v)
N * first() const
void copyAndClearPrepend(QForwardFieldList< N, nextMember, Tag > &)
int count() const
void prepend(N *)
void insertAfter(N *, QFieldList< N, nextMember > &)
void append(N *)
bool isOne() const
void setFlag()
void copyAndClear(QFieldList< N, nextMember > &)
bool isMany() const
bool flag() const
bool isEmpty() const
void append(QFieldList< N, nextMember > &)
void copyAndClearAppend(QForwardFieldList< N, nextMember, Tag > &)
void prepend(QFieldList< N, nextMember > &)
N * takeFirst()
void setTag(Tag t)
void copyAndClearPrepend(QForwardFieldList< N, nextMember, OtherTag > &)
bool isOne() const
static N * next(N *v)
bool isMany() const
bool isEmpty() const
N * first() const