From 73fe229eb434236402ec1685b1f17f96417001b9 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 7 Sep 2020 09:57:30 +0200 Subject: [PATCH] QMetaContainer: Add an "input" iterator capability For completeness' sake we should expose this. The iterators provided by QIterable and friends will check the category at runtime, and should give sensible feedback. Change-Id: I778894f340c862f79a18c6c5607bcbba98dd7598 Reviewed-by: Lars Knoll --- src/corelib/kernel/qmetacontainer.cpp | 17 +++++++++++++++++ src/corelib/kernel/qmetacontainer.h | 10 +++++++--- .../corelib/kernel/qvariant/tst_qvariant.cpp | 6 ++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qmetacontainer.cpp b/src/corelib/kernel/qmetacontainer.cpp index 553deffe33..77ac152508 100644 --- a/src/corelib/kernel/qmetacontainer.cpp +++ b/src/corelib/kernel/qmetacontainer.cpp @@ -70,6 +70,23 @@ QT_BEGIN_NAMESPACE Returns the QMetaSequence corresponding to the type given as template parameter. */ +/*! + Returns \c true if the underlying container provides at least an input + iterator as defined by std::input_iterator_tag, otherwise returns + \c false. Forward, Bi-directional, and random access iterators are + specializations of input iterators. This method will also return + \c true if the container provides one of those. + + QMetaSequence assumes that const and non-const iterators for the same + container have the same iterator traits. + */ +bool QMetaSequence::hasInputIterator() const +{ + if (!d_ptr) + return false; + return d_ptr->iteratorCapabilities & QtMetaContainerPrivate::InputCapability; +} + /*! Returns \c true if the underlying container provides at least a forward iterator as defined by std::forward_iterator_tag, otherwise returns diff --git a/src/corelib/kernel/qmetacontainer.h b/src/corelib/kernel/qmetacontainer.h index 34e99f920d..1e2157951e 100644 --- a/src/corelib/kernel/qmetacontainer.h +++ b/src/corelib/kernel/qmetacontainer.h @@ -50,9 +50,10 @@ QT_BEGIN_NAMESPACE namespace QtMetaContainerPrivate { enum IteratorCapability : quint8 { - ForwardCapability = 1 << 0, - BiDirectionalCapability = 1 << 1, - RandomAccessCapability = 1 << 2, + InputCapability = 1 << 0, + ForwardCapability = 1 << 1, + BiDirectionalCapability = 1 << 2, + RandomAccessCapability = 1 << 3, }; Q_DECLARE_FLAGS(IteratorCapabilities, IteratorCapability) @@ -122,6 +123,8 @@ class QMetaSequenceForContainer { using Tag = typename std::iterator_traits::iterator_category; IteratorCapabilities caps {}; + if constexpr (std::is_base_of_v) + caps |= InputCapability; if constexpr (std::is_base_of_v) caps |= ForwardCapability; if constexpr (std::is_base_of_v) @@ -515,6 +518,7 @@ public: return QMetaSequence(QtMetaContainerPrivate::qMetaSequenceInterfaceForContainer()); } + bool hasInputIterator() const; bool hasForwardIterator() const; bool hasBidirectionalIterator() const; bool hasRandomAccessIterator() const; diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index a444a100be..d606f449cf 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -4531,7 +4531,8 @@ void tst_QVariant::shouldDeleteVariantDataWorksForSequential() QtMetaContainerPrivate::QMetaSequenceInterface metaSequence {}; metaSequence.iteratorCapabilities = QtMetaContainerPrivate::RandomAccessCapability | QtMetaContainerPrivate::BiDirectionalCapability - | QtMetaContainerPrivate::ForwardCapability; + | QtMetaContainerPrivate::ForwardCapability + | QtMetaContainerPrivate::InputCapability; metaSequence.sizeFn = [](const void *) { return qsizetype(1); }; metaSequence.createConstIteratorFn = @@ -4680,7 +4681,8 @@ void tst_QVariant::sequentialIterableEndianessSanityCheck() { namespace QMTP = QtMetaContainerPrivate; QMTP::IteratorCapabilities oldIteratorCaps - = QMTP::ForwardCapability | QMTP::BiDirectionalCapability | QMTP::RandomAccessCapability; + = QMTP::InputCapability | QMTP::ForwardCapability + | QMTP::BiDirectionalCapability | QMTP::RandomAccessCapability; QMTP::QMetaSequenceInterface seqImpl {}; QCOMPARE(seqImpl.revision, 0u); memcpy(&seqImpl.iteratorCapabilities, &oldIteratorCaps, sizeof(oldIteratorCaps));