1// Copyright (C) 2022 Intel Corporation.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QCBORARRAY_H
5#define QCBORARRAY_H
6
7#include <QtCore/qcborvalue.h>
8
9#include <initializer_list>
10
11QT_BEGIN_NAMESPACE
12
13class QJsonArray;
14class QDataStream;
15
16namespace QJsonPrivate { class Variant; }
17
18class QCborContainerPrivate;
19class Q_CORE_EXPORT QCborArray
20{
21public:
22 class ConstIterator;
23 class Iterator {
24 QCborValueRef item {};
25 friend class ConstIterator;
26 friend class QCborArray;
27 Iterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
28 public:
29 typedef std::random_access_iterator_tag iterator_category;
30 typedef qsizetype difference_type;
31 typedef QCborValue value_type;
32 typedef QCborValueRef reference;
33 typedef QCborValueRef *pointer;
34
35 constexpr Iterator() = default;
36 constexpr Iterator(const Iterator &) = default;
37 Iterator &operator=(const Iterator &other)
38 {
39 // rebind the reference
40 item.d = other.item.d;
41 item.i = other.item.i;
42 return *this;
43 }
44
45 QCborValueRef operator*() const { return item; }
46 QCborValueRef *operator->() { return &item; }
47 const QCborValueConstRef *operator->() const { return &item; }
48 QCborValueRef operator[](qsizetype j) const { return { item.d, item.i + j }; }
49#if QT_CORE_REMOVED_SINCE(6, 8)
50 bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
51 bool operator!=(const Iterator &o) const { return !operator==(o); }
52 bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
53 bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
54 bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
55 bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
56 bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
57 bool operator!=(const ConstIterator &o) const { return !operator==(o); }
58 bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
59 bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
60 bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
61 bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
62#endif
63 Iterator &operator++() { ++item.i; return *this; }
64 Iterator operator++(int) { Iterator n = *this; ++item.i; return n; }
65 Iterator &operator--() { item.i--; return *this; }
66 Iterator operator--(int) { Iterator n = *this; item.i--; return n; }
67 Iterator &operator+=(qsizetype j) { item.i += j; return *this; }
68 Iterator &operator-=(qsizetype j) { item.i -= j; return *this; }
69 Iterator operator+(qsizetype j) const { return Iterator({ item.d, item.i + j }); }
70 Iterator operator-(qsizetype j) const { return Iterator({ item.d, item.i - j }); }
71 qsizetype operator-(Iterator j) const { return item.i - j.item.i; }
72 private:
73 // Helper functions
74 static bool comparesEqual_helper(const Iterator &lhs, const Iterator &rhs) noexcept
75 {
76 return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i;
77 }
78
79 static bool comparesEqual_helper(const Iterator &lhs, const ConstIterator &rhs) noexcept
80 {
81 return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i;
82 }
83
84 static Qt::strong_ordering compareThreeWay_helper(const Iterator &lhs,
85 const Iterator &rhs) noexcept
86 {
87 Q_ASSERT(lhs.item.d == rhs.item.d);
88 return Qt::compareThreeWay(lhs: lhs.item.i, rhs: rhs.item.i);
89 }
90
91 static Qt::strong_ordering compareThreeWay_helper(const Iterator &lhs,
92 const ConstIterator &rhs) noexcept
93 {
94 Q_ASSERT(lhs.item.d == rhs.item.d);
95 return Qt::compareThreeWay(lhs: lhs.item.i, rhs: rhs.item.i);
96 }
97
98 // Compare friends
99 friend bool comparesEqual(const Iterator &lhs, const Iterator &rhs) noexcept
100 {
101 return comparesEqual_helper(lhs, rhs);
102 }
103 friend Qt::strong_ordering compareThreeWay(const Iterator &lhs,
104 const Iterator &rhs) noexcept
105 {
106 return compareThreeWay_helper(lhs, rhs);
107 }
108 Q_DECLARE_STRONGLY_ORDERED(Iterator)
109 friend bool comparesEqual(const Iterator &lhs, const ConstIterator &rhs) noexcept
110 {
111 return comparesEqual_helper(lhs, rhs);
112 }
113 friend Qt::strong_ordering compareThreeWay(const Iterator &lhs,
114 const ConstIterator &rhs) noexcept
115 {
116 return compareThreeWay_helper(lhs, rhs);
117 }
118 Q_DECLARE_STRONGLY_ORDERED(Iterator, ConstIterator)
119 };
120
121 class ConstIterator {
122 QCborValueConstRef item;
123 friend class Iterator;
124 friend class QCborArray;
125 ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
126 public:
127 typedef std::random_access_iterator_tag iterator_category;
128 typedef qsizetype difference_type;
129 typedef const QCborValue value_type;
130 typedef const QCborValueRef reference;
131 typedef const QCborValueRef *pointer;
132
133 constexpr ConstIterator() = default;
134 constexpr ConstIterator(const ConstIterator &) = default;
135 ConstIterator &operator=(const ConstIterator &other)
136 {
137 // rebind the reference
138 item.d = other.item.d;
139 item.i = other.item.i;
140 return *this;
141 }
142
143 QCborValueConstRef operator*() const { return item; }
144 const QCborValueConstRef *operator->() const { return &item; }
145 QCborValueConstRef operator[](qsizetype j) const { return QCborValueRef{ item.d, item.i + j }; }
146#if QT_CORE_REMOVED_SINCE(6, 8)
147 bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
148 bool operator!=(const Iterator &o) const { return !operator==(o); }
149 bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
150 bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
151 bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
152 bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
153 bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
154 bool operator!=(const ConstIterator &o) const { return !operator==(o); }
155 bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
156 bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
157 bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
158 bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
159#endif
160 ConstIterator &operator++() { ++item.i; return *this; }
161 ConstIterator operator++(int) { ConstIterator n = *this; ++item.i; return n; }
162 ConstIterator &operator--() { item.i--; return *this; }
163 ConstIterator operator--(int) { ConstIterator n = *this; item.i--; return n; }
164 ConstIterator &operator+=(qsizetype j) { item.i += j; return *this; }
165 ConstIterator &operator-=(qsizetype j) { item.i -= j; return *this; }
166 ConstIterator operator+(qsizetype j) const { return ConstIterator({ item.d, item.i + j }); }
167 ConstIterator operator-(qsizetype j) const { return ConstIterator({ item.d, item.i - j }); }
168 qsizetype operator-(ConstIterator j) const { return item.i - j.item.i; }
169 private:
170 // Helper functions
171 static bool comparesEqual_helper(const ConstIterator &lhs,
172 const ConstIterator &rhs) noexcept
173 {
174 return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i;
175 }
176 static Qt::strong_ordering compareThreeWay_helper(const ConstIterator &lhs,
177 const ConstIterator &rhs) noexcept
178 {
179 Q_ASSERT(lhs.item.d == rhs.item.d);
180 return Qt::compareThreeWay(lhs: lhs.item.i, rhs: rhs.item.i);
181 }
182
183 // Compare friends
184 friend bool comparesEqual(const ConstIterator &lhs, const ConstIterator &rhs) noexcept
185 {
186 return comparesEqual_helper(lhs, rhs);
187 }
188 friend Qt::strong_ordering compareThreeWay(const ConstIterator &lhs,
189 const ConstIterator &rhs) noexcept
190 {
191 return compareThreeWay_helper(lhs, rhs);
192 }
193 Q_DECLARE_STRONGLY_ORDERED(ConstIterator)
194 };
195
196 typedef qsizetype size_type;
197 typedef QCborValue value_type;
198 typedef value_type *pointer;
199 typedef const value_type *const_pointer;
200 typedef QCborValue &reference;
201 typedef const QCborValue &const_reference;
202 typedef qsizetype difference_type;
203
204 QCborArray() noexcept;
205 QCborArray(const QCborArray &other) noexcept;
206 QCborArray &operator=(const QCborArray &other) noexcept;
207 QCborArray(std::initializer_list<QCborValue> args)
208 : QCborArray()
209 {
210 detach(reserve: qsizetype(args.size()));
211 for (const QCborValue &v : args)
212 append(value: v);
213 }
214 ~QCborArray();
215
216 void swap(QCborArray &other) noexcept
217 {
218 d.swap(other&: other.d);
219 }
220
221 QCborValue toCborValue() const { return *this; }
222
223 qsizetype size() const noexcept;
224 bool isEmpty() const { return size() == 0; }
225 void clear();
226
227 QCborValue at(qsizetype i) const;
228 QCborValue first() const { return at(i: 0); }
229 QCborValue last() const { return at(i: size() - 1); }
230 const QCborValue operator[](qsizetype i) const { return at(i); }
231 QCborValueRef first() { Q_ASSERT(!isEmpty()); return begin()[0]; }
232 QCborValueRef last() { Q_ASSERT(!isEmpty()); return begin()[size() - 1]; }
233 QCborValueRef operator[](qsizetype i)
234 {
235 if (i >= size())
236 insert(i, value: QCborValue());
237 return begin()[i];
238 }
239
240 void insert(qsizetype i, const QCborValue &value);
241 void insert(qsizetype i, QCborValue &&value);
242 void prepend(const QCborValue &value) { insert(i: 0, value); }
243 void prepend(QCborValue &&value) { insert(i: 0, value: std::move(value)); }
244 void append(const QCborValue &value) { insert(i: -1, value); }
245 void append(QCborValue &&value) { insert(i: -1, value: std::move(value)); }
246 QCborValue extract(ConstIterator it) { return extract(it: Iterator{ it.item.d, it.item.i }); }
247 QCborValue extract(Iterator it);
248 void removeAt(qsizetype i);
249 QCborValue takeAt(qsizetype i) { Q_ASSERT(i < size()); return extract(it: begin() + i); }
250 void removeFirst() { removeAt(i: 0); }
251 void removeLast() { removeAt(i: size() - 1); }
252 QCborValue takeFirst() { return takeAt(i: 0); }
253 QCborValue takeLast() { return takeAt(i: size() - 1); }
254
255 bool contains(const QCborValue &value) const;
256
257 int compare(const QCborArray &other) const noexcept Q_DECL_PURE_FUNCTION;
258#if QT_CORE_REMOVED_SINCE(6, 8)
259 bool operator==(const QCborArray &other) const noexcept
260 { return compare(other) == 0; }
261 bool operator!=(const QCborArray &other) const noexcept
262 { return !operator==(other); }
263 bool operator<(const QCborArray &other) const
264 { return compare(other) < 0; }
265#endif
266
267 typedef Iterator iterator;
268 typedef ConstIterator const_iterator;
269 iterator begin() { detach(); return iterator{d.data(), 0}; }
270 const_iterator constBegin() const { return const_iterator{d.data(), 0}; }
271 const_iterator begin() const { return constBegin(); }
272 const_iterator cbegin() const { return constBegin(); }
273 iterator end() { detach(); return iterator{d.data(), size()}; }
274 const_iterator constEnd() const { return const_iterator{d.data(), size()}; }
275 const_iterator end() const { return constEnd(); }
276 const_iterator cend() const { return constEnd(); }
277 iterator insert(iterator before, const QCborValue &value)
278 { insert(i: before.item.i, value); return iterator{d.data(), before.item.i}; }
279 iterator insert(const_iterator before, const QCborValue &value)
280 { insert(i: before.item.i, value); return iterator{d.data(), before.item.i}; }
281 iterator erase(iterator it) { removeAt(i: it.item.i); return iterator{d.data(), it.item.i}; }
282 iterator erase(const_iterator it) { removeAt(i: it.item.i); return iterator{d.data(), it.item.i}; }
283
284 void push_back(const QCborValue &t) { append(value: t); }
285 void push_front(const QCborValue &t) { prepend(value: t); }
286 void pop_front() { removeFirst(); }
287 void pop_back() { removeLast(); }
288 bool empty() const { return isEmpty(); }
289
290 // convenience
291 QCborArray operator+(const QCborValue &v) const
292 { QCborArray n = *this; n += v; return n; }
293 QCborArray &operator+=(const QCborValue &v)
294 { append(value: v); return *this; }
295 QCborArray &operator<<(const QCborValue &v)
296 { append(value: v); return *this; }
297
298 static QCborArray fromStringList(const QStringList &list);
299 static QCborArray fromVariantList(const QVariantList &list);
300 static QCborArray fromJsonArray(const QJsonArray &array);
301 static QCborArray fromJsonArray(QJsonArray &&array) noexcept;
302 QVariantList toVariantList() const;
303 QJsonArray toJsonArray() const;
304
305private:
306 friend Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool
307 comparesEqual(const QCborArray &lhs, const QCborArray &rhs) noexcept;
308 friend Qt::strong_ordering compareThreeWay(const QCborArray &lhs,
309 const QCborArray &rhs) noexcept
310 {
311 int c = lhs.compare(other: rhs);
312 return Qt::compareThreeWay(lhs: c, rhs: 0);
313 }
314 Q_DECLARE_STRONGLY_ORDERED(QCborArray)
315
316 static Q_DECL_PURE_FUNCTION bool
317 comparesEqual_helper(const QCborArray &lhs, const QCborValue &rhs) noexcept;
318 static Q_DECL_PURE_FUNCTION Qt::strong_ordering
319 compareThreeWay_helper(const QCborArray &lhs, const QCborValue &rhs) noexcept;
320 friend bool comparesEqual(const QCborArray &lhs,
321 const QCborValue &rhs) noexcept
322 {
323 return comparesEqual_helper(lhs, rhs);
324 }
325 friend Qt::strong_ordering compareThreeWay(const QCborArray &lhs,
326 const QCborValue &rhs) noexcept
327 {
328 return compareThreeWay_helper(lhs, rhs);
329 }
330 Q_DECLARE_STRONGLY_ORDERED(QCborArray, QCborValue)
331
332 static Q_DECL_PURE_FUNCTION bool
333 comparesEqual_helper(const QCborArray &lhs, QCborValueConstRef rhs) noexcept;
334 static Q_DECL_PURE_FUNCTION Qt::strong_ordering
335 compareThreeWay_helper(const QCborArray &lhs, QCborValueConstRef rhs) noexcept;
336 friend bool comparesEqual(const QCborArray &lhs,
337 const QCborValueConstRef &rhs) noexcept
338 {
339 return comparesEqual_helper(lhs, rhs);
340 }
341 friend Qt::strong_ordering compareThreeWay(const QCborArray &lhs,
342 const QCborValueConstRef &rhs) noexcept
343 {
344 return compareThreeWay_helper(lhs, rhs);
345 }
346 Q_DECLARE_STRONGLY_ORDERED(QCborArray, QCborValueConstRef)
347
348 void detach(qsizetype reserve = 0);
349
350 friend QCborValue;
351 friend QCborValueRef;
352 friend class QJsonPrivate::Variant;
353 explicit QCborArray(QCborContainerPrivate &dd) noexcept;
354 QExplicitlySharedDataPointer<QCborContainerPrivate> d;
355};
356
357Q_DECLARE_SHARED(QCborArray)
358
359inline QCborValue::QCborValue(QCborArray &&a)
360 : n(-1), container(a.d.take()), t(Array)
361{
362}
363
364#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
365inline QCborArray QCborValueRef::toArray() const
366{
367 return concrete().toArray();
368}
369
370inline QCborArray QCborValueRef::toArray(const QCborArray &a) const
371{
372 return concrete().toArray(defaultValue: a);
373}
374#endif
375
376inline QCborArray QCborValueConstRef::toArray() const
377{
378 return concrete().toArray();
379}
380
381inline QCborArray QCborValueConstRef::toArray(const QCborArray &a) const
382{
383 return concrete().toArray(defaultValue: a);
384}
385
386Q_CORE_EXPORT size_t qHash(const QCborArray &array, size_t seed = 0);
387
388#if !defined(QT_NO_DEBUG_STREAM)
389Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a);
390#endif
391
392#ifndef QT_NO_DATASTREAM
393#if QT_CONFIG(cborstreamwriter)
394Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QCborArray &);
395#endif
396Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QCborArray &);
397#endif
398
399QT_END_NAMESPACE
400
401#endif // QCBORARRAY_H
402

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/serialization/qcborarray.h