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 <lars.knoll@qt.io>
bb10
Ulf Hermann 2020-09-07 09:57:30 +02:00
parent 89c65bc8f7
commit 73fe229eb4
3 changed files with 28 additions and 5 deletions

View File

@ -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

View File

@ -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>::iterator_category;
IteratorCapabilities caps {};
if constexpr (std::is_base_of_v<std::input_iterator_tag, Tag>)
caps |= InputCapability;
if constexpr (std::is_base_of_v<std::forward_iterator_tag, Tag>)
caps |= ForwardCapability;
if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, Tag>)
@ -515,6 +518,7 @@ public:
return QMetaSequence(QtMetaContainerPrivate::qMetaSequenceInterfaceForContainer<T>());
}
bool hasInputIterator() const;
bool hasForwardIterator() const;
bool hasBidirectionalIterator() const;
bool hasRandomAccessIterator() const;

View File

@ -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));