215 template <
typename Iterator>
216 static constexpr IteratorCapabilities capabilitiesForIterator()
218 using Tag =
typename std::iterator_traits<Iterator>::iterator_category;
219 IteratorCapabilities caps {};
220 if constexpr (
std::is_base_of_v<
std::input_iterator_tag, Tag>)
222 if constexpr (
std::is_base_of_v<
std::forward_iterator_tag, Tag>)
224 if constexpr (
std::is_base_of_v<
std::bidirectional_iterator_tag, Tag>)
226 if constexpr (
std::is_base_of_v<
std::random_access_iterator_tag, Tag>)
231 static constexpr IteratorCapabilities getIteratorCapabilities()
233 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>)
234 return capabilitiesForIterator<QContainerInfo::iterator<C>>();
235 else if constexpr (QContainerInfo::has_const_iterator_v<C>)
236 return capabilitiesForIterator<QContainerInfo::const_iterator<C>>();
241 static constexpr QMetaContainerInterface::SizeFn getSizeFn()
243 if constexpr (QContainerInfo::has_size_v<C>) {
244 return [](
const void *c) -> qsizetype {
return static_cast<
const C *>(c)->size(); };
250 static constexpr QMetaContainerInterface::ClearFn getClearFn()
252 if constexpr (QContainerInfo::has_clear_v<C>) {
253 return [](
void *c) {
return static_cast<C *>(c)->clear(); };
259 static constexpr QMetaContainerInterface::CreateIteratorFn getCreateIteratorFn()
261 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
262 return [](
void *c, QMetaContainerInterface::Position p) ->
void* {
263 using Iterator = QContainerInfo::iterator<C>;
265 case QMetaContainerInterface::Unspecified:
267 case QMetaContainerInterface::AtBegin:
268 return new Iterator(
static_cast<C *>(c)->begin());
269 case QMetaContainerInterface::AtEnd:
270 return new Iterator(
static_cast<C *>(c)->end());
279 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyIteratorFn()
281 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
282 return [](
const void *i) {
283 using Iterator = QContainerInfo::iterator<C>;
284 delete static_cast<
const Iterator *>(i);
291 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareIteratorFn()
293 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
294 return [](
const void *i,
const void *j) {
295 using Iterator = QContainerInfo::iterator<C>;
296 return *
static_cast<
const Iterator *>(i) == *
static_cast<
const Iterator *>(j);
303 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyIteratorFn()
305 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
306 return [](
void *i,
const void *j) {
307 using Iterator = QContainerInfo::iterator<C>;
308 *
static_cast<Iterator *>(i) = *
static_cast<
const Iterator *>(j);
315 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceIteratorFn()
317 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
318 return [](
void *i, qsizetype step) {
319 std::advance(*
static_cast<QContainerInfo::iterator<C> *>(i), step);
326 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffIteratorFn()
328 if constexpr (QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {
329 return [](
const void *i,
const void *j) -> qsizetype {
330 return std::distance(*
static_cast<
const QContainerInfo::iterator<C> *>(j),
331 *
static_cast<
const QContainerInfo::iterator<C> *>(i));
338 static constexpr QMetaContainerInterface::CreateConstIteratorFn getCreateConstIteratorFn()
340 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
341 return [](
const void *c, QMetaContainerInterface::Position p) ->
void* {
342 using Iterator = QContainerInfo::const_iterator<C>;
344 case QMetaContainerInterface::Unspecified:
346 case QMetaContainerInterface::AtBegin:
347 return new Iterator(
static_cast<
const C *>(c)->begin());
348 case QMetaContainerInterface::AtEnd:
349 return new Iterator(
static_cast<
const C *>(c)->end());
358 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyConstIteratorFn()
360 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
361 return [](
const void *i) {
362 using Iterator = QContainerInfo::const_iterator<C>;
363 delete static_cast<
const Iterator *>(i);
370 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareConstIteratorFn()
372 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
373 return [](
const void *i,
const void *j) {
374 using Iterator = QContainerInfo::const_iterator<C>;
375 return *
static_cast<
const Iterator *>(i) == *
static_cast<
const Iterator *>(j);
382 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyConstIteratorFn()
384 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
385 return [](
void *i,
const void *j) {
386 using Iterator = QContainerInfo::const_iterator<C>;
387 *
static_cast<Iterator *>(i) = *
static_cast<
const Iterator *>(j);
394 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceConstIteratorFn()
396 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
397 return [](
void *i, qsizetype step) {
398 std::advance(*
static_cast<QContainerInfo::const_iterator<C> *>(i), step);
405 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffConstIteratorFn()
407 if constexpr (QContainerInfo::has_const_iterator_v<C>) {
408 return [](
const void *i,
const void *j) -> qsizetype {
409 return std::distance(*
static_cast<
const QContainerInfo::const_iterator<C> *>(j),
410 *
static_cast<
const QContainerInfo::const_iterator<C> *>(i));
419 template<
typename EraseFn>
422 if constexpr (QContainerInfo::has_iterator_v<C>
423 && QContainerInfo::can_erase_at_iterator_v<C> && !std::is_const_v<C>) {
424 return [](
void *c,
const void *i) {
425 static_cast<C *>(c)->erase(*
static_cast<
const QContainerInfo::iterator<C> *>(i));
440 if constexpr (QContainerInfo::has_value_type_v<C>)
441 return QtPrivate::qMetaTypeInterfaceForType<
typename C::value_type>();
446 static constexpr AddRemoveCapabilities getAddRemoveCapabilities()
448 AddRemoveCapabilities caps;
449 if constexpr (QContainerInfo::has_push_back_v<C>)
451 if constexpr (QContainerInfo::has_pop_back_v<C>)
452 caps |= CanRemoveAtEnd;
453 if constexpr (QContainerInfo::has_push_front_v<C>)
454 caps |= CanAddAtBegin;
455 if constexpr (QContainerInfo::has_pop_front_v<C>)
456 caps |= CanRemoveAtBegin;
462 if constexpr (QContainerInfo::has_at_index_v<C>) {
463 return [](
const void *c, qsizetype i,
void *r) {
464 *
static_cast<QContainerInfo::value_type<C> *>(r)
465 =
static_cast<
const C *>(c)->at(i);
467 }
else if constexpr (QContainerInfo::can_get_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))[i];
479 if constexpr (QContainerInfo::can_set_at_index_v<C>) {
480 return [](
void *c, qsizetype i,
const void *e) {
481 (*
static_cast<C *>(c))[i]
482 = *
static_cast<
const QContainerInfo::value_type<C> *>(e);
491 if constexpr (QContainerInfo::has_push_back_v<C>) {
492 if constexpr (QContainerInfo::has_push_front_v<C>) {
493 return [](
void *c,
const void *v, QMetaSequenceInterface::Position position) {
494 const auto &value = *
static_cast<
const QContainerInfo::value_type<C> *>(v);
496 case QMetaSequenceInterface::AtBegin:
497 static_cast<C *>(c)->push_front(value);
499 case QMetaSequenceInterface::AtEnd:
500 case QMetaSequenceInterface::Unspecified:
501 static_cast<C *>(c)->push_back(value);
506 return [](
void *c,
const void *v, QMetaSequenceInterface::Position position) {
507 const auto &value = *
static_cast<
const QContainerInfo::value_type<C> *>(v);
509 case QMetaSequenceInterface::AtBegin:
511 case QMetaSequenceInterface::AtEnd:
512 case QMetaSequenceInterface::Unspecified:
513 static_cast<C *>(c)->push_back(value);
518 }
else if constexpr (QContainerInfo::has_push_front_v<C>) {
519 return [](
void *c,
const void *v, QMetaSequenceInterface::Position position) {
520 const auto &value = *
static_cast<
const QContainerInfo::value_type<C> *>(v);
522 case QMetaSequenceInterface::Unspecified:
523 case QMetaSequenceInterface::AtBegin:
524 static_cast<C *>(c)->push_front(value);
525 case QMetaSequenceInterface::AtEnd:
529 }
else if constexpr (QContainerInfo::has_insert_v<C>) {
530 return [](
void *c,
const void *v, QMetaSequenceInterface::Position position) {
531 if (position == QMetaSequenceInterface::Unspecified) {
532 static_cast<C *>(c)->insert(
533 *
static_cast<
const QContainerInfo::value_type<C> *>(v));
543 if constexpr (QContainerInfo::has_pop_back_v<C>) {
544 if constexpr (QContainerInfo::has_pop_front_v<C>) {
545 return [](
void *c, QMetaSequenceInterface::Position position) {
547 case QMetaSequenceInterface::AtBegin:
548 static_cast<C *>(c)->pop_front();
550 case QMetaSequenceInterface::AtEnd:
551 case QMetaSequenceInterface::Unspecified:
552 static_cast<C *>(c)->pop_back();
557 return [](
void *c, QMetaSequenceInterface::Position position) {
559 case QMetaSequenceInterface::AtBegin:
561 case QMetaSequenceInterface::Unspecified:
562 case QMetaSequenceInterface::AtEnd:
563 static_cast<C *>(c)->pop_back();
568 }
else if constexpr (QContainerInfo::has_pop_front_v<C>) {
569 return [](
void *c, QMetaSequenceInterface::Position position) {
571 case QMetaSequenceInterface::Unspecified:
572 case QMetaSequenceInterface::AtBegin:
573 static_cast<C *>(c)->pop_front();
575 case QMetaSequenceInterface::AtEnd:
586 if constexpr (QContainerInfo::has_iterator_v<C>
587 && QContainerInfo::iterator_dereferences_to_value_v<C> && !std::is_const_v<C>) {
588 return [](
const void *i,
void *r) {
589 *
static_cast<QContainerInfo::value_type<C> *>(r) =
590 *(*
static_cast<
const QContainerInfo::iterator<C> *>(i));
599 if constexpr (QContainerInfo::has_iterator_v<C>
600 && QContainerInfo::can_set_value_at_iterator_v<C> && !std::is_const_v<C>) {
601 return [](
const void *i,
const void *e) {
602 *(*
static_cast<
const QContainerInfo::iterator<C> *>(i))
603 = *
static_cast<
const QContainerInfo::value_type<C> *>(e);
612 if constexpr (QContainerInfo::has_iterator_v<C>
613 && QContainerInfo::can_insert_value_at_iterator_v<C> && !std::is_const_v<C>) {
614 return [](
void *c,
const void *i,
const void *e) {
615 static_cast<C *>(c)->insert(
616 *
static_cast<
const QContainerInfo::iterator<C> *>(i),
617 *
static_cast<
const QContainerInfo::value_type<C> *>(e));
626 if constexpr (QContainerInfo::has_const_iterator_v<C>
627 && QContainerInfo::iterator_dereferences_to_value_v<C>) {
628 return [](
const void *i,
void *r) {
629 *
static_cast<QContainerInfo::value_type<C> *>(r) =
630 *(*
static_cast<
const QContainerInfo::const_iterator<C> *>(i));
645 if constexpr (QContainerInfo::has_iterator_v<C>
646 && QContainerInfo::can_erase_range_at_iterator_v<C> && !std::is_const_v<C>) {
647 return [](
void *c,
const void *i,
const void *j) {
648 static_cast<C *>(c)->erase(*
static_cast<
const QContainerInfo::iterator<C> *>(i),
649 *
static_cast<
const QContainerInfo::iterator<C> *>(j));
664 if constexpr (QContainerInfo::has_key_type_v<C>)
665 return QtPrivate::qMetaTypeInterfaceForType<
typename C::key_type>();
672 if constexpr (QContainerInfo::has_mapped_type_v<C>)
673 return QtPrivate::qMetaTypeInterfaceForType<
typename C::mapped_type>();
680 if constexpr (QContainerInfo::can_insert_key_v<C>) {
681 return [](
void *c,
const void *k) {
682 static_cast<C *>(c)->insert(
683 *
static_cast<
const QContainerInfo::key_type<C> *>(k));
685 }
else if constexpr (QContainerInfo::can_insert_pair_v<C>) {
686 return [](
void *c,
const void *k) {
687 static_cast<C *>(c)->insert(
688 {*
static_cast<
const QContainerInfo::key_type<C> *>(k), {}});
690 }
else if constexpr (QContainerInfo::can_insert_key_mapped_v<C>) {
691 return [](
void *c,
const void *k) {
692 static_cast<C *>(c)->insert(
693 *
static_cast<
const QContainerInfo::key_type<C> *>(k), {});
702 if constexpr (QContainerInfo::can_erase_at_key_v<C>) {
703 return [](
void *c,
const void *k) {
704 static_cast<C *>(c)->erase(*
static_cast<
const QContainerInfo::key_type<C> *>(k));
706 }
else if constexpr (QContainerInfo::can_remove_at_key_v<C>) {
707 return [](
void *c,
const void *k) {
708 static_cast<C *>(c)->remove(*
static_cast<
const QContainerInfo::key_type<C> *>(k));
717 if constexpr (QContainerInfo::has_contains_v<C>) {
718 return [](
const void *c,
const void *k) {
719 return static_cast<
const C *>(c)->contains(
720 *
static_cast<
const QContainerInfo::key_type<C> *>(k));
722 }
else if (QContainerInfo::has_find_v<C>) {
723 return [](
const void *c,
const void *k) {
724 const C *container =
static_cast<
const C *>(c);
725 return container->find(
726 *
static_cast<
const QContainerInfo::key_type<C> *>(k))
736 if constexpr (QContainerInfo::has_at_key_v<C>) {
737 return [](
const void *c,
const void *k,
void *r) {
738 *
static_cast<QContainerInfo::mapped_type<C> *>(r)
739 =
static_cast<
const C *>(c)->at(
740 *
static_cast<
const QContainerInfo::key_type<C> *>(k));
742 }
else if constexpr (QContainerInfo::can_get_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))[
746 *
static_cast<
const QContainerInfo::key_type<C> *>(k)];
755 if constexpr (QContainerInfo::can_set_at_key_v<C>) {
756 return [](
void *c,
const void *k,
const void *m) {
757 (*
static_cast<C *>(c))[*
static_cast<
const QContainerInfo::key_type<C> *>(k)] =
758 *
static_cast<
const QContainerInfo::mapped_type<C> *>(m);
767 if constexpr (QContainerInfo::has_find_v<C>) {
768 return [](
void *c,
const void *k) ->
void* {
769 using Iterator = QContainerInfo::iterator<C>;
770 return new Iterator(
static_cast<C *>(c)->find(
771 *
static_cast<
const QContainerInfo::key_type<C> *>(k)));
780 if constexpr (QContainerInfo::has_find_v<C>) {
781 return [](
const void *c,
const void *k) ->
void* {
782 using Iterator = QContainerInfo::const_iterator<C>;
783 return new Iterator(
static_cast<
const C *>(c)->find(
784 *
static_cast<
const QContainerInfo::key_type<C> *>(k)));
791 template<
typename Iterator>
794 if constexpr (QContainerInfo::iterator_has_key_v<C>) {
795 return [](
const void *i,
void *k) {
796 *
static_cast<QContainerInfo::key_type<C> *>(k)
797 =
static_cast<
const Iterator *>(i)->key();
799 }
else if constexpr (QContainerInfo::iterator_dereferences_to_value_v<C>
800 && QContainerInfo::value_type_has_first_v<C>) {
801 return [](
const void *i,
void *k) {
802 *
static_cast<QContainerInfo::key_type<C> *>(k)
803 = (*
static_cast<
const Iterator *>(i))->first;
805 }
else if constexpr (QContainerInfo::iterator_dereferences_to_key_v<C>) {
806 return [](
const void *i,
void *k) {
807 *
static_cast<QContainerInfo::key_type<C> *>(k)
808 = *(*
static_cast<
const Iterator *>(i));
817 return keyAtIteratorFn<QContainerInfo::iterator<C>>();
822 return keyAtIteratorFn<QContainerInfo::const_iterator<C>>();
825 template<
typename Iterator>
828 if constexpr (QContainerInfo::iterator_has_value_v<C>) {
829 return [](
const void *i,
void *k) {
830 *
static_cast<QContainerInfo::mapped_type<C> *>(k)
831 =
static_cast<
const Iterator *>(i)->value();
833 }
else if constexpr (QContainerInfo::iterator_dereferences_to_value_v<C>
834 && QContainerInfo::value_type_has_second_v<C>) {
835 return [](
const void *i,
void *k) {
836 *
static_cast<QContainerInfo::mapped_type<C> *>(k)
837 = (*
static_cast<
const Iterator *>(i))->second;
839 }
else if constexpr (QContainerInfo::iterator_dereferences_to_mapped_v<C>) {
840 return [](
const void *i,
void *k) {
841 *
static_cast<QContainerInfo::mapped_type<C> *>(k)
842 = *
static_cast<
const Iterator *>(i);
851 return mappedAtIteratorFn<QContainerInfo::iterator<C>>();
856 return mappedAtIteratorFn<QContainerInfo::const_iterator<C>>();
861 if constexpr (QContainerInfo::can_set_mapped_at_iterator_v<C> && !std::is_const_v<C>) {
862 return [](
const void *i,
const void *m) {
863 *(*
static_cast<
const QContainerInfo::iterator<C> *>(i))
864 = *
static_cast<
const QContainerInfo::mapped_type<C> *>(m);
866 }
else if constexpr (QContainerInfo::iterator_dereferences_to_value_v<C>
867 && QContainerInfo::value_type_has_second_v<C>) {
868 return [](
const void *i,
const void *m) {
869 (*
static_cast<
const QContainerInfo::iterator<C> *>(i))->second
870 = *
static_cast<
const QContainerInfo::mapped_type<C> *>(m);