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> |

128 | QForwardFieldList<N, nextMember>::QForwardFieldList() |

129 | { |

130 | } |

131 | |

132 | template<class N, N *N::*nextMember> |

133 | N *QForwardFieldList<N, nextMember>::first() const |

134 | { |

135 | return *_first; |

136 | } |

137 | |

138 | template<class N, N *N::*nextMember> |

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> |

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> |

158 | bool QForwardFieldList<N, nextMember>::isEmpty() const |

159 | { |

160 | return _first.isNull(); |

161 | } |

162 | |

163 | template<class N, N *N::*nextMember> |

164 | bool QForwardFieldList<N, nextMember>::isOne() const |

165 | { |

166 | return *_first && _first->*nextMember == 0; |

167 | } |

168 | |

169 | template<class N, N *N::*nextMember> |

170 | bool QForwardFieldList<N, nextMember>::isMany() const |

171 | { |

172 | return *_first && _first->*nextMember != 0; |

173 | } |

174 | |

175 | template<class N, N *N::*nextMember> |

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> |

183 | bool QForwardFieldList<N, nextMember>::flag() const |

184 | { |

185 | return _first.flag(); |

186 | } |

187 | |

188 | template<class N, N *N::*nextMember> |

189 | void QForwardFieldList<N, nextMember>::setFlag() |

190 | { |

191 | _first.setFlag(); |

192 | } |

193 | |

194 | template<class N, N *N::*nextMember> |

195 | void QForwardFieldList<N, nextMember>::clearFlag() |

196 | { |

197 | _first.clearFlag(); |

198 | } |

199 | |

200 | template<class N, N *N::*nextMember> |

201 | void QForwardFieldList<N, nextMember>::setFlagValue(bool v) |

202 | { |

203 | _first.setFlagValue(v); |

204 | } |

205 | |

206 | template<class N, N *N::*nextMember> |

207 | bool QForwardFieldList<N, nextMember>::flag2() const |

208 | { |

209 | return _first.flag2(); |

210 | } |

211 | |

212 | template<class N, N *N::*nextMember> |

213 | void QForwardFieldList<N, nextMember>::setFlag2() |

214 | { |

215 | _first.setFlag2(); |

216 | } |

217 | |

218 | template<class N, N *N::*nextMember> |

219 | void QForwardFieldList<N, nextMember>::clearFlag2() |

220 | { |

221 | _first.clearFlag2(); |

222 | } |

223 | |

224 | template<class N, N *N::*nextMember> |

225 | void QForwardFieldList<N, nextMember>::setFlag2Value(bool v) |

226 | { |

227 | _first.setFlag2Value(v); |

228 | } |

229 | |

230 | template<class N, N *N::*nextMember> |

231 | QFieldList<N, nextMember>::QFieldList() |

232 | : _first(nullptr), _last(nullptr), _flag(0), _count(0) |

233 | { |

234 | } |

235 | |

236 | template<class N, N *N::*nextMember> |

237 | N *QFieldList<N, nextMember>::first() const |

238 | { |

239 | return _first; |

240 | } |

241 | |

242 | template<class N, N *N::*nextMember> |

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> |

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> |

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> |

287 | bool QFieldList<N, nextMember>::isEmpty() const |

288 | { |

289 | return _count == 0; |

290 | } |

291 | |

292 | template<class N, N *N::*nextMember> |

293 | bool QFieldList<N, nextMember>::isOne() const |

294 | { |

295 | return _count == 1; |

296 | } |

297 | |

298 | template<class N, N *N::*nextMember> |

299 | bool QFieldList<N, nextMember>::isMany() const |

300 | { |

301 | return _count > 1; |

302 | } |

303 | |

304 | template<class N, N *N::*nextMember> |

305 | int QFieldList<N, nextMember>::count() const |

306 | { |

307 | return _count; |

308 | } |

309 | |

310 | template<class N, N *N::*nextMember> |

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> |

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> |

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> |

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> |

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> |

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> |

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> |

401 | bool QFieldList<N, nextMember>::flag() const |

402 | { |

403 | return _flag; |

404 | } |

405 | |

406 | template<class N, N *N::*nextMember> |

407 | void QFieldList<N, nextMember>::setFlag() |

408 | { |

409 | _flag = true; |

410 | } |

411 | |

412 | template<class N, N *N::*nextMember> |

413 | void QFieldList<N, nextMember>::clearFlag() |

414 | { |

415 | _flag = false; |

416 | } |

417 | |

418 | template<class N, N *N::*nextMember> |

419 | void QFieldList<N, nextMember>::setFlagValue(bool v) |

420 | { |

421 | _flag = v; |

422 | } |

423 | |

424 | #endif // QFIELDLIST_P_H |

425 |