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 "qmetacontainer.h"
5#include "qmetatype.h"
6
7QT_BEGIN_NAMESPACE
8
9/*!
10 \class QMetaSequence
11 \inmodule QtCore
12 \since 6.0
13 \brief The QMetaSequence class allows type erased access to sequential containers.
14
15 \ingroup objectmodel
16
17 \compares equality
18
19 The class provides a number of primitive container operations, using void*
20 as operands. This way, you can manipulate a generic container retrieved from
21 a Variant without knowing its type.
22
23 The void* arguments to the various methods are typically created by using
24 a \l QVariant of the respective container or value type, and calling
25 its \l QVariant::data() or \l QVariant::constData() methods. However, you
26 can also pass plain pointers to objects of the container or value type.
27
28 Iterator invalidation follows the rules given by the underlying containers
29 and is not expressed in the API. Therefore, for a truly generic container,
30 any iterators should be considered invalid after any write operation.
31*/
32
33/*!
34 \fn template<typename C> QMetaSequence QMetaSequence::fromContainer()
35 \since 6.0
36
37 Returns the QMetaSequence corresponding to the type given as template parameter.
38*/
39
40/*!
41 \class QMetaContainer
42 \inmodule QtCore
43 \since 6.0
44 \brief The QMetaContainer class provides common functionality for sequential
45 and associative containers.
46
47 \ingroup objectmodel
48
49 \compares equality
50*/
51
52/*!
53 Returns \c true if the underlying container provides at least an input
54 iterator as defined by std::input_iterator_tag, otherwise returns
55 \c false. Forward, Bi-directional, and random access iterators are
56 specializations of input iterators. This method will also return
57 \c true if the container provides one of those.
58
59 QMetaSequence assumes that const and non-const iterators for the same
60 container have the same iterator traits.
61 */
62bool QMetaContainer::hasInputIterator() const
63{
64 if (!d_ptr)
65 return false;
66 return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::InputCapability);
67}
68
69/*!
70 Returns \c true if the underlying container provides at least a forward
71 iterator as defined by std::forward_iterator_tag, otherwise returns
72 \c false. Bi-directional iterators and random access iterators are
73 specializations of forward iterators. This method will also return
74 \c true if the container provides one of those.
75
76 QMetaSequence assumes that const and non-const iterators for the same
77 container have the same iterator traits.
78 */
79bool QMetaContainer::hasForwardIterator() const
80{
81 if (!d_ptr)
82 return false;
83 return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::ForwardCapability);
84}
85
86/*!
87 Returns \c true if the underlying container provides a bi-directional
88 iterator or a random access iterator as defined by
89 std::bidirectional_iterator_tag and std::random_access_iterator_tag,
90 respectively. Otherwise returns \c false.
91
92 QMetaSequence assumes that const and non-const iterators for the same
93 container have the same iterator traits.
94 */
95bool QMetaContainer::hasBidirectionalIterator() const
96{
97 if (!d_ptr)
98 return false;
99 return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::BiDirectionalCapability);
100}
101
102/*!
103 Returns \c true if the underlying container provides a random access
104 iterator as defined by std::random_access_iterator_tag, otherwise returns
105 \c false.
106
107 QMetaSequence assumes that const and non-const iterators for the same
108 container have the same iterator traits.
109 */
110bool QMetaContainer::hasRandomAccessIterator() const
111{
112 if (!d_ptr)
113 return false;
114 return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::RandomAccessCapability);
115}
116
117/*!
118 Returns the meta type for values stored in the container.
119 */
120QMetaType QMetaSequence::valueMetaType() const
121{
122 if (auto iface = d())
123 return QMetaType(iface->valueMetaType);
124 return QMetaType();
125}
126
127/*!
128 Returns \c true if the underlying container is sortable, otherwise returns
129 \c false. A container is considered sortable if values added to it are
130 placed in a defined location. Inserting into or adding to a sortable
131 container will always succeed. Inserting into or adding to an unsortable
132 container may not succeed, for example if the container is a QSet that
133 already contains the value being inserted.
134
135 \sa addValue(), insertValueAtIterator(), canAddValueAtBegin(),
136 canAddValueAtEnd(), canRemoveValueAtBegin(), canRemoveValueAtEnd()
137 */
138bool QMetaSequence::isSortable() const
139{
140 if (auto iface = d()) {
141 return (iface->addRemoveCapabilities
142 & (QtMetaContainerPrivate::CanAddAtBegin | QtMetaContainerPrivate::CanAddAtEnd))
143 && (iface->addRemoveCapabilities
144 & (QtMetaContainerPrivate::CanRemoveAtBegin
145 | QtMetaContainerPrivate::CanRemoveAtEnd));
146 }
147 return false;
148}
149
150/*!
151 Returns \c true if values added using \l addValue() can be placed at the
152 beginning of the container, otherwise returns \c false.
153
154 \sa addValueAtBegin(), canAddValueAtEnd()
155 */
156bool QMetaSequence::canAddValueAtBegin() const
157{
158 if (auto iface = d()) {
159 return iface->addValueFn
160 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtBegin;
161 }
162 return false;
163}
164
165/*!
166 Adds \a value to the beginning of \a container if possible. If
167 \l canAddValueAtBegin() returns \c false, the \a value is not added.
168
169 \sa canAddValueAtBegin(), isSortable(), removeValueAtBegin()
170 */
171void QMetaSequence::addValueAtBegin(void *container, const void *value) const
172{
173 if (canAddValueAtBegin())
174 d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
175}
176
177/*!
178 Returns \c true if values can be removed from the beginning of the container
179 using \l removeValue() can be placed at the, otherwise returns \c false.
180
181 \sa removeValueAtBegin(), canRemoveValueAtEnd()
182 */
183bool QMetaSequence::canRemoveValueAtBegin() const
184{
185 if (auto iface = d()) {
186 return iface->removeValueFn
187 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtBegin;
188 }
189 return false;
190}
191
192/*!
193 Removes a value from the beginning of \a container if possible. If
194 \l canRemoveValueAtBegin() returns \c false, the value is not removed.
195
196 \sa canRemoveValueAtBegin(), isSortable(), addValueAtBegin()
197 */
198void QMetaSequence::removeValueAtBegin(void *container) const
199{
200 if (canRemoveValueAtBegin())
201 d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
202}
203
204/*!
205 Returns \c true if values added using \l addValue() can be placed at the
206 end of the container, otherwise returns \c false.
207
208 \sa addValueAtEnd(), canAddValueAtBegin()
209 */
210bool QMetaSequence::canAddValueAtEnd() const
211{
212 if (auto iface = d()) {
213 return iface->addValueFn
214 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtEnd;
215 }
216 return false;
217}
218
219/*!
220 Adds \a value to the end of \a container if possible. If
221 \l canAddValueAtEnd() returns \c false, the \a value is not added.
222
223 \sa canAddValueAtEnd(), isSortable(), removeValueAtEnd()
224 */
225void QMetaSequence::addValueAtEnd(void *container, const void *value) const
226{
227 if (canAddValueAtEnd())
228 d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
229}
230
231/*!
232 Returns \c true if values can be removed from the end of the container
233 using \l removeValue() can be placed at the, otherwise returns \c false.
234
235 \sa removeValueAtEnd(), canRemoveValueAtBegin()
236 */
237bool QMetaSequence::canRemoveValueAtEnd() const
238{
239 if (auto iface = d()) {
240 return iface->removeValueFn
241 && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtEnd;
242 }
243 return false;
244}
245
246/*!
247 Removes a value from the end of \a container if possible. If
248 \l canRemoveValueAtEnd() returns \c false, the value is not removed.
249
250 \sa canRemoveValueAtEnd(), isSortable(), addValueAtEnd()
251 */
252void QMetaSequence::removeValueAtEnd(void *container) const
253{
254 if (canRemoveValueAtEnd())
255 d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
256}
257
258/*!
259 Returns \c true if the container can be queried for its size, \c false
260 otherwise.
261
262 \sa size()
263 */
264bool QMetaContainer::hasSize() const
265{
266 return d_ptr && d_ptr->sizeFn;
267}
268
269/*!
270 Returns the number of values in the given \a container if it can be
271 queried for its size. Otherwise returns \c -1.
272
273 \sa hasSize()
274 */
275qsizetype QMetaContainer::size(const void *container) const
276{
277 return hasSize() ? d_ptr->sizeFn(container) : -1;
278}
279
280/*!
281 Returns \c true if the container can be cleared, \c false otherwise.
282
283 \sa clear()
284 */
285bool QMetaContainer::canClear() const
286{
287 return d_ptr && d_ptr->clearFn;
288}
289
290/*!
291 Clears the given \a container if it can be cleared.
292
293 \sa canClear()
294 */
295void QMetaContainer::clear(void *container) const
296{
297 if (canClear())
298 d_ptr->clearFn(container);
299}
300
301/*!
302 Returns \c true if values can be retrieved from the container by index,
303 otherwise \c false.
304
305 \sa valueAtIndex()
306 */
307bool QMetaSequence::canGetValueAtIndex() const
308{
309 if (auto iface = d())
310 return iface->valueAtIndexFn;
311 return false;
312}
313
314/*!
315 Retrieves the value at \a index in the \a container and places it in the
316 memory location pointed to by \a result, if that is possible.
317
318 \sa canGetValueAtIndex()
319 */
320void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *result) const
321{
322 if (canGetValueAtIndex())
323 d()->valueAtIndexFn(container, index, result);
324}
325
326/*!
327 Returns \c true if an value can be written to the container by index,
328 otherwise \c false.
329
330 \sa setValueAtIndex()
331*/
332bool QMetaSequence::canSetValueAtIndex() const
333{
334 if (auto iface = d())
335 return iface->setValueAtIndexFn;
336 return false;
337}
338
339/*!
340 Overwrites the value at \a index in the \a container using the \a value
341 passed as parameter if that is possible.
342
343 \sa canSetValueAtIndex()
344 */
345void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void *value) const
346{
347 if (canSetValueAtIndex())
348 d()->setValueAtIndexFn(container, index, value);
349}
350
351/*!
352 Returns \c true if values can be added to the container, \c false
353 otherwise.
354
355 \sa addValue(), isSortable()
356 */
357bool QMetaSequence::canAddValue() const
358{
359 if (auto iface = d())
360 return iface->addValueFn;
361 return false;
362}
363
364/*!
365 Adds \a value to the \a container if possible. If \l canAddValue()
366 returns \c false, the \a value is not added. Else, if
367 \l canAddValueAtEnd() returns \c true, the \a value is added
368 to the end of the \a container. Else, if
369 \l canAddValueAtBegin() returns \c true, the \a value is added to
370 the beginning of the container. Else, the value is added in an unspecified
371 place or not at all. The latter is the case for adding values to an
372 unordered container, for example \l QSet.
373
374 \sa canAddValue(), canAddValueAtBegin(),
375 canAddValueAtEnd(), isSortable(), removeValue()
376 */
377void QMetaSequence::addValue(void *container, const void *value) const
378{
379 if (canAddValue()) {
380 d()->addValueFn(container, value,
381 QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
382 }
383}
384
385/*!
386 Returns \c true if values can be removed from the container, \c false
387 otherwise.
388
389 \sa removeValue(), isSortable()
390 */
391bool QMetaSequence::canRemoveValue() const
392{
393 if (auto iface = d())
394 return iface->removeValueFn;
395 return false;
396}
397
398/*!
399 Removes an value from the \a container if possible. If
400 \l canRemoveValue() returns \c false, no value is removed. Else, if
401 \l canRemoveValueAtEnd() returns \c true, the last value in
402 the \a container is removed. Else, if \l canRemoveValueAtBegin()
403 returns \c true, the first value in the \a container is removed. Else,
404 an unspecified value or nothing is removed.
405
406 \sa canRemoveValue(), canRemoveValueAtBegin(),
407 canRemoveValueAtEnd(), isSortable(), addValue()
408 */
409void QMetaSequence::removeValue(void *container) const
410{
411 if (canRemoveValue()) {
412 d()->removeValueFn(container,
413 QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
414 }
415}
416
417/*!
418 Returns \c true if the underlying container offers a non-const iterator,
419 \c false otherwise.
420
421 \sa begin(), end(), destroyIterator(), compareIterator(), diffIterator(),
422 advanceIterator(), copyIterator()
423 */
424bool QMetaContainer::hasIterator() const
425{
426 if (!d_ptr || !d_ptr->createIteratorFn)
427 return false;
428 Q_ASSERT(d_ptr->destroyIteratorFn);
429 Q_ASSERT(d_ptr->compareIteratorFn);
430 Q_ASSERT(d_ptr->copyIteratorFn);
431 Q_ASSERT(d_ptr->advanceIteratorFn);
432 Q_ASSERT(d_ptr->diffIteratorFn);
433 return true;
434}
435
436/*!
437 Creates and returns a non-const iterator pointing to the beginning of
438 \a container. The iterator is allocated on the heap using new. It has to be
439 destroyed using \l destroyIterator eventually, to reclaim the memory.
440
441 Returns \c nullptr if the container doesn't offer any non-const iterators.
442
443 \sa end(), constBegin(), constEnd(), destroyIterator()
444 */
445void *QMetaContainer::begin(void *container) const
446{
447 return hasIterator()
448 ? d_ptr->createIteratorFn(
449 container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin)
450 : nullptr;
451}
452
453/*!
454 Creates and returns a non-const iterator pointing to the end of
455 \a container. The iterator is allocated on the heap using new. It has to be
456 destroyed using \l destroyIterator eventually, to reclaim the memory.
457
458 Returns \c nullptr if the container doesn't offer any non-const iterators.
459
460 \sa hasIterator(), end(), constBegin(), constEnd(), destroyIterator()
461 */
462void *QMetaContainer::end(void *container) const
463{
464 return hasIterator()
465 ? d_ptr->createIteratorFn(
466 container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd)
467 : nullptr;
468}
469
470/*!
471 Destroys a non-const \a iterator previously created using \l begin() or
472 \l end().
473
474 \sa begin(), end(), destroyConstIterator()
475 */
476void QMetaContainer::destroyIterator(const void *iterator) const
477{
478 if (hasIterator())
479 d_ptr->destroyIteratorFn(iterator);
480}
481
482/*!
483 Returns \c true if the non-const iterators \a i and \a j point to the same
484 value in the container they are iterating over, otherwise returns \c
485 false.
486
487 \sa begin(), end()
488 */
489bool QMetaContainer::compareIterator(const void *i, const void *j) const
490{
491 return hasIterator() ? d_ptr->compareIteratorFn(i, j) : false;
492}
493
494/*!
495 Copies the non-const iterator \a source into the non-const iterator
496 \a target. Afterwards compareIterator(target, source) returns \c true.
497
498 \sa begin(), end()
499 */
500void QMetaContainer::copyIterator(void *target, const void *source) const
501{
502 if (hasIterator())
503 d_ptr->copyIteratorFn(target, source);
504}
505
506/*!
507 Advances the non-const \a iterator by \a step steps. If \a step is negative
508 the \a iterator is moved backwards, towards the beginning of the container.
509 The behavior is unspecified for negative values of \a step if
510 \l hasBidirectionalIterator() returns false.
511
512 \sa begin(), end()
513 */
514void QMetaContainer::advanceIterator(void *iterator, qsizetype step) const
515{
516 if (hasIterator())
517 d_ptr->advanceIteratorFn(iterator, step);
518}
519
520/*!
521 Returns the distance between the non-const iterators \a i and \a j, the
522 equivalent of \a i \c - \a j. If \a j is closer to the end of the container
523 than \a i, the returned value is negative. The behavior is unspecified in
524 this case if \l hasBidirectionalIterator() returns false.
525
526 \sa begin(), end()
527 */
528qsizetype QMetaContainer::diffIterator(const void *i, const void *j) const
529{
530 return hasIterator() ? d_ptr->diffIteratorFn(i, j) : 0;
531}
532
533/*!
534 Returns \c true if the underlying container can retrieve the value pointed
535 to by a non-const iterator, \c false otherwise.
536
537 \sa hasIterator(), valueAtIterator()
538 */
539bool QMetaSequence::canGetValueAtIterator() const
540{
541 if (auto iface = d())
542 return iface->valueAtIteratorFn;
543 return false;
544}
545
546/*!
547 Retrieves the value pointed to by the non-const \a iterator and stores it
548 in the memory location pointed to by \a result, if possible.
549
550 \sa canGetValueAtIterator(), begin(), end()
551 */
552void QMetaSequence::valueAtIterator(const void *iterator, void *result) const
553{
554 if (canGetValueAtIterator())
555 d()->valueAtIteratorFn(iterator, result);
556}
557
558/*!
559 Returns \c true if the underlying container can write to the value pointed
560 to by a non-const iterator, \c false otherwise.
561
562 \sa hasIterator(), setValueAtIterator()
563 */
564bool QMetaSequence::canSetValueAtIterator() const
565{
566 if (auto iface = d())
567 return iface->setValueAtIteratorFn;
568 return false;
569}
570
571/*!
572 Writes \a value to the value pointed to by the non-const \a iterator, if
573 possible.
574
575 \sa canSetValueAtIterator(), begin(), end()
576 */
577void QMetaSequence::setValueAtIterator(const void *iterator, const void *value) const
578{
579 if (canSetValueAtIterator())
580 d()->setValueAtIteratorFn(iterator, value);
581}
582
583/*!
584 Returns \c true if the underlying container can insert a new value, taking
585 the location pointed to by a non-const iterator into account.
586
587 \sa hasIterator(), insertValueAtIterator()
588 */
589bool QMetaSequence::canInsertValueAtIterator() const
590{
591 if (auto iface = d())
592 return iface->insertValueAtIteratorFn;
593 return false;
594}
595
596/*!
597 Inserts \a value into the \a container, if possible, taking the non-const
598 \a iterator into account. If \l canInsertValueAtIterator() returns
599 \c false, the \a value is not inserted. Else if \l isSortable() returns
600 \c true, the value is inserted before the value pointed to by
601 \a iterator. Else, the \a value is inserted at an unspecified place or not
602 at all. In the latter case, the \a iterator is taken as a hint. If it points
603 to the correct place for the \a value, the operation may be faster than a
604 \l addValue() without iterator.
605
606 \sa canInsertValueAtIterator(), isSortable(), begin(), end()
607 */
608void QMetaSequence::insertValueAtIterator(void *container, const void *iterator,
609 const void *value) const
610{
611 if (canInsertValueAtIterator())
612 d()->insertValueAtIteratorFn(container, iterator, value);
613}
614
615/*!
616 Returns \c true if the value pointed to by a non-const iterator can be
617 erased, \c false otherwise.
618
619 \sa hasIterator(), eraseValueAtIterator()
620 */
621bool QMetaSequence::canEraseValueAtIterator() const
622{
623 if (auto iface = d())
624 return iface->eraseValueAtIteratorFn;
625 return false;
626}
627
628/*!
629 Erases the value pointed to by the non-const \a iterator from the
630 \a container, if possible.
631
632 \sa canEraseValueAtIterator(), begin(), end()
633 */
634void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) const
635{
636 if (canEraseValueAtIterator())
637 d()->eraseValueAtIteratorFn(container, iterator);
638}
639
640/*!
641 Returns \c true if a range between two iterators can be erased from the
642 container, \c false otherwise.
643 */
644bool QMetaSequence::canEraseRangeAtIterator() const
645{
646 if (auto iface = d())
647 return iface->eraseRangeAtIteratorFn;
648 return false;
649}
650
651/*!
652 Erases the range of values between the iterators \a iterator1 and
653 \a iterator2 from the \a container, if possible.
654
655 \sa canEraseValueAtIterator(), begin(), end()
656 */
657void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1,
658 const void *iterator2) const
659{
660 if (canEraseRangeAtIterator())
661 d()->eraseRangeAtIteratorFn(container, iterator1, iterator2);
662}
663
664/*!
665 Returns \c true if the underlying container offers a const iterator,
666 \c false otherwise.
667
668 \sa constBegin(), constEnd(), destroyConstIterator(),
669 compareConstIterator(), diffConstIterator(), advanceConstIterator(),
670 copyConstIterator()
671 */
672bool QMetaContainer::hasConstIterator() const
673{
674 if (!d_ptr || !d_ptr->createConstIteratorFn)
675 return false;
676 Q_ASSERT(d_ptr->destroyConstIteratorFn);
677 Q_ASSERT(d_ptr->compareConstIteratorFn);
678 Q_ASSERT(d_ptr->copyConstIteratorFn);
679 Q_ASSERT(d_ptr->advanceConstIteratorFn);
680 Q_ASSERT(d_ptr->diffConstIteratorFn);
681 return true;
682}
683
684/*!
685 Creates and returns a const iterator pointing to the beginning of
686 \a container. The iterator is allocated on the heap using new. It has to be
687 destroyed using \l destroyConstIterator eventually, to reclaim the memory.
688
689 Returns \c nullptr if the container doesn't offer any const iterators.
690
691 \sa constEnd(), begin(), end(), destroyConstIterator()
692 */
693void *QMetaContainer::constBegin(const void *container) const
694{
695 return hasConstIterator()
696 ? d_ptr->createConstIteratorFn(
697 container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin)
698 : nullptr;
699}
700
701/*!
702 Creates and returns a const iterator pointing to the end of
703 \a container. The iterator is allocated on the heap using new. It has to be
704 destroyed using \l destroyConstIterator eventually, to reclaim the memory.
705
706 Returns \c nullptr if the container doesn't offer any const iterators.
707
708 \sa constBegin(), begin(), end(), destroyConstIterator()
709 */
710void *QMetaContainer::constEnd(const void *container) const
711{
712 return hasConstIterator()
713 ? d_ptr->createConstIteratorFn(
714 container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd)
715 : nullptr;
716}
717
718/*!
719 Destroys a const \a iterator previously created using \l constBegin() or
720 \l constEnd().
721
722 \sa constBegin(), constEnd(), destroyIterator()
723 */
724void QMetaContainer::destroyConstIterator(const void *iterator) const
725{
726 if (hasConstIterator())
727 d_ptr->destroyConstIteratorFn(iterator);
728}
729
730/*!
731 Returns \c true if the const iterators \a i and \a j point to the same
732 value in the container they are iterating over, otherwise returns \c
733 false.
734
735 \sa constBegin(), constEnd()
736 */
737bool QMetaContainer::compareConstIterator(const void *i, const void *j) const
738{
739 return hasConstIterator() ? d_ptr->compareConstIteratorFn(i, j) : false;
740}
741
742/*!
743 Copies the const iterator \a source into the const iterator
744 \a target. Afterwards compareConstIterator(target, source) returns \c true.
745
746 \sa constBegin(), constEnd()
747 */
748void QMetaContainer::copyConstIterator(void *target, const void *source) const
749{
750 if (hasConstIterator())
751 d_ptr->copyConstIteratorFn(target, source);
752}
753
754/*!
755 Advances the const \a iterator by \a step steps. If \a step is negative
756 the \a iterator is moved backwards, towards the beginning of the container.
757 The behavior is unspecified for negative values of \a step if
758 \l hasBidirectionalIterator() returns false.
759
760 \sa constBegin(), constEnd()
761 */
762void QMetaContainer::advanceConstIterator(void *iterator, qsizetype step) const
763{
764 if (hasConstIterator())
765 d_ptr->advanceConstIteratorFn(iterator, step);
766}
767
768/*!
769 Returns the distance between the const iterators \a i and \a j, the
770 equivalent of \a i \c - \a j. If \a j is closer to the end of the container
771 than \a i, the returned value is negative. The behavior is unspecified in
772 this case if \l hasBidirectionalIterator() returns false.
773
774 \sa constBegin(), constEnd()
775 */
776qsizetype QMetaContainer::diffConstIterator(const void *i, const void *j) const
777{
778 return hasConstIterator() ? d_ptr->diffConstIteratorFn(i, j) : 0;
779}
780
781/*!
782 Returns \c true if the underlying container can retrieve the value pointed
783 to by a const iterator, \c false otherwise.
784
785 \sa hasConstIterator(), valueAtConstIterator()
786 */
787bool QMetaSequence::canGetValueAtConstIterator() const
788{
789 if (auto iface = d())
790 return iface->valueAtConstIteratorFn;
791 return false;
792}
793
794/*!
795 Retrieves the value pointed to by the const \a iterator and stores it
796 in the memory location pointed to by \a result, if possible.
797
798 \sa canGetValueAtConstIterator(), constBegin(), constEnd()
799 */
800void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) const
801{
802 if (canGetValueAtConstIterator())
803 d()->valueAtConstIteratorFn(iterator, result);
804}
805
806/*!
807 \fn bool QMetaSequence::operator==(const QMetaSequence &lhs, const QMetaSequence &rhs)
808 \since 6.0
809
810 Returns \c true if the QMetaSequence \a lhs represents the same container type
811 as the QMetaSequence \a rhs, otherwise returns \c false.
812*/
813
814/*!
815 \fn bool QMetaSequence::operator!=(const QMetaSequence &lhs, const QMetaSequence &rhs)
816 \since 6.0
817
818 Returns \c true if the QMetaSequence \a lhs represents a different container
819 type than the QMetaSequence \a rhs, otherwise returns \c false.
820*/
821
822
823/*!
824 Returns the meta type for keys in the container.
825 */
826QMetaType QMetaAssociation::keyMetaType() const
827{
828 if (auto iface = d())
829 return QMetaType(iface->keyMetaType);
830 return QMetaType();
831}
832
833/*!
834 Returns the meta type for mapped values in the container.
835 */
836QMetaType QMetaAssociation::mappedMetaType() const
837{
838 if (auto iface = d())
839 return QMetaType(iface->mappedMetaType);
840 return QMetaType();
841}
842
843QT_END_NAMESPACE
844

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/kernel/qmetacontainer.cpp