1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #ifndef QFIELDLIST_P_H
41 #define QFIELDLIST_P_H
42
43 //
44 // W A R N I N G
45 // -------------
46 //
47 // This file is not part of the Qt API. It exists purely as an
48 // implementation detail. This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53
54 #include <QtCore/qglobal.h>
55
56 #include <private/qflagpointer_p.h>
57
58 // QForwardFieldList is a super simple linked list that can only prepend
59 template<class N, N *N::*nextMember>
60 class QForwardFieldList
61 {
62 public:
63 inline QForwardFieldList();
64 inline N *first() const;
65 inline N *takeFirst();
66
67 inline void prepend(N *);
68
69 inline bool isEmpty() const;
70 inline bool isOne() const;
71 inline bool isMany() const;
72
73 static inline N *next(N *v);
74
75 inline bool flag() const;
76 inline void setFlag();
77 inline void clearFlag();
78 inline void setFlagValue(bool);
79
80 inline bool flag2() const;
81 inline void setFlag2();
82 inline void clearFlag2();
83 inline void setFlag2Value(bool);
84 private:
85 QFlagPointer<N> _first;
86 };
87
88 // QFieldList is a simple linked list, that can append and prepend and also
89 // maintains a count
90 template<class N, N *N::*nextMember>
91 class QFieldList
92 {
93 public:
94 inline QFieldList();
95 inline N *first() const;
96 inline N *takeFirst();
97
98 inline void append(N *);
99 inline void prepend(N *);
100
101 inline bool isEmpty() const;
102 inline bool isOne() const;
103 inline bool isMany() const;
104 inline int count() const;
105
106 inline void append(QFieldList<N, nextMember> &);
107 inline void prepend(QFieldList<N, nextMember> &);
108 inline void insertAfter(N *, QFieldList<N, nextMember> &);
109
110 inline void copyAndClear(QFieldList<N, nextMember> &);
111 inline void copyAndClearAppend(QForwardFieldList<N, nextMember> &);
112 inline void copyAndClearPrepend(QForwardFieldList<N, nextMember> &);
113
114 static inline N *next(N *v);
115
116 inline bool flag() const;
117 inline void setFlag();
118 inline void clearFlag();
119 inline void setFlagValue(bool);
120 private:
121 N *_first;
122 N *_last;
123 quint32 _flag:1;
124 quint32 _count:31;
125 };
126
127 template<class N, N *N::*nextMember>
QForwardFieldList()128 QForwardFieldList<N, nextMember>::QForwardFieldList()
129 {
130 }
131
132 template<class N, N *N::*nextMember>
first()133 N *QForwardFieldList<N, nextMember>::first() const
134 {
135 return *_first;
136 }
137
138 template<class N, N *N::*nextMember>
takeFirst()139 N *QForwardFieldList<N, nextMember>::takeFirst()
140 {
141 N *value = *_first;
142 if (value) {
143 _first = next(value);
144 value->*nextMember = nullptr;
145 }
146 return value;
147 }
148
149 template<class N, N *N::*nextMember>
prepend(N * v)150 void QForwardFieldList<N, nextMember>::prepend(N *v)
151 {
152 Q_ASSERT(v->*nextMember == nullptr);
153 v->*nextMember = *_first;
154 _first = v;
155 }
156
157 template<class N, N *N::*nextMember>
isEmpty()158 bool QForwardFieldList<N, nextMember>::isEmpty() const
159 {
160 return _first.isNull();
161 }
162
163 template<class N, N *N::*nextMember>
isOne()164 bool QForwardFieldList<N, nextMember>::isOne() const
165 {
166 return *_first && _first->*nextMember == 0;
167 }
168
169 template<class N, N *N::*nextMember>
isMany()170 bool QForwardFieldList<N, nextMember>::isMany() const
171 {
172 return *_first && _first->*nextMember != 0;
173 }
174
175 template<class N, N *N::*nextMember>
next(N * v)176 N *QForwardFieldList<N, nextMember>::next(N *v)
177 {
178 Q_ASSERT(v);
179 return v->*nextMember;
180 }
181
182 template<class N, N *N::*nextMember>
flag()183 bool QForwardFieldList<N, nextMember>::flag() const
184 {
185 return _first.flag();
186 }
187
188 template<class N, N *N::*nextMember>
setFlag()189 void QForwardFieldList<N, nextMember>::setFlag()
190 {
191 _first.setFlag();
192 }
193
194 template<class N, N *N::*nextMember>
clearFlag()195 void QForwardFieldList<N, nextMember>::clearFlag()
196 {
197 _first.clearFlag();
198 }
199
200 template<class N, N *N::*nextMember>
setFlagValue(bool v)201 void QForwardFieldList<N, nextMember>::setFlagValue(bool v)
202 {
203 _first.setFlagValue(v);
204 }
205
206 template<class N, N *N::*nextMember>
flag2()207 bool QForwardFieldList<N, nextMember>::flag2() const
208 {
209 return _first.flag2();
210 }
211
212 template<class N, N *N::*nextMember>
setFlag2()213 void QForwardFieldList<N, nextMember>::setFlag2()
214 {
215 _first.setFlag2();
216 }
217
218 template<class N, N *N::*nextMember>
clearFlag2()219 void QForwardFieldList<N, nextMember>::clearFlag2()
220 {
221 _first.clearFlag2();
222 }
223
224 template<class N, N *N::*nextMember>
setFlag2Value(bool v)225 void QForwardFieldList<N, nextMember>::setFlag2Value(bool v)
226 {
227 _first.setFlag2Value(v);
228 }
229
230 template<class N, N *N::*nextMember>
QFieldList()231 QFieldList<N, nextMember>::QFieldList()
232 : _first(nullptr), _last(nullptr), _flag(0), _count(0)
233 {
234 }
235
236 template<class N, N *N::*nextMember>
first()237 N *QFieldList<N, nextMember>::first() const
238 {
239 return _first;
240 }
241
242 template<class N, N *N::*nextMember>
takeFirst()243 N *QFieldList<N, nextMember>::takeFirst()
244 {
245 N *value = _first;
246 if (value) {
247 _first = next(value);
248 if (_last == value) {
249 Q_ASSERT(_first == nullptr);
250 _last = nullptr;
251 }
252 value->*nextMember = nullptr;
253 --_count;
254 }
255 return value;
256 }
257
258 template<class N, N *N::*nextMember>
append(N * v)259 void QFieldList<N, nextMember>::append(N *v)
260 {
261 Q_ASSERT(v->*nextMember == nullptr);
262 if (isEmpty()) {
263 _first = v;
264 _last = v;
265 } else {
266 _last->*nextMember = v;
267 _last = v;
268 }
269 ++_count;
270 }
271
272 template<class N, N *N::*nextMember>
prepend(N * v)273 void QFieldList<N, nextMember>::prepend(N *v)
274 {
275 Q_ASSERT(v->*nextMember == nullptr);
276 if (isEmpty()) {
277 _first = v;
278 _last = v;
279 } else {
280 v->*nextMember = _first;
281 _first = v;
282 }
283 ++_count;
284 }
285
286 template<class N, N *N::*nextMember>
isEmpty()287 bool QFieldList<N, nextMember>::isEmpty() const
288 {
289 return _count == 0;
290 }
291
292 template<class N, N *N::*nextMember>
isOne()293 bool QFieldList<N, nextMember>::isOne() const
294 {
295 return _count == 1;
296 }
297
298 template<class N, N *N::*nextMember>
isMany()299 bool QFieldList<N, nextMember>::isMany() const
300 {
301 return _count > 1;
302 }
303
304 template<class N, N *N::*nextMember>
count()305 int QFieldList<N, nextMember>::count() const
306 {
307 return _count;
308 }
309
310 template<class N, N *N::*nextMember>
next(N * v)311 N *QFieldList<N, nextMember>::next(N *v)
312 {
313 Q_ASSERT(v);
314 return v->*nextMember;
315 }
316
317 template<class N, N *N::*nextMember>
append(QFieldList<N,nextMember> & o)318 void QFieldList<N, nextMember>::append(QFieldList<N, nextMember> &o)
319 {
320 if (!o.isEmpty()) {
321 if (isEmpty()) {
322 _first = o._first;
323 _last = o._last;
324 _count = o._count;
325 } else {
326 _last->*nextMember = o._first;
327 _last = o._last;
328 _count += o._count;
329 }
330 o._first = o._last = 0; o._count = 0;
331 }
332 }
333
334 template<class N, N *N::*nextMember>
prepend(QFieldList<N,nextMember> & o)335 void QFieldList<N, nextMember>::prepend(QFieldList<N, nextMember> &o)
336 {
337 if (!o.isEmpty()) {
338 if (isEmpty()) {
339 _first = o._first;
340 _last = o._last;
341 _count = o._count;
342 } else {
343 o._last->*nextMember = _first;
344 _first = o._first;
345 _count += o._count;
346 }
347 o._first = o._last = 0; o._count = 0;
348 }
349 }
350
351 template<class N, N *N::*nextMember>
insertAfter(N * after,QFieldList<N,nextMember> & o)352 void QFieldList<N, nextMember>::insertAfter(N *after, QFieldList<N, nextMember> &o)
353 {
354 if (after == 0) {
355 prepend(o);
356 } else if (after == _last) {
357 append(o);
358 } else if (!o.isEmpty()) {
359 if (isEmpty()) {
360 _first = o._first;
361 _last = o._last;
362 _count = o._count;
363 } else {
364 o._last->*nextMember = after->*nextMember;
365 after->*nextMember = o._first;
366 _count += o._count;
367 }
368 o._first = o._last = 0; o._count = 0;
369 }
370 }
371
372 template<class N, N *N::*nextMember>
copyAndClear(QFieldList<N,nextMember> & o)373 void QFieldList<N, nextMember>::copyAndClear(QFieldList<N, nextMember> &o)
374 {
375 _first = o._first;
376 _last = o._last;
377 _count = o._count;
378 o._first = o._last = nullptr;
379 o._count = 0;
380 }
381
382 template<class N, N *N::*nextMember>
copyAndClearAppend(QForwardFieldList<N,nextMember> & o)383 void QFieldList<N, nextMember>::copyAndClearAppend(QForwardFieldList<N, nextMember> &o)
384 {
385 _first = 0;
386 _last = 0;
387 _count = 0;
388 while (N *n = o.takeFirst()) append(n);
389 }
390
391 template<class N, N *N::*nextMember>
copyAndClearPrepend(QForwardFieldList<N,nextMember> & o)392 void QFieldList<N, nextMember>::copyAndClearPrepend(QForwardFieldList<N, nextMember> &o)
393 {
394 _first = nullptr;
395 _last = nullptr;
396 _count = 0;
397 while (N *n = o.takeFirst()) prepend(n);
398 }
399
400 template<class N, N *N::*nextMember>
flag()401 bool QFieldList<N, nextMember>::flag() const
402 {
403 return _flag;
404 }
405
406 template<class N, N *N::*nextMember>
setFlag()407 void QFieldList<N, nextMember>::setFlag()
408 {
409 _flag = true;
410 }
411
412 template<class N, N *N::*nextMember>
clearFlag()413 void QFieldList<N, nextMember>::clearFlag()
414 {
415 _flag = false;
416 }
417
418 template<class N, N *N::*nextMember>
setFlagValue(bool v)419 void QFieldList<N, nextMember>::setFlagValue(bool v)
420 {
421 _flag = v;
422 }
423
424 #endif // QFIELDLIST_P_H
425