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
qmetasequence.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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// Qt-Security score:significant reason:default
4
5#include <QtCore/qmetasequence.h>
6#include <QtCore/qmetatype.h>
7
9
10/*!
11 \class QMetaSequence
12 \inmodule QtCore
13 \since 6.0
14 \brief The QMetaSequence class allows type erased access to sequential containers.
15
16 \ingroup objectmodel
17
18 \compares equality
19
20 The class provides a number of primitive container operations, using void*
21 as operands. This way, you can manipulate a generic container retrieved from
22 a Variant without knowing its type.
23
24 The void* arguments to the various methods are typically created by using
25 a \l QVariant of the respective container or value type, and calling
26 its \l QVariant::data() or \l QVariant::constData() methods. However, you
27 can also pass plain pointers to objects of the container or value type.
28
29 Iterator invalidation follows the rules given by the underlying containers
30 and is not expressed in the API. Therefore, for a truly generic container,
31 any iterators should be considered invalid after any write operation.
32*/
33
34/*!
35 \fn template<typename C> QMetaSequence QMetaSequence::fromContainer()
36 \since 6.0
37
38 Returns the QMetaSequence corresponding to the type given as template parameter.
39*/
40
41/*!
42 Returns the meta type for values stored in the container.
43 */
44QMetaType QMetaSequence::valueMetaType() const
45{
46 if (auto iface = d())
47 return QMetaType(iface->valueMetaType);
48 return QMetaType();
49}
50
51/*!
52 Returns \c true if the underlying container is sortable, otherwise returns
53 \c false. A container is considered sortable if values added to it are
54 placed in a defined location. Inserting into or adding to a sortable
55 container will always succeed. Inserting into or adding to an unsortable
56 container may not succeed, for example if the container is a QSet that
57 already contains the value being inserted.
58
59 \sa addValue(), insertValueAtIterator(), canAddValueAtBegin(),
60 canAddValueAtEnd(), canRemoveValueAtBegin(), canRemoveValueAtEnd()
61 */
62bool QMetaSequence::isSortable() const
63{
64 if (auto iface = d()) {
65 return (iface->addRemoveCapabilities
66 & (QtMetaContainerPrivate::CanAddAtBegin | QtMetaContainerPrivate::CanAddAtEnd))
67 && (iface->addRemoveCapabilities
68 & (QtMetaContainerPrivate::CanRemoveAtBegin
69 | QtMetaContainerPrivate::CanRemoveAtEnd));
70 }
71 return false;
72}
73
74/*!
75 Returns \c true if values added using \l addValue() can be placed at the
76 beginning of the container, otherwise returns \c false.
77
78 \sa addValueAtBegin(), canAddValueAtEnd()
79 */
80bool QMetaSequence::canAddValueAtBegin() const
81{
82 if (auto iface = d()) {
83 return iface->addValueFn
84 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtBegin;
85 }
86 return false;
87}
88
89/*!
90 Adds \a value to the beginning of \a container if possible. If
91 \l canAddValueAtBegin() returns \c false, the \a value is not added.
92
93 \sa canAddValueAtBegin(), isSortable(), removeValueAtBegin()
94 */
95void QMetaSequence::addValueAtBegin(void *container, const void *value) const
96{
97 if (canAddValueAtBegin())
98 d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
99}
100
101/*!
102 Returns \c true if values can be removed from the beginning of the container
103 using \l removeValue(), otherwise returns \c false.
104
105 \sa removeValueAtBegin(), canRemoveValueAtEnd()
106 */
107bool QMetaSequence::canRemoveValueAtBegin() const
108{
109 if (auto iface = d()) {
110 return iface->removeValueFn
111 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtBegin;
112 }
113 return false;
114}
115
116/*!
117 Removes a value from the beginning of \a container if possible. If
118 \l canRemoveValueAtBegin() returns \c false, the value is not removed.
119
120 \sa canRemoveValueAtBegin(), isSortable(), addValueAtBegin()
121 */
122void QMetaSequence::removeValueAtBegin(void *container) const
123{
124 if (canRemoveValueAtBegin())
125 d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
126}
127
128/*!
129 Returns \c true if values added using \l addValue() can be placed at the
130 end of the container, otherwise returns \c false.
131
132 \sa addValueAtEnd(), canAddValueAtBegin()
133 */
134bool QMetaSequence::canAddValueAtEnd() const
135{
136 if (auto iface = d()) {
137 return iface->addValueFn
138 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtEnd;
139 }
140 return false;
141}
142
143/*!
144 Adds \a value to the end of \a container if possible. If
145 \l canAddValueAtEnd() returns \c false, the \a value is not added.
146
147 \sa canAddValueAtEnd(), isSortable(), removeValueAtEnd()
148 */
149void QMetaSequence::addValueAtEnd(void *container, const void *value) const
150{
151 if (canAddValueAtEnd())
152 d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
153}
154
155/*!
156 Returns \c true if values can be removed from the end of the container
157 using \l removeValue(), otherwise returns \c false.
158
159 \sa removeValueAtEnd(), canRemoveValueAtBegin()
160 */
161bool QMetaSequence::canRemoveValueAtEnd() const
162{
163 if (auto iface = d()) {
164 return iface->removeValueFn
165 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtEnd;
166 }
167 return false;
168}
169
170/*!
171 Removes a value from the end of \a container if possible. If
172 \l canRemoveValueAtEnd() returns \c false, the value is not removed.
173
174 \sa canRemoveValueAtEnd(), isSortable(), addValueAtEnd()
175 */
176void QMetaSequence::removeValueAtEnd(void *container) const
177{
178 if (canRemoveValueAtEnd())
179 d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
180}
181
182/*!
183 Returns \c true if values can be retrieved from the container by index,
184 otherwise \c false.
185
186 \sa valueAtIndex()
187 */
188bool QMetaSequence::canGetValueAtIndex() const
189{
190 if (auto iface = d())
191 return iface->valueAtIndexFn;
192 return false;
193}
194
195/*!
196 Retrieves the value at \a index in the \a container and places it in the
197 memory location pointed to by \a result, if that is possible.
198
199 \sa canGetValueAtIndex()
200 */
201void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *result) const
202{
203 if (canGetValueAtIndex())
204 d()->valueAtIndexFn(container, index, result);
205}
206
207/*!
208 Returns \c true if a value can be written to the container by index,
209 otherwise \c false.
210
211 \sa setValueAtIndex()
212*/
213bool QMetaSequence::canSetValueAtIndex() const
214{
215 if (auto iface = d())
216 return iface->setValueAtIndexFn;
217 return false;
218}
219
220/*!
221 Overwrites the value at \a index in the \a container using the \a value
222 passed as parameter if that is possible.
223
224 \sa canSetValueAtIndex()
225 */
226void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void *value) const
227{
228 if (canSetValueAtIndex())
229 d()->setValueAtIndexFn(container, index, value);
230}
231
232/*!
233 Returns \c true if values can be added to the container, \c false
234 otherwise.
235
236 \sa addValue(), isSortable()
237 */
238bool QMetaSequence::canAddValue() const
239{
240 if (auto iface = d())
241 return iface->addValueFn;
242 return false;
243}
244
245/*!
246 Adds \a value to the \a container if possible. If \l canAddValue()
247 returns \c false, the \a value is not added. Else, if
248 \l canAddValueAtEnd() returns \c true, the \a value is added
249 to the end of the \a container. Else, if
250 \l canAddValueAtBegin() returns \c true, the \a value is added to
251 the beginning of the container. Else, the value is added in an unspecified
252 place or not at all. The latter is the case for adding values to an
253 unordered container, for example \l QSet.
254
255 \sa canAddValue(), canAddValueAtBegin(),
256 canAddValueAtEnd(), isSortable(), removeValue()
257 */
258void QMetaSequence::addValue(void *container, const void *value) const
259{
260 if (canAddValue()) {
261 d()->addValueFn(container, value,
262 QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
263 }
264}
265
266/*!
267 Returns \c true if values can be removed from the container, \c false
268 otherwise.
269
270 \sa removeValue(), isSortable()
271 */
272bool QMetaSequence::canRemoveValue() const
273{
274 if (auto iface = d())
275 return iface->removeValueFn;
276 return false;
277}
278
279/*!
280 Removes a value from the \a container if possible. If
281 \l canRemoveValue() returns \c false, no value is removed. Else, if
282 \l canRemoveValueAtEnd() returns \c true, the last value in
283 the \a container is removed. Else, if \l canRemoveValueAtBegin()
284 returns \c true, the first value in the \a container is removed. Else,
285 an unspecified value or nothing is removed.
286
287 \sa canRemoveValue(), canRemoveValueAtBegin(),
288 canRemoveValueAtEnd(), isSortable(), addValue()
289 */
290void QMetaSequence::removeValue(void *container) const
291{
292 if (canRemoveValue()) {
293 d()->removeValueFn(container,
294 QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
295 }
296}
297
298
299/*!
300 Returns \c true if the underlying container can retrieve the value pointed
301 to by a non-const iterator, \c false otherwise.
302
303 \sa hasIterator(), valueAtIterator()
304 */
305bool QMetaSequence::canGetValueAtIterator() const
306{
307 if (auto iface = d())
308 return iface->valueAtIteratorFn;
309 return false;
310}
311
312/*!
313 Retrieves the value pointed to by the non-const \a iterator and stores it
314 in the memory location pointed to by \a result, if possible.
315
316 \sa canGetValueAtIterator(), begin(), end()
317 */
318void QMetaSequence::valueAtIterator(const void *iterator, void *result) const
319{
320 if (canGetValueAtIterator())
321 d()->valueAtIteratorFn(iterator, result);
322}
323
324/*!
325 Returns \c true if the underlying container can write to the value pointed
326 to by a non-const iterator, \c false otherwise.
327
328 \sa hasIterator(), setValueAtIterator()
329 */
330bool QMetaSequence::canSetValueAtIterator() const
331{
332 if (auto iface = d())
333 return iface->setValueAtIteratorFn;
334 return false;
335}
336
337/*!
338 Writes \a value to the value pointed to by the non-const \a iterator, if
339 possible.
340
341 \sa canSetValueAtIterator(), begin(), end()
342 */
343void QMetaSequence::setValueAtIterator(const void *iterator, const void *value) const
344{
345 if (canSetValueAtIterator())
346 d()->setValueAtIteratorFn(iterator, value);
347}
348
349/*!
350 Returns \c true if the underlying container can insert a new value, taking
351 the location pointed to by a non-const iterator into account.
352
353 \sa hasIterator(), insertValueAtIterator()
354 */
355bool QMetaSequence::canInsertValueAtIterator() const
356{
357 if (auto iface = d())
358 return iface->insertValueAtIteratorFn;
359 return false;
360}
361
362/*!
363 Inserts \a value into the \a container, if possible, taking the non-const
364 \a iterator into account. If \l canInsertValueAtIterator() returns
365 \c false, the \a value is not inserted. Else if \l isSortable() returns
366 \c true, the value is inserted before the value pointed to by
367 \a iterator. Else, the \a value is inserted at an unspecified place or not
368 at all. In the latter case, the \a iterator is taken as a hint. If it points
369 to the correct place for the \a value, the operation may be faster than a
370 \l addValue() without iterator.
371
372 \sa canInsertValueAtIterator(), isSortable(), begin(), end()
373 */
374void QMetaSequence::insertValueAtIterator(void *container, const void *iterator,
375 const void *value) const
376{
377 if (canInsertValueAtIterator())
378 d()->insertValueAtIteratorFn(container, iterator, value);
379}
380
381/*!
382 Returns \c true if the value pointed to by a non-const iterator can be
383 erased, \c false otherwise.
384
385 \sa hasIterator(), eraseValueAtIterator()
386 */
387bool QMetaSequence::canEraseValueAtIterator() const
388{
389 if (auto iface = d())
390 return iface->eraseValueAtIteratorFn;
391 return false;
392}
393
394/*!
395 Erases the value pointed to by the non-const \a iterator from the
396 \a container, if possible.
397
398 \sa canEraseValueAtIterator(), begin(), end()
399 */
400void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) const
401{
402 if (canEraseValueAtIterator())
403 d()->eraseValueAtIteratorFn(container, iterator);
404}
405
406/*!
407 Returns \c true if a range between two iterators can be erased from the
408 container, \c false otherwise.
409 */
410bool QMetaSequence::canEraseRangeAtIterator() const
411{
412 if (auto iface = d())
413 return iface->eraseRangeAtIteratorFn;
414 return false;
415}
416
417/*!
418 Erases the range of values between the iterators \a iterator1 and
419 \a iterator2 from the \a container, if possible.
420
421 \sa canEraseValueAtIterator(), begin(), end()
422 */
423void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1,
424 const void *iterator2) const
425{
426 if (canEraseRangeAtIterator())
427 d()->eraseRangeAtIteratorFn(container, iterator1, iterator2);
428}
429
430
431/*!
432 Returns \c true if the underlying container can retrieve the value pointed
433 to by a const iterator, \c false otherwise.
434
435 \sa hasConstIterator(), valueAtConstIterator()
436 */
437bool QMetaSequence::canGetValueAtConstIterator() const
438{
439 if (auto iface = d())
440 return iface->valueAtConstIteratorFn;
441 return false;
442}
443
444/*!
445 Retrieves the value pointed to by the const \a iterator and stores it
446 in the memory location pointed to by \a result, if possible.
447
448 \sa canGetValueAtConstIterator(), constBegin(), constEnd()
449 */
450void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) const
451{
452 if (canGetValueAtConstIterator())
453 d()->valueAtConstIteratorFn(iterator, result);
454}
455
456/*!
457 \fn bool QMetaSequence::operator==(const QMetaSequence &lhs, const QMetaSequence &rhs)
458 \since 6.0
459
460 Returns \c true if the QMetaSequence \a lhs represents the same container type
461 as the QMetaSequence \a rhs, otherwise returns \c false.
462*/
463
464/*!
465 \fn bool QMetaSequence::operator!=(const QMetaSequence &lhs, const QMetaSequence &rhs)
466 \since 6.0
467
468 Returns \c true if the QMetaSequence \a lhs represents a different container
469 type than the QMetaSequence \a rhs, otherwise returns \c false.
470*/
471
472/*!
473 \class QMetaSequence::Iterable
474 \inherits QIterable
475 \since 6.11
476 \inmodule QtCore
477 \brief The QMetaSequence::Iterable class is an iterable interface for a container in a QVariant.
478
479 This class allows several methods of accessing the values of a container
480 held within a QVariant. An instance of QMetaSequence::Iterable can be
481 extracted from a QVariant if it can be converted to a QVariantList, or if
482 the container it contains is registered using
483 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE. Most sequential containers found
484 in Qt and some found in the C++ standard library are automatically
485 registered.
486
487 \snippet code/src_corelib_kernel_qvariant.cpp 9
488
489 The container itself is not copied before iterating over it.
490
491 \sa QVariant
492*/
493
494/*!
495 \typealias QMetaSequence::Iterable::RandomAccessIterator
496 Exposes an iterator using std::random_access_iterator_tag.
497*/
498
499/*!
500 \typealias QMetaSequence::Iterable::BidirectionalIterator
501 Exposes an iterator using std::bidirectional_iterator_tag.
502*/
503
504/*!
505 \typealias QMetaSequence::Iterable::ForwardIterator
506 Exposes an iterator using std::forward_iterator_tag.
507*/
508
509/*!
510 \typealias QMetaSequence::Iterable::InputIterator
511 Exposes an iterator using std::input_iterator_tag.
512*/
513
514/*!
515 \typealias QMetaSequence::Iterable::RandomAccessConstIterator
516 Exposes a const_iterator using std::random_access_iterator_tag.
517*/
518
519/*!
520 \typealias QMetaSequence::Iterable::BidirectionalConstIterator
521 Exposes a const_iterator using std::bidirectional_iterator_tag.
522*/
523
524/*!
525 \typealias QMetaSequence::Iterable::ForwardConstIterator
526 Exposes a const_iterator using std::forward_iterator_tag.
527*/
528
529/*!
530 \typealias QMetaSequence::Iterable::InputConstIterator
531 Exposes a const_iterator using std::input_iterator_tag.
532*/
533
534/*!
535 \fn QVariant QMetaSequence::Iterable::at(qsizetype idx) const
536 Returns the value at position \a idx in the container.
537
538 \note If the underlying container does not provide a native way to retrieve
539 an element at an index, this method will synthesize the access using
540 iterators. This behavior is deprecated and will be removed in a future
541 version of Qt.
542*/
543
544/*!
545 \fn void QMetaSequence::Iterable::setAt(qsizetype idx, const QVariant &value)
546 Sets the element at position \a idx in the container to \a value.
547*/
548
549/*!
550 \class QMetaSequence::Iterable::ConstIterator
551 \inmodule QtCore
552 \inherits QConstIterator
553 \since 6.11
554 \brief QMetaSequence::Iterable::ConstIterator allows iteration over a container in a QVariant.
555
556 A QMetaSequence::Iterable::ConstIterator can only be created by a
557 QMetaSequence::Iterable instance, and can be used in a way similar to other
558 stl-style iterators.
559
560 \snippet code/src_corelib_kernel_qvariant.cpp 9
561*/
562
563/*!
564 \class QMetaSequence::Iterable::Iterator
565 \inmodule QtCore
566 \inherits QIterator
567 \since 6.11
568 \brief QMetaSequence::Iterable::Iterator allows iteration over a container in a QVariant.
569
570 A QMetaSequence::Iterable::Iterator can only be created by a QMetaSequence::Iterable
571 instance, and can be used in a way similar to other stl-style iterators.
572*/
573
574/*!
575 \fn QVariant::Reference<QMetaSequence::Iterable::Iterator> QMetaSequence::Iterable::Iterator::operator*() const
576 Returns the current item, converted to a QVariant::Reference.
577*/
578
579/*!
580 \fn QVariant::Pointer<QMetaSequence::Iterable::Iterator> QMetaSequence::Iterable::Iterator::operator->() const
581 Returns the current item, converted to a QVariant::Pointer.
582*/
583
584/*!
585 \fn QVariant::Reference<QMetaSequence::Iterable::Iterator> QMetaSequence::Iterable::Iterator::operator[](qsizetype n) const
586 Returns the item offset from the current one by \a n, converted to a
587 QVariant::Reference.
588*/
589
590/*!
591 \fn QVariant QMetaSequence::Iterable::ConstIterator::operator*() const
592 Returns the current item, converted to a QVariant.
593*/
594
595/*!
596 \fn QVariant::ConstPointer<QMetaSequence::Iterable::ConstIterator> QMetaSequence::Iterable::ConstIterator::operator->() const
597 Returns the current item, converted to a QVariant::ConstPointer.
598*/
599
600/*!
601 \fn QVariant QMetaSequence::Iterable::ConstIterator::operator[](qsizetype n) const
602 Returns the item offset from the current one by \a n, converted to a
603 QVariant.
604*/
605
606QT_END_NAMESPACE
\inmodule QtCore
Definition qmetatype.h:383