summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetacontainer.h
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-09-03 13:41:39 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-09-12 09:12:26 +0200
commitef93fdeb098f78a0afe1df72c53ba26bf7a11c60 (patch)
tree4862c44b7013f5965ba6c888d1059d24dfb5d87a /src/corelib/kernel/qmetacontainer.h
parent73fe229eb434236402ec1685b1f17f96417001b9 (diff)
Provide methods for adding values to a sequential iterable
Provide functionality to add and remove values, so that you can use a sequential iterable as stack or queue if the underlying container supports this. To this end, provide a way to specify whether the value should be added or removed at the beginning or the end of the iterable. Change-Id: If63d302f3ca085e56d601116ce4dfaa6b94a0c4f Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/corelib/kernel/qmetacontainer.h')
-rw-r--r--src/corelib/kernel/qmetacontainer.h138
1 files changed, 110 insertions, 28 deletions
diff --git a/src/corelib/kernel/qmetacontainer.h b/src/corelib/kernel/qmetacontainer.h
index 1e2157951e..8c0d723f64 100644
--- a/src/corelib/kernel/qmetacontainer.h
+++ b/src/corelib/kernel/qmetacontainer.h
@@ -59,15 +59,24 @@ enum IteratorCapability : quint8 {
Q_DECLARE_FLAGS(IteratorCapabilities, IteratorCapability)
Q_DECLARE_OPERATORS_FOR_FLAGS(IteratorCapabilities)
+enum AddRemoveCapability : quint8 {
+ CanAddAtBegin = 1 << 0,
+ CanRemoveAtBegin = 1 << 1,
+ CanAddAtEnd = 1 << 2,
+ CanRemoveAtEnd = 1 << 3
+};
+Q_DECLARE_FLAGS(AddRemoveCapabilities, AddRemoveCapability)
+Q_DECLARE_OPERATORS_FOR_FLAGS(AddRemoveCapabilities)
+
class QMetaSequenceInterface
{
public:
- enum Position : quint8 { AtBegin, AtEnd, Random };
+ enum Position : quint8 { AtBegin, AtEnd, Unspecified };
ushort revision;
IteratorCapabilities iteratorCapabilities;
- Position addRemovePosition;
QMetaType valueMetaType;
+ AddRemoveCapabilities addRemoveCapabilities;
using SizeFn = qsizetype(*)(const void *);
SizeFn sizeFn;
@@ -79,9 +88,9 @@ public:
using SetValueAtIndexFn = void(*)(void *, qsizetype, const void *);
SetValueAtIndexFn setValueAtIndexFn;
- using AddValueFn = void(*)(void *, const void *);
+ using AddValueFn = void(*)(void *, const void *, Position);
AddValueFn addValueFn;
- using RemoveValueFn = void(*)(void *);
+ using RemoveValueFn = void(*)(void *, Position);
RemoveValueFn removeValueFn;
using CreateIteratorFn = void *(*)(void *, Position);
@@ -144,13 +153,18 @@ class QMetaSequenceForContainer
return {};
}
- static constexpr QMetaSequenceInterface::Position getAddRemovePosition()
+ static constexpr AddRemoveCapabilities getAddRemoveCapabilities()
{
- if constexpr (QContainerTraits::has_push_back_v<C> && QContainerTraits::has_pop_back_v<C>)
- return QMetaSequenceInterface::AtEnd;
- if constexpr (QContainerTraits::has_push_front_v<C> && QContainerTraits::has_pop_front_v<C>)
- return QMetaSequenceInterface::AtBegin;
- return QMetaSequenceInterface::Random;
+ AddRemoveCapabilities caps;
+ if constexpr (QContainerTraits::has_push_back_v<C>)
+ caps |= CanAddAtEnd;
+ if constexpr (QContainerTraits::has_pop_back_v<C>)
+ caps |= CanRemoveAtEnd;
+ if constexpr (QContainerTraits::has_push_front_v<C>)
+ caps |= CanAddAtBegin;
+ if constexpr (QContainerTraits::has_pop_front_v<C>)
+ caps |= CanRemoveAtBegin;
+ return caps;
}
static constexpr QMetaType getValueMetaType()
@@ -208,19 +222,49 @@ class QMetaSequenceForContainer
static constexpr QMetaSequenceInterface::AddValueFn getAddValueFn()
{
if constexpr (QContainerTraits::has_push_back_v<C>) {
- return [](void *c, const void *v) {
- static_cast<C *>(c)->push_back(
- *static_cast<const QContainerTraits::value_type<C> *>(v));
- };
+ if constexpr (QContainerTraits::has_push_front_v<C>) {
+ return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
+ const auto &value = *static_cast<const QContainerTraits::value_type<C> *>(v);
+ switch (position) {
+ case QMetaSequenceInterface::AtBegin:
+ static_cast<C *>(c)->push_front(value);
+ break;
+ case QMetaSequenceInterface::AtEnd:
+ case QMetaSequenceInterface::Unspecified:
+ static_cast<C *>(c)->push_back(value);
+ break;
+ }
+ };
+ } else {
+ return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
+ const auto &value = *static_cast<const QContainerTraits::value_type<C> *>(v);
+ switch (position) {
+ case QMetaSequenceInterface::AtBegin:
+ break;
+ case QMetaSequenceInterface::AtEnd:
+ case QMetaSequenceInterface::Unspecified:
+ static_cast<C *>(c)->push_back(value);
+ break;
+ }
+ };
+ }
} else if constexpr (QContainerTraits::has_push_front_v<C>) {
- return [](void *c, const void *v) {
- static_cast<C *>(c)->push_front(
- *static_cast<const QContainerTraits::value_type<C> *>(v));
+ return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
+ const auto &value = *static_cast<const QContainerTraits::value_type<C> *>(v);
+ switch (position) {
+ case QMetaSequenceInterface::Unspecified:
+ case QMetaSequenceInterface::AtBegin:
+ static_cast<C *>(c)->push_front(value);
+ case QMetaSequenceInterface::AtEnd:
+ break;
+ }
};
} else if constexpr (QContainerTraits::has_insert_v<C>) {
- return [](void *c, const void *v) {
- static_cast<C *>(c)->insert(
- *static_cast<const QContainerTraits::value_type<C> *>(v));
+ return [](void *c, const void *v, QMetaSequenceInterface::Position position) {
+ if (position == QMetaSequenceInterface::Unspecified) {
+ static_cast<C *>(c)->insert(
+ *static_cast<const QContainerTraits::value_type<C> *>(v));
+ }
};
} else {
return nullptr;
@@ -230,9 +274,41 @@ class QMetaSequenceForContainer
static constexpr QMetaSequenceInterface::RemoveValueFn getRemoveValueFn()
{
if constexpr (QContainerTraits::has_pop_back_v<C>) {
- return [](void *c) { static_cast<C *>(c)->pop_back(); };
+ if constexpr (QContainerTraits::has_pop_front_v<C>) {
+ return [](void *c, QMetaSequenceInterface::Position position) {
+ switch (position) {
+ case QMetaSequenceInterface::AtBegin:
+ static_cast<C *>(c)->pop_front();
+ break;
+ case QMetaSequenceInterface::AtEnd:
+ case QMetaSequenceInterface::Unspecified:
+ static_cast<C *>(c)->pop_back();
+ break;
+ }
+ };
+ } else {
+ return [](void *c, QMetaSequenceInterface::Position position) {
+ switch (position) {
+ case QMetaSequenceInterface::AtBegin:
+ break;
+ case QMetaSequenceInterface::Unspecified:
+ case QMetaSequenceInterface::AtEnd:
+ static_cast<C *>(c)->pop_back();
+ break;
+ }
+ };
+ }
} else if constexpr (QContainerTraits::has_pop_front_v<C>) {
- return [](void *c) { static_cast<C *>(c)->pop_front(); };
+ return [](void *c, QMetaSequenceInterface::Position position) {
+ switch (position) {
+ case QMetaSequenceInterface::Unspecified:
+ case QMetaSequenceInterface::AtBegin:
+ static_cast<C *>(c)->pop_front();
+ break;
+ case QMetaSequenceInterface::AtEnd:
+ break;
+ }
+ };
} else {
return nullptr;
}
@@ -245,7 +321,7 @@ class QMetaSequenceForContainer
using Iterator = QContainerTraits::iterator<C>;
switch (p) {
case QMetaSequenceInterface::AtBegin:
- case QMetaSequenceInterface::Random:
+ case QMetaSequenceInterface::Unspecified:
return new Iterator(static_cast<C *>(c)->begin());
break;
case QMetaSequenceInterface::AtEnd:
@@ -377,7 +453,7 @@ class QMetaSequenceForContainer
using Iterator = QContainerTraits::const_iterator<C>;
switch (p) {
case QMetaSequenceInterface::AtBegin:
- case QMetaSequenceInterface::Random:
+ case QMetaSequenceInterface::Unspecified:
return new Iterator(static_cast<const C *>(c)->begin());
break;
case QMetaSequenceInterface::AtEnd:
@@ -471,8 +547,8 @@ template<typename C>
QMetaSequenceInterface QMetaSequenceForContainer<C>::metaSequence = {
/*.revision=*/ 0,
/*.iteratorCapabilities=*/ getIteratorCapabilities(),
- /*.addRemovePosition=*/ getAddRemovePosition(),
/*.valueMetaType=*/ getValueMetaType(),
+ /*.addRemoveCapabilities=*/ getAddRemoveCapabilities(),
/*.sizeFn=*/ getSizeFn(),
/*.clearFn=*/ getClearFn(),
/*.valueAtIndexFn=*/ getValueAtIndexFn(),
@@ -525,9 +601,15 @@ public:
QMetaType valueMetaType() const;
- bool isOrdered() const;
- bool addsAndRemovesValuesAtBegin() const;
- bool addsAndRemovesValuesAtEnd() const;
+ bool isSortable() const;
+ bool canAddValueAtBegin() const;
+ void addValueAtBegin(void *container, const void *value) const;
+ bool canAddValueAtEnd() const;
+ void addValueAtEnd(void *container, const void *value) const;
+ bool canRemoveValueAtBegin() const;
+ void removeValueAtBegin(void *container) const;
+ bool canRemoveValueAtEnd() const;
+ void removeValueAtEnd(void *container) const;
bool hasSize() const;
qsizetype size(const void *container) const;