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