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
13QT_BEGIN_NAMESPACE
14
15class QDebug;
16
17class QCborContainerPrivate;
18
19class Q_CORE_EXPORT QJsonObject
20{
21public:
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
238private:
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
270Q_DECLARE_SHARED(QJsonObject)
271
272#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED)
273inline QJsonValueConstRef::QJsonValueConstRef(QJsonObject *o, qsizetype idx)
274 : d(o ? o->o.data() : nullptr), is_object(true), index(idx)
275{}
276#endif
277
278Q_CORE_EXPORT size_t qHash(const QJsonObject &object, size_t seed = 0);
279
280#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
281Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
282#endif
283
284#ifndef QT_NO_DATASTREAM
285Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonObject &);
286Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonObject &);
287#endif
288
289QT_END_NAMESPACE
290
291#endif // QJSONOBJECT_H
292