summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qvarlengtharray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qvarlengtharray.h')
-rw-r--r--src/corelib/tools/qvarlengtharray.h78
1 files changed, 32 insertions, 46 deletions
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 1702ab04e9..2434402eaf 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -183,7 +183,12 @@ public:
}
inline bool isEmpty() const { return (s == 0); }
inline void resize(qsizetype size);
- inline void clear() { resize(0); }
+ void clear()
+ {
+ if constexpr (QTypeInfo<T>::isComplex)
+ std::destroy_n(data(), size());
+ s = 0;
+ }
inline void squeeze();
inline qsizetype capacity() const { return a; }
@@ -368,6 +373,20 @@ public:
private:
void reallocate(qsizetype size, qsizetype alloc);
+ void resize_impl(qsizetype newSize, const T &t)
+ {
+ const auto increment = newSize - size();
+ if (increment > 0 && QtPrivate::q_points_into_range(&t, cbegin(), cend())) {
+ resize_impl(newSize, T(t));
+ return;
+ }
+ reallocate(qMin(size(), newSize), qMax(newSize, capacity()));
+
+ if (increment > 0)
+ std::uninitialized_fill_n(end(), increment, t);
+ s = newSize;
+ }
+
qsizetype a; // capacity
qsizetype s; // size
T *ptr; // data
@@ -625,29 +644,12 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
Q_ASSERT(s <= a);
Q_ASSERT(a > 0);
- qsizetype offset = qsizetype(before - ptr);
- if (s == a)
- reserve(s * 2);
- if (!QTypeInfo<T>::isRelocatable) {
- T *b = ptr + offset;
- T *i = ptr + s;
- T *j = i + 1;
- // The new end-element needs to be constructed, the rest must be move assigned
- if (i != b) {
- new (--j) T(std::move(*--i));
- while (i != b)
- *--j = std::move(*--i);
- *b = std::move(t);
- } else {
- new (b) T(std::move(t));
- }
- } else {
- T *b = ptr + offset;
- memmove(static_cast<void *>(b + 1), static_cast<const void *>(b), (s - offset) * sizeof(T));
- new (b) T(std::move(t));
- }
- s += 1;
- return ptr + offset;
+ const qsizetype offset = qsizetype(before - ptr);
+ append(std::move(t));
+ const auto b = begin() + offset;
+ const auto e = end();
+ QtPrivate::q_rotate(b, e - 1, e);
+ return b;
}
template <class T, qsizetype Prealloc>
@@ -655,28 +657,12 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
{
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
- qsizetype offset = qsizetype(before - ptr);
- if (n != 0) {
- const T copy(t); // `t` could alias an element in [begin(), end()[
- resize(s + n);
- if (!QTypeInfo<T>::isRelocatable) {
- T *b = ptr + offset;
- T *j = ptr + s;
- T *i = j - n;
- while (i != b)
- *--j = *--i;
- i = b + n;
- while (i != b)
- *--i = copy;
- } else {
- T *b = ptr + offset;
- T *i = b + n;
- memmove(static_cast<void *>(i), static_cast<const void *>(b), (s - offset - n) * sizeof(T));
- while (i != b)
- new (--i) T(copy);
- }
- }
- return ptr + offset;
+ const qsizetype offset = qsizetype(before - cbegin());
+ resize_impl(size() + n, t);
+ const auto b = begin() + offset;
+ const auto e = end();
+ QtPrivate::q_rotate(b, e - n, e);
+ return b;
}
template <class T, qsizetype Prealloc>