1 | // Copyright (C) 2016 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 | |
4 | #ifndef QJSONARRAY_H |
5 | #define QJSONARRAY_H |
6 | |
7 | #include <QtCore/qjsonvalue.h> |
8 | #include <QtCore/qiterator.h> |
9 | #include <QtCore/qshareddata.h> |
10 | #include <initializer_list> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | class QDebug; |
15 | typedef QList<QVariant> QVariantList; |
16 | |
17 | class Q_CORE_EXPORT QJsonArray |
18 | { |
19 | public: |
20 | QJsonArray(); |
21 | |
22 | QJsonArray(std::initializer_list<QJsonValue> args); |
23 | |
24 | ~QJsonArray(); |
25 | |
26 | QJsonArray(const QJsonArray &other) noexcept; |
27 | QJsonArray &operator =(const QJsonArray &other) noexcept; |
28 | |
29 | QJsonArray(QJsonArray &&other) noexcept; |
30 | |
31 | QJsonArray &operator =(QJsonArray &&other) noexcept |
32 | { |
33 | swap(other); |
34 | return *this; |
35 | } |
36 | |
37 | static QJsonArray fromStringList(const QStringList &list); |
38 | static QJsonArray fromVariantList(const QVariantList &list); |
39 | QVariantList toVariantList() const; |
40 | |
41 | qsizetype size() const; |
42 | inline qsizetype count() const { return size(); } |
43 | |
44 | bool isEmpty() const; |
45 | QJsonValue at(qsizetype i) const; |
46 | QJsonValue first() const; |
47 | QJsonValue last() const; |
48 | |
49 | void prepend(const QJsonValue &value); |
50 | void append(const QJsonValue &value); |
51 | void removeAt(qsizetype i); |
52 | QJsonValue takeAt(qsizetype i); |
53 | inline void removeFirst() { removeAt(i: 0); } |
54 | inline void removeLast() { removeAt(i: size() - 1); } |
55 | |
56 | void insert(qsizetype i, const QJsonValue &value); |
57 | void replace(qsizetype i, const QJsonValue &value); |
58 | |
59 | bool contains(const QJsonValue &element) const; |
60 | QJsonValueRef operator[](qsizetype i); |
61 | QJsonValue operator[](qsizetype i) const; |
62 | |
63 | bool operator==(const QJsonArray &other) const; |
64 | bool operator!=(const QJsonArray &other) const; |
65 | |
66 | void swap(QJsonArray &other) noexcept |
67 | { |
68 | a.swap(other&: other.a); |
69 | } |
70 | |
71 | class const_iterator; |
72 | |
73 | class iterator { |
74 | public: |
75 | typedef std::random_access_iterator_tag iterator_category; |
76 | typedef qsizetype difference_type; |
77 | typedef QJsonValue value_type; |
78 | typedef QJsonValueRef reference; |
79 | typedef QJsonValueRef *pointer; |
80 | |
81 | inline iterator() : item(static_cast<QJsonArray *>(nullptr), 0) { } |
82 | explicit inline iterator(QJsonArray *array, qsizetype index) : item(array, index) { } |
83 | |
84 | constexpr iterator(const iterator &other) = default; |
85 | iterator &operator=(const iterator &other) |
86 | { |
87 | item.rebind(other: other.item); |
88 | return *this; |
89 | } |
90 | |
91 | inline QJsonValueRef operator*() const { return item; } |
92 | inline const QJsonValueConstRef *operator->() const { return &item; } |
93 | inline QJsonValueRef *operator->() { return &item; } |
94 | inline QJsonValueRef operator[](qsizetype j) const { return *(*this + j); } |
95 | |
96 | inline bool operator==(const iterator &o) const |
97 | { return item.d == o.item.d && item.index == o.item.index; } |
98 | inline bool operator!=(const iterator &o) const { return !(*this == o); } |
99 | inline bool operator<(const iterator &other) const |
100 | { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } |
101 | inline bool operator<=(const iterator &other) const |
102 | { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } |
103 | inline bool operator>(const iterator &other) const { return !(*this <= other); } |
104 | inline bool operator>=(const iterator &other) const { return !(*this < other); } |
105 | inline bool operator==(const const_iterator &o) const |
106 | { return item.d == o.item.d && item.index == o.item.index; } |
107 | inline bool operator!=(const const_iterator &o) const { return !(*this == o); } |
108 | inline bool operator<(const const_iterator &other) const |
109 | { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } |
110 | inline bool operator<=(const const_iterator &other) const |
111 | { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } |
112 | inline bool operator>(const const_iterator &other) const { return !(*this <= other); } |
113 | inline bool operator>=(const const_iterator &other) const { return !(*this < other); } |
114 | inline iterator &operator++() { ++item.index; return *this; } |
115 | inline iterator operator++(int) { iterator n = *this; ++item.index; return n; } |
116 | inline iterator &operator--() { item.index--; return *this; } |
117 | inline iterator operator--(int) { iterator n = *this; item.index--; return n; } |
118 | inline iterator &operator+=(qsizetype j) { item.index += quint64(j); return *this; } |
119 | inline iterator &operator-=(qsizetype j) { item.index -= quint64(j); return *this; } |
120 | inline iterator operator+(qsizetype j) const { iterator r = *this; return r += j; } |
121 | inline iterator operator-(qsizetype j) const { return operator+(j: -j); } |
122 | inline qsizetype operator-(iterator j) const { return item.index - j.item.index; } |
123 | |
124 | private: |
125 | QJsonValueRef item; |
126 | friend class QJsonArray; |
127 | }; |
128 | friend class iterator; |
129 | |
130 | class const_iterator { |
131 | public: |
132 | typedef std::random_access_iterator_tag iterator_category; |
133 | typedef qptrdiff difference_type; |
134 | typedef QJsonValue value_type; |
135 | typedef const QJsonValueRef reference; |
136 | typedef const QJsonValueRef *pointer; |
137 | |
138 | inline const_iterator() : item(static_cast<QJsonArray *>(nullptr), 0) { } |
139 | explicit inline const_iterator(const QJsonArray *array, qsizetype index) |
140 | : item(const_cast<QJsonArray *>(array), index) { } |
141 | inline const_iterator(const iterator &o) : item(o.item) { } |
142 | |
143 | constexpr const_iterator(const const_iterator &other) = default; |
144 | const_iterator &operator=(const const_iterator &other) |
145 | { |
146 | item.rebind(other: other.item); |
147 | return *this; |
148 | } |
149 | |
150 | inline const QJsonValueConstRef operator*() const { return item; } |
151 | inline const QJsonValueConstRef *operator->() const { return &item; } |
152 | |
153 | inline QJsonValueConstRef operator[](qsizetype j) const { return *(*this + j); } |
154 | inline bool operator==(const const_iterator &o) const |
155 | { return item.d == o.item.d && item.index == o.item.index; } |
156 | inline bool operator!=(const const_iterator &o) const { return !(*this == o); } |
157 | inline bool operator<(const const_iterator &other) const |
158 | { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } |
159 | inline bool operator<=(const const_iterator &other) const |
160 | { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } |
161 | inline bool operator>(const const_iterator &other) const { return !(*this <= other); } |
162 | inline bool operator>=(const const_iterator &other) const { return !(*this < other); } |
163 | inline const_iterator &operator++() { ++item.index; return *this; } |
164 | inline const_iterator operator++(int) { const_iterator n = *this; ++item.index; return n; } |
165 | inline const_iterator &operator--() { item.index--; return *this; } |
166 | inline const_iterator operator--(int) { const_iterator n = *this; item.index--; return n; } |
167 | inline const_iterator &operator+=(qsizetype j) { item.index += quint64(j); return *this; } |
168 | inline const_iterator &operator-=(qsizetype j) { item.index -= quint64(j); return *this; } |
169 | inline const_iterator operator+(qsizetype j) const { const_iterator r = *this; return r += j; } |
170 | inline const_iterator operator-(qsizetype j) const { return operator+(j: -j); } |
171 | inline qsizetype operator-(const_iterator j) const { return item.index - j.item.index; } |
172 | |
173 | private: |
174 | QJsonValueConstRef item; |
175 | friend class QJsonArray; |
176 | }; |
177 | friend class const_iterator; |
178 | |
179 | // stl style |
180 | inline iterator begin() { detach(); return iterator(this, 0); } |
181 | inline const_iterator begin() const { return const_iterator(this, 0); } |
182 | inline const_iterator constBegin() const { return const_iterator(this, 0); } |
183 | inline const_iterator cbegin() const { return const_iterator(this, 0); } |
184 | inline iterator end() { detach(); return iterator(this, size()); } |
185 | inline const_iterator end() const { return const_iterator(this, size()); } |
186 | inline const_iterator constEnd() const { return const_iterator(this, size()); } |
187 | inline const_iterator cend() const { return const_iterator(this, size()); } |
188 | iterator insert(iterator before, const QJsonValue &value) |
189 | { insert(i: before.item.index, value); return before; } |
190 | iterator erase(iterator it) |
191 | { removeAt(i: it.item.index); return it; } |
192 | |
193 | // more Qt |
194 | typedef iterator Iterator; |
195 | typedef const_iterator ConstIterator; |
196 | |
197 | // convenience |
198 | inline QJsonArray operator+(const QJsonValue &v) const |
199 | { QJsonArray n = *this; n += v; return n; } |
200 | inline QJsonArray &operator+=(const QJsonValue &v) |
201 | { append(value: v); return *this; } |
202 | inline QJsonArray &operator<< (const QJsonValue &v) |
203 | { append(value: v); return *this; } |
204 | |
205 | // stl compatibility |
206 | inline void push_back(const QJsonValue &t) { append(value: t); } |
207 | inline void push_front(const QJsonValue &t) { prepend(value: t); } |
208 | inline void pop_front() { removeFirst(); } |
209 | inline void pop_back() { removeLast(); } |
210 | inline bool empty() const { return isEmpty(); } |
211 | typedef qsizetype size_type; |
212 | typedef QJsonValue value_type; |
213 | typedef value_type *pointer; |
214 | typedef const value_type *const_pointer; |
215 | typedef QJsonValueRef reference; |
216 | typedef QJsonValue const_reference; |
217 | typedef qsizetype difference_type; |
218 | |
219 | private: |
220 | friend class QJsonValue; |
221 | friend class QJsonValueConstRef; |
222 | friend class QJsonValueRef; |
223 | friend class QJsonPrivate::Value; |
224 | friend class QJsonDocument; |
225 | friend class QCborArray; |
226 | friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &); |
227 | |
228 | QJsonArray(QCborContainerPrivate *array); |
229 | bool detach(qsizetype reserve = 0); |
230 | |
231 | QExplicitlySharedDataPointer<QCborContainerPrivate> a; |
232 | }; |
233 | |
234 | Q_DECLARE_SHARED(QJsonArray) |
235 | |
236 | #if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) |
237 | inline QJsonValueConstRef::QJsonValueConstRef(QJsonArray *a, qsizetype idx) |
238 | : d(a ? a->a.data() : nullptr), is_object(false), index(idx) |
239 | {} |
240 | #endif |
241 | |
242 | Q_CORE_EXPORT size_t qHash(const QJsonArray &array, size_t seed = 0); |
243 | |
244 | #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) |
245 | Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &); |
246 | #endif |
247 | |
248 | #ifndef QT_NO_DATASTREAM |
249 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonArray &); |
250 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonArray &); |
251 | #endif |
252 | |
253 | QT_END_NAMESPACE |
254 | |
255 | #endif // QJSONARRAY_H |
256 | |