diff options
Diffstat (limited to 'src/corelib/tools/qvarlengtharray.h')
-rw-r--r-- | src/corelib/tools/qvarlengtharray.h | 29 |
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> |