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 QJSONOBJECT_H |
5 | #define QJSONOBJECT_H |
6 | |
7 | #include <QtCore/qjsonvalue.h> |
8 | #include <QtCore/qiterator.h> |
9 | #include <QtCore/qpair.h> |
10 | #include <QtCore/qshareddata.h> |
11 | #include <initializer_list> |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | class QDebug; |
16 | |
17 | class QCborContainerPrivate; |
18 | |
19 | class Q_CORE_EXPORT QJsonObject |
20 | { |
21 | public: |
22 | QJsonObject(); |
23 | |
24 | QJsonObject(std::initializer_list<std::pair<QString, QJsonValue> > args); |
25 | |
26 | ~QJsonObject(); |
27 | |
28 | QJsonObject(const QJsonObject &other) noexcept; |
29 | QJsonObject &operator =(const QJsonObject &other) noexcept; |
30 | |
31 | QJsonObject(QJsonObject &&other) noexcept; |
32 | |
33 | QJsonObject &operator =(QJsonObject &&other) noexcept |
34 | { |
35 | swap(other); |
36 | return *this; |
37 | } |
38 | |
39 | void swap(QJsonObject &other) noexcept |
40 | { |
41 | o.swap(other&: other.o); |
42 | } |
43 | |
44 | static QJsonObject fromVariantMap(const QVariantMap &map); |
45 | QVariantMap toVariantMap() const; |
46 | static QJsonObject fromVariantHash(const QVariantHash &map); |
47 | QVariantHash toVariantHash() const; |
48 | |
49 | QStringList keys() const; |
50 | qsizetype size() const; |
51 | inline qsizetype count() const { return size(); } |
52 | inline qsizetype length() const { return size(); } |
53 | bool isEmpty() const; |
54 | |
55 | QJsonValue value(const QString &key) const; |
56 | QJsonValue operator[] (const QString &key) const; |
57 | QJsonValueRef operator[] (const QString &key); |
58 | QJsonValue value(QStringView key) const; |
59 | QJsonValue value(QLatin1StringView key) const; |
60 | QJsonValue operator[] (QStringView key) const { return value(key); } |
61 | QJsonValue operator[] (QLatin1StringView key) const { return value(key); } |
62 | QJsonValueRef operator[] (QStringView key); |
63 | QJsonValueRef operator[] (QLatin1StringView key); |
64 | |
65 | void remove(const QString &key); |
66 | QJsonValue take(const QString &key); |
67 | bool contains(const QString &key) const; |
68 | void remove(QStringView key); |
69 | void remove(QLatin1StringView key); |
70 | QJsonValue take(QStringView key); |
71 | QJsonValue take(QLatin1StringView key); |
72 | bool contains(QStringView key) const; |
73 | bool contains(QLatin1StringView key) const; |
74 | |
75 | bool operator==(const QJsonObject &other) const; |
76 | bool operator!=(const QJsonObject &other) const; |
77 | |
78 | class const_iterator; |
79 | |
80 | class iterator |
81 | { |
82 | friend class const_iterator; |
83 | friend class QJsonObject; |
84 | QJsonValueRef item; |
85 | |
86 | public: |
87 | typedef std::random_access_iterator_tag iterator_category; |
88 | typedef qsizetype difference_type; |
89 | typedef QJsonValue value_type; |
90 | typedef QJsonValueRef reference; |
91 | typedef QJsonValueRef *pointer; |
92 | |
93 | inline iterator() : item(static_cast<QJsonObject*>(nullptr), 0) { } |
94 | inline iterator(QJsonObject *obj, qsizetype index) : item(obj, index) { } |
95 | |
96 | constexpr iterator(const iterator &other) = default; |
97 | iterator &operator=(const iterator &other) |
98 | { |
99 | item.rebind(other: other.item); |
100 | return *this; |
101 | } |
102 | |
103 | inline QString key() const { return item.objectKey(); } |
104 | inline QJsonValueRef value() const { return item; } |
105 | inline QJsonValueRef operator*() const { return item; } |
106 | inline const QJsonValueConstRef *operator->() const { return &item; } |
107 | inline QJsonValueRef *operator->() { return &item; } |
108 | inline QJsonValueRef operator[](qsizetype j) const { return *(*this + j); } |
109 | |
110 | inline bool operator==(const iterator &other) const |
111 | { return item.d == other.item.d && item.index == other.item.index; } |
112 | inline bool operator!=(const iterator &other) const { return !(*this == other); } |
113 | bool operator<(const iterator& other) const |
114 | { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } |
115 | bool operator<=(const iterator& other) const |
116 | { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } |
117 | bool operator>(const iterator& other) const { return !(*this <= other); } |
118 | bool operator>=(const iterator& other) const { return !(*this < other); } |
119 | |
120 | inline iterator &operator++() { ++item.index; return *this; } |
121 | inline iterator operator++(int) { iterator r = *this; ++item.index; return r; } |
122 | inline iterator &operator--() { --item.index; return *this; } |
123 | inline iterator operator--(int) { iterator r = *this; --item.index; return r; } |
124 | inline iterator operator+(qsizetype j) const { iterator r = *this; return r += j; } |
125 | inline iterator operator-(qsizetype j) const { return operator+(j: -j); } |
126 | inline iterator &operator+=(qsizetype j) { item.index += quint64(j); return *this; } |
127 | inline iterator &operator-=(qsizetype j) { item.index -= quint64(j); return *this; } |
128 | qsizetype operator-(iterator j) const { return item.index - j.item.index; } |
129 | |
130 | public: |
131 | inline bool operator==(const const_iterator &other) const |
132 | { return item.d == other.item.d && item.index == other.item.index; } |
133 | inline bool operator!=(const const_iterator &other) const { return !(*this == other); } |
134 | bool operator<(const const_iterator& other) const |
135 | { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } |
136 | bool operator<=(const const_iterator& other) const |
137 | { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } |
138 | bool operator>(const const_iterator& other) const { return !(*this <= other); } |
139 | bool operator>=(const const_iterator& other) const { return !(*this < other); } |
140 | }; |
141 | friend class iterator; |
142 | |
143 | class const_iterator |
144 | { |
145 | friend class iterator; |
146 | QJsonValueConstRef item; |
147 | |
148 | public: |
149 | typedef std::random_access_iterator_tag iterator_category; |
150 | typedef qsizetype difference_type; |
151 | typedef QJsonValue value_type; |
152 | typedef const QJsonValueConstRef reference; |
153 | typedef const QJsonValueConstRef *pointer; |
154 | |
155 | inline const_iterator() : item(static_cast<QJsonObject*>(nullptr), 0) { } |
156 | inline const_iterator(const QJsonObject *obj, qsizetype index) |
157 | : item(const_cast<QJsonObject*>(obj), index) { } |
158 | inline const_iterator(const iterator &other) |
159 | : item(other.item) { } |
160 | |
161 | constexpr const_iterator(const const_iterator &other) = default; |
162 | const_iterator &operator=(const const_iterator &other) |
163 | { |
164 | item.rebind(other: other.item); |
165 | return *this; |
166 | } |
167 | |
168 | inline QString key() const { return item.objectKey(); } |
169 | inline QJsonValueConstRef value() const { return item; } |
170 | inline const QJsonValueConstRef operator*() const { return item; } |
171 | inline const QJsonValueConstRef *operator->() const { return &item; } |
172 | inline QJsonValueConstRef operator[](qsizetype j) const { return *(*this + j); } |
173 | |
174 | inline bool operator==(const const_iterator &other) const |
175 | { return item.d == other.item.d && item.index == other.item.index; } |
176 | inline bool operator!=(const const_iterator &other) const { return !(*this == other); } |
177 | bool operator<(const const_iterator& other) const |
178 | { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } |
179 | bool operator<=(const const_iterator& other) const |
180 | { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } |
181 | bool operator>(const const_iterator& other) const { return !(*this <= other); } |
182 | bool operator>=(const const_iterator& other) const { return !(*this < other); } |
183 | |
184 | inline const_iterator &operator++() { ++item.index; return *this; } |
185 | inline const_iterator operator++(int) { const_iterator r = *this; ++item.index; return r; } |
186 | inline const_iterator &operator--() { --item.index; return *this; } |
187 | inline const_iterator operator--(int) { const_iterator r = *this; --item.index; return r; } |
188 | inline const_iterator operator+(qsizetype j) const { const_iterator r = *this; return r += j; } |
189 | inline const_iterator operator-(qsizetype j) const { return operator+(j: -j); } |
190 | inline const_iterator &operator+=(qsizetype j) { item.index += quint64(j); return *this; } |
191 | inline const_iterator &operator-=(qsizetype j) { item.index -= quint64(j); return *this; } |
192 | qsizetype operator-(const_iterator j) const { return item.index - j.item.index; } |
193 | |
194 | inline bool operator==(const iterator &other) const |
195 | { return item.d == other.item.d && item.index == other.item.index; } |
196 | inline bool operator!=(const iterator &other) const { return !(*this == other); } |
197 | bool operator<(const iterator& other) const |
198 | { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } |
199 | bool operator<=(const iterator& other) const |
200 | { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } |
201 | bool operator>(const iterator& other) const { return !(*this <= other); } |
202 | bool operator>=(const iterator& other) const { return !(*this < other); } |
203 | }; |
204 | friend class const_iterator; |
205 | |
206 | // STL style |
207 | inline iterator begin() { detach(); return iterator(this, 0); } |
208 | inline const_iterator begin() const { return const_iterator(this, 0); } |
209 | inline const_iterator constBegin() const { return const_iterator(this, 0); } |
210 | inline iterator end() { detach(); return iterator(this, size()); } |
211 | inline const_iterator end() const { return const_iterator(this, size()); } |
212 | inline const_iterator constEnd() const { return const_iterator(this, size()); } |
213 | iterator erase(iterator it); |
214 | |
215 | // more Qt |
216 | typedef iterator Iterator; |
217 | typedef const_iterator ConstIterator; |
218 | iterator find(const QString &key); |
219 | const_iterator find(const QString &key) const { return constFind(key); } |
220 | const_iterator constFind(const QString &key) const; |
221 | iterator insert(const QString &key, const QJsonValue &value); |
222 | iterator find(QStringView key); |
223 | iterator find(QLatin1StringView key); |
224 | const_iterator find(QStringView key) const { return constFind(key); } |
225 | const_iterator find(QLatin1StringView key) const { return constFind(key); } |
226 | const_iterator constFind(QStringView key) const; |
227 | const_iterator constFind(QLatin1StringView key) const; |
228 | iterator insert(QStringView key, const QJsonValue &value); |
229 | iterator insert(QLatin1StringView key, const QJsonValue &value); |
230 | |
231 | // STL compatibility |
232 | typedef QJsonValue mapped_type; |
233 | typedef QString key_type; |
234 | typedef qsizetype size_type; |
235 | |
236 | inline bool empty() const { return isEmpty(); } |
237 | |
238 | private: |
239 | friend class QJsonValue; |
240 | friend class QJsonDocument; |
241 | friend class QJsonPrivate::Value; |
242 | friend class QJsonValueConstRef; |
243 | friend class QJsonValueRef; |
244 | friend class QCborMap; |
245 | friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &); |
246 | |
247 | QJsonObject(QCborContainerPrivate *object); |
248 | bool detach(qsizetype reserve = 0); |
249 | |
250 | template <typename T> QJsonValue valueImpl(T key) const; |
251 | template <typename T> QJsonValueRef atImpl(T key); |
252 | template <typename T> void removeImpl(T key); |
253 | template <typename T> QJsonValue takeImpl(T key); |
254 | template <typename T> bool containsImpl(T key) const; |
255 | template <typename T> iterator findImpl(T key); |
256 | template <typename T> const_iterator constFindImpl(T key) const; |
257 | template <typename T> iterator insertImpl(T key, const QJsonValue &value); |
258 | |
259 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) |
260 | QString keyAt(qsizetype i) const; |
261 | QJsonValue valueAt(qsizetype i) const; |
262 | void setValueAt(qsizetype i, const QJsonValue &val); |
263 | #endif |
264 | void removeAt(qsizetype i); |
265 | template <typename T> iterator insertAt(qsizetype i, T key, const QJsonValue &val, bool exists); |
266 | |
267 | QExplicitlySharedDataPointer<QCborContainerPrivate> o; |
268 | }; |
269 | |
270 | Q_DECLARE_SHARED(QJsonObject) |
271 | |
272 | #if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) |
273 | inline QJsonValueConstRef::QJsonValueConstRef(QJsonObject *o, qsizetype idx) |
274 | : d(o ? o->o.data() : nullptr), is_object(true), index(idx) |
275 | {} |
276 | #endif |
277 | |
278 | Q_CORE_EXPORT size_t qHash(const QJsonObject &object, size_t seed = 0); |
279 | |
280 | #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) |
281 | Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &); |
282 | #endif |
283 | |
284 | #ifndef QT_NO_DATASTREAM |
285 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonObject &); |
286 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonObject &); |
287 | #endif |
288 | |
289 | QT_END_NAMESPACE |
290 | |
291 | #endif // QJSONOBJECT_H |
292 | |