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
qmetacontainer.h
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#ifndef QMETACONTAINER_H
5#define QMETACONTAINER_H
6
7#include <QtCore/qcontainerinfo.h>
8#include <QtCore/qcompare.h>
9#include <QtCore/qflags.h>
10#include <QtCore/qglobal.h>
11
12#include <iterator>
13
14QT_BEGIN_NAMESPACE
15
16class QMetaType;
17namespace QtPrivate {
19template<typename T>
21}
22
24
25class Sequence;
27class Association;
29
36
39
48
50{
51public:
55
56 using SizeFn = qsizetype(*)(const void *);
58 using ClearFn = void(*)(void *);
60
61 using CreateIteratorFn = void *(*)(void *, Position);
63 using DestroyIteratorFn = void(*)(const void *);
65 using CompareIteratorFn = bool(*)(const void *, const void *);
67 using CopyIteratorFn = void(*)(void *, const void *);
69 using AdvanceIteratorFn = void(*)(void *, qsizetype);
71 using DiffIteratorFn = qsizetype(*)(const void *, const void *);
73
74 using CreateConstIteratorFn = void *(*)(const void *, Position);
81
83
84 template<typename MetaContainer>
102};
103
105{
106public:
109
110 using ValueAtIndexFn = void(*)(const void *, qsizetype, void *);
112 using SetValueAtIndexFn = void(*)(void *, qsizetype, const void *);
114
115 using AddValueFn = void(*)(void *, const void *, Position);
117 using RemoveValueFn = void(*)(void *, Position);
119
120 using ValueAtIteratorFn = void(*)(const void *, void *);
122 using SetValueAtIteratorFn = void(*)(const void *, const void *);
124 using InsertValueAtIteratorFn = void(*)(void *, const void *, const void *);
126
128
129 using EraseValueAtIteratorFn = void(*)(void *, const void *);
131
132 using EraseRangeAtIteratorFn = void(*)(void *, const void *, const void *);
134
136
137 template<typename MetaSequence>
138 constexpr QMetaSequenceInterface(const MetaSequence &m)
140 , valueMetaType(MetaSequence::getValueMetaType())
142 , valueAtIndexFn(MetaSequence::getValueAtIndexFn())
143 , setValueAtIndexFn(MetaSequence::getSetValueAtIndexFn())
144 , addValueFn(MetaSequence::getAddValueFn())
145 , removeValueFn(MetaSequence::getRemoveValueFn())
146 , valueAtIteratorFn(MetaSequence::getValueAtIteratorFn())
147 , setValueAtIteratorFn(MetaSequence::getSetValueAtIteratorFn())
148 , insertValueAtIteratorFn(MetaSequence::getInsertValueAtIteratorFn())
149 , valueAtConstIteratorFn(MetaSequence::getValueAtConstIteratorFn())
150 , eraseValueAtIteratorFn(MetaSequence::getEraseValueAtIteratorFn())
151 , eraseRangeAtIteratorFn(MetaSequence::getEraseRangeAtIteratorFn())
152 {}
153};
154
156{
157public:
160
161 using InsertKeyFn = void(*)(void *, const void *);
163 using RemoveKeyFn = void(*)(void *, const void *);
165 using ContainsKeyFn = bool(*)(const void *, const void *);
167
168 using MappedAtKeyFn = void(*)(const void *, const void *, void *);
170 using SetMappedAtKeyFn = void(*)(void *, const void *, const void *);
172
173 using CreateIteratorAtKeyFn = void *(*)(void *, const void *);
175 using CreateConstIteratorAtKeyFn = void *(*)(const void *, const void *);
177
178 using KeyAtIteratorFn = void(*)(const void *, void *);
181
182 using MappedAtIteratorFn = void(*)(const void *, void *);
185
186 using SetMappedAtIteratorFn = void(*)(const void *, const void *);
188
189 using EraseKeyAtIteratorFn = void(*)(void *, const void *);
191
193
194 template<typename MetaAssociation>
195 constexpr QMetaAssociationInterface(const MetaAssociation &m)
197 , keyMetaType(MetaAssociation::getKeyMetaType())
198 , mappedMetaType(MetaAssociation::getMappedMetaType())
199 , insertKeyFn(MetaAssociation::getInsertKeyFn())
200 , removeKeyFn(MetaAssociation::getRemoveKeyFn())
201 , containsKeyFn(MetaAssociation::getContainsKeyFn())
202 , mappedAtKeyFn(MetaAssociation::getMappedAtKeyFn())
203 , setMappedAtKeyFn(MetaAssociation::getSetMappedAtKeyFn())
204 , createIteratorAtKeyFn(MetaAssociation::createIteratorAtKeyFn())
205 , createConstIteratorAtKeyFn(MetaAssociation::createConstIteratorAtKeyFn())
206 , keyAtIteratorFn(MetaAssociation::getKeyAtIteratorFn())
207 , keyAtConstIteratorFn(MetaAssociation::getKeyAtConstIteratorFn())
208 , mappedAtIteratorFn(MetaAssociation::getMappedAtIteratorFn())
209 , mappedAtConstIteratorFn(MetaAssociation::getMappedAtConstIteratorFn())
210 , setMappedAtIteratorFn(MetaAssociation::getSetMappedAtIteratorFn())
211 , eraseKeyAtIteratorFn(MetaAssociation::getEraseKeyAtIteratorFn())
212 {}
213};
214
215template<typename C>
217{
219
220 template <typename Iterator>
221 static constexpr IteratorCapabilities capabilitiesForIterator()
222 {
223 using Tag = typename std::iterator_traits<Iterator>::iterator_category;
224 IteratorCapabilities caps {};
225 if constexpr (std::is_base_of_v<std::input_iterator_tag, Tag>)
226 caps |= InputCapability;
227 if constexpr (std::is_base_of_v<std::forward_iterator_tag, Tag>)
228 caps |= ForwardCapability;
229 if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, Tag>)
231 if constexpr (std::is_base_of_v<std::random_access_iterator_tag, Tag>)
233 return caps;
234 }
235
236 static constexpr IteratorCapabilities getIteratorCapabilities()
237 {
238 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>)
239 return capabilitiesForIterator<QContainerInfo::iterator<C>>();
240 else if constexpr (QContainerInfo::has_const_iterator_v<C>)
241 return capabilitiesForIterator<QContainerInfo::const_iterator<C>>();
242 else
243 return {};
244 }
245
246 static constexpr QMetaContainerInterface::SizeFn getSizeFn()
247 {
248 if constexpr (QContainerInfo::has_size_v<C>) {
249 return [](const void *c) -> qsizetype { return static_cast<const C *>(c)->size(); };
250 } else {
251 return nullptr;
252 }
253 }
254
255 static constexpr QMetaContainerInterface::ClearFn getClearFn()
256 {
257 if constexpr (QContainerInfo::has_clear_v<C>) {
258 return [](void *c) { return static_cast<C *>(c)->clear(); };
259 } else {
260 return nullptr;
261 }
262 }
263
264 static constexpr QMetaContainerInterface::CreateIteratorFn getCreateIteratorFn()
265 {
266 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
267 return [](void *c, QMetaContainerInterface::Position p) -> void* {
268 using Iterator = QContainerInfo::iterator<C>;
269 switch (p) {
270 case QMetaContainerInterface::Unspecified:
271 return new Iterator;
272 case QMetaContainerInterface::AtBegin:
273 return new Iterator(static_cast<C *>(c)->begin());
274 case QMetaContainerInterface::AtEnd:
275 return new Iterator(static_cast<C *>(c)->end());
276 }
277 return nullptr;
278 };
279 } else {
280 return nullptr;
281 }
282 }
283
284 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyIteratorFn()
285 {
286 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
287 return [](const void *i) {
288 using Iterator = QContainerInfo::iterator<C>;
289 delete static_cast<const Iterator *>(i);
290 };
291 } else {
292 return nullptr;
293 }
294 }
295
296 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareIteratorFn()
297 {
298 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
299 return [](const void *i, const void *j) {
300 using Iterator = QContainerInfo::iterator<C>;
301 return *static_cast<const Iterator *>(i) == *static_cast<const Iterator *>(j);
302 };
303 } else {
304 return nullptr;
305 }
306 }
307
308 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyIteratorFn()
309 {
310 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
311 return [](void *i, const void *j) {
312 using Iterator = QContainerInfo::iterator<C>;
313 *static_cast<Iterator *>(i) = *static_cast<const Iterator *>(j);
314 };
315 } else {
316 return nullptr;
317 }
318 }
319
320 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceIteratorFn()
321 {
322 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
323 return [](void *i, qsizetype step) {
324 std::advance(*static_cast<QContainerInfo::iterator<C> *>(i), step);
325 };
326 } else {
327 return nullptr;
328 }
329 }
330
331 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffIteratorFn()
332 {
333 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
334 return [](const void *i, const void *j) -> qsizetype {
335 return std::distance(*static_cast<const QContainerInfo::iterator<C> *>(j),
336 *static_cast<const QContainerInfo::iterator<C> *>(i));
337 };
338 } else {
339 return nullptr;
340 }
341 }
342
343 static constexpr QMetaContainerInterface::CreateConstIteratorFn getCreateConstIteratorFn()
344 {
345 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
346 return [](const void *c, QMetaContainerInterface::Position p) -> void* {
347 using Iterator = QContainerInfo::const_iterator<C>;
348 switch (p) {
349 case QMetaContainerInterface::Unspecified:
350 return new Iterator;
351 case QMetaContainerInterface::AtBegin:
352 return new Iterator(static_cast<const C *>(c)->begin());
353 case QMetaContainerInterface::AtEnd:
354 return new Iterator(static_cast<const C *>(c)->end());
355 }
356 return nullptr;
357 };
358 } else {
359 return nullptr;
360 }
361 }
362
363 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyConstIteratorFn()
364 {
365 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
366 return [](const void *i) {
367 using Iterator = QContainerInfo::const_iterator<C>;
368 delete static_cast<const Iterator *>(i);
369 };
370 } else {
371 return nullptr;
372 }
373 }
374
375 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareConstIteratorFn()
376 {
377 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
378 return [](const void *i, const void *j) {
379 using Iterator = QContainerInfo::const_iterator<C>;
380 return *static_cast<const Iterator *>(i) == *static_cast<const Iterator *>(j);
381 };
382 } else {
383 return nullptr;
384 }
385 }
386
387 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyConstIteratorFn()
388 {
389 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
390 return [](void *i, const void *j) {
391 using Iterator = QContainerInfo::const_iterator<C>;
392 *static_cast<Iterator *>(i) = *static_cast<const Iterator *>(j);
393 };
394 } else {
395 return nullptr;
396 }
397 }
398
399 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceConstIteratorFn()
400 {
401 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
402 return [](void *i, qsizetype step) {
403 std::advance(*static_cast<QContainerInfo::const_iterator<C> *>(i), step);
404 };
405 } else {
406 return nullptr;
407 }
408 }
409
410 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffConstIteratorFn()
411 {
412 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
413 return [](const void *i, const void *j) -> qsizetype {
414 return std::distance(*static_cast<const QContainerInfo::const_iterator<C> *>(j),
415 *static_cast<const QContainerInfo::const_iterator<C> *>(i));
416 };
417 } else {
418 return nullptr;
419 }
420 }
421
422protected:
423
424 template<typename EraseFn>
425 static constexpr EraseFn getEraseAtIteratorFn()
426 {
427 if constexpr (QContainerInfo::has_iterator_v<C>
428 && QContainerInfo::can_erase_at_iterator_v<C> && !std::is_const_v<C>) {
429 return [](void *c, const void *i) {
430 static_cast<C *>(c)->erase(*static_cast<const QContainerInfo::iterator<C> *>(i));
431 };
432 } else {
433 return nullptr;
434 }
435 }
436};
437
438template<typename C>
440{
442
443 static constexpr const QtPrivate::QMetaTypeInterface *getValueMetaType()
444 {
445 if constexpr (QContainerInfo::has_value_type_v<C>)
446 return QtPrivate::qMetaTypeInterfaceForType<typename C::value_type>();
447 else
448 return nullptr;
449 }
450
451 static constexpr AddRemoveCapabilities getAddRemoveCapabilities()
452 {
453 AddRemoveCapabilities caps;
454 if constexpr (QContainerInfo::has_push_back_v<C>)
455 caps |= CanAddAtEnd;
456 if constexpr (QContainerInfo::has_pop_back_v<C>)
457 caps |= CanRemoveAtEnd;
458 if constexpr (QContainerInfo::has_push_front_v<C>)
459 caps |= CanAddAtBegin;
460 if constexpr (QContainerInfo::has_pop_front_v<C>)
461 caps |= CanRemoveAtBegin;
462 return caps;
463 }
464
465 static constexpr QMetaSequenceInterface::ValueAtIndexFn getValueAtIndexFn()
466 {
467 if constexpr (QContainerInfo::has_at_index_v<C>) {
468 return [](const void *c, qsizetype i, void *r) {
469 *static_cast<QContainerInfo::value_type<C> *>(r)
470 = static_cast<const C *>(c)->at(i);
471 };
472 } else if constexpr (QContainerInfo::can_get_at_index_v<C>) {
473 return [](const void *c, qsizetype i, void *r) {
474 *static_cast<QContainerInfo::value_type<C> *>(r)
475 = (*static_cast<const C *>(c))[i];
476 };
477 } else {
478 return nullptr;
479 }
480 }
481
482 static constexpr QMetaSequenceInterface::SetValueAtIndexFn getSetValueAtIndexFn()
483 {
484 if constexpr (QContainerInfo::can_set_at_index_v<C>) {
485 return [](void *c, qsizetype i, const void *e) {
486 (*static_cast<C *>(c))[i]
487 = *static_cast<const QContainerInfo::value_type<C> *>(e);
488 };
489 } else {
490 return nullptr;
491 }
492 }
493
494 static constexpr QMetaSequenceInterface::AddValueFn getAddValueFn()
495 {
496 if constexpr (QContainerInfo::has_push_back_v<C>) {
497 if constexpr (QContainerInfo::has_push_front_v<C>) {
498 return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
499 const auto &value = *static_cast<const QContainerInfo::value_type<C> *>(v);
500 switch (position) {
501 case QMetaSequenceInterface::AtBegin:
502 static_cast<C *>(c)->push_front(value);
503 break;
504 case QMetaSequenceInterface::AtEnd:
505 case QMetaSequenceInterface::Unspecified:
506 static_cast<C *>(c)->push_back(value);
507 break;
508 }
509 };
510 } else {
511 return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
512 const auto &value = *static_cast<const QContainerInfo::value_type<C> *>(v);
513 switch (position) {
514 case QMetaSequenceInterface::AtBegin:
515 break;
516 case QMetaSequenceInterface::AtEnd:
517 case QMetaSequenceInterface::Unspecified:
518 static_cast<C *>(c)->push_back(value);
519 break;
520 }
521 };
522 }
523 } else if constexpr (QContainerInfo::has_push_front_v<C>) {
524 return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
525 const auto &value = *static_cast<const QContainerInfo::value_type<C> *>(v);
526 switch (position) {
527 case QMetaSequenceInterface::Unspecified:
528 case QMetaSequenceInterface::AtBegin:
529 static_cast<C *>(c)->push_front(value);
530 case QMetaSequenceInterface::AtEnd:
531 break;
532 }
533 };
534 } else if constexpr (QContainerInfo::has_insert_v<C>) {
535 return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
536 if (position == QMetaSequenceInterface::Unspecified) {
537 static_cast<C *>(c)->insert(
538 *static_cast<const QContainerInfo::value_type<C> *>(v));
539 }
540 };
541 } else {
542 return nullptr;
543 }
544 }
545
546 static constexpr QMetaSequenceInterface::RemoveValueFn getRemoveValueFn()
547 {
548 if constexpr (QContainerInfo::has_pop_back_v<C>) {
549 if constexpr (QContainerInfo::has_pop_front_v<C>) {
550 return [](void *c, QMetaSequenceInterface::Position position) {
551 switch (position) {
552 case QMetaSequenceInterface::AtBegin:
553 static_cast<C *>(c)->pop_front();
554 break;
555 case QMetaSequenceInterface::AtEnd:
556 case QMetaSequenceInterface::Unspecified:
557 static_cast<C *>(c)->pop_back();
558 break;
559 }
560 };
561 } else {
562 return [](void *c, QMetaSequenceInterface::Position position) {
563 switch (position) {
564 case QMetaSequenceInterface::AtBegin:
565 break;
566 case QMetaSequenceInterface::Unspecified:
567 case QMetaSequenceInterface::AtEnd:
568 static_cast<C *>(c)->pop_back();
569 break;
570 }
571 };
572 }
573 } else if constexpr (QContainerInfo::has_pop_front_v<C>) {
574 return [](void *c, QMetaSequenceInterface::Position position) {
575 switch (position) {
576 case QMetaSequenceInterface::Unspecified:
577 case QMetaSequenceInterface::AtBegin:
578 static_cast<C *>(c)->pop_front();
579 break;
580 case QMetaSequenceInterface::AtEnd:
581 break;
582 }
583 };
584 } else {
585 return nullptr;
586 }
587 }
588
589 static constexpr QMetaSequenceInterface::ValueAtIteratorFn getValueAtIteratorFn()
590 {
591 if constexpr (QContainerInfo::has_iterator_v<C>
592 && QContainerInfo::iterator_dereferences_to_value_v<C> && !std::is_const_v<C>) {
593 return [](const void *i, void *r) {
594 *static_cast<QContainerInfo::value_type<C> *>(r) =
595 *(*static_cast<const QContainerInfo::iterator<C> *>(i));
596 };
597 } else {
598 return nullptr;
599 }
600 }
601
602 static constexpr QMetaSequenceInterface::SetValueAtIteratorFn getSetValueAtIteratorFn()
603 {
604 if constexpr (QContainerInfo::has_iterator_v<C>
605 && QContainerInfo::can_set_value_at_iterator_v<C> && !std::is_const_v<C>) {
606 return [](const void *i, const void *e) {
607 *(*static_cast<const QContainerInfo::iterator<C> *>(i))
608 = *static_cast<const QContainerInfo::value_type<C> *>(e);
609 };
610 } else {
611 return nullptr;
612 }
613 }
614
615 static constexpr QMetaSequenceInterface::InsertValueAtIteratorFn getInsertValueAtIteratorFn()
616 {
617 if constexpr (QContainerInfo::has_iterator_v<C>
618 && QContainerInfo::can_insert_value_at_iterator_v<C> && !std::is_const_v<C>) {
619 return [](void *c, const void *i, const void *e) {
620 static_cast<C *>(c)->insert(
621 *static_cast<const QContainerInfo::iterator<C> *>(i),
622 *static_cast<const QContainerInfo::value_type<C> *>(e));
623 };
624 } else {
625 return nullptr;
626 }
627 }
628
629 static constexpr QMetaSequenceInterface::ValueAtIteratorFn getValueAtConstIteratorFn()
630 {
631 if constexpr (QContainerInfo::has_const_iterator_v<C>
632 && QContainerInfo::iterator_dereferences_to_value_v<C>) {
633 return [](const void *i, void *r) {
634 *static_cast<QContainerInfo::value_type<C> *>(r) =
635 *(*static_cast<const QContainerInfo::const_iterator<C> *>(i));
636 };
637 } else {
638 return nullptr;
639 }
640 }
641
642 static constexpr QMetaSequenceInterface::EraseValueAtIteratorFn getEraseValueAtIteratorFn()
643 {
644 return QMetaContainerForContainer<C>::template getEraseAtIteratorFn<
646 }
647
648 static constexpr QMetaSequenceInterface::EraseRangeAtIteratorFn getEraseRangeAtIteratorFn()
649 {
650 if constexpr (QContainerInfo::has_iterator_v<C>
651 && QContainerInfo::can_erase_range_at_iterator_v<C> && !std::is_const_v<C>) {
652 return [](void *c, const void *i, const void *j) {
653 static_cast<C *>(c)->erase(*static_cast<const QContainerInfo::iterator<C> *>(i),
654 *static_cast<const QContainerInfo::iterator<C> *>(j));
655 };
656 } else {
657 return nullptr;
658 }
659 }
660};
661
662template<typename C>
664{
666
667 static constexpr const QtPrivate::QMetaTypeInterface *getKeyMetaType()
668 {
669 if constexpr (QContainerInfo::has_key_type_v<C>)
670 return QtPrivate::qMetaTypeInterfaceForType<typename C::key_type>();
671 else
672 return nullptr;
673 }
674
675 static constexpr const QtPrivate::QMetaTypeInterface *getMappedMetaType()
676 {
677 if constexpr (QContainerInfo::has_mapped_type_v<C>)
678 return QtPrivate::qMetaTypeInterfaceForType<typename C::mapped_type>();
679 else
680 return nullptr;
681 }
682
683 static constexpr QMetaAssociationInterface::InsertKeyFn getInsertKeyFn()
684 {
685 if constexpr (QContainerInfo::can_insert_key_v<C>) {
686 return [](void *c, const void *k) {
687 static_cast<C *>(c)->insert(
688 *static_cast<const QContainerInfo::key_type<C> *>(k));
689 };
690 } else if constexpr (QContainerInfo::can_insert_pair_v<C>) {
691 return [](void *c, const void *k) {
692 static_cast<C *>(c)->insert(
693 {*static_cast<const QContainerInfo::key_type<C> *>(k), {}});
694 };
695 } else if constexpr (QContainerInfo::can_insert_key_mapped_v<C>) {
696 return [](void *c, const void *k) {
697 static_cast<C *>(c)->insert(
698 *static_cast<const QContainerInfo::key_type<C> *>(k), {});
699 };
700 } else {
701 return nullptr;
702 }
703 }
704
705 static constexpr QMetaAssociationInterface::RemoveKeyFn getRemoveKeyFn()
706 {
707 if constexpr (QContainerInfo::can_erase_at_key_v<C>) {
708 return [](void *c, const void *k) {
709 static_cast<C *>(c)->erase(*static_cast<const QContainerInfo::key_type<C> *>(k));
710 };
711 } else if constexpr (QContainerInfo::can_remove_at_key_v<C>) {
712 return [](void *c, const void *k) {
713 static_cast<C *>(c)->remove(*static_cast<const QContainerInfo::key_type<C> *>(k));
714 };
715 } else {
716 return nullptr;
717 }
718 }
719
720 static constexpr QMetaAssociationInterface::ContainsKeyFn getContainsKeyFn()
721 {
722 if constexpr (QContainerInfo::has_contains_v<C>) {
723 return [](const void *c, const void *k) {
724 return static_cast<const C *>(c)->contains(
725 *static_cast<const QContainerInfo::key_type<C> *>(k));
726 };
727 } else if (QContainerInfo::has_find_v<C>) {
728 return [](const void *c, const void *k) {
729 const C *container = static_cast<const C *>(c);
730 return container->find(
731 *static_cast<const QContainerInfo::key_type<C> *>(k))
732 != container->end();
733 };
734 } else {
735 return nullptr;
736 }
737 }
738
739 static constexpr QMetaAssociationInterface::MappedAtKeyFn getMappedAtKeyFn()
740 {
741 if constexpr (QContainerInfo::has_at_key_v<C>) {
742 return [](const void *c, const void *k, void *r) {
743 *static_cast<QContainerInfo::mapped_type<C> *>(r)
744 = static_cast<const C *>(c)->at(
745 *static_cast<const QContainerInfo::key_type<C> *>(k));
746 };
747 } else if constexpr (QContainerInfo::can_get_at_key_v<C>) {
748 return [](const void *c, const void *k, void *r) {
749 *static_cast<QContainerInfo::mapped_type<C> *>(r)
750 = (*static_cast<const C *>(c))[
751 *static_cast<const QContainerInfo::key_type<C> *>(k)];
752 };
753 } else {
754 return nullptr;
755 }
756 }
757
758 static constexpr QMetaAssociationInterface::SetMappedAtKeyFn getSetMappedAtKeyFn()
759 {
760 if constexpr (QContainerInfo::can_set_at_key_v<C>) {
761 return [](void *c, const void *k, const void *m) {
762 (*static_cast<C *>(c))[*static_cast<const QContainerInfo::key_type<C> *>(k)] =
763 *static_cast<const QContainerInfo::mapped_type<C> *>(m);
764 };
765 } else {
766 return nullptr;
767 }
768 }
769
770 static constexpr QMetaAssociationInterface::CreateIteratorAtKeyFn createIteratorAtKeyFn()
771 {
772 if constexpr (QContainerInfo::has_find_v<C>) {
773 return [](void *c, const void *k) -> void* {
774 using Iterator = QContainerInfo::iterator<C>;
775 return new Iterator(static_cast<C *>(c)->find(
776 *static_cast<const QContainerInfo::key_type<C> *>(k)));
777 };
778 } else {
779 return nullptr;
780 }
781 }
782
783 static constexpr QMetaAssociationInterface::CreateConstIteratorAtKeyFn createConstIteratorAtKeyFn()
784 {
785 if constexpr (QContainerInfo::has_find_v<C>) {
786 return [](const void *c, const void *k) -> void* {
787 using Iterator = QContainerInfo::const_iterator<C>;
788 return new Iterator(static_cast<const C *>(c)->find(
789 *static_cast<const QContainerInfo::key_type<C> *>(k)));
790 };
791 } else {
792 return nullptr;
793 }
794 }
795
796 template<typename Iterator>
797 static constexpr QMetaAssociationInterface::KeyAtIteratorFn keyAtIteratorFn()
798 {
799 if constexpr (QContainerInfo::iterator_has_key_v<C>) {
800 return [](const void *i, void *k) {
801 *static_cast<QContainerInfo::key_type<C> *>(k)
802 = static_cast<const Iterator *>(i)->key();
803 };
804 } else if constexpr (QContainerInfo::iterator_dereferences_to_value_v<C>
805 && QContainerInfo::value_type_has_first_v<C>) {
806 return [](const void *i, void *k) {
807 *static_cast<QContainerInfo::key_type<C> *>(k)
808 = (*static_cast<const Iterator *>(i))->first;
809 };
810 } else if constexpr (QContainerInfo::iterator_dereferences_to_key_v<C>) {
811 return [](const void *i, void *k) {
812 *static_cast<QContainerInfo::key_type<C> *>(k)
813 = *(*static_cast<const Iterator *>(i));
814 };
815 } else {
816 return nullptr;
817 }
818 }
819
820 static constexpr QMetaAssociationInterface::KeyAtIteratorFn getKeyAtIteratorFn()
821 {
822 return keyAtIteratorFn<QContainerInfo::iterator<C>>();
823 }
824
825 static constexpr QMetaAssociationInterface::KeyAtIteratorFn getKeyAtConstIteratorFn()
826 {
827 return keyAtIteratorFn<QContainerInfo::const_iterator<C>>();
828 }
829
830 template<typename Iterator>
831 static constexpr QMetaAssociationInterface::MappedAtIteratorFn mappedAtIteratorFn()
832 {
833 if constexpr (QContainerInfo::iterator_has_value_v<C>) {
834 return [](const void *i, void *k) {
835 *static_cast<QContainerInfo::mapped_type<C> *>(k)
836 = static_cast<const Iterator *>(i)->value();
837 };
838 } else if constexpr (QContainerInfo::iterator_dereferences_to_value_v<C>
839 && QContainerInfo::value_type_has_second_v<C>) {
840 return [](const void *i, void *k) {
841 *static_cast<QContainerInfo::mapped_type<C> *>(k)
842 = (*static_cast<const Iterator *>(i))->second;
843 };
844 } else if constexpr (QContainerInfo::iterator_dereferences_to_mapped_v<C>) {
845 return [](const void *i, void *k) {
846 *static_cast<QContainerInfo::mapped_type<C> *>(k)
847 = *static_cast<const Iterator *>(i);
848 };
849 } else {
850 return nullptr;
851 }
852 }
853
854 static constexpr QMetaAssociationInterface::MappedAtIteratorFn getMappedAtIteratorFn()
855 {
856 return mappedAtIteratorFn<QContainerInfo::iterator<C>>();
857 }
858
859 static constexpr QMetaAssociationInterface::MappedAtIteratorFn getMappedAtConstIteratorFn()
860 {
861 return mappedAtIteratorFn<QContainerInfo::const_iterator<C>>();
862 }
863
864 static constexpr QMetaAssociationInterface::SetMappedAtIteratorFn getSetMappedAtIteratorFn()
865 {
866 if constexpr (QContainerInfo::can_set_mapped_at_iterator_v<C> && !std::is_const_v<C>) {
867 return [](const void *i, const void *m) {
868 *(*static_cast<const QContainerInfo::iterator<C> *>(i))
869 = *static_cast<const QContainerInfo::mapped_type<C> *>(m);
870 };
871 } else if constexpr (QContainerInfo::iterator_dereferences_to_value_v<C>
872 && QContainerInfo::value_type_has_second_v<C>) {
873 return [](const void *i, const void *m) {
874 (*static_cast<const QContainerInfo::iterator<C> *>(i))->second
875 = *static_cast<const QContainerInfo::mapped_type<C> *>(m);
876 };
877 } else {
878 return nullptr;
879 }
880 }
881
882 static constexpr QMetaAssociationInterface::EraseKeyAtIteratorFn getEraseKeyAtIteratorFn()
883 {
884 return QMetaContainerForContainer<C>::template getEraseAtIteratorFn<
886 }
887};
888
889} // namespace QtMetaContainerPrivate
890
891class Q_CORE_EXPORT QMetaContainer
892{
893public:
894 QMetaContainer() = default;
895 explicit QMetaContainer(const QtMetaContainerPrivate::QMetaContainerInterface *d) : d_ptr(d) {}
896
897 bool hasInputIterator() const;
898 bool hasForwardIterator() const;
899 bool hasBidirectionalIterator() const;
900 bool hasRandomAccessIterator() const;
901
902 bool hasSize() const;
903 qsizetype size(const void *container) const;
904
905 bool canClear() const;
906 void clear(void *container) const;
907
908 bool hasIterator() const;
909 void *begin(void *container) const;
910 void *end(void *container) const;
911 void destroyIterator(const void *iterator) const;
912 bool compareIterator(const void *i, const void *j) const;
913 void copyIterator(void *target, const void *source) const;
914 void advanceIterator(void *iterator, qsizetype step) const;
915 qsizetype diffIterator(const void *i, const void *j) const;
916
917 bool hasConstIterator() const;
918 void *constBegin(const void *container) const;
919 void *constEnd(const void *container) const;
920 void destroyConstIterator(const void *iterator) const;
921 bool compareConstIterator(const void *i, const void *j) const;
922 void copyConstIterator(void *target, const void *source) const;
923 void advanceConstIterator(void *iterator, qsizetype step) const;
924 qsizetype diffConstIterator(const void *i, const void *j) const;
925
926protected:
927 const QtMetaContainerPrivate::QMetaContainerInterface *d_ptr = nullptr;
928};
929
930// ### Qt7: Move this to qmetasequence.h, including QtMetaContainerPrivate parts above.
931class Q_CORE_EXPORT QMetaSequence : public QMetaContainer
932{
933public:
934#ifdef Q_QDOC
935 class Iterable : public QIterable<QMetaSequence>
936 {
937 public:
938 class Iterator : public QIterator<QMetaSequence>
939 {
940 public:
941 QVariant::Reference<Iterator> operator*() const;
942 QVariant::Pointer<Iterator> operator->() const;
943 QVariant::Reference<Iterator> operator[](qsizetype n) const;
944 };
945
946 class ConstIterator : public QConstIterator<QMetaSequence>
947 {
948 public:
949 QVariant operator*() const;
950 QVariant::ConstPointer<ConstIterator> operator->() const;
951 QVariant operator[](qsizetype n) const;
952 };
953
954 using RandomAccessIterator = Iterator;
955 using BidirectionalIterator = Iterator;
956 using ForwardIterator = Iterator;
957 using InputIterator = Iterator;
958
959 using RandomAccessConstIterator = ConstIterator;
960 using BidirectionalConstIterator = ConstIterator;
961 using ForwardConstIterator = ConstIterator;
962 using InputConstIterator = ConstIterator;
963
964 ConstIterator begin() const;
965 ConstIterator end() const;
966
967 ConstIterator constBegin() const;
968 ConstIterator constEnd() const;
969
970 Iterator mutableBegin();
971 Iterator mutableEnd();
972
973 QVariant at(qsizetype idx) const;
974 void setAt(qsizetype idx, const QVariant &value);
975 void append(const QVariant &value);
976 void prepend(const QVariant &value);
977 void removeLast();
978 void removeFirst();
979 };
980#else
981 using Iterable = QtMetaContainerPrivate::Sequence;
982#endif
983
984 QMetaSequence() = default;
985 explicit QMetaSequence(const QtMetaContainerPrivate::QMetaSequenceInterface *d) : QMetaContainer(d) {}
986
987 template<typename T>
988 static constexpr QMetaSequence fromContainer()
989 {
990 return QMetaSequence(&MetaSequence<T>::value);
991 }
992
993 QMetaType valueMetaType() const;
994
995 bool isSortable() const;
996 bool canAddValueAtBegin() const;
997 void addValueAtBegin(void *container, const void *value) const;
998 bool canAddValueAtEnd() const;
999 void addValueAtEnd(void *container, const void *value) const;
1000 bool canRemoveValueAtBegin() const;
1001 void removeValueAtBegin(void *container) const;
1002 bool canRemoveValueAtEnd() const;
1003 void removeValueAtEnd(void *container) const;
1004
1005 bool canGetValueAtIndex() const;
1006 void valueAtIndex(const void *container, qsizetype index, void *result) const;
1007
1008 bool canSetValueAtIndex() const;
1009 void setValueAtIndex(void *container, qsizetype index, const void *value) const;
1010
1011 bool canAddValue() const;
1012 void addValue(void *container, const void *value) const;
1013
1014 bool canRemoveValue() const;
1015 void removeValue(void *container) const;
1016
1017 bool canGetValueAtIterator() const;
1018 void valueAtIterator(const void *iterator, void *result) const;
1019
1020 bool canSetValueAtIterator() const;
1021 void setValueAtIterator(const void *iterator, const void *value) const;
1022
1023 bool canInsertValueAtIterator() const;
1024 void insertValueAtIterator(void *container, const void *iterator, const void *value) const;
1025
1026 bool canEraseValueAtIterator() const;
1027 void eraseValueAtIterator(void *container, const void *iterator) const;
1028
1029 bool canEraseRangeAtIterator() const;
1030 void eraseRangeAtIterator(void *container, const void *iterator1, const void *iterator2) const;
1031
1032 bool canGetValueAtConstIterator() const;
1033 void valueAtConstIterator(const void *iterator, void *result) const;
1034
1035 const QtMetaContainerPrivate::QMetaSequenceInterface *iface() const { return d(); }
1036
1037private:
1038 friend bool comparesEqual(const QMetaSequence &lhs, const QMetaSequence &rhs) noexcept
1039 {
1040 return lhs.d() == rhs.d();
1041 }
1042 Q_DECLARE_EQUALITY_COMPARABLE(QMetaSequence)
1043
1044 template<typename T>
1045 struct MetaSequence
1046 {
1047 static constexpr const QtMetaContainerPrivate::QMetaSequenceInterface value
1048 = QtMetaContainerPrivate::QMetaSequenceInterface(
1049 QtMetaContainerPrivate::QMetaSequenceForContainer<T>());
1050 };
1051
1052 const QtMetaContainerPrivate::QMetaSequenceInterface *d() const
1053 {
1054 return static_cast<const QtMetaContainerPrivate::QMetaSequenceInterface *>(d_ptr);
1055 }
1056};
1057
1058// ### Qt7: Move this to qmetaassociation.h, including QtMetaContainerPrivate parts above.
1059class Q_CORE_EXPORT QMetaAssociation : public QMetaContainer
1060{
1061public:
1062#ifdef Q_QDOC
1063 class Iterable : public QIterable<QMetaAssociation>
1064 {
1065 public:
1066 class Iterator : public QIterator<QMetaAssociation>
1067 {
1068 public:
1069 QVariant key() const;
1070 QVariant value() const;
1071
1072 QVariant::Reference<Iterator> operator*() const;
1073 QVariant::Pointer<Iterator> operator->() const;
1074 };
1075
1076 class ConstIterator : public QConstIterator<QMetaAssociation>
1077 {
1078 public:
1079 QVariant key() const;
1080 QVariant value() const;
1081
1082 QVariant operator*() const;
1083 QVariant::ConstPointer<ConstIterator> operator->() const;
1084 };
1085
1086 using RandomAccessIterator = Iterator;
1087 using BidirectionalIterator = Iterator;
1088 using ForwardIterator = Iterator;
1089 using InputIterator = Iterator;
1090
1091 using RandomAccessConstIterator = ConstIterator;
1092 using BidirectionalConstIterator = ConstIterator;
1093 using ForwardConstIterator = ConstIterator;
1094 using InputConstIterator = ConstIterator;
1095
1096 ConstIterator begin() const;
1097 ConstIterator end() const;
1098
1099 ConstIterator constBegin() const;
1100 ConstIterator constEnd() const;
1101
1102 Iterator mutableBegin();
1103 Iterator mutableEnd();
1104
1105 ConstIterator find(const QVariant &key) const;
1106 ConstIterator constFind(const QVariant &key) const;
1107 Iterator mutableFind(const QVariant &key);
1108
1109 bool containsKey(const QVariant &key) const;
1110 void insertKey(const QVariant &key);
1111 void removeKey(const QVariant &key);
1112 QVariant value(const QVariant &key) const;
1113 void setValue(const QVariant &key, const QVariant &mapped);
1114 };
1115#else
1116 using Iterable = QtMetaContainerPrivate::Association;
1117#endif
1118
1119 QMetaAssociation() = default;
1120 explicit QMetaAssociation(const QtMetaContainerPrivate::QMetaAssociationInterface *d) : QMetaContainer(d) {}
1121
1122 template<typename T>
1123 static constexpr QMetaAssociation fromContainer()
1124 {
1125 return QMetaAssociation(&MetaAssociation<T>::value);
1126 }
1127
1128 QMetaType keyMetaType() const;
1129 QMetaType mappedMetaType() const;
1130
1131 bool canInsertKey() const
1132 {
1133 if (auto iface = d())
1134 return iface->insertKeyFn;
1135 return false;
1136 }
1137 void insertKey(void *container, const void *key) const
1138 {
1139 if (canInsertKey())
1140 d()->insertKeyFn(container, key);
1141 }
1142
1143 bool canRemoveKey() const
1144 {
1145 if (auto iface = d())
1146 return iface->removeKeyFn;
1147 return false;
1148 }
1149 void removeKey(void *container, const void *key) const
1150 {
1151 if (canRemoveKey())
1152 d()->removeKeyFn(container, key);
1153 }
1154
1155 bool canContainsKey() const
1156 {
1157 if (auto iface = d())
1158 return iface->containsKeyFn;
1159 return false;
1160 }
1161 bool containsKey(const void *container, const void *key) const
1162 {
1163 if (canContainsKey())
1164 return d()->containsKeyFn(container, key);
1165 return false;
1166 }
1167
1168
1169 bool canGetMappedAtKey() const
1170 {
1171 if (auto iface = d())
1172 return iface->mappedAtKeyFn;
1173 return false;
1174 }
1175 void mappedAtKey(const void *container, const void *key, void *mapped) const
1176 {
1177 if (canGetMappedAtKey())
1178 d()->mappedAtKeyFn(container, key, mapped);
1179 }
1180
1181 bool canSetMappedAtKey() const
1182 {
1183 if (auto iface = d())
1184 return iface->setMappedAtKeyFn;
1185 return false;
1186 }
1187 void setMappedAtKey(void *container, const void *key, const void *mapped) const
1188 {
1189 if (canSetMappedAtKey())
1190 d()->setMappedAtKeyFn(container, key, mapped);
1191 }
1192
1193 bool canGetKeyAtIterator() const
1194 {
1195 if (auto iface = d())
1196 return iface->keyAtIteratorFn;
1197 return false;
1198 }
1199
1200 void keyAtIterator(const void *iterator, void *key) const
1201 {
1202 if (canGetKeyAtIterator())
1203 d()->keyAtIteratorFn(iterator, key);
1204 }
1205
1206 bool canGetKeyAtConstIterator() const
1207 {
1208 if (auto iface = d())
1209 return iface->keyAtConstIteratorFn;
1210 return false;
1211 }
1212
1213 void keyAtConstIterator(const void *iterator, void *key) const
1214 {
1215 if (canGetKeyAtConstIterator())
1216 d()->keyAtConstIteratorFn(iterator, key);
1217 }
1218
1219 bool canGetMappedAtIterator() const
1220 {
1221 if (auto iface = d())
1222 return iface->mappedAtIteratorFn;
1223 return false;
1224 }
1225
1226 void mappedAtIterator(const void *iterator, void *mapped) const
1227 {
1228 if (canGetMappedAtIterator())
1229 d()->mappedAtIteratorFn(iterator, mapped);
1230 }
1231
1232 bool canGetMappedAtConstIterator() const
1233 {
1234 if (auto iface = d())
1235 return iface->mappedAtConstIteratorFn;
1236 return false;
1237 }
1238
1239 void mappedAtConstIterator(const void *iterator, void *mapped) const
1240 {
1241 if (canGetMappedAtConstIterator())
1242 d()->mappedAtConstIteratorFn(iterator, mapped);
1243 }
1244
1245 bool canSetMappedAtIterator() const
1246 {
1247 if (auto iface = d())
1248 return iface->setMappedAtIteratorFn;
1249 return false;
1250 }
1251
1252 void setMappedAtIterator(const void *iterator, const void *mapped) const
1253 {
1254 if (canSetMappedAtIterator())
1255 d()->setMappedAtIteratorFn(iterator, mapped);
1256 }
1257
1258 bool canCreateIteratorAtKey() const
1259 {
1260 if (auto iface = d())
1261 return iface->createIteratorAtKeyFn;
1262 return false;
1263 }
1264
1265 void *createIteratorAtKey(void *container, const void *key) const
1266 {
1267 if (canCreateIteratorAtKey())
1268 return d()->createIteratorAtKeyFn(container, key);
1269 return nullptr;
1270 }
1271
1272 bool canCreateConstIteratorAtKey() const
1273 {
1274 if (auto iface = d())
1275 return iface->createConstIteratorAtKeyFn;
1276 return false;
1277 }
1278
1279 void *createConstIteratorAtKey(const void *container, const void *key) const
1280 {
1281 if (canCreateConstIteratorAtKey())
1282 return d()->createConstIteratorAtKeyFn(container, key);
1283 return nullptr;
1284 }
1285
1286 const QtMetaContainerPrivate::QMetaAssociationInterface *iface() const { return d(); }
1287
1288private:
1289 friend bool comparesEqual(const QMetaAssociation &lhs, const QMetaAssociation &rhs) noexcept
1290 {
1291 return lhs.d() == rhs.d();
1292 }
1293 Q_DECLARE_EQUALITY_COMPARABLE(QMetaAssociation)
1294
1295 template<typename T>
1296 struct MetaAssociation
1297 {
1298 static constexpr const QtMetaContainerPrivate::QMetaAssociationInterface value
1299 = QtMetaContainerPrivate::QMetaAssociationInterface(
1300 QtMetaContainerPrivate::QMetaAssociationForContainer<T>());
1301 };
1302
1303 const QtMetaContainerPrivate::QMetaAssociationInterface *d() const
1304 {
1305 return static_cast<const QtMetaContainerPrivate::QMetaAssociationInterface *>(d_ptr);
1306 }
1307};
1308
1309QT_END_NAMESPACE
1310
1311#endif // QMETACONTAINER_H
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
void(*)(void *, const void *, const void *) SetMappedAtKeyFn
void(*)(void *, const void *) EraseKeyAtIteratorFn
bool(*)(const void *, const void *) ContainsKeyFn
void(*)(const void *, const void *, void *) MappedAtKeyFn
void(*)(const void *, const void *) SetMappedAtIteratorFn
const QtPrivate::QMetaTypeInterface * keyMetaType
void *(*)(void *, const void *) CreateIteratorAtKeyFn
void *(*)(const void *, const void *) CreateConstIteratorAtKeyFn
const QtPrivate::QMetaTypeInterface * mappedMetaType
constexpr QMetaAssociationInterface(const MetaAssociation &m)
void(*)(const void *, qsizetype, void *) ValueAtIndexFn
void(*)(void *, qsizetype, const void *) SetValueAtIndexFn
void(*)(const void *, void *) ValueAtIteratorFn
void(*)(void *, const void *, const void *) InsertValueAtIteratorFn
const QtPrivate::QMetaTypeInterface * valueMetaType
void(*)(void *, const void *, Position) AddValueFn
void(*)(const void *, const void *) SetValueAtIteratorFn
void(*)(void *, const void *, const void *) EraseRangeAtIteratorFn
void(*)(void *, const void *) EraseValueAtIteratorFn
constexpr QMetaSequenceInterface(const MetaSequence &m)
Combined button and popup list for selecting options.
constexpr const QMetaTypeInterface * qMetaTypeInterfaceForType()
Definition qmetatype.h:2646