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 QCBORMAP_H
5#define QCBORMAP_H
6
7#include <QtCore/qcborvalue.h>
8#include <QtCore/qpair.h>
9
10#include <initializer_list>
11
12QT_BEGIN_NAMESPACE
13
14class QJsonObject;
15class QDataStream;
16
17namespace QJsonPrivate { class Variant; }
18
19class QCborContainerPrivate;
20class Q_CORE_EXPORT QCborMap
21{
22public:
23 typedef QPair<QCborValue, QCborValue> value_type;
24 typedef QCborValue key_type;
25 typedef QCborValue mapped_type;
26 typedef qsizetype size_type;
27
28 class ConstIterator;
29 class Iterator {
30 QCborValueRef item {}; // points to the value
31 friend class ConstIterator;
32 friend class QCborMap;
33 Iterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
34 public:
35 typedef std::random_access_iterator_tag iterator_category;
36 typedef qsizetype difference_type;
37 typedef QPair<QCborValueConstRef, QCborValueRef> value_type;
38 typedef QPair<QCborValueConstRef, QCborValueRef> reference;
39 typedef QPair<QCborValueConstRef, QCborValueRef> pointer;
40
41 constexpr Iterator() = default;
42 constexpr Iterator(const Iterator &) = default;
43 Iterator &operator=(const Iterator &other)
44 {
45 // rebind the reference
46 item.d = other.item.d;
47 item.i = other.item.i;
48 return *this;
49 }
50
51 value_type operator*() const { return { QCborValueRef{item.d, item.i - 1}, item }; }
52 value_type operator[](qsizetype j) const { return *(*this + j); }
53 QCborValueRef *operator->() { return &item; }
54 const QCborValueConstRef *operator->() const { return &item; }
55#if QT_VERSION >= QT_VERSION_CHECK(7,0,0)
56 QCborValueConstRef
57#else
58 QCborValue
59#endif
60 key() const { return QCborValueRef(item.d, item.i - 1); }
61 QCborValueRef value() const { return item; }
62
63 bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
64 bool operator!=(const Iterator &o) const { return !(*this == o); }
65 bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
66 bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
67 bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
68 bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
69 bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
70 bool operator!=(const ConstIterator &o) const { return !(*this == o); }
71 bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
72 bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
73 bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
74 bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
75 Iterator &operator++() { item.i += 2; return *this; }
76 Iterator operator++(int) { Iterator n = *this; item.i += 2; return n; }
77 Iterator &operator--() { item.i -= 2; return *this; }
78 Iterator operator--(int) { Iterator n = *this; item.i -= 2; return n; }
79 Iterator &operator+=(qsizetype j) { item.i += 2 * j; return *this; }
80 Iterator &operator-=(qsizetype j) { item.i -= 2 * j; return *this; }
81 Iterator operator+(qsizetype j) const { return Iterator({ item.d, item.i + 2 * j }); }
82 Iterator operator-(qsizetype j) const { return Iterator({ item.d, item.i - 2 * j }); }
83 qsizetype operator-(Iterator j) const { return (item.i - j.item.i) / 2; }
84 };
85
86 class ConstIterator {
87 QCborValueConstRef item; // points to the value
88 friend class Iterator;
89 friend class QCborMap;
90 friend class QCborValue;
91 friend class QCborValueRef;
92 constexpr ConstIterator(QCborValueConstRef it) : item{it} {}
93 ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
94 public:
95 typedef std::random_access_iterator_tag iterator_category;
96 typedef qsizetype difference_type;
97 typedef QPair<QCborValueConstRef, QCborValueConstRef> value_type;
98 typedef QPair<QCborValueConstRef, QCborValueConstRef> reference;
99 typedef QPair<QCborValueConstRef, QCborValueConstRef> pointer;
100
101 constexpr ConstIterator() = default;
102 constexpr ConstIterator(const ConstIterator &) = default;
103 ConstIterator &operator=(const ConstIterator &other)
104 {
105 // rebind the reference
106 item.d = other.item.d;
107 item.i = other.item.i;
108 return *this;
109 }
110
111 value_type operator*() const { return { QCborValueRef(item.d, item.i - 1), item }; }
112 value_type operator[](qsizetype j) const { return *(*this + j); }
113 const QCborValueConstRef *operator->() const { return &item; }
114#if QT_VERSION >= QT_VERSION_CHECK(7,0,0)
115 QCborValueConstRef
116#else
117 QCborValue
118#endif
119 key() const { return QCborValueRef(item.d, item.i - 1); }
120 QCborValueConstRef value() const { return item; }
121
122 bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
123 bool operator!=(const Iterator &o) const { return !(*this == o); }
124 bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
125 bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
126 bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
127 bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
128 bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
129 bool operator!=(const ConstIterator &o) const { return !(*this == o); }
130 bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
131 bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
132 bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
133 bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
134 ConstIterator &operator++() { item.i += 2; return *this; }
135 ConstIterator operator++(int) { ConstIterator n = *this; item.i += 2; return n; }
136 ConstIterator &operator--() { item.i -= 2; return *this; }
137 ConstIterator operator--(int) { ConstIterator n = *this; item.i -= 2; return n; }
138 ConstIterator &operator+=(qsizetype j) { item.i += 2 * j; return *this; }
139 ConstIterator &operator-=(qsizetype j) { item.i -= 2 * j; return *this; }
140 ConstIterator operator+(qsizetype j) const { return ConstIterator{ item.d, item.i + 2 * j }; }
141 ConstIterator operator-(qsizetype j) const { return ConstIterator{ item.d, item.i - 2 * j }; }
142 qsizetype operator-(ConstIterator j) const { return (item.i - j.item.i) / 2; }
143 };
144
145 QCborMap() noexcept;
146 QCborMap(const QCborMap &other) noexcept;
147 QCborMap &operator=(const QCborMap &other) noexcept;
148 QCborMap(std::initializer_list<value_type> args)
149 : QCborMap()
150 {
151 detach(reserve: args.size());
152 for (const auto &pair : args)
153 insert(key: pair.first, value_: pair.second);
154 }
155 ~QCborMap();
156
157 void swap(QCborMap &other) noexcept
158 {
159 d.swap(other&: other.d);
160 }
161
162 QCborValue toCborValue() const { return *this; }
163
164 qsizetype size() const noexcept Q_DECL_PURE_FUNCTION;
165 bool isEmpty() const { return size() == 0; }
166 void clear();
167 QList<QCborValue> keys() const;
168
169 QCborValue value(qint64 key) const
170 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
171 QCborValue value(QLatin1StringView key) const
172 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
173 QCborValue value(const QString & key) const
174 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
175 QCborValue value(const QCborValue &key) const
176 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
177#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
178 template<size_t N> QT_ASCII_CAST_WARN const QCborValue value(const char (&key)[N]) const
179 { return value(QString::fromUtf8(key, N - 1)); }
180#endif
181 const QCborValue operator[](qint64 key) const
182 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
183 const QCborValue operator[](QLatin1StringView key) const
184 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
185 const QCborValue operator[](const QString & key) const
186 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
187 const QCborValue operator[](const QCborValue &key) const
188 { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
189#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
190 template<size_t N> QT_ASCII_CAST_WARN const QCborValue operator[](const char (&key)[N]) const
191 { return operator[](QString::fromUtf8(key, N - 1)); }
192#endif
193 QCborValueRef operator[](qint64 key);
194 QCborValueRef operator[](QLatin1StringView key);
195 QCborValueRef operator[](const QString & key);
196 QCborValueRef operator[](const QCborValue &key);
197
198 QCborValue take(qint64 key)
199 { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
200 QCborValue take(QLatin1StringView key)
201 { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
202 QCborValue take(const QString &key)
203 { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
204 QCborValue take(const QCborValue &key)
205 { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
206 void remove(qint64 key)
207 { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
208 void remove(QLatin1StringView key)
209 { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
210 void remove(const QString & key)
211 { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
212 void remove(const QCborValue &key)
213 { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
214 bool contains(qint64 key) const
215 { const_iterator it = find(key); return it != end(); }
216 bool contains(QLatin1StringView key) const
217 { const_iterator it = find(key); return it != end(); }
218 bool contains(const QString & key) const
219 { const_iterator it = find(key); return it != end(); }
220 bool contains(const QCborValue &key) const
221 { const_iterator it = find(key); return it != end(); }
222
223 int compare(const QCborMap &other) const noexcept Q_DECL_PURE_FUNCTION;
224#if 0 && __has_include(<compare>)
225 std::strong_ordering operator<=>(const QCborMap &other) const
226 {
227 int c = compare(other);
228 if (c > 0) return std::strong_ordering::greater;
229 if (c == 0) return std::strong_ordering::equivalent;
230 return std::strong_ordering::less;
231 }
232#else
233 bool operator==(const QCborMap &other) const noexcept
234 { return compare(other) == 0; }
235 bool operator!=(const QCborMap &other) const noexcept
236 { return !(*this == other); }
237 bool operator<(const QCborMap &other) const
238 { return compare(other) < 0; }
239#endif
240
241 typedef Iterator iterator;
242 typedef ConstIterator const_iterator;
243 iterator begin() { detach(); return iterator{d.data(), 1}; }
244 const_iterator constBegin() const { return const_iterator{d.data(), 1}; }
245 const_iterator begin() const { return constBegin(); }
246 const_iterator cbegin() const { return constBegin(); }
247 iterator end() { detach(); return iterator{d.data(), 2 * size() + 1}; }
248 const_iterator constEnd() const { return const_iterator{d.data(), 2 * size() + 1}; }
249 const_iterator end() const { return constEnd(); }
250 const_iterator cend() const { return constEnd(); }
251 iterator erase(iterator it);
252 iterator erase(const_iterator it) { return erase(it: iterator{ it.item.d, it.item.i }); }
253 QCborValue extract(iterator it);
254 QCborValue extract(const_iterator it) { return extract(it: iterator{ it.item.d, it.item.i }); }
255 bool empty() const { return isEmpty(); }
256
257 iterator find(qint64 key);
258 iterator find(QLatin1StringView key);
259 iterator find(const QString & key);
260 iterator find(const QCborValue &key);
261 const_iterator constFind(qint64 key) const;
262 const_iterator constFind(QLatin1StringView key) const;
263 const_iterator constFind(const QString & key) const;
264 const_iterator constFind(const QCborValue &key) const;
265 const_iterator find(qint64 key) const { return constFind(key); }
266 const_iterator find(QLatin1StringView key) const { return constFind(key); }
267 const_iterator find(const QString & key) const { return constFind(key); }
268 const_iterator find(const QCborValue &key) const { return constFind(key); }
269
270 iterator insert(qint64 key, const QCborValue &value_)
271 {
272 QCborValueRef v = operator[](key); // detaches
273 v = value_;
274 return { d.data(), v.i };
275 }
276 iterator insert(QLatin1StringView key, const QCborValue &value_)
277 {
278 QCborValueRef v = operator[](key); // detaches
279 v = value_;
280 return { d.data(), v.i };
281 }
282 iterator insert(const QString &key, const QCborValue &value_)
283 {
284 QCborValueRef v = operator[](key); // detaches
285 v = value_;
286 return { d.data(), v.i };
287 }
288 iterator insert(const QCborValue &key, const QCborValue &value_)
289 {
290 QCborValueRef v = operator[](key); // detaches
291 v = value_;
292 return { d.data(), v.i };
293 }
294 iterator insert(value_type v) { return insert(key: v.first, value_: v.second); }
295
296 static QCborMap fromVariantMap(const QVariantMap &map);
297 static QCborMap fromVariantHash(const QVariantHash &hash);
298 static QCborMap fromJsonObject(const QJsonObject &o);
299 static QCborMap fromJsonObject(QJsonObject &&o) noexcept;
300 QVariantMap toVariantMap() const;
301 QVariantHash toVariantHash() const;
302 QJsonObject toJsonObject() const;
303
304private:
305 friend class QCborContainerPrivate;
306 friend class QCborValue;
307 friend class QCborValueRef;
308 friend class QJsonPrivate::Variant;
309 void detach(qsizetype reserve = 0);
310
311 explicit QCborMap(QCborContainerPrivate &dd) noexcept;
312 QExplicitlySharedDataPointer<QCborContainerPrivate> d;
313};
314
315Q_DECLARE_SHARED(QCborMap)
316
317inline QCborValue::QCborValue(QCborMap &&m)
318 : n(-1), container(m.d.take()), t(Map)
319{
320}
321
322#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
323inline QCborMap QCborValueRef::toMap() const
324{
325 return concrete().toMap();
326}
327
328inline QCborMap QCborValueRef::toMap(const QCborMap &m) const
329{
330 return concrete().toMap(defaultValue: m);
331}
332#endif
333
334inline QCborMap QCborValueConstRef::toMap() const
335{
336 return concrete().toMap();
337}
338
339inline QCborMap QCborValueConstRef::toMap(const QCborMap &m) const
340{
341 return concrete().toMap(defaultValue: m);
342}
343
344Q_CORE_EXPORT size_t qHash(const QCborMap &map, size_t seed = 0);
345
346#if !defined(QT_NO_DEBUG_STREAM)
347Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m);
348#endif
349
350#ifndef QT_NO_DATASTREAM
351#if QT_CONFIG(cborstreamwriter)
352Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QCborMap &);
353#endif
354Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QCborMap &);
355#endif
356
357
358QT_END_NAMESPACE
359
360#endif // QCBORMAP_H
361

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