diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 7295c29670f..79c1a53c5b1 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -910,29 +910,17 @@ Q_OUTOFLINE_TEMPLATE auto QVLABase::emplace_impl(qsizetype prealloc, void *ar Q_ASSERT(size() <= capacity()); Q_ASSERT(capacity() > 0); - qsizetype offset = qsizetype(before - cbegin()); - if (size() == capacity()) - growBy(prealloc, array, 1); - if constexpr (!QTypeInfo::isRelocatable) { - T *b = begin() + offset; - T *i = end(); - T *j = i + 1; - // The new end-element needs to be constructed, the rest must be move assigned - if (i != b) { - q20::construct_at(--j, std::move(*--i)); - while (i != b) - *--j = std::move(*--i); - *b = T(std::forward(args)...); - } else { - q20::construct_at(b, std::forward(args)...); - } + const qsizetype offset = qsizetype(before - cbegin()); + emplace_back_impl(prealloc, array, std::forward(args)...); + const auto b = begin() + offset; + const auto e = end(); + if constexpr (QTypeInfo::isRelocatable) { + auto cast = [](T *p) { return reinterpret_cast(p); }; + std::rotate(cast(b), cast(e - 1), cast(e)); } else { - T *b = begin() + offset; - memmove(static_cast(b + 1), static_cast(b), (size() - offset) * sizeof(T)); - q20::construct_at(b, std::forward(args)...); + std::rotate(b, e - 1, e); } - this->s += 1; - return data() + offset; + return b; } template