Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qassociativeiterable.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 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#include <QtCore/qassociativeiterable.h>
5#include <QtCore/qiterable_impl.h>
6#include <QtCore/qvariant.h>
7
9
10/*!
11 Returns the key this iterator points to.
12*/
13QVariant QAssociativeIterator::key() const
14{
15 return QIterablePrivate::retrieveElement(
16 metaContainer().keyMetaType(), [this](void *dataPtr) {
17 metaContainer().keyAtIterator(constIterator(), dataPtr);
18 });
19}
20
21/*!
22 Returns the mapped value this iterator points to. If the container does not
23 provide a mapped value (for example a set), returns an invalid QVariantRef.
24*/
25QVariantRef<QAssociativeIterator> QAssociativeIterator::value() const
26{
27 const QMetaType mappedMetaType(metaContainer().mappedMetaType());
28 return QVariantRef<QAssociativeIterator>(mappedMetaType.isValid() ? this : nullptr);
29}
30
31/*!
32 Returns the current item, converted to a QVariantRef. The resulting
33 QVariantRef resolves to the mapped value if there is one, or to the key
34 value if not.
35*/
36QVariantRef<QAssociativeIterator> QAssociativeIterator::operator*() const
37{
38 return QVariantRef<QAssociativeIterator>(this);
39}
40
41/*!
42 Returns the current item, converted to a QVariantPointer. The resulting
43 QVariantPointer resolves to the mapped value if there is one, or to the key
44 value if not.
45*/
46QVariantPointer<QAssociativeIterator> QAssociativeIterator::operator->() const
47{
48 return QVariantPointer<QAssociativeIterator>(this);
49}
50
51/*!
52 Returns the key this iterator points to.
53*/
54QVariant QAssociativeConstIterator::key() const
55{
56 return QIterablePrivate::retrieveElement(
57 metaContainer().keyMetaType(), [this](void *dataPtr) {
58 metaContainer().keyAtConstIterator(constIterator(), dataPtr);
59 });
60}
61
62/*!
63 Returns the mapped value this iterator points to, or an invalid QVariant if
64 there is no mapped value.
65*/
66QVariant QAssociativeConstIterator::value() const
67{
68 return QIterablePrivate::retrieveElement(
69 metaContainer().mappedMetaType(), [this](void *dataPtr) {
70 metaContainer().mappedAtConstIterator(constIterator(), dataPtr);
71 });
72}
73
74/*!
75 Returns the current item, converted to a QVariant. The returned value is the
76 mapped value at the current iterator if there is one, or otherwise the key.
77*/
78QVariant QAssociativeConstIterator::operator*() const
79{
80 const QMetaType mappedMetaType(metaContainer().mappedMetaType());
81 return mappedMetaType.isValid() ? value() : key();
82}
83
84/*!
85 Returns the current item, converted to a QVariantConstPointer. The
86 QVariantConstPointer will resolve to the mapped value at the current
87 iterator if there is one, or otherwise the key.
88*/
89QVariantConstPointer QAssociativeConstIterator::operator->() const
90{
91 return QVariantConstPointer(operator*());
92}
93
94/*!
95 \class QAssociativeIterable
96 \since 5.2
97 \inmodule QtCore
98 \brief The QAssociativeIterable class is an iterable interface for an associative container in a QVariant.
99
100 This class allows several methods of accessing the elements of an associative container held within
101 a QVariant. An instance of QAssociativeIterable can be extracted from a QVariant if it can
102 be converted to a QVariantHash or QVariantMap or if a custom mutable view has been registered.
103
104 \snippet code/src_corelib_kernel_qvariant.cpp 10
105
106 The container itself is not copied before iterating over it.
107
108 \sa QVariant
109*/
110
111/*!
112 \typedef QAssociativeIterable::RandomAccessIterator
113 Exposes an iterator using std::random_access_iterator_tag.
114*/
115
116/*!
117 \typedef QAssociativeIterable::BidirectionalIterator
118 Exposes an iterator using std::bidirectional_iterator_tag.
119*/
120
121/*!
122 \typedef QAssociativeIterable::ForwardIterator
123 Exposes an iterator using std::forward_iterator_tag.
124*/
125
126/*!
127 \typedef QAssociativeIterable::InputIterator
128 Exposes an iterator using std::input_iterator_tag.
129*/
130
131/*!
132 \typedef QAssociativeIterable::RandomAccessConstIterator
133 Exposes a const_iterator using std::random_access_iterator_tag.
134*/
135
136/*!
137 \typedef QAssociativeIterable::BidirectionalConstIterator
138 Exposes a const_iterator using std::bidirectional_iterator_tag.
139*/
140
141/*!
142 \typedef QAssociativeIterable::ForwardConstIterator
143 Exposes a const_iterator using std::forward_iterator_tag.
144*/
145
146/*!
147 \typedef QAssociativeIterable::InputConstIterator
148 Exposes a const_iterator using std::input_iterator_tag.
149*/
150
151/*!
152 Retrieves a const_iterator pointing to the element at the given \a key, or
153 the end of the container if that key does not exist. If the \a key isn't
154 convertible to the expected type, the end of the container is returned.
155 */
156QAssociativeIterable::const_iterator QAssociativeIterable::find(const QVariant &key) const
157{
158 const QMetaAssociation meta = metaContainer();
159 QtPrivate::QVariantTypeCoercer coercer;
160 if (const void *keyData = coercer.convert(key, meta.keyMetaType())) {
161 return const_iterator(QConstIterator(this, meta.createConstIteratorAtKey(
162 constIterable(), keyData)));
163 }
164 return constEnd();
165}
166
167/*!
168 Retrieves an iterator pointing to the element at the given \a key, or
169 the end of the container if that key does not exist. If the \a key isn't
170 convertible to the expected type, the end of the container is returned.
171 */
172QAssociativeIterable::iterator QAssociativeIterable::mutableFind(const QVariant &key)
173{
174 const QMetaAssociation meta = metaContainer();
175 QtPrivate::QVariantTypeCoercer coercer;
176 if (const void *keyData = coercer.convert(key, meta.keyMetaType()))
177 return iterator(QIterator(this, meta.createIteratorAtKey(mutableIterable(), keyData)));
178 return mutableEnd();
179}
180
181/*!
182 Returns \c true if the container has an entry with the given \a key, or
183 \c false otherwise. If the \a key isn't convertible to the expected type,
184 \c false is returned.
185 */
186bool QAssociativeIterable::containsKey(const QVariant &key)
187{
188 QtPrivate::QVariantTypeCoercer keyCoercer;
189 QMetaAssociation meta = metaContainer();
190 if (const void *keyData = keyCoercer.convert(key, meta.keyMetaType()))
191 return meta.containsKey(constIterable(), keyData);
192 return false;
193}
194
195/*!
196 Inserts a new entry with the given \a key, or resets the mapped value of
197 any existing entry with the given \a key to the default constructed
198 mapped value. The \a key is coerced to the expected type: If it isn't
199 convertible, a default value is inserted.
200 */
201void QAssociativeIterable::insertKey(const QVariant &key)
202{
203 QMetaAssociation meta = metaContainer();
204 QtPrivate::QVariantTypeCoercer keyCoercer;
205 meta.insertKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()));
206}
207
208/*!
209 Removes the entry with the given \a key from the container. The \a key is
210 coerced to the expected type: If it isn't convertible, the default value
211 is removed.
212 */
213void QAssociativeIterable::removeKey(const QVariant &key)
214{
215 QMetaAssociation meta = metaContainer();
216 QtPrivate::QVariantTypeCoercer keyCoercer;
217 meta.removeKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()));
218}
219
220
221/*!
222 Retrieves the mapped value at the given \a key, or a default-constructed
223 QVariant of the mapped type, if the key does not exist. If the \a key is not
224 convertible to the key type, the mapped value associated with the
225 default-constructed key is returned.
226 */
227QVariant QAssociativeIterable::value(const QVariant &key) const
228{
229 const QMetaAssociation meta = metaContainer();
230 const QMetaType mappedMetaType = meta.mappedMetaType();
231
232 QtPrivate::QVariantTypeCoercer coercer;
233 const void *keyData = coercer.coerce(key, meta.keyMetaType());
234
235 if (mappedMetaType == QMetaType::fromType<QVariant>()) {
236 QVariant result;
237 meta.mappedAtKey(constIterable(), keyData, &result);
238 return result;
239 }
240
241 QVariant result(mappedMetaType);
242 meta.mappedAtKey(constIterable(), keyData, result.data());
243 return result;
244}
245
246/*!
247 Sets the mapped value associated with \a key to \a mapped, if possible.
248 Inserts a new entry if none exists yet, for the given \a key. If the \a key
249 is not convertible to the key type, the value for the default-constructed
250 key type is overwritten.
251 */
252void QAssociativeIterable::setValue(const QVariant &key, const QVariant &mapped)
253{
254 QtPrivate::QVariantTypeCoercer keyCoercer;
255 QtPrivate::QVariantTypeCoercer mappedCoercer;
256 QMetaAssociation meta = metaContainer();
257 meta.setMappedAtKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()),
258 mappedCoercer.coerce(mapped, meta.mappedMetaType()));
259}
260
261/*!
262 \typealias QAssociativeIterable::const_iterator
263 \inmodule QtCore
264 \brief The QAssociativeIterable::const_iterator allows iteration over a container in a QVariant.
265
266 A QAssociativeIterable::const_iterator can only be created by a QAssociativeIterable instance,
267 and can be used in a way similar to other stl-style iterators.
268
269 \snippet code/src_corelib_kernel_qvariant.cpp 10
270
271 \sa QAssociativeIterable
272*/
273
274/*!
275 \typealias QAssociativeIterable::iterator
276 \since 6.0
277 \inmodule QtCore
278 \brief The QAssociativeIterable::iterator allows iteration over a container in a QVariant.
279
280 A QAssociativeIterable::iterator can only be created by a QAssociativeIterable instance,
281 and can be used in a way similar to other stl-style iterators.
282
283 \sa QAssociativeIterable
284*/
285
286QT_END_NAMESPACE
\inmodule QtCore
Definition qvariant.h:66