diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2023-02-16 11:23:18 +0100 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2023-02-24 16:10:11 +0100 |
commit | 2457dd8bd0a0a2be567173e3bb9dbfeb1318a02b (patch) | |
tree | 8e68bca7580b98c6ac61c8826e7e11c4ddfd968e /src/corelib/tools/qvarlengtharray.h | |
parent | cb15967014196c03a32bf2423aa350716f1d2dff (diff) | |
download | qtbase-2457dd8bd0a0a2be567173e3bb9dbfeb1318a02b.tar.gz |
QVLA: Optimize assign() for non-throwing copies
Change-Id: I39e2bef482fa638a6d197623759b5163fc7cc3a6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qvarlengtharray.h')
-rw-r--r-- | src/corelib/tools/qvarlengtharray.h | 23 |
1 files 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 <typename Iterator> Q_OUTOFLINE_TEMPLATE void QVLABase<T>::assign_impl(qsizetype prealloc, void *array, Iterator first, Iterator last) { // This function only provides the basic exception guarantee. - if constexpr (std::is_convertible_v<typename std::iterator_traits<Iterator>::iterator_category, std::forward_iterator_tag>) { + constexpr bool IsFwdIt = + std::is_convertible_v<typename std::iterator_traits<Iterator>::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<T>::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()); } |