From 5c808073af5b8f1290602fcccf60666c9a3682f8 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 10 Sep 2020 18:25:02 +0200 Subject: Extend QSequentialIterable and add QAssociativeIterable And add mutable iterators. This requires some refactoring of the existing iterators. Task-number: QTBUG-81716 Change-Id: I61b3a3e8c0df5fd449679257a29d9f0c3d19c4f0 Reviewed-by: Lars Knoll --- src/corelib/kernel/qmetatype.h | 318 ++++++----------------------------------- 1 file changed, 46 insertions(+), 272 deletions(-) (limited to 'src/corelib/kernel/qmetatype.h') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 6d31441b73..f28bfead5c 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -48,6 +48,7 @@ #include #include #include +#include #ifndef QT_NO_QOBJECT #include #endif @@ -600,268 +601,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags) Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \ namespace QtMetaTypePrivate { -namespace QtMetaTypePrivate { - -template -struct IteratorOwnerCommon -{ - static void assign(void **ptr, const_iterator iterator) - { - *ptr = new const_iterator(iterator); - } - static void assign(void **ptr, void * const * src) - { - *ptr = new const_iterator(*static_cast(*src)); - } - - static void advance(void **iterator, int step) - { - const_iterator &it = *static_cast(*iterator); - std::advance(it, step); - } - - static void destroy(void **ptr) - { - delete static_cast(*ptr); - } - - static bool equal(void * const *it, void * const *other) - { - return *static_cast(*it) == *static_cast(*other); - } -}; - -template -struct IteratorOwner : IteratorOwnerCommon -{ - static void getData(void * const *iterator, void *dataPtr) - { - const_iterator *it = static_cast(*iterator); - typename const_iterator::value_type *data = static_cast(dataPtr); - *data = **it; - } - - static void getData(const_iterator it, void *dataPtr) - { - typename const_iterator::value_type *data = static_cast(dataPtr); - *data = *it; - } -}; - -template -struct IteratorOwner -{ -private: - // We need to disable typed overloads of assign() and getData() if the value_type - // is void* to avoid overloads conflicts. We do it by injecting unaccessible Dummy - // type as part of the overload signature. - struct Dummy {}; - typedef typename std::conditional::value, Dummy, value_type>::type value_type_OR_Dummy; -public: - static void assign(void **ptr, const value_type_OR_Dummy *iterator ) - { - *ptr = const_cast(iterator); - } - static void assign(void **ptr, void * const * src) - { - *ptr = static_cast(*src); - } - - static void advance(void **iterator, int step) - { - value_type *it = static_cast(*iterator); - std::advance(it, step); - *iterator = it; - } - - static void destroy(void **) - { - } - - static void getData(void * const *iterator, void *dataPtr) - { - *static_cast(dataPtr) = *static_cast(*iterator); - } - - static void getData(const value_type_OR_Dummy *it, void *dataPtr) - { - *static_cast(dataPtr) = *static_cast(it); - } - - static bool equal(void * const *it, void * const *other) - { - return static_cast(*it) == static_cast(*other); - } -}; - -} namespace QtMetaTypePrivate { -template::value> -struct AssociativeContainerAccessor -{ - static const typename T::key_type& getKey(const typename T::const_iterator &it) - { - return it.key(); - } - - static const typename T::mapped_type& getValue(const typename T::const_iterator &it) - { - return it.value(); - } -}; - -template >::value> -struct StlStyleAssociativeContainerAccessor; - -template -struct StlStyleAssociativeContainerAccessor -{ - static const typename T::key_type& getKey(const typename T::const_iterator &it) - { - return it->first; - } - - static const typename T::mapped_type& getValue(const typename T::const_iterator &it) - { - return it->second; - } -}; - -template -struct AssociativeContainerAccessor : public StlStyleAssociativeContainerAccessor -{ -}; - -class QAssociativeIterableImpl -{ -public: - const void *_iterable; - void *_iterator; - QMetaType _metaType_key; - QMetaType _metaType_value; - typedef int(*sizeFunc)(const void *p); - typedef void (*findFunc)(const void *container, const void *p, void **iterator); - typedef void (*beginFunc)(const void *p, void **); - typedef void (*advanceFunc)(void **p, int); - typedef void (*getFunc)(void * const *p, void *dataPtr); - typedef void (*destroyIterFunc)(void **p); - typedef bool (*equalIterFunc)(void * const *p, void * const *other); - typedef void (*copyIterFunc)(void **, void * const *); - - sizeFunc _size; - findFunc _find; - beginFunc _begin; - beginFunc _end; - advanceFunc _advance; - getFunc _getKey; - getFunc _getValue; - destroyIterFunc _destroyIter; - equalIterFunc _equalIter; - copyIterFunc _copyIter; - - template - static int sizeImpl(const void *p) - { return int(std::distance(static_cast(p)->begin(), - static_cast(p)->end())); } - - template - static void findImpl(const void *container, const void *p, void **iterator) - { IteratorOwner::assign(iterator, - static_cast(container)->find(*static_cast(p))); } - - template - static void advanceImpl(void **p, int step) - { std::advance(*static_cast(*p), step); } - - template - static void beginImpl(const void *container, void **iterator) - { IteratorOwner::assign(iterator, static_cast(container)->begin()); } - - template - static void endImpl(const void *container, void **iterator) - { IteratorOwner::assign(iterator, static_cast(container)->end()); } - - template - static void getKeyImpl(void * const *iterator, void *dataPtr) - { - auto *data = static_cast(dataPtr); - *data = AssociativeContainerAccessor::getKey(*static_cast(*iterator)); - } - - template - static void getValueImpl(void * const *iterator, void *dataPtr) - { - auto *data = static_cast(dataPtr); - *data = AssociativeContainerAccessor::getValue(*static_cast(*iterator)); - } - -public: - template QAssociativeIterableImpl(const T*p) - : _iterable(p) - , _iterator(nullptr) - , _metaType_key(QMetaType::fromType()) - , _metaType_value(QMetaType::fromType()) - , _size(sizeImpl) - , _find(findImpl) - , _begin(beginImpl) - , _end(endImpl) - , _advance(advanceImpl) - , _getKey(getKeyImpl) - , _getValue(getValueImpl) - , _destroyIter(IteratorOwner::destroy) - , _equalIter(IteratorOwner::equal) - , _copyIter(IteratorOwner::assign) - { - } - - QAssociativeIterableImpl() - : _iterable(nullptr) - , _iterator(nullptr) - , _size(nullptr) - , _find(nullptr) - , _begin(nullptr) - , _end(nullptr) - , _advance(nullptr) - , _getKey(nullptr) - , _getValue(nullptr) - , _destroyIter(nullptr) - , _equalIter(nullptr) - , _copyIter(nullptr) - { - } - - inline void begin() { _begin(_iterable, &_iterator); } - inline void end() { _end(_iterable, &_iterator); } - inline bool equal(const QAssociativeIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); } - inline QAssociativeIterableImpl &advance(int i) { _advance(&_iterator, i); return *this; } - - inline void destroyIter() { _destroyIter(&_iterator); } - - inline void getCurrentKey(void *dataPtr) const { return _getKey(&_iterator, dataPtr); } - inline void getCurrentValue(void *dataPtr) const { return _getValue(&_iterator, dataPtr); } - - inline void find(const void *key) - { _find(_iterable, key, &_iterator); } - - int size() const { Q_ASSERT(_iterable); return _size(_iterable); } - - void copy(const QAssociativeIterableImpl &other) - { - *this = other; - _copyIter(&_iterator, &other._iterator); - } -}; -QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QAssociativeIterableImpl, Q_MOVABLE_TYPE) - -template -struct QAssociativeIterableConvertFunctor -{ - QAssociativeIterableImpl operator()(const From& f) const - { - return QAssociativeIterableImpl(&f); - } -}; class QPairVariantInterfaceImpl { @@ -1675,7 +1416,6 @@ QT_END_NAMESPACE QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE) -Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl) Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl) QT_BEGIN_NAMESPACE @@ -1692,19 +1432,53 @@ inline bool QtPrivate::IsMetaTypePair::registerConverter(int id) } namespace QtPrivate { - template - struct AssociativeValueTypeIsMetaType + +template +struct QSequentialIterableConvertFunctor +{ + QIterable operator()(const From &f) const { - static bool registerConverter(int id) - { - const int toId = qMetaTypeId(); - if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { - QtMetaTypePrivate::QAssociativeIterableConvertFunctor o; - return QMetaType::registerConverter(o); - } - return true; + return QIterable(QMetaSequence::fromContainer(), &f); + } +}; + +template +struct SequentialValueTypeIsMetaType +{ + static bool registerConverter(int id) + { + const int toId = qMetaTypeId>(); + if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { + QSequentialIterableConvertFunctor o; + return QMetaType::registerConverter>(o); } - }; + return true; + } +}; + +template +struct QAssociativeIterableConvertFunctor +{ + QIterable operator()(const From &f) const + { + return QIterable(QMetaAssociation::fromContainer(), &f); + } +}; + +template +struct AssociativeValueTypeIsMetaType +{ + static bool registerConverter(int id) + { + const int toId = qMetaTypeId>(); + if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { + QAssociativeIterableConvertFunctor o; + return QMetaType::registerConverter>(o); + } + return true; + } +}; + } namespace QtPrivate { -- cgit v1.2.3