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 std::pair<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 std::pair<QCborValueConstRef, QCborValueRef> value_type;
38 typedef std::pair<QCborValueConstRef, QCborValueRef> reference;
39 typedef std::pair<QCborValueConstRef, QCborValueRef> pointer;
40
41 constexpr Iterator() = default;
42 constexpr Iterator(const Iterator &) = default;
43 ~Iterator() = default;
44 Iterator &operator=(const Iterator &other)
45 {
46 // rebind the reference
47 item.d = other.item.d;
48 item.i = other.item.i;
49 return *this;
50 }
51
52 value_type operator*() const { return { QCborValueRef{item.d, item.i - 1}, item }; }
53 value_type operator[](qsizetype j) const { return *(*this + j); }
54 QCborValueRef *operator->() { return &item; }
55 const QCborValueConstRef *operator->() const { return &item; }
56#if QT_VERSION >= QT_VERSION_CHECK(7,0,0)
57 QCborValueConstRef
58#else
59 QCborValue
60#endif
61 key() const { return QCborValueRef(item.d, item.i - 1); }
62 QCborValueRef value() const { return item; }
63
64#if QT_CORE_REMOVED_SINCE(6, 8)
65 bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
66 bool operator!=(const Iterator &o) const { return !operator==(o); }
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 Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
70 bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
71 bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
72 bool operator!=(const ConstIterator &o) const { return !operator==(o); }
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 bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
76 bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
77#endif
78 Iterator &operator++() { item.i += 2; return *this; }
79 Iterator operator++(int) { Iterator n = *this; item.i += 2; return n; }
80 Iterator &operator--() { item.i -= 2; return *this; }
81 Iterator operator--(int) { Iterator n = *this; item.i -= 2; return n; }
82 Iterator &operator+=(qsizetype j) { item.i += 2 * j; return *this; }
83 Iterator &operator-=(qsizetype j) { item.i -= 2 * j; return *this; }
84 Iterator operator+(qsizetype j) const { return Iterator({ item.d, item.i + 2 * j }); }
85 Iterator operator-(qsizetype j) const { return Iterator({ item.d, item.i - 2 * j }); }
86 qsizetype operator-(Iterator j) const { return (item.i - j.item.i) / 2; }
87
88 private:
89 // Helper functions
90 static bool comparesEqual_helper(const Iterator &lhs, const Iterator &rhs) noexcept
91 {
92 return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i;
93 }
94
95 static bool comparesEqual_helper(const Iterator &lhs, const ConstIterator &rhs) noexcept
96 {
97 return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i;
98 }
99
100 static Qt::strong_ordering compareThreeWay_helper(const Iterator &lhs,
101 const Iterator &rhs)
102 {
103 Q_ASSERT(lhs.item.d == rhs.item.d);
104 return Qt::compareThreeWay(lhs: lhs.item.i, rhs: rhs.item.i);
105 }
106
107 static Qt::strong_ordering compareThreeWay_helper(const Iterator &lhs,
108 const ConstIterator &rhs)
109 {
110 Q_ASSERT(lhs.item.d == rhs.item.d);
111 return Qt::compareThreeWay(lhs: lhs.item.i, rhs: rhs.item.i);
112 }
113
114 // Compare friends
115 friend bool comparesEqual(const Iterator &lhs, const Iterator &rhs) noexcept
116 {
117 return comparesEqual_helper(lhs, rhs);
118 }
119 friend Qt::strong_ordering compareThreeWay(const Iterator &lhs,
120 const Iterator &rhs)
121 {
122 return compareThreeWay_helper(lhs, rhs);
123 }
124 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(Iterator)
125 friend bool comparesEqual(const Iterator &lhs, const ConstIterator &rhs) noexcept
126 {
127 return comparesEqual_helper(lhs, rhs);
128 }
129 friend Qt::strong_ordering compareThreeWay(const Iterator &lhs,
130 const ConstIterator &rhs)
131 {
132 return compareThreeWay_helper(lhs, rhs);
133 }
134 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(Iterator, ConstIterator)
135 };
136
137 class ConstIterator {
138 QCborValueConstRef item; // points to the value
139 friend class Iterator;
140 friend class QCborMap;
141 friend class QCborValue;
142 friend class QCborValueRef;
143 constexpr ConstIterator(QCborValueConstRef it) : item{it} {}
144 ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
145 public:
146 typedef std::random_access_iterator_tag iterator_category;
147 typedef qsizetype difference_type;
148 typedef std::pair<QCborValueConstRef, QCborValueConstRef> value_type;
149 typedef std::pair<QCborValueConstRef, QCborValueConstRef> reference;
150 typedef std::pair<QCborValueConstRef, QCborValueConstRef> pointer;
151
152 constexpr ConstIterator() = default;
153 constexpr ConstIterator(const ConstIterator &) = default;
154 ~ConstIterator() = default;
155 ConstIterator &operator=(const ConstIterator &other)
156 {
157 // rebind the reference
158 item.d = other.item.d;
159 item.i = other.item.i;
160 return *this;
161 }
162
163 value_type operator*() const { return { QCborValueRef(item.d, item.i - 1), item }; }
164 value_type operator[](qsizetype j) const { return *(*this + j); }
165 const QCborValueConstRef *operator->() const { return &item; }
166#if QT_VERSION >= QT_VERSION_CHECK(7,0,0)
167 QCborValueConstRef
168#else
169 QCborValue
170#endif
171 key() const { return QCborValueRef(item.d, item.i - 1); }
172 QCborValueConstRef value() const { return item; }
173
174#if QT_CORE_REMOVED_SINCE(6, 8)
175 bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
176 bool operator!=(const Iterator &o) const { return !operator==(o); }
177 bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
178 bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
179 bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
180 bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
181 bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
182 bool operator!=(const ConstIterator &o) const { return !operator==(o); }
183 bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
184 bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
185 bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
186 bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
187#endif
188 ConstIterator &operator++() { item.i += 2; return *this; }
189 ConstIterator operator++(int) { ConstIterator n = *this; item.i += 2; return n; }
190 ConstIterator &operator--() { item.i -= 2; return *this; }
191 ConstIterator operator--(int) { ConstIterator n = *this; item.i -= 2; return n; }
192 ConstIterator &operator+=(qsizetype j) { item.i += 2 * j; return *this; }
193 ConstIterator &operator-=(qsizetype j) { item.i -= 2 * j; return *this; }
194 ConstIterator operator+(qsizetype j) const { return ConstIterator{ item.d, item.i + 2 * j }; }
195 ConstIterator operator-(qsizetype j) const { return ConstIterator{ item.d, item.i - 2 * j }; }
196 qsizetype operator-(ConstIterator j) const { return (item.i - j.item.i) / 2; }
197 private:
198 // Helper functions
199 static bool comparesEqual_helper(const ConstIterator &lhs,
200 const ConstIterator &rhs) noexcept
201 {
202 return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i;
203 }
204 static Qt::strong_ordering compareThreeWay_helper(const ConstIterator &lhs,
205 const ConstIterator &rhs)
206 {
207 Q_ASSERT(lhs.item.d == rhs.item.d);
208 return Qt::compareThreeWay(lhs: lhs.item.i, rhs: rhs.item.i);
209 }
210
211 // Compare friends
212 friend bool comparesEqual(const ConstIterator &lhs, const ConstIterator &rhs) noexcept
213 {
214 return comparesEqual_helper(lhs, rhs);
215 }
216 friend Qt::strong_ordering compareThreeWay(const ConstIterator &lhs,
217 const ConstIterator &rhs)
218 {
219 return compareThreeWay_helper(lhs, rhs);
220 }
221 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(ConstIterator)
222 };
223
224 QCborMap() noexcept;
225 QCborMap(const QCborMap &other) noexcept;
226 QCborMap &operator=(const QCborMap &other) noexcept;
227 QCborMap(std::initializer_list<value_type> args)
228 : QCborMap()
229 {
230 detach(reserve: args.size());
231 for (const auto &pair : args)
232 insert(key: pair.first, value_: pair.second);
233 }
234 ~QCborMap();
235
236 void swap(QCborMap &other) noexcept
237 {
238 d.swap(other&: other.d);
239 }
240
241 QCborValue toCborValue() const { return *this; }
242
243 qsizetype size() const noexcept Q_DECL_PURE_FUNCTION;
244 bool isEmpty() const { return size() == 0; }
245 void clear();
246 QList<QCborValue> keys() const;
247
248 QCborValue value(qint64 key) const
249 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
250 QCborValue value(QLatin1StringView key) const
251 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
252 QCborValue value(const QString & key) const
253 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
254 QCborValue value(const QCborValue &key) const
255 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
256#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
257 template<size_t N> QT_ASCII_CAST_WARN const QCborValue value(const char (&key)[N]) const
258 { return value(QString::fromUtf8(key, N - 1)); }
259#endif
260 const QCborValue operator[](qint64 key) const
261 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
262 const QCborValue operator[](QLatin1StringView key) const
263 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
264 const QCborValue operator[](const QString & key) const
265 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
266 const QCborValue operator[](const QCborValue &key) const
267 { const_iterator it = find(key); return comparesEqual(lhs: it, rhs: end()) ? QCborValue() : it.value(); }
268#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
269 template<size_t N> QT_ASCII_CAST_WARN const QCborValue operator[](const char (&key)[N]) const
270 { return operator[](QString::fromUtf8(key, N - 1)); }
271#endif
272 QCborValueRef operator[](qint64 key);
273 QCborValueRef operator[](QLatin1StringView key);
274 QCborValueRef operator[](const QString & key);
275 QCborValueRef operator[](const QCborValue &key);
276
277 QCborValue take(qint64 key)
278 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) return extract(it); return QCborValue(); }
279 QCborValue take(QLatin1StringView key)
280 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) return extract(it); return QCborValue(); }
281 QCborValue take(const QString &key)
282 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) return extract(it); return QCborValue(); }
283 QCborValue take(const QCborValue &key)
284 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) return extract(it); return QCborValue(); }
285 void remove(qint64 key)
286 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) erase(it); }
287 void remove(QLatin1StringView key)
288 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) erase(it); }
289 void remove(const QString & key)
290 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) erase(it); }
291 void remove(const QCborValue &key)
292 { const_iterator it = constFind(key); if (!comparesEqual(lhs: it, rhs: constEnd())) erase(it); }
293 bool contains(qint64 key) const
294 { const_iterator it = find(key); return !comparesEqual(lhs: it, rhs: end()); }
295 bool contains(QLatin1StringView key) const
296 { const_iterator it = find(key); return !comparesEqual(lhs: it, rhs: end()); }
297 bool contains(const QString & key) const
298 { const_iterator it = find(key); return !comparesEqual(lhs: it, rhs: end()); }
299 bool contains(const QCborValue &key) const
300 { const_iterator it = find(key); return !comparesEqual(lhs: it, rhs: end()); }
301
302 int compare(const QCborMap &other) const noexcept Q_DECL_PURE_FUNCTION;
303#if QT_CORE_REMOVED_SINCE(6, 8)
304 bool operator==(const QCborMap &other) const noexcept
305 { return compare(other) == 0; }
306 bool operator!=(const QCborMap &other) const noexcept
307 { return !operator==(other); }
308 bool operator<(const QCborMap &other) const
309 { return compare(other) < 0; }
310#endif
311
312 typedef Iterator iterator;
313 typedef ConstIterator const_iterator;
314 iterator begin() { detach(); return iterator{d.data(), 1}; }
315 const_iterator constBegin() const { return const_iterator{d.data(), 1}; }
316 const_iterator begin() const { return constBegin(); }
317 const_iterator cbegin() const { return constBegin(); }
318 iterator end() { detach(); return iterator{d.data(), 2 * size() + 1}; }
319 const_iterator constEnd() const { return const_iterator{d.data(), 2 * size() + 1}; }
320 const_iterator end() const { return constEnd(); }
321 const_iterator cend() const { return constEnd(); }
322 iterator erase(iterator it);
323 iterator erase(const_iterator it) { return erase(it: iterator{ it.item.d, it.item.i }); }
324 QCborValue extract(iterator it);
325 QCborValue extract(const_iterator it) { return extract(it: iterator{ it.item.d, it.item.i }); }
326 bool empty() const { return isEmpty(); }
327
328 iterator find(qint64 key);
329 iterator find(QLatin1StringView key);
330 iterator find(const QString & key);
331 iterator find(const QCborValue &key);
332 const_iterator constFind(qint64 key) const;
333 const_iterator constFind(QLatin1StringView key) const;
334 const_iterator constFind(const QString & key) const;
335 const_iterator constFind(const QCborValue &key) const;
336 const_iterator find(qint64 key) const { return constFind(key); }
337 const_iterator find(QLatin1StringView key) const { return constFind(key); }
338 const_iterator find(const QString & key) const { return constFind(key); }
339 const_iterator find(const QCborValue &key) const { return constFind(key); }
340
341 iterator insert(qint64 key, const QCborValue &value_)
342 {
343 QCborValueRef v = operator[](key); // detaches
344 v = value_;
345 return { d.data(), v.i };
346 }
347 iterator insert(QLatin1StringView key, const QCborValue &value_)
348 {
349 QCborValueRef v = operator[](key); // detaches
350 v = value_;
351 return { d.data(), v.i };
352 }
353 iterator insert(const QString &key, const QCborValue &value_)
354 {
355 QCborValueRef v = operator[](key); // detaches
356 v = value_;
357 return { d.data(), v.i };
358 }
359 iterator insert(const QCborValue &key, const QCborValue &value_)
360 {
361 QCborValueRef v = operator[](key); // detaches
362 v = value_;
363 return { d.data(), v.i };
364 }
365 iterator insert(value_type v) { return insert(key: v.first, value_: v.second); }
366
367 static QCborMap fromVariantMap(const QVariantMap &map);
368 static QCborMap fromVariantHash(const QVariantHash &hash);
369 static QCborMap fromJsonObject(const QJsonObject &o);
370 static QCborMap fromJsonObject(QJsonObject &&o) noexcept;
371 QVariantMap toVariantMap() const;
372 QVariantHash toVariantHash() const;
373 QJsonObject toJsonObject() const;
374
375private:
376 friend class QCborContainerPrivate;
377 friend class QCborValue;
378 friend class QCborValueRef;
379 friend class QJsonPrivate::Variant;
380 void detach(qsizetype reserve = 0);
381
382 friend Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool
383 comparesEqual(const QCborMap &lhs, const QCborMap &rhs) noexcept;
384 friend Qt::strong_ordering compareThreeWay(const QCborMap &lhs,
385 const QCborMap &rhs) noexcept
386 {
387 int c = lhs.compare(other: rhs);
388 return Qt::compareThreeWay(lhs: c, rhs: 0);
389 }
390 Q_DECLARE_STRONGLY_ORDERED(QCborMap)
391
392 static Q_DECL_PURE_FUNCTION bool
393 comparesEqual_helper(const QCborMap &lhs, const QCborValue &rhs) noexcept;
394 static Q_DECL_PURE_FUNCTION Qt::strong_ordering
395 compareThreeWay_helper(const QCborMap &lhs, const QCborValue &rhs) noexcept;
396 friend bool comparesEqual(const QCborMap &lhs,
397 const QCborValue &rhs) noexcept
398 {
399 return comparesEqual_helper(lhs, rhs);
400 }
401 friend Qt::strong_ordering compareThreeWay(const QCborMap &lhs,
402 const QCborValue &rhs) noexcept
403 {
404 return compareThreeWay_helper(lhs, rhs);
405 }
406 Q_DECLARE_STRONGLY_ORDERED(QCborMap, QCborValue)
407
408 static Q_DECL_PURE_FUNCTION bool
409 comparesEqual_helper(const QCborMap &lhs, QCborValueConstRef rhs) noexcept;
410 static Q_DECL_PURE_FUNCTION Qt::strong_ordering
411 compareThreeWay_helper(const QCborMap &lhs, QCborValueConstRef rhs) noexcept;
412 friend bool comparesEqual(const QCborMap &lhs,
413 const QCborValueConstRef &rhs) noexcept
414 {
415 return comparesEqual_helper(lhs, rhs);
416 }
417 friend Qt::strong_ordering compareThreeWay(const QCborMap &lhs,
418 const QCborValueConstRef &rhs) noexcept
419 {
420 return compareThreeWay_helper(lhs, rhs);
421 }
422 Q_DECLARE_STRONGLY_ORDERED(QCborMap, QCborValueConstRef)
423
424 explicit QCborMap(QCborContainerPrivate &dd) noexcept;
425 QExplicitlySharedDataPointer<QCborContainerPrivate> d;
426};
427
428Q_DECLARE_SHARED(QCborMap)
429
430inline QCborValue::QCborValue(QCborMap &&m)
431 : n(-1), container(m.d.take()), t(Map)
432{
433}
434
435#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
436inline QCborMap QCborValueRef::toMap() const
437{
438 return concrete().toMap();
439}
440
441inline QCborMap QCborValueRef::toMap(const QCborMap &m) const
442{
443 return concrete().toMap(defaultValue: m);
444}
445#endif
446
447inline QCborMap QCborValueConstRef::toMap() const
448{
449 return concrete().toMap();
450}
451
452inline QCborMap QCborValueConstRef::toMap(const QCborMap &m) const
453{
454 return concrete().toMap(defaultValue: m);
455}
456
457Q_CORE_EXPORT size_t qHash(const QCborMap &map, size_t seed = 0);
458
459#if !defined(QT_NO_DEBUG_STREAM)
460Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m);
461#endif
462
463#ifndef QT_NO_DATASTREAM
464#if QT_CONFIG(cborstreamwriter)
465Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QCborMap &);
466#endif
467Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QCborMap &);
468#endif
469
470
471QT_END_NAMESPACE
472
473#endif // QCBORMAP_H
474

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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