220 template <
typename Iterator>
221 static constexpr IteratorCapabilities capabilitiesForIterator()
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>)
227 if constexpr (
std::is_base_of_v<
std::forward_iterator_tag, Tag>)
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>)
236 static constexpr IteratorCapabilities getIteratorCapabilities()
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>>();
246 static constexpr QMetaContainerInterface::SizeFn getSizeFn()
248 if constexpr (QContainerInfo::has_size_v<C>) {
249 return [](
const void *c) -> qsizetype {
return static_cast<
const C *>(c)->size(); };
255 static constexpr QMetaContainerInterface::ClearFn getClearFn()
257 if constexpr (QContainerInfo::has_clear_v<C>) {
258 return [](
void *c) {
return static_cast<C *>(c)->clear(); };
264 static constexpr QMetaContainerInterface::CreateIteratorFn getCreateIteratorFn()
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>;
270 case QMetaContainerInterface::Unspecified:
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());
284 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyIteratorFn()
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);
296 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareIteratorFn()
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);
308 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyIteratorFn()
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);
320 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceIteratorFn()
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);
331 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffIteratorFn()
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));
343 static constexpr QMetaContainerInterface::CreateConstIteratorFn getCreateConstIteratorFn()
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>;
349 case QMetaContainerInterface::Unspecified:
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());
363 static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyConstIteratorFn()
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);
375 static constexpr QMetaContainerInterface::CompareIteratorFn getCompareConstIteratorFn()
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);
387 static constexpr QMetaContainerInterface::CopyIteratorFn getCopyConstIteratorFn()
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);
399 static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceConstIteratorFn()
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);
410 static constexpr QMetaContainerInterface::DiffIteratorFn getDiffConstIteratorFn()
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));
424 template<
typename EraseFn>
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));
445 if constexpr (QContainerInfo::has_value_type_v<C>)
446 return QtPrivate::qMetaTypeInterfaceForType<
typename C::value_type>();
451 static constexpr AddRemoveCapabilities getAddRemoveCapabilities()
453 AddRemoveCapabilities caps;
454 if constexpr (QContainerInfo::has_push_back_v<C>)
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;
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);
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];
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);
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);
501 case QMetaSequenceInterface::AtBegin:
502 static_cast<C *>(c)->push_front(value);
504 case QMetaSequenceInterface::AtEnd:
505 case QMetaSequenceInterface::Unspecified:
506 static_cast<C *>(c)->push_back(value);
511 return [](
void *c,
const void *v, QMetaSequenceInterface::Position position) {
512 const auto &value = *
static_cast<
const QContainerInfo::value_type<C> *>(v);
514 case QMetaSequenceInterface::AtBegin:
516 case QMetaSequenceInterface::AtEnd:
517 case QMetaSequenceInterface::Unspecified:
518 static_cast<C *>(c)->push_back(value);
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);
527 case QMetaSequenceInterface::Unspecified:
528 case QMetaSequenceInterface::AtBegin:
529 static_cast<C *>(c)->push_front(value);
530 case QMetaSequenceInterface::AtEnd:
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));
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) {
552 case QMetaSequenceInterface::AtBegin:
553 static_cast<C *>(c)->pop_front();
555 case QMetaSequenceInterface::AtEnd:
556 case QMetaSequenceInterface::Unspecified:
557 static_cast<C *>(c)->pop_back();
562 return [](
void *c, QMetaSequenceInterface::Position position) {
564 case QMetaSequenceInterface::AtBegin:
566 case QMetaSequenceInterface::Unspecified:
567 case QMetaSequenceInterface::AtEnd:
568 static_cast<C *>(c)->pop_back();
573 }
else if constexpr (QContainerInfo::has_pop_front_v<C>) {
574 return [](
void *c, QMetaSequenceInterface::Position position) {
576 case QMetaSequenceInterface::Unspecified:
577 case QMetaSequenceInterface::AtBegin:
578 static_cast<C *>(c)->pop_front();
580 case QMetaSequenceInterface::AtEnd:
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));
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);
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));
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));
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));
669 if constexpr (QContainerInfo::has_key_type_v<C>)
670 return QtPrivate::qMetaTypeInterfaceForType<
typename C::key_type>();
677 if constexpr (QContainerInfo::has_mapped_type_v<C>)
678 return QtPrivate::qMetaTypeInterfaceForType<
typename C::mapped_type>();
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));
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), {}});
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), {});
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));
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));
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));
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))
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));
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)];
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);
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)));
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)));
796 template<
typename Iterator>
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();
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;
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));
822 return keyAtIteratorFn<QContainerInfo::iterator<C>>();
827 return keyAtIteratorFn<QContainerInfo::const_iterator<C>>();
830 template<
typename Iterator>
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();
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;
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);
856 return mappedAtIteratorFn<QContainerInfo::iterator<C>>();
861 return mappedAtIteratorFn<QContainerInfo::const_iterator<C>>();
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);
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);