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.h29
1 files changed, 9 insertions, 20 deletions
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index d8c229dea8..4b7e277187 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -475,28 +475,17 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
{
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
- int offset = int(before - ptr);
- reserve(s + 1);
- 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));
- }
+ const int offset = int(before - ptr);
+ append(std::move(t));
+ const auto b = begin() + offset;
+ const auto e = end();
+ if (QTypeInfo<T>::isRelocatable) {
+ auto cast = [](T *p) { return reinterpret_cast<uchar*>(p); };
+ std::rotate(cast(b), cast(e - 1), cast(e));
} 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));
+ std::rotate(b, e - 1, e);
}
- s += 1;
- return ptr + offset;
+ return b;
}
template <class T, int Prealloc>