221 template <
typename Iterator>
222 static constexpr IteratorCapabilities capabilitiesForIterator()
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>)
228 if constexpr (
std::is_base_of_v<
std::forward_iterator_tag, Tag>)
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>)
237 static constexpr IteratorCapabilities getIteratorCapabilities()
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>>();
247 static constexpr QMetaContainerInterface::SizeFn getSizeFn()
249 if constexpr (QContainerInfo::has_size_v<C>) {
250 return [](
const void *c) -> qsizetype {
return static_cast<
const C *>(c)->size(); };
256 static constexpr QMetaContainerInterface::ClearFn getClearFn()
258 if constexpr (QContainerInfo::has_clear_v<C>) {
259 return [](
void *c) {
return static_cast<C *>(c)->clear(); };
265 static constexpr QMetaContainerInterface::CreateIteratorFn getCreateIteratorFn()
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>;
271 case QMetaContainerInterface::Unspecified:
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());
285 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyIteratorFn()
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);
297 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareIteratorFn()
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);
309 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyIteratorFn()
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);
321 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceIteratorFn()
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);
332 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffIteratorFn()
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));
344 static constexpr QMetaContainerInterface::CreateConstIteratorFn getCreateConstIteratorFn()
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>;
350 case QMetaContainerInterface::Unspecified:
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());
364 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyConstIteratorFn()
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);
376 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareConstIteratorFn()
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);
388 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyConstIteratorFn()
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);
400 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceConstIteratorFn()
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);
411 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffConstIteratorFn()
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));
425 template<
typename EraseFn>
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));
446 if constexpr (QContainerInfo::has_value_type_v<C>)
447 return QtPrivate::qMetaTypeInterfaceForType<
typename C::value_type>();
452 static constexpr AddRemoveCapabilities getAddRemoveCapabilities()
454 AddRemoveCapabilities caps;
455 if constexpr (QContainerInfo::has_push_back_v<C>)
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;
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);
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];
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);
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);
502 case QMetaSequenceInterface::AtBegin:
503 static_cast<C *>(c)->push_front(value);
505 case QMetaSequenceInterface::AtEnd:
506 case QMetaSequenceInterface::Unspecified:
507 static_cast<C *>(c)->push_back(value);
512 return [](
void *c,
const void *v, QMetaSequenceInterface::Position position) {
513 const auto &value = *
static_cast<
const QContainerInfo::value_type<C> *>(v);
515 case QMetaSequenceInterface::AtBegin:
517 case QMetaSequenceInterface::AtEnd:
518 case QMetaSequenceInterface::Unspecified:
519 static_cast<C *>(c)->push_back(value);
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);
528 case QMetaSequenceInterface::Unspecified:
529 case QMetaSequenceInterface::AtBegin:
530 static_cast<C *>(c)->push_front(value);
531 case QMetaSequenceInterface::AtEnd:
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));
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) {
553 case QMetaSequenceInterface::AtBegin:
554 static_cast<C *>(c)->pop_front();
556 case QMetaSequenceInterface::AtEnd:
557 case QMetaSequenceInterface::Unspecified:
558 static_cast<C *>(c)->pop_back();
563 return [](
void *c, QMetaSequenceInterface::Position position) {
565 case QMetaSequenceInterface::AtBegin:
567 case QMetaSequenceInterface::Unspecified:
568 case QMetaSequenceInterface::AtEnd:
569 static_cast<C *>(c)->pop_back();
574 }
else if constexpr (QContainerInfo::has_pop_front_v<C>) {
575 return [](
void *c, QMetaSequenceInterface::Position position) {
577 case QMetaSequenceInterface::Unspecified:
578 case QMetaSequenceInterface::AtBegin:
579 static_cast<C *>(c)->pop_front();
581 case QMetaSequenceInterface::AtEnd:
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));
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);
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));
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));
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));
670 if constexpr (QContainerInfo::has_key_type_v<C>)
671 return QtPrivate::qMetaTypeInterfaceForType<
typename C::key_type>();
678 if constexpr (QContainerInfo::has_mapped_type_v<C>)
679 return QtPrivate::qMetaTypeInterfaceForType<
typename C::mapped_type>();
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));
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), {}});
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), {});
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));
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));
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));
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))
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));
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)];
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);
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)));
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)));
797 template<
typename Iterator>
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();
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;
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));
823 return keyAtIteratorFn<QContainerInfo::iterator<C>>();
828 return keyAtIteratorFn<QContainerInfo::const_iterator<C>>();
831 template<
typename Iterator>
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();
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;
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);
857 return mappedAtIteratorFn<QContainerInfo::iterator<C>>();
862 return mappedAtIteratorFn<QContainerInfo::const_iterator<C>>();
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);
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);