Add a QMetaAssociation

This requires refactoring of QMetaSequence, as they share a lot of
common functionality. QMetaAssociation provides a low level interface to
an associative container.

Task-number: QTBUG-81716
Change-Id: I273e00abd82f1549ba8803c323d82aa3a2d12ded
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Ulf Hermann 2020-09-10 18:23:23 +02:00
parent d423fe9851
commit 1162b4bfc9
5 changed files with 1347 additions and 393 deletions

View File

@ -51,6 +51,12 @@ namespace QContainerTraits
template<typename C> template<typename C>
using value_type = typename C::value_type; using value_type = typename C::value_type;
template<typename C>
using key_type = typename C::key_type;
template<typename C>
using mapped_type = typename C::mapped_type;
template<typename C> template<typename C>
using iterator = typename C::iterator; using iterator = typename C::iterator;
@ -61,6 +67,21 @@ using const_iterator = typename C::const_iterator;
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wunused-const-variable") QT_WARNING_DISABLE_CLANG("-Wunused-const-variable")
template<typename C, typename = void>
constexpr bool has_value_type_v = false;
template<typename C>
constexpr bool has_value_type_v<C, std::void_t<value_type<C>>> = true;
template<typename C, typename = void>
constexpr bool has_key_type_v = false;
template<typename C>
constexpr bool has_key_type_v<C, std::void_t<key_type<C>>> = true;
template<typename C, typename = void>
constexpr bool has_mapped_type_v = false;
template<typename C>
constexpr bool has_mapped_type_v<C, std::void_t<mapped_type<C>>> = true;
template<typename C, typename = void> template<typename C, typename = void>
constexpr bool has_size_v = false; constexpr bool has_size_v = false;
template<typename C> template<typename C>
@ -72,9 +93,14 @@ template<typename C>
constexpr bool has_clear_v<C, std::void_t<decltype(C().clear())>> = true; constexpr bool has_clear_v<C, std::void_t<decltype(C().clear())>> = true;
template<typename, typename = void> template<typename, typename = void>
constexpr bool has_at_v = false; constexpr bool has_at_index_v = false;
template<typename C> template<typename C>
constexpr bool has_at_v<C, std::void_t<decltype(C().at(0))>> = true; constexpr bool has_at_index_v<C, std::void_t<decltype(C().at(0))>> = true;
template<typename, typename = void>
constexpr bool has_at_key_v = false;
template<typename C>
constexpr bool has_at_key_v<C, std::void_t<decltype(C().at(key_type<C>()))>> = true;
template<typename, typename = void> template<typename, typename = void>
constexpr bool can_get_at_index_v = false; constexpr bool can_get_at_index_v = false;
@ -122,19 +148,19 @@ template<typename C>
constexpr bool has_const_iterator_v<C, std::void_t<const_iterator<C>>> = true; constexpr bool has_const_iterator_v<C, std::void_t<const_iterator<C>>> = true;
template<typename, typename = void> template<typename, typename = void>
constexpr bool can_get_at_iterator_v = false; constexpr bool can_set_value_at_iterator_v = false;
template<typename C> template<typename C>
constexpr bool can_get_at_iterator_v<C, std::void_t<value_type<C>(decltype(*C().begin()))>> = true; constexpr bool can_set_value_at_iterator_v<C, std::void_t<decltype(*C().begin() = value_type<C>())>> = true;
template<typename, typename = void> template<typename, typename = void>
constexpr bool can_set_at_iterator_v = false; constexpr bool can_set_mapped_at_iterator_v = false;
template<typename C> template<typename C>
constexpr bool can_set_at_iterator_v<C, std::void_t<decltype(*C().begin() = value_type<C>())>> = true; constexpr bool can_set_mapped_at_iterator_v<C, std::void_t<decltype(*C().begin() = mapped_type<C>())>> = true;
template<typename, typename = void> template<typename, typename = void>
constexpr bool can_insert_at_iterator_v = false; constexpr bool can_insert_value_at_iterator_v = false;
template<typename C> template<typename C>
constexpr bool can_insert_at_iterator_v<C, std::void_t<decltype(C().insert(C().begin(), value_type<C>()))>> = true; constexpr bool can_insert_value_at_iterator_v<C, std::void_t<decltype(C().insert(C().begin(), value_type<C>()))>> = true;
template<typename, typename = void> template<typename, typename = void>
constexpr bool can_erase_at_iterator_v = false; constexpr bool can_erase_at_iterator_v = false;
@ -146,6 +172,86 @@ constexpr bool can_erase_range_at_iterator_v = false;
template<typename C> template<typename C>
constexpr bool can_erase_range_at_iterator_v<C, std::void_t<decltype(C().erase(C().begin(), C().end()))>> = true; constexpr bool can_erase_range_at_iterator_v<C, std::void_t<decltype(C().erase(C().begin(), C().end()))>> = true;
template<typename, typename = void>
constexpr bool can_get_at_key_v = false;
template<typename C>
constexpr bool can_get_at_key_v<C, std::void_t<mapped_type<C>(decltype(C()[key_type<C>()]))>> = true;
template<typename, typename = void>
constexpr bool can_set_at_key_v = false;
template<typename C>
constexpr bool can_set_at_key_v<C, std::void_t<decltype(C()[key_type<C>()] = mapped_type<C>())>> = true;
template<typename, typename = void>
constexpr bool can_erase_at_key_v = false;
template<typename C>
constexpr bool can_erase_at_key_v<C, std::void_t<decltype(C().erase(key_type<C>()))>> = true;
template<typename, typename = void>
constexpr bool can_remove_at_key_v = false;
template<typename C>
constexpr bool can_remove_at_key_v<C, std::void_t<decltype(C().remove(key_type<C>()))>> = true;
template<typename, typename = void>
constexpr bool can_insert_key_v = false;
template<typename C>
constexpr bool can_insert_key_v<C, std::void_t<decltype(C().insert(key_type<C>()))>> = true;
template<typename, typename = void>
constexpr bool can_insert_pair_v = false;
template<typename C>
constexpr bool can_insert_pair_v<C, std::void_t<decltype(C().insert({key_type<C>(), mapped_type<C>()}))>> = true;
template<typename, typename = void>
constexpr bool can_insert_key_mapped_v = false;
template<typename C>
constexpr bool can_insert_key_mapped_v<C, std::void_t<decltype(C().insert(key_type<C>(), mapped_type<C>()))>> = true;
template<typename, typename = void>
constexpr bool has_contains_v = false;
template<typename C>
constexpr bool has_contains_v<C, std::void_t<decltype(bool(C().contains(key_type<C>())))>> = true;
template<typename, typename = void>
constexpr bool has_find_v = false;
template<typename C>
constexpr bool has_find_v<C, std::void_t<decltype(C().find(key_type<C>()))>> = true;
template<typename, typename = void>
constexpr bool iterator_dereferences_to_value_v = false;
template<typename C>
constexpr bool iterator_dereferences_to_value_v<C, std::void_t<decltype(value_type<C>(*C().begin()))>> = true;
template<typename, typename = void>
constexpr bool iterator_has_key_v = false;
template<typename C>
constexpr bool iterator_has_key_v<C, std::void_t<decltype(key_type<C>(C().begin().key()))>> = true;
template<typename, typename = void>
constexpr bool value_type_has_first_v = false;
template<typename C>
constexpr bool value_type_has_first_v<C, std::void_t<decltype(key_type<C>(value_type<C>().first))>> = true;
template<typename, typename = void>
constexpr bool iterator_dereferences_to_key_v = false;
template<typename C>
constexpr bool iterator_dereferences_to_key_v<C, std::void_t<decltype(key_type<C>(*C().begin()))>> = true;
template<typename, typename = void>
constexpr bool iterator_has_value_v = false;
template<typename C>
constexpr bool iterator_has_value_v<C, std::void_t<decltype(mapped_type<C>(C().begin().value()))>> = true;
template<typename, typename = void>
constexpr bool value_type_has_second_v = false;
template<typename C>
constexpr bool value_type_has_second_v<C, std::void_t<decltype(mapped_type<C>(value_type<C>().second))>> = true;
template<typename, typename = void>
constexpr bool iterator_dereferences_to_mapped_v = false;
template<typename C>
constexpr bool iterator_dereferences_to_mapped_v<C, std::void_t<decltype(mapped_type<C>(*C().begin()))>> = true;
QT_WARNING_POP QT_WARNING_POP
} }

View File

@ -38,6 +38,7 @@
****************************************************************************/ ****************************************************************************/
#include "qmetacontainer.h" #include "qmetacontainer.h"
#include "qmetatype.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -80,7 +81,7 @@ QT_BEGIN_NAMESPACE
QMetaSequence assumes that const and non-const iterators for the same QMetaSequence assumes that const and non-const iterators for the same
container have the same iterator traits. container have the same iterator traits.
*/ */
bool QMetaSequence::hasInputIterator() const bool QMetaContainer::hasInputIterator() const
{ {
if (!d_ptr) if (!d_ptr)
return false; return false;
@ -97,7 +98,7 @@ bool QMetaSequence::hasInputIterator() const
QMetaSequence assumes that const and non-const iterators for the same QMetaSequence assumes that const and non-const iterators for the same
container have the same iterator traits. container have the same iterator traits.
*/ */
bool QMetaSequence::hasForwardIterator() const bool QMetaContainer::hasForwardIterator() const
{ {
if (!d_ptr) if (!d_ptr)
return false; return false;
@ -113,7 +114,7 @@ bool QMetaSequence::hasForwardIterator() const
QMetaSequence assumes that const and non-const iterators for the same QMetaSequence assumes that const and non-const iterators for the same
container have the same iterator traits. container have the same iterator traits.
*/ */
bool QMetaSequence::hasBidirectionalIterator() const bool QMetaContainer::hasBidirectionalIterator() const
{ {
if (!d_ptr) if (!d_ptr)
return false; return false;
@ -128,7 +129,7 @@ bool QMetaSequence::hasBidirectionalIterator() const
QMetaSequence assumes that const and non-const iterators for the same QMetaSequence assumes that const and non-const iterators for the same
container have the same iterator traits. container have the same iterator traits.
*/ */
bool QMetaSequence::hasRandomAccessIterator() const bool QMetaContainer::hasRandomAccessIterator() const
{ {
if (!d_ptr) if (!d_ptr)
return false; return false;
@ -140,7 +141,9 @@ bool QMetaSequence::hasRandomAccessIterator() const
*/ */
QMetaType QMetaSequence::valueMetaType() const QMetaType QMetaSequence::valueMetaType() const
{ {
return d_ptr ? d_ptr->valueMetaType : QMetaType(); if (auto iface = d())
return QMetaType(iface->valueMetaType);
return QMetaType();
} }
/*! /*!
@ -156,10 +159,10 @@ QMetaType QMetaSequence::valueMetaType() const
*/ */
bool QMetaSequence::isSortable() const bool QMetaSequence::isSortable() const
{ {
if (d_ptr) { if (auto iface = d()) {
return (d_ptr->addRemoveCapabilities return (iface->addRemoveCapabilities
& (QtMetaContainerPrivate::CanAddAtBegin | QtMetaContainerPrivate::CanAddAtEnd)) & (QtMetaContainerPrivate::CanAddAtBegin | QtMetaContainerPrivate::CanAddAtEnd))
&& (d_ptr->addRemoveCapabilities && (iface->addRemoveCapabilities
& (QtMetaContainerPrivate::CanRemoveAtBegin & (QtMetaContainerPrivate::CanRemoveAtBegin
| QtMetaContainerPrivate::CanRemoveAtEnd)); | QtMetaContainerPrivate::CanRemoveAtEnd));
} }
@ -174,9 +177,9 @@ bool QMetaSequence::isSortable() const
*/ */
bool QMetaSequence::canAddValueAtBegin() const bool QMetaSequence::canAddValueAtBegin() const
{ {
if (d_ptr) { if (auto iface = d()) {
return d_ptr->addValueFn return iface->addValueFn
&& d_ptr->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtBegin; && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtBegin;
} }
return false; return false;
} }
@ -190,7 +193,7 @@ bool QMetaSequence::canAddValueAtBegin() const
void QMetaSequence::addValueAtBegin(void *container, const void *value) const void QMetaSequence::addValueAtBegin(void *container, const void *value) const
{ {
if (canAddValueAtBegin()) if (canAddValueAtBegin())
d_ptr->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin); d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
} }
/*! /*!
@ -201,9 +204,9 @@ void QMetaSequence::addValueAtBegin(void *container, const void *value) const
*/ */
bool QMetaSequence::canRemoveValueAtBegin() const bool QMetaSequence::canRemoveValueAtBegin() const
{ {
if (d_ptr) { if (auto iface = d()) {
return d_ptr->removeValueFn return iface->removeValueFn
&& d_ptr->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtBegin; && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtBegin;
} }
return false; return false;
} }
@ -217,7 +220,7 @@ bool QMetaSequence::canRemoveValueAtBegin() const
void QMetaSequence::removeValueAtBegin(void *container) const void QMetaSequence::removeValueAtBegin(void *container) const
{ {
if (canRemoveValueAtBegin()) if (canRemoveValueAtBegin())
d_ptr->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin); d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
} }
/*! /*!
@ -228,9 +231,9 @@ void QMetaSequence::removeValueAtBegin(void *container) const
*/ */
bool QMetaSequence::canAddValueAtEnd() const bool QMetaSequence::canAddValueAtEnd() const
{ {
if (d_ptr) { if (auto iface = d()) {
return d_ptr->addValueFn return iface->addValueFn
&& d_ptr->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtEnd; && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtEnd;
} }
return false; return false;
} }
@ -244,7 +247,7 @@ bool QMetaSequence::canAddValueAtEnd() const
void QMetaSequence::addValueAtEnd(void *container, const void *value) const void QMetaSequence::addValueAtEnd(void *container, const void *value) const
{ {
if (canAddValueAtEnd()) if (canAddValueAtEnd())
d_ptr->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd); d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
} }
/*! /*!
@ -255,9 +258,9 @@ void QMetaSequence::addValueAtEnd(void *container, const void *value) const
*/ */
bool QMetaSequence::canRemoveValueAtEnd() const bool QMetaSequence::canRemoveValueAtEnd() const
{ {
if (d_ptr) { if (auto iface = d()) {
return d_ptr->removeValueFn return iface->removeValueFn
&& d_ptr->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtEnd; && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtEnd;
} }
return false; return false;
} }
@ -271,7 +274,7 @@ bool QMetaSequence::canRemoveValueAtEnd() const
void QMetaSequence::removeValueAtEnd(void *container) const void QMetaSequence::removeValueAtEnd(void *container) const
{ {
if (canRemoveValueAtEnd()) if (canRemoveValueAtEnd())
d_ptr->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd); d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
} }
/*! /*!
@ -280,7 +283,7 @@ void QMetaSequence::removeValueAtEnd(void *container) const
\sa size() \sa size()
*/ */
bool QMetaSequence::hasSize() const bool QMetaContainer::hasSize() const
{ {
return d_ptr && d_ptr->sizeFn; return d_ptr && d_ptr->sizeFn;
} }
@ -291,7 +294,7 @@ bool QMetaSequence::hasSize() const
\sa hasSize() \sa hasSize()
*/ */
qsizetype QMetaSequence::size(const void *container) const qsizetype QMetaContainer::size(const void *container) const
{ {
return hasSize() ? d_ptr->sizeFn(container) : -1; return hasSize() ? d_ptr->sizeFn(container) : -1;
} }
@ -301,7 +304,7 @@ qsizetype QMetaSequence::size(const void *container) const
\sa clear() \sa clear()
*/ */
bool QMetaSequence::canClear() const bool QMetaContainer::canClear() const
{ {
return d_ptr && d_ptr->clearFn; return d_ptr && d_ptr->clearFn;
} }
@ -311,7 +314,7 @@ bool QMetaSequence::canClear() const
\sa canClear() \sa canClear()
*/ */
void QMetaSequence::clear(void *container) const void QMetaContainer::clear(void *container) const
{ {
if (canClear()) if (canClear())
d_ptr->clearFn(container); d_ptr->clearFn(container);
@ -325,7 +328,9 @@ void QMetaSequence::clear(void *container) const
*/ */
bool QMetaSequence::canGetValueAtIndex() const bool QMetaSequence::canGetValueAtIndex() const
{ {
return d_ptr && d_ptr->valueAtIndexFn; if (auto iface = d())
return iface->valueAtIndexFn;
return false;
} }
/*! /*!
@ -337,7 +342,7 @@ bool QMetaSequence::canGetValueAtIndex() const
void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *result) const void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *result) const
{ {
if (canGetValueAtIndex()) if (canGetValueAtIndex())
d_ptr->valueAtIndexFn(container, index, result); d()->valueAtIndexFn(container, index, result);
} }
/*! /*!
@ -348,7 +353,9 @@ void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *r
*/ */
bool QMetaSequence::canSetValueAtIndex() const bool QMetaSequence::canSetValueAtIndex() const
{ {
return d_ptr && d_ptr->setValueAtIndexFn; if (auto iface = d())
return iface->setValueAtIndexFn;
return false;
} }
/*! /*!
@ -360,7 +367,7 @@ bool QMetaSequence::canSetValueAtIndex() const
void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void *value) const void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void *value) const
{ {
if (canSetValueAtIndex()) if (canSetValueAtIndex())
d_ptr->setValueAtIndexFn(container, index, value); d()->setValueAtIndexFn(container, index, value);
} }
/*! /*!
@ -371,7 +378,9 @@ void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void
*/ */
bool QMetaSequence::canAddValue() const bool QMetaSequence::canAddValue() const
{ {
return d_ptr && d_ptr->addValueFn; if (auto iface = d())
return iface->addValueFn;
return false;
} }
/*! /*!
@ -390,7 +399,7 @@ bool QMetaSequence::canAddValue() const
void QMetaSequence::addValue(void *container, const void *value) const void QMetaSequence::addValue(void *container, const void *value) const
{ {
if (canAddValue()) { if (canAddValue()) {
d_ptr->addValueFn(container, value, d()->addValueFn(container, value,
QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified); QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
} }
} }
@ -403,7 +412,9 @@ void QMetaSequence::addValue(void *container, const void *value) const
*/ */
bool QMetaSequence::canRemoveValue() const bool QMetaSequence::canRemoveValue() const
{ {
return d_ptr && d_ptr->removeValueFn; if (auto iface = d())
return iface->removeValueFn;
return false;
} }
/*! /*!
@ -420,7 +431,7 @@ bool QMetaSequence::canRemoveValue() const
void QMetaSequence::removeValue(void *container) const void QMetaSequence::removeValue(void *container) const
{ {
if (canRemoveValue()) { if (canRemoveValue()) {
d_ptr->removeValueFn(container, d()->removeValueFn(container,
QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified); QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
} }
} }
@ -432,7 +443,7 @@ void QMetaSequence::removeValue(void *container) const
\sa begin(), end(), destroyIterator(), compareIterator(), diffIterator(), \sa begin(), end(), destroyIterator(), compareIterator(), diffIterator(),
advanceIterator(), copyIterator() advanceIterator(), copyIterator()
*/ */
bool QMetaSequence::hasIterator() const bool QMetaContainer::hasIterator() const
{ {
if (!d_ptr || !d_ptr->createIteratorFn) if (!d_ptr || !d_ptr->createIteratorFn)
return false; return false;
@ -453,7 +464,7 @@ bool QMetaSequence::hasIterator() const
\sa end(), constBegin(), constEnd(), destroyIterator() \sa end(), constBegin(), constEnd(), destroyIterator()
*/ */
void *QMetaSequence::begin(void *container) const void *QMetaContainer::begin(void *container) const
{ {
return hasIterator() return hasIterator()
? d_ptr->createIteratorFn( ? d_ptr->createIteratorFn(
@ -470,7 +481,7 @@ void *QMetaSequence::begin(void *container) const
\sa hasIterator(), end(), constBegin(), constEnd(), destroyIterator() \sa hasIterator(), end(), constBegin(), constEnd(), destroyIterator()
*/ */
void *QMetaSequence::end(void *container) const void *QMetaContainer::end(void *container) const
{ {
return hasIterator() return hasIterator()
? d_ptr->createIteratorFn( ? d_ptr->createIteratorFn(
@ -484,7 +495,7 @@ void *QMetaSequence::end(void *container) const
\sa begin(), end(), destroyConstIterator() \sa begin(), end(), destroyConstIterator()
*/ */
void QMetaSequence::destroyIterator(const void *iterator) const void QMetaContainer::destroyIterator(const void *iterator) const
{ {
if (hasIterator()) if (hasIterator())
d_ptr->destroyIteratorFn(iterator); d_ptr->destroyIteratorFn(iterator);
@ -497,7 +508,7 @@ void QMetaSequence::destroyIterator(const void *iterator) const
\sa begin(), end() \sa begin(), end()
*/ */
bool QMetaSequence::compareIterator(const void *i, const void *j) const bool QMetaContainer::compareIterator(const void *i, const void *j) const
{ {
return hasIterator() ? d_ptr->compareIteratorFn(i, j) : false; return hasIterator() ? d_ptr->compareIteratorFn(i, j) : false;
} }
@ -508,7 +519,7 @@ bool QMetaSequence::compareIterator(const void *i, const void *j) const
\sa begin(), end() \sa begin(), end()
*/ */
void QMetaSequence::copyIterator(void *target, const void *source) const void QMetaContainer::copyIterator(void *target, const void *source) const
{ {
if (hasIterator()) if (hasIterator())
d_ptr->copyIteratorFn(target, source); d_ptr->copyIteratorFn(target, source);
@ -522,7 +533,7 @@ void QMetaSequence::copyIterator(void *target, const void *source) const
\sa begin(), end() \sa begin(), end()
*/ */
void QMetaSequence::advanceIterator(void *iterator, qsizetype step) const void QMetaContainer::advanceIterator(void *iterator, qsizetype step) const
{ {
if (hasIterator()) if (hasIterator())
d_ptr->advanceIteratorFn(iterator, step); d_ptr->advanceIteratorFn(iterator, step);
@ -536,7 +547,7 @@ void QMetaSequence::advanceIterator(void *iterator, qsizetype step) const
\sa begin(), end() \sa begin(), end()
*/ */
qsizetype QMetaSequence::diffIterator(const void *i, const void *j) const qsizetype QMetaContainer::diffIterator(const void *i, const void *j) const
{ {
return hasIterator() ? d_ptr->diffIteratorFn(i, j) : 0; return hasIterator() ? d_ptr->diffIteratorFn(i, j) : 0;
} }
@ -549,7 +560,9 @@ qsizetype QMetaSequence::diffIterator(const void *i, const void *j) const
*/ */
bool QMetaSequence::canGetValueAtIterator() const bool QMetaSequence::canGetValueAtIterator() const
{ {
return d_ptr && d_ptr->valueAtIteratorFn; if (auto iface = d())
return iface->valueAtIteratorFn;
return false;
} }
/*! /*!
@ -561,7 +574,7 @@ bool QMetaSequence::canGetValueAtIterator() const
void QMetaSequence::valueAtIterator(const void *iterator, void *result) const void QMetaSequence::valueAtIterator(const void *iterator, void *result) const
{ {
if (canGetValueAtIterator()) if (canGetValueAtIterator())
d_ptr->valueAtIteratorFn(iterator, result); d()->valueAtIteratorFn(iterator, result);
} }
/*! /*!
@ -572,7 +585,9 @@ void QMetaSequence::valueAtIterator(const void *iterator, void *result) const
*/ */
bool QMetaSequence::canSetValueAtIterator() const bool QMetaSequence::canSetValueAtIterator() const
{ {
return d_ptr && d_ptr->setValueAtIteratorFn; if (auto iface = d())
return iface->setValueAtIteratorFn;
return false;
} }
/*! /*!
@ -584,7 +599,7 @@ bool QMetaSequence::canSetValueAtIterator() const
void QMetaSequence::setValueAtIterator(const void *iterator, const void *value) const void QMetaSequence::setValueAtIterator(const void *iterator, const void *value) const
{ {
if (canSetValueAtIterator()) if (canSetValueAtIterator())
d_ptr->setValueAtIteratorFn(iterator, value); d()->setValueAtIteratorFn(iterator, value);
} }
/*! /*!
@ -595,7 +610,9 @@ void QMetaSequence::setValueAtIterator(const void *iterator, const void *value)
*/ */
bool QMetaSequence::canInsertValueAtIterator() const bool QMetaSequence::canInsertValueAtIterator() const
{ {
return d_ptr && d_ptr->insertValueAtIteratorFn; if (auto iface = d())
return iface->insertValueAtIteratorFn;
return false;
} }
/*! /*!
@ -614,7 +631,7 @@ void QMetaSequence::insertValueAtIterator(void *container, const void *iterator,
const void *value) const const void *value) const
{ {
if (canInsertValueAtIterator()) if (canInsertValueAtIterator())
d_ptr->insertValueAtIteratorFn(container, iterator, value); d()->insertValueAtIteratorFn(container, iterator, value);
} }
/*! /*!
@ -625,7 +642,9 @@ void QMetaSequence::insertValueAtIterator(void *container, const void *iterator,
*/ */
bool QMetaSequence::canEraseValueAtIterator() const bool QMetaSequence::canEraseValueAtIterator() const
{ {
return d_ptr && d_ptr->eraseValueAtIteratorFn; if (auto iface = d())
return iface->eraseValueAtIteratorFn;
return false;
} }
/*! /*!
@ -637,7 +656,7 @@ bool QMetaSequence::canEraseValueAtIterator() const
void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) const void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) const
{ {
if (canEraseValueAtIterator()) if (canEraseValueAtIterator())
d_ptr->eraseValueAtIteratorFn(container, iterator); d()->eraseValueAtIteratorFn(container, iterator);
} }
/*! /*!
@ -646,8 +665,8 @@ void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator)
*/ */
bool QMetaSequence::canEraseRangeAtIterator() const bool QMetaSequence::canEraseRangeAtIterator() const
{ {
if (d_ptr) if (auto iface = d())
return d_ptr->eraseRangeAtIteratorFn; return iface->eraseRangeAtIteratorFn;
return false; return false;
} }
@ -661,7 +680,7 @@ void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1,
const void *iterator2) const const void *iterator2) const
{ {
if (canEraseRangeAtIterator()) if (canEraseRangeAtIterator())
d_ptr->eraseRangeAtIteratorFn(container, iterator1, iterator2); d()->eraseRangeAtIteratorFn(container, iterator1, iterator2);
} }
/*! /*!
@ -672,7 +691,7 @@ void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1,
compareConstIterator(), diffConstIterator(), advanceConstIterator(), compareConstIterator(), diffConstIterator(), advanceConstIterator(),
copyConstIterator() copyConstIterator()
*/ */
bool QMetaSequence::hasConstIterator() const bool QMetaContainer::hasConstIterator() const
{ {
if (!d_ptr || !d_ptr->createConstIteratorFn) if (!d_ptr || !d_ptr->createConstIteratorFn)
return false; return false;
@ -693,7 +712,7 @@ bool QMetaSequence::hasConstIterator() const
\sa constEnd(), begin(), end(), destroyConstIterator() \sa constEnd(), begin(), end(), destroyConstIterator()
*/ */
void *QMetaSequence::constBegin(const void *container) const void *QMetaContainer::constBegin(const void *container) const
{ {
return hasConstIterator() return hasConstIterator()
? d_ptr->createConstIteratorFn( ? d_ptr->createConstIteratorFn(
@ -710,7 +729,7 @@ void *QMetaSequence::constBegin(const void *container) const
\sa constBegin(), begin(), end(), destroyConstIterator() \sa constBegin(), begin(), end(), destroyConstIterator()
*/ */
void *QMetaSequence::constEnd(const void *container) const void *QMetaContainer::constEnd(const void *container) const
{ {
return hasConstIterator() return hasConstIterator()
? d_ptr->createConstIteratorFn( ? d_ptr->createConstIteratorFn(
@ -724,7 +743,7 @@ void *QMetaSequence::constEnd(const void *container) const
\sa constBegin(), constEnd(), destroyIterator() \sa constBegin(), constEnd(), destroyIterator()
*/ */
void QMetaSequence::destroyConstIterator(const void *iterator) const void QMetaContainer::destroyConstIterator(const void *iterator) const
{ {
if (hasConstIterator()) if (hasConstIterator())
d_ptr->destroyConstIteratorFn(iterator); d_ptr->destroyConstIteratorFn(iterator);
@ -737,7 +756,7 @@ void QMetaSequence::destroyConstIterator(const void *iterator) const
\sa constBegin(), constEnd() \sa constBegin(), constEnd()
*/ */
bool QMetaSequence::compareConstIterator(const void *i, const void *j) const bool QMetaContainer::compareConstIterator(const void *i, const void *j) const
{ {
return hasConstIterator() ? d_ptr->compareConstIteratorFn(i, j) : false; return hasConstIterator() ? d_ptr->compareConstIteratorFn(i, j) : false;
} }
@ -748,7 +767,7 @@ bool QMetaSequence::compareConstIterator(const void *i, const void *j) const
\sa constBegin(), constEnd() \sa constBegin(), constEnd()
*/ */
void QMetaSequence::copyConstIterator(void *target, const void *source) const void QMetaContainer::copyConstIterator(void *target, const void *source) const
{ {
if (hasConstIterator()) if (hasConstIterator())
d_ptr->copyConstIteratorFn(target, source); d_ptr->copyConstIteratorFn(target, source);
@ -762,7 +781,7 @@ void QMetaSequence::copyConstIterator(void *target, const void *source) const
\sa constBegin(), constEnd() \sa constBegin(), constEnd()
*/ */
void QMetaSequence::advanceConstIterator(void *iterator, qsizetype step) const void QMetaContainer::advanceConstIterator(void *iterator, qsizetype step) const
{ {
if (hasConstIterator()) if (hasConstIterator())
d_ptr->advanceConstIteratorFn(iterator, step); d_ptr->advanceConstIteratorFn(iterator, step);
@ -776,7 +795,7 @@ void QMetaSequence::advanceConstIterator(void *iterator, qsizetype step) const
\sa constBegin(), constEnd() \sa constBegin(), constEnd()
*/ */
qsizetype QMetaSequence::diffConstIterator(const void *i, const void *j) const qsizetype QMetaContainer::diffConstIterator(const void *i, const void *j) const
{ {
return hasConstIterator() ? d_ptr->diffConstIteratorFn(i, j) : 0; return hasConstIterator() ? d_ptr->diffConstIteratorFn(i, j) : 0;
} }
@ -789,7 +808,9 @@ qsizetype QMetaSequence::diffConstIterator(const void *i, const void *j) const
*/ */
bool QMetaSequence::canGetValueAtConstIterator() const bool QMetaSequence::canGetValueAtConstIterator() const
{ {
return d_ptr && d_ptr->valueAtConstIteratorFn; if (auto iface = d())
return iface->valueAtConstIteratorFn;
return false;
} }
/*! /*!
@ -801,7 +822,7 @@ bool QMetaSequence::canGetValueAtConstIterator() const
void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) const void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) const
{ {
if (canGetValueAtConstIterator()) if (canGetValueAtConstIterator())
d_ptr->valueAtConstIteratorFn(iterator, result); d()->valueAtConstIteratorFn(iterator, result);
} }
/*! /*!
@ -822,4 +843,25 @@ void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) con
type than the QMetaSequence \a b, otherwise returns \c false. type than the QMetaSequence \a b, otherwise returns \c false.
*/ */
/*!
Returns the meta type for keys in the container.
*/
QMetaType QMetaAssociation::keyMetaType() const
{
if (auto iface = d())
return QMetaType(iface->keyMetaType);
return QMetaType();
}
/*!
Returns the meta type for mapped values in the container.
*/
QMetaType QMetaAssociation::mappedMetaType() const
{
if (auto iface = d())
return QMetaType(iface->mappedMetaType);
return QMetaType();
}
QT_END_NAMESPACE QT_END_NAMESPACE

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,7 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <forward_list> #include <forward_list>
#include <unordered_map>
namespace CheckContainerTraits namespace CheckContainerTraits
{ {
@ -57,12 +58,12 @@ static_assert(QContainerTraits::has_clear_v<std::vector<int>>);
static_assert(QContainerTraits::has_clear_v<std::set<int>>); static_assert(QContainerTraits::has_clear_v<std::set<int>>);
static_assert(QContainerTraits::has_clear_v<std::forward_list<int>>); static_assert(QContainerTraits::has_clear_v<std::forward_list<int>>);
static_assert(QContainerTraits::has_at_v<QVector<int>>); static_assert(QContainerTraits::has_at_index_v<QVector<int>>);
static_assert(!QContainerTraits::has_at_v<QSet<int>>); static_assert(!QContainerTraits::has_at_index_v<QSet<int>>);
static_assert(!QContainerTraits::has_at_v<NotAContainer>); static_assert(!QContainerTraits::has_at_index_v<NotAContainer>);
static_assert(QContainerTraits::has_at_v<std::vector<int>>); static_assert(QContainerTraits::has_at_index_v<std::vector<int>>);
static_assert(!QContainerTraits::has_at_v<std::set<int>>); static_assert(!QContainerTraits::has_at_index_v<std::set<int>>);
static_assert(!QContainerTraits::has_at_v<std::forward_list<int>>); static_assert(!QContainerTraits::has_at_index_v<std::forward_list<int>>);
static_assert(QContainerTraits::can_get_at_index_v<QVector<int>>); static_assert(QContainerTraits::can_get_at_index_v<QVector<int>>);
static_assert(!QContainerTraits::can_get_at_index_v<QSet<int>>); static_assert(!QContainerTraits::can_get_at_index_v<QSet<int>>);
@ -127,30 +128,30 @@ static_assert(QContainerTraits::has_const_iterator_v<std::vector<int>>);
static_assert(QContainerTraits::has_const_iterator_v<std::set<int>>); static_assert(QContainerTraits::has_const_iterator_v<std::set<int>>);
static_assert(QContainerTraits::has_const_iterator_v<std::forward_list<int>>); static_assert(QContainerTraits::has_const_iterator_v<std::forward_list<int>>);
static_assert(QContainerTraits::can_get_at_iterator_v<QVector<int>>); static_assert(QContainerTraits::iterator_dereferences_to_value_v<QVector<int>>);
static_assert(QContainerTraits::can_get_at_iterator_v<QSet<int>>); static_assert(QContainerTraits::iterator_dereferences_to_value_v<QSet<int>>);
static_assert(!QContainerTraits::can_get_at_iterator_v<NotAContainer>); static_assert(!QContainerTraits::iterator_dereferences_to_value_v<NotAContainer>);
static_assert(QContainerTraits::can_get_at_iterator_v<std::vector<int>>); static_assert(QContainerTraits::iterator_dereferences_to_value_v<std::vector<int>>);
static_assert(QContainerTraits::can_get_at_iterator_v<std::set<int>>); static_assert(QContainerTraits::iterator_dereferences_to_value_v<std::set<int>>);
static_assert(QContainerTraits::can_get_at_iterator_v<std::forward_list<int>>); static_assert(QContainerTraits::iterator_dereferences_to_value_v<std::forward_list<int>>);
static_assert(QContainerTraits::can_set_at_iterator_v<QVector<int>>); static_assert(QContainerTraits::can_set_value_at_iterator_v<QVector<int>>);
static_assert(!QContainerTraits::can_set_at_iterator_v<QSet<int>>); static_assert(!QContainerTraits::can_set_value_at_iterator_v<QSet<int>>);
static_assert(!QContainerTraits::can_get_at_iterator_v<NotAContainer>); static_assert(!QContainerTraits::can_set_value_at_iterator_v<NotAContainer>);
static_assert(QContainerTraits::can_set_at_iterator_v<std::vector<int>>); static_assert(QContainerTraits::can_set_value_at_iterator_v<std::vector<int>>);
static_assert(!QContainerTraits::can_set_at_iterator_v<std::set<int>>); static_assert(!QContainerTraits::can_set_value_at_iterator_v<std::set<int>>);
static_assert(QContainerTraits::can_set_at_iterator_v<std::forward_list<int>>); static_assert(QContainerTraits::can_set_value_at_iterator_v<std::forward_list<int>>);
static_assert(QContainerTraits::can_insert_at_iterator_v<QVector<int>>); static_assert(QContainerTraits::can_insert_value_at_iterator_v<QVector<int>>);
static_assert(!QContainerTraits::can_insert_at_iterator_v<QSet<int>>); static_assert(!QContainerTraits::can_insert_value_at_iterator_v<QSet<int>>);
static_assert(!QContainerTraits::can_insert_at_iterator_v<NotAContainer>); static_assert(!QContainerTraits::can_insert_value_at_iterator_v<NotAContainer>);
static_assert(QContainerTraits::can_insert_at_iterator_v<std::vector<int>>); static_assert(QContainerTraits::can_insert_value_at_iterator_v<std::vector<int>>);
static_assert(!QContainerTraits::can_insert_at_iterator_v<std::forward_list<int>>); static_assert(!QContainerTraits::can_insert_value_at_iterator_v<std::forward_list<int>>);
// The iterator is only a hint, but syntactically indistinguishable from others. // The iterator is only a hint, but syntactically indistinguishable from others.
// It's explicitly there to be signature compatible with std::vector::insert, though. // It's explicitly there to be signature compatible with std::vector::insert, though.
// Also, inserting into a set is not guaranteed to actually do anything. // Also, inserting into a set is not guaranteed to actually do anything.
static_assert(QContainerTraits::can_insert_at_iterator_v<std::set<int>>); static_assert(QContainerTraits::can_insert_value_at_iterator_v<std::set<int>>);
static_assert(QContainerTraits::can_erase_at_iterator_v<QVector<int>>); static_assert(QContainerTraits::can_erase_at_iterator_v<QVector<int>>);
static_assert(QContainerTraits::can_erase_at_iterator_v<QSet<int>>); static_assert(QContainerTraits::can_erase_at_iterator_v<QSet<int>>);
@ -172,10 +173,19 @@ private:
std::set<int> stdset; std::set<int> stdset;
std::forward_list<QMetaSequence> forwardList; std::forward_list<QMetaSequence> forwardList;
QHash<int, QMetaType> qhash;
QMap<QByteArray, bool> qmap;
std::map<QString, int> stdmap;
std::unordered_map<int, QMetaAssociation> stdunorderedmap;
private slots: private slots:
void init(); void init();
void testSequence_data(); void testSequence_data();
void testSequence(); void testSequence();
void testAssociation_data();
void testAssociation();
void cleanup(); void cleanup();
}; };
@ -192,6 +202,28 @@ void tst_QMetaContainer::init()
QMetaSequence::fromContainer<std::set<int>>(), QMetaSequence::fromContainer<std::set<int>>(),
QMetaSequence::fromContainer<std::forward_list<QMetaSequence>>() QMetaSequence::fromContainer<std::forward_list<QMetaSequence>>()
}; };
qhash = {
{ 233, QMetaType() },
{ 11, QMetaType::fromType<QByteArray>() },
{ 6626, QMetaType::fromType<bool>() }
};
qmap = {
{ "eins", true },
{ "zwei", false },
{ "elfundvierzig", true }
};
stdmap = {
{ QStringLiteral("dkdkdkd"), 58583 },
{ QStringLiteral("ooo30393"), 12 },
{ QStringLiteral("2dddd30393"), 999999 },
};
stdunorderedmap = {
{ 11, QMetaAssociation::fromContainer<QHash<int, QMetaType>>() },
{ 12, QMetaAssociation::fromContainer<QMap<QByteArray, bool>>() },
{ 393, QMetaAssociation::fromContainer<std::map<QString, int>>() },
{ 293, QMetaAssociation::fromContainer<std::unordered_map<int, QMetaAssociation>>() }
};
} }
void tst_QMetaContainer::cleanup() void tst_QMetaContainer::cleanup()
@ -201,6 +233,10 @@ void tst_QMetaContainer::cleanup()
qset.clear(); qset.clear();
stdset.clear(); stdset.clear();
forwardList.clear(); forwardList.clear();
qhash.clear();
qmap.clear();
stdmap.clear();
stdunorderedmap.clear();
} }
void tst_QMetaContainer::testSequence_data() void tst_QMetaContainer::testSequence_data()
@ -486,5 +522,230 @@ void tst_QMetaContainer::testSequence()
metaSequence.destroyConstIterator(constEnd); metaSequence.destroyConstIterator(constEnd);
} }
void tst_QMetaContainer::testAssociation_data()
{
QTest::addColumn<void *>("container");
QTest::addColumn<QMetaAssociation>("metaAssociation");
QTest::addColumn<QMetaType>("keyType");
QTest::addColumn<QMetaType>("mappedType");
QTest::addColumn<bool>("hasSize");
QTest::addColumn<bool>("canRemove");
QTest::addColumn<bool>("canSetMapped");
QTest::addColumn<bool>("hasBidirectionalIterator");
QTest::addColumn<bool>("hasRandomAccessIterator");
QTest::addRow("QHash")
<< static_cast<void *>(&qhash)
<< QMetaAssociation::fromContainer<QHash<int, QMetaType>>()
<< QMetaType::fromType<int>()
<< QMetaType::fromType<QMetaType>()
<< true << true << true << false << false;
QTest::addRow("QMap")
<< static_cast<void *>(&qmap)
<< QMetaAssociation::fromContainer<QMap<QByteArray, bool>>()
<< QMetaType::fromType<QByteArray>()
<< QMetaType::fromType<bool>()
<< true << true << true << true << false;
QTest::addRow("std::map")
<< static_cast<void *>(&stdmap)
<< QMetaAssociation::fromContainer<std::map<QString, int>>()
<< QMetaType::fromType<QString>()
<< QMetaType::fromType<int>()
<< true << true << true << true << false;
QTest::addRow("std::unorderedmap")
<< static_cast<void *>(&stdunorderedmap)
<< QMetaAssociation::fromContainer<std::unordered_map<int, QMetaAssociation>>()
<< QMetaType::fromType<int>()
<< QMetaType::fromType<QMetaAssociation>()
<< true << true << true << false << false;
QTest::addRow("QSet")
<< static_cast<void *>(&qset)
<< QMetaAssociation::fromContainer<QSet<QByteArray>>()
<< QMetaType::fromType<QByteArray>()
<< QMetaType()
<< true << true << false << false << false;
QTest::addRow("std::set")
<< static_cast<void *>(&stdset)
<< QMetaAssociation::fromContainer<std::set<int>>()
<< QMetaType::fromType<int>()
<< QMetaType()
<< true << true << false << true << false;
}
void tst_QMetaContainer::testAssociation()
{
QFETCH(void *, container);
QFETCH(QMetaAssociation, metaAssociation);
QFETCH(QMetaType, keyType);
QFETCH(QMetaType, mappedType);
QFETCH(bool, hasSize);
QFETCH(bool, canRemove);
QFETCH(bool, canSetMapped);
QFETCH(bool, hasBidirectionalIterator);
QFETCH(bool, hasRandomAccessIterator);
QCOMPARE(metaAssociation.hasSize(), hasSize);
QCOMPARE(metaAssociation.canRemoveKey(), canRemove);
QCOMPARE(metaAssociation.canSetMappedAtKey(), canSetMapped);
QCOMPARE(metaAssociation.canSetMappedAtIterator(), canSetMapped);
// Apparently implementations can choose to provide "better" iterators than required by the std.
if (hasBidirectionalIterator)
QCOMPARE(metaAssociation.hasBidirectionalIterator(), hasBidirectionalIterator);
if (hasRandomAccessIterator)
QCOMPARE(metaAssociation.hasRandomAccessIterator(), hasRandomAccessIterator);
QVariant key1(keyType);
QVariant key2(keyType);
QVariant key3(keyType);
QVariant mapped1(mappedType);
QVariant mapped2(mappedType);
QVariant mapped3(mappedType);
if (hasSize) {
const qsizetype size = metaAssociation.size(container);
QVERIFY(metaAssociation.canInsertKey());
// var1 is invalid, and our containers do not contain an invalid key so far.
metaAssociation.insertKey(container, key1.constData());
QCOMPARE(metaAssociation.size(container), size + 1);
metaAssociation.removeKey(container, key1.constData());
QCOMPARE(metaAssociation.size(container), size);
} else {
metaAssociation.insertKey(container, key1.constData());
metaAssociation.removeKey(container, key1.constData());
}
QVERIFY(metaAssociation.hasIterator());
QVERIFY(metaAssociation.hasConstIterator());
QVERIFY(metaAssociation.canGetKeyAtIterator());
QVERIFY(metaAssociation.canGetKeyAtConstIterator());
void *it = metaAssociation.begin(container);
void *end = metaAssociation.end(container);
QVERIFY(it);
QVERIFY(end);
void *constIt = metaAssociation.constBegin(container);
void *constEnd = metaAssociation.constEnd(container);
QVERIFY(constIt);
QVERIFY(constEnd);
const qsizetype size = metaAssociation.diffIterator(end, it);
QCOMPARE(size, metaAssociation.diffConstIterator(constEnd, constIt));
if (hasSize)
QCOMPARE(size, metaAssociation.size(container));
qsizetype count = 0;
for (; !metaAssociation.compareIterator(it, end);
metaAssociation.advanceIterator(it, 1), metaAssociation.advanceConstIterator(constIt, 1)) {
metaAssociation.keyAtIterator(it, key1.data());
metaAssociation.keyAtConstIterator(constIt, key3.data());
QCOMPARE(key3, key1);
++count;
}
QCOMPARE(count, size);
QVERIFY(metaAssociation.compareConstIterator(constIt, constEnd));
metaAssociation.destroyIterator(it);
metaAssociation.destroyIterator(end);
metaAssociation.destroyConstIterator(constIt);
metaAssociation.destroyConstIterator(constEnd);
if (metaAssociation.canSetMappedAtIterator()) {
void *it = metaAssociation.begin(container);
void *end = metaAssociation.end(container);
QVERIFY(it);
QVERIFY(end);
for (; !metaAssociation.compareIterator(it, end); metaAssociation.advanceIterator(it, 1)) {
metaAssociation.mappedAtIterator(it, mapped1.data());
metaAssociation.setMappedAtIterator(it, mapped2.constData());
metaAssociation.mappedAtIterator(it, mapped3.data());
QCOMPARE(mapped2, mapped3);
mapped2 = mapped1;
}
metaAssociation.destroyIterator(it);
metaAssociation.destroyIterator(end);
it = metaAssociation.constBegin(container);
end = metaAssociation.constEnd(container);
QVERIFY(it);
QVERIFY(end);
for (; !metaAssociation.compareConstIterator(it, end); metaAssociation.advanceConstIterator(it, 1)) {
metaAssociation.mappedAtConstIterator(it, mapped1.data());
metaAssociation.keyAtConstIterator(it, key1.data());
metaAssociation.setMappedAtKey(container, key1.constData(), mapped2.constData());
metaAssociation.mappedAtConstIterator(it, mapped3.data());
QCOMPARE(mapped2, mapped3);
mapped2 = mapped1;
}
metaAssociation.destroyConstIterator(it);
metaAssociation.destroyConstIterator(end);
}
if (metaAssociation.hasBidirectionalIterator()) {
void *it = metaAssociation.end(container);
void *end = metaAssociation.begin(container);
QVERIFY(it);
QVERIFY(end);
void *constIt = metaAssociation.constEnd(container);
void *constEnd = metaAssociation.constBegin(container);
QVERIFY(constIt);
QVERIFY(constEnd);
qsizetype size = 0;
if (metaAssociation.hasRandomAccessIterator()) {
size = metaAssociation.diffIterator(end, it);
QCOMPARE(size, metaAssociation.diffConstIterator(constEnd, constIt));
} else {
size = -metaAssociation.diffIterator(it, end);
}
if (hasSize)
QCOMPARE(size, -metaAssociation.size(container));
qsizetype count = 0;
do {
metaAssociation.advanceIterator(it, -1);
metaAssociation.advanceConstIterator(constIt, -1);
--count;
metaAssociation.keyAtIterator(it, key1.data());
metaAssociation.keyAtConstIterator(constIt, key3.data());
QCOMPARE(key3, key1);
} while (!metaAssociation.compareIterator(it, end));
QCOMPARE(count, size);
QVERIFY(metaAssociation.compareConstIterator(constIt, constEnd));
metaAssociation.destroyIterator(it);
metaAssociation.destroyIterator(end);
metaAssociation.destroyConstIterator(constIt);
metaAssociation.destroyConstIterator(constEnd);
}
QVERIFY(metaAssociation.canClear());
constIt = metaAssociation.constBegin(container);
constEnd = metaAssociation.constEnd(container);
QVERIFY(!metaAssociation.compareConstIterator(constIt, constEnd));
metaAssociation.destroyConstIterator(constIt);
metaAssociation.destroyConstIterator(constEnd);
metaAssociation.clear(container);
constIt = metaAssociation.constBegin(container);
constEnd = metaAssociation.constEnd(container);
QVERIFY(metaAssociation.compareConstIterator(constIt, constEnd));
metaAssociation.destroyConstIterator(constIt);
metaAssociation.destroyConstIterator(constEnd);
}
QTEST_MAIN(tst_QMetaContainer) QTEST_MAIN(tst_QMetaContainer)
#include "tst_qmetacontainer.moc" #include "tst_qmetacontainer.moc"

View File

@ -4558,7 +4558,7 @@ void tst_QVariant::shouldDeleteVariantDataWorksForSequential()
MyType mytype {2, "zwei"}; MyType mytype {2, "zwei"};
*static_cast<MyType *>(dataPtr) = mytype; *static_cast<MyType *>(dataPtr) = mytype;
}; };
metaSequence.valueMetaType = QMetaType::fromType<MyType>(); metaSequence.valueMetaType = QtPrivate::qMetaTypeInterfaceForType<MyType>();
QSequentialIterable iterable(QMetaSequence(&metaSequence), nullptr); QSequentialIterable iterable(QMetaSequence(&metaSequence), nullptr);
QVariant value1 = iterable.at(0); QVariant value1 = iterable.at(0);