summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydataops.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qarraydataops.h')
-rw-r--r--src/corelib/tools/qarraydataops.h55
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