From e07710007b4cf9c0665ac9d5c2b6c7ef588aae0a Mon Sep 17 00:00:00 2001 From: Dennis Oberst Date: Thu, 25 May 2023 11:27:10 +0200 Subject: [PATCH] QArrayDataPointer: fix optional projection in assign() When a custom projection is used in the assign() function, there is a problem with the optimization step at: dst = std::uninitialized_copy(first, last, dst); The issue arises because this copy doesn't respect the custom projection. To address this problem, we need to ensure that the optimization is only applied when using the identity projection. Amends: 7ca633d9a82f90e5bba5e12ba923bfb0a257af63. Change-Id: I912525c716333ee2c22c419f2bf70201086c5635 Reviewed-by: Qt CI Bot Reviewed-by: Marc Mutz --- src/corelib/tools/qarraydatapointer.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index ad9ca428de..eb20330f0f 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -315,6 +315,7 @@ public: constexpr bool IsFwdIt = std::is_convertible_v< typename std::iterator_traits::iterator_category, std::forward_iterator_tag>; + constexpr bool IsIdentity = std::is_same_v; if constexpr (IsFwdIt) { const qsizetype n = std::distance(first, last); @@ -379,9 +380,14 @@ public: break; } if (dst == dend) { // ran out of existing elements to overwrite - if constexpr (IsFwdIt) { + if constexpr (IsFwdIt && IsIdentity) { dst = std::uninitialized_copy(first, last, dst); break; + } else if constexpr (IsFwdIt && !IsIdentity + && std::is_nothrow_constructible_v) { + for (; first != last; ++dst, ++first) // uninitialized_copy with projection + q20::construct_at(dst, std::invoke(proj, *first)); + break; } else { do { (*this)->emplace(size, std::invoke(proj, *first));