From a7b85e59931443dd33adeb02c7201c1bd1d7cd1d Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 8 Sep 2020 15:34:42 +0200 Subject: [PATCH] QMetaContainer: Add function to erase ranges from sequences Change-Id: Ic51103c36d288f236106e2d3aec1401d53b97a15 Reviewed-by: Lars Knoll --- src/corelib/global/qcontainerinfo.h | 5 +++++ src/corelib/kernel/qmetacontainer.cpp | 24 ++++++++++++++++++++++++ src/corelib/kernel/qmetacontainer.h | 19 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/corelib/global/qcontainerinfo.h b/src/corelib/global/qcontainerinfo.h index ad3ef301e4..c6ee9328ec 100644 --- a/src/corelib/global/qcontainerinfo.h +++ b/src/corelib/global/qcontainerinfo.h @@ -141,6 +141,11 @@ constexpr bool can_erase_at_iterator_v = false; template constexpr bool can_erase_at_iterator_v> = true; +template +constexpr bool can_erase_range_at_iterator_v = false; +template +constexpr bool can_erase_range_at_iterator_v> = true; + QT_WARNING_POP } diff --git a/src/corelib/kernel/qmetacontainer.cpp b/src/corelib/kernel/qmetacontainer.cpp index e11381c1bd..9382909092 100644 --- a/src/corelib/kernel/qmetacontainer.cpp +++ b/src/corelib/kernel/qmetacontainer.cpp @@ -640,6 +640,30 @@ void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) d_ptr->eraseValueAtIteratorFn(container, iterator); } +/*! + Returns \c true if a range between two iterators can be erased from the + container, \c false otherwise. + */ +bool QMetaSequence::canEraseRangeAtIterator() const +{ + if (d_ptr) + return d_ptr->eraseRangeAtIteratorFn; + return false; +} + +/*! + Erases the range of values between the iterators \a iterator1 and + \a iterator2 from the \a container, if possible. + + \sa canEraseValueAtIterator(), begin(), end() + */ +void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1, + const void *iterator2) const +{ + if (canEraseRangeAtIterator()) + d_ptr->eraseRangeAtIteratorFn(container, iterator1, iterator2); +} + /*! Returns \c true if the underlying container offers a const iterator, \c false otherwise. diff --git a/src/corelib/kernel/qmetacontainer.h b/src/corelib/kernel/qmetacontainer.h index f3a6266eb4..1f7771a0bc 100644 --- a/src/corelib/kernel/qmetacontainer.h +++ b/src/corelib/kernel/qmetacontainer.h @@ -113,6 +113,8 @@ public: InsertValueAtIteratorFn insertValueAtIteratorFn; using EraseValueAtIteratorFn = void(*)(void *, const void *); EraseValueAtIteratorFn eraseValueAtIteratorFn; + using EraseRangeAtIteratorFn = void(*)(void *, const void *, const void *); + EraseRangeAtIteratorFn eraseRangeAtIteratorFn; using CreateConstIteratorFn = void *(*)(const void *, Position); CreateConstIteratorFn createConstIteratorFn; @@ -446,6 +448,19 @@ class QMetaSequenceForContainer } } + static constexpr QMetaSequenceInterface::EraseRangeAtIteratorFn getEraseRangeAtIteratorFn() + { + if constexpr (QContainerTraits::has_iterator_v + && QContainerTraits::can_erase_range_at_iterator_v && !std::is_const_v) { + return [](void *c, const void *i, const void *j) { + static_cast(c)->erase(*static_cast *>(i), + *static_cast *>(j)); + }; + } else { + return nullptr; + } + } + static constexpr QMetaSequenceInterface::CreateConstIteratorFn getCreateConstIteratorFn() { if constexpr (QContainerTraits::has_const_iterator_v) { @@ -565,6 +580,7 @@ QMetaSequenceInterface QMetaSequenceForContainer::metaSequence = { /*.setValueAtIteratorFn=*/ getSetValueAtIteratorFn(), /*.insertValueAtIteratorFn=*/ getInsertValueAtIteratorFn(), /*.eraseValueAtIteratorFn=*/ getEraseValueAtIteratorFn(), + /*.eraseRangeAtIteratorFn=*/ getEraseRangeAtIteratorFn(), /*.createConstIteratorFn=*/ getCreateConstIteratorFn(), /*.destroyConstIteratorFn=*/ getDestroyConstIteratorFn(), /*.equalConstIteratorFn=*/ getCompareConstIteratorFn(), @@ -659,6 +675,9 @@ public: void advanceConstIterator(void *iterator, qsizetype step) const; qsizetype diffConstIterator(const void *i, const void *j) const; + bool canEraseRangeAtIterator() const; + void eraseRangeAtIterator(void *container, const void *iterator1, const void *iterator2) const; + bool canGetValueAtConstIterator() const; void valueAtConstIterator(const void *iterator, void *result) const;