From 2457dd8bd0a0a2be567173e3bb9dbfeb1318a02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 16 Feb 2023 11:23:18 +0100 Subject: [PATCH] QVLA: Optimize assign() for non-throwing copies Change-Id: I39e2bef482fa638a6d197623759b5163fc7cc3a6 Reviewed-by: Thiago Macieira --- src/corelib/tools/qvarlengtharray.h | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index a35d6cce40..a47530219f 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -779,7 +779,10 @@ template Q_OUTOFLINE_TEMPLATE void QVLABase::assign_impl(qsizetype prealloc, void *array, Iterator first, Iterator last) { // This function only provides the basic exception guarantee. - if constexpr (std::is_convertible_v::iterator_category, std::forward_iterator_tag>) { + constexpr bool IsFwdIt = + std::is_convertible_v::iterator_category, + std::forward_iterator_tag>; + if constexpr (IsFwdIt) { const qsizetype n = std::distance(first, last); if (n > capacity()) reallocate_impl(prealloc, array, 0, n); // clear & reserve n @@ -792,11 +795,19 @@ Q_OUTOFLINE_TEMPLATE void QVLABase::assign_impl(qsizetype prealloc, void *arr ++first; } - qsizetype n = dst - begin(); - while (first != last) { - emplace_back_impl(prealloc, array, *first); - ++first; - ++n; + qsizetype n = 0; + if constexpr (IsFwdIt && noexcept(T(*first))) { + dst = std::uninitialized_copy(first, last, dst); + n = dst - begin(); + if (n > s) // otherwise: readjust 's' in erase() later + s = n; + } else { + n = dst - begin(); + while (first != last) { + emplace_back_impl(prealloc, array, *first); + ++first; + ++n; + } } erase(data() + n, data() + size()); }