QMetaContainer: Add function to erase ranges from sequences

Change-Id: Ic51103c36d288f236106e2d3aec1401d53b97a15
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
bb10
Ulf Hermann 2020-09-08 15:34:42 +02:00
parent ac493c335c
commit a7b85e5993
3 changed files with 48 additions and 0 deletions

View File

@ -141,6 +141,11 @@ constexpr bool can_erase_at_iterator_v = false;
template<typename C>
constexpr bool can_erase_at_iterator_v<C, std::void_t<decltype(C().erase(C().begin()))>> = true;
template<typename, typename = void>
constexpr bool can_erase_range_at_iterator_v = false;
template<typename C>
constexpr bool can_erase_range_at_iterator_v<C, std::void_t<decltype(C().erase(C().begin(), C().end()))>> = true;
QT_WARNING_POP
}

View File

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

View File

@ -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<C>
&& QContainerTraits::can_erase_range_at_iterator_v<C> && !std::is_const_v<C>) {
return [](void *c, const void *i, const void *j) {
static_cast<C *>(c)->erase(*static_cast<const QContainerTraits::iterator<C> *>(i),
*static_cast<const QContainerTraits::iterator<C> *>(j));
};
} else {
return nullptr;
}
}
static constexpr QMetaSequenceInterface::CreateConstIteratorFn getCreateConstIteratorFn()
{
if constexpr (QContainerTraits::has_const_iterator_v<C>) {
@ -565,6 +580,7 @@ QMetaSequenceInterface QMetaSequenceForContainer<C>::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;