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
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 !(*this == 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 !(*this == 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 Iterator &operator++() { ++item.i; return *this; }
63 Iterator operator++(int) { Iterator n = *this; ++item.i; return n; }
64 Iterator &operator--() { item.i--; return *this; }
65 Iterator operator--(int) { Iterator n = *this; item.i--; return n; }
66 Iterator &operator+=(qsizetype j) { item.i += j; return *this; }
67 Iterator &operator-=(qsizetype j) { item.i -= j; return *this; }
68 Iterator operator+(qsizetype j) const { return Iterator({ item.d, item.i + j }); }
69 Iterator operator-(qsizetype j) const { return Iterator({ item.d, item.i - j }); }
70 qsizetype operator-(Iterator j) const { return item.i - j.item.i; }
71 };
72
73 class ConstIterator {
74 QCborValueConstRef item;
75 friend class Iterator;
76 friend class QCborArray;
77 ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
78 public:
79 typedef std::random_access_iterator_tag iterator_category;
80 typedef qsizetype difference_type;
81 typedef const QCborValue value_type;
82 typedef const QCborValueRef reference;
83 typedef const QCborValueRef *pointer;
84
85 constexpr ConstIterator() = default;
86 constexpr ConstIterator(const ConstIterator &) = default;
87 ConstIterator &operator=(const ConstIterator &other)
88 {
89 // rebind the reference
90 item.d = other.item.d;
91 item.i = other.item.i;
92 return *this;
93 }
94
95 QCborValueConstRef operator*() const { return item; }
96 const QCborValueConstRef *operator->() const { return &item; }
97 QCborValueConstRef operator[](qsizetype j) const { return QCborValueRef{ item.d, item.i + j }; }
98
99 bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
100 bool operator!=(const Iterator &o) const { return !(*this == o); }
101 bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
102 bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
103 bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
104 bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
105 bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
106 bool operator!=(const ConstIterator &o) const { return !(*this == o); }
107 bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
108 bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
109 bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
110 bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
111 ConstIterator &operator++() { ++item.i; return *this; }
112 ConstIterator operator++(int) { ConstIterator n = *this; ++item.i; return n; }
113 ConstIterator &operator--() { item.i--; return *this; }
114 ConstIterator operator--(int) { ConstIterator n = *this; item.i--; return n; }
115 ConstIterator &operator+=(qsizetype j) { item.i += j; return *this; }
116 ConstIterator &operator-=(qsizetype j) { item.i -= j; return *this; }
117 ConstIterator operator+(qsizetype j) const { return ConstIterator({ item.d, item.i + j }); }
118 ConstIterator operator-(qsizetype j) const { return ConstIterator({ item.d, item.i - j }); }
119 qsizetype operator-(ConstIterator j) const { return item.i - j.item.i; }
120 };
121
122 typedef qsizetype size_type;
123 typedef QCborValue value_type;
124 typedef value_type *pointer;
125 typedef const value_type *const_pointer;
126 typedef QCborValue &reference;
127 typedef const QCborValue &const_reference;
128 typedef qsizetype difference_type;
129
130 QCborArray() noexcept;
131 QCborArray(const QCborArray &other) noexcept;
132 QCborArray &operator=(const QCborArray &other) noexcept;
133 QCborArray(std::initializer_list<QCborValue> args)
134 : QCborArray()
135 {
136 detach(reserve: qsizetype(args.size()));
137 for (const QCborValue &v : args)
138 append(value: v);
139 }
140 ~QCborArray();
141
142 void swap(QCborArray &other) noexcept
143 {
144 d.swap(other&: other.d);
145 }
146
147 QCborValue toCborValue() const { return *this; }
148
149 qsizetype size() const noexcept;
150 bool isEmpty() const { return size() == 0; }
151 void clear();
152
153 QCborValue at(qsizetype i) const;
154 QCborValue first() const { return at(i: 0); }
155 QCborValue last() const { return at(i: size() - 1); }
156 const QCborValue operator[](qsizetype i) const { return at(i); }
157 QCborValueRef first() { Q_ASSERT(!isEmpty()); return begin()[0]; }
158 QCborValueRef last() { Q_ASSERT(!isEmpty()); return begin()[size() - 1]; }
159 QCborValueRef operator[](qsizetype i)
160 {
161 if (i >= size())
162 insert(i, value: QCborValue());
163 return begin()[i];
164 }
165
166 void insert(qsizetype i, const QCborValue &value);
167 void insert(qsizetype i, QCborValue &&value);
168 void prepend(const QCborValue &value) { insert(i: 0, value); }
169 void prepend(QCborValue &&value) { insert(i: 0, value: std::move(value)); }
170 void append(const QCborValue &value) { insert(i: -1, value); }
171 void append(QCborValue &&value) { insert(i: -1, value: std::move(value)); }
172 QCborValue extract(ConstIterator it) { return extract(it: Iterator{ it.item.d, it.item.i }); }
173 QCborValue extract(Iterator it);
174 void removeAt(qsizetype i);
175 QCborValue takeAt(qsizetype i) { Q_ASSERT(i < size()); return extract(it: begin() + i); }
176 void removeFirst() { removeAt(i: 0); }
177 void removeLast() { removeAt(i: size() - 1); }
178 QCborValue takeFirst() { return takeAt(i: 0); }
179 QCborValue takeLast() { return takeAt(i: size() - 1); }
180
181 bool contains(const QCborValue &value) const;
182
183 int compare(const QCborArray &other) const noexcept Q_DECL_PURE_FUNCTION;
184#if 0 && __has_include(<compare>)
185 std::strong_ordering operator<=>(const QCborArray &other) const
186 {
187 int c = compare(other);
188 if (c > 0) return std::strong_ordering::greater;
189 if (c == 0) return std::strong_ordering::equivalent;
190 return std::strong_ordering::less;
191 }
192#else
193 bool operator==(const QCborArray &other) const noexcept
194 { return compare(other) == 0; }
195 bool operator!=(const QCborArray &other) const noexcept
196 { return !(*this == other); }
197 bool operator<(const QCborArray &other) const
198 { return compare(other) < 0; }
199#endif
200
201 typedef Iterator iterator;
202 typedef ConstIterator const_iterator;
203 iterator begin() { detach(); return iterator{d.data(), 0}; }
204 const_iterator constBegin() const { return const_iterator{d.data(), 0}; }
205 const_iterator begin() const { return constBegin(); }
206 const_iterator cbegin() const { return constBegin(); }
207 iterator end() { detach(); return iterator{d.data(), size()}; }
208 const_iterator constEnd() const { return const_iterator{d.data(), size()}; }
209 const_iterator end() const { return constEnd(); }
210 const_iterator cend() const { return constEnd(); }
211 iterator insert(iterator before, const QCborValue &value)
212 { insert(i: before.item.i, value); return iterator{d.data(), before.item.i}; }
213 iterator insert(const_iterator before, const QCborValue &value)
214 { insert(i: before.item.i, value); return iterator{d.data(), before.item.i}; }
215 iterator erase(iterator it) { removeAt(i: it.item.i); return iterator{d.data(), it.item.i}; }
216 iterator erase(const_iterator it) { removeAt(i: it.item.i); return iterator{d.data(), it.item.i}; }
217
218 void push_back(const QCborValue &t) { append(value: t); }
219 void push_front(const QCborValue &t) { prepend(value: t); }
220 void pop_front() { removeFirst(); }
221 void pop_back() { removeLast(); }
222 bool empty() const { return isEmpty(); }
223
224 // convenience
225 QCborArray operator+(const QCborValue &v) const
226 { QCborArray n = *this; n += v; return n; }
227 QCborArray &operator+=(const QCborValue &v)
228 { append(value: v); return *this; }
229 QCborArray &operator<<(const QCborValue &v)
230 { append(value: v); return *this; }
231
232 static QCborArray fromStringList(const QStringList &list);
233 static QCborArray fromVariantList(const QVariantList &list);
234 static QCborArray fromJsonArray(const QJsonArray &array);
235 static QCborArray fromJsonArray(QJsonArray &&array) noexcept;
236 QVariantList toVariantList() const;
237 QJsonArray toJsonArray() const;
238
239private:
240 void detach(qsizetype reserve = 0);
241
242 friend QCborValue;
243 friend QCborValueRef;
244 friend class QJsonPrivate::Variant;
245 explicit QCborArray(QCborContainerPrivate &dd) noexcept;
246 QExplicitlySharedDataPointer<QCborContainerPrivate> d;
247};
248
249Q_DECLARE_SHARED(QCborArray)
250
251inline QCborValue::QCborValue(QCborArray &&a)
252 : n(-1), container(a.d.take()), t(Array)
253{
254}
255
256#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
257inline QCborArray QCborValueRef::toArray() const
258{
259 return concrete().toArray();
260}
261
262inline QCborArray QCborValueRef::toArray(const QCborArray &a) const
263{
264 return concrete().toArray(defaultValue: a);
265}
266#endif
267
268inline QCborArray QCborValueConstRef::toArray() const
269{
270 return concrete().toArray();
271}
272
273inline QCborArray QCborValueConstRef::toArray(const QCborArray &a) const
274{
275 return concrete().toArray(defaultValue: a);
276}
277
278Q_CORE_EXPORT size_t qHash(const QCborArray &array, size_t seed = 0);
279
280#if !defined(QT_NO_DEBUG_STREAM)
281Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a);
282#endif
283
284#ifndef QT_NO_DATASTREAM
285#if QT_CONFIG(cborstreamwriter)
286Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QCborArray &);
287#endif
288Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QCborArray &);
289#endif
290
291QT_END_NAMESPACE
292
293#endif // QCBORARRAY_H
294

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