diff options
Diffstat (limited to 'src/corelib/tools/qarraydataops.h')
-rw-r--r-- | src/corelib/tools/qarraydataops.h | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 9b29b8a180..c3e9821e81 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -7,6 +7,7 @@ #include <QtCore/qarraydata.h> #include <QtCore/qcontainertools_impl.h> +#include <QtCore/qnamespace.h> #include <memory> #include <new> @@ -35,6 +36,8 @@ protected: public: typedef typename QArrayDataPointer<T>::parameter_type parameter_type; + using QArrayDataPointer<T>::QArrayDataPointer; + void appendInitialize(qsizetype newSize) noexcept { Q_ASSERT(this->isMutable()); @@ -213,6 +216,40 @@ public: --this->size; } + template <typename Predicate> + qsizetype eraseIf(Predicate pred) + { + qsizetype result = 0; + if (this->size == 0) + return result; + + if (!this->needsDetach()) { + auto end = this->end(); + auto it = std::remove_if(this->begin(), end, pred); + if (it != end) { + result = std::distance(it, end); + erase(it, result); + } + } else { + const auto begin = this->begin(); + const auto end = this->end(); + auto it = std::find_if(begin, end, pred); + if (it == end) + return result; + + QPodArrayOps<T> other(this->size); + Q_CHECK_PTR(other.data()); + auto dest = other.begin(); + // std::uninitialized_copy will fallback to ::memcpy/memmove() + dest = std::uninitialized_copy(begin, it, dest); + dest = q_uninitialized_remove_copy_if(std::next(it), end, dest, pred); + other.size = std::distance(other.data(), dest); + result = this->size - other.size; + this->swap(other); + } + return result; + } + struct Span { T *begin; T *end; }; void copyRanges(std::initializer_list<Span> ranges) @@ -924,6 +961,24 @@ public: // b might be updated so use [b, n) this->copyAppend(b, b + n); } + + void appendUninitialized(qsizetype newSize) + { + Q_ASSERT(this->isMutable()); + Q_ASSERT(!this->isShared()); + Q_ASSERT(newSize > this->size); + Q_ASSERT(newSize - this->size <= this->freeSpaceAtEnd()); + + T *const b = this->begin(); + do { + auto ptr = b + this->size; + + if constexpr (std::is_constructible_v<T, Qt::Initialization>) + new (ptr) T(Qt::Uninitialized); + else + new (ptr) T; // not T() -- default-construct + } while (++this->size != newSize); + } }; } // namespace QtPrivate |