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: 7ca633d9a8
.
Change-Id: I912525c716333ee2c22c419f2bf70201086c5635
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
9da9ca0ac7
commit
e07710007b
@ -315,6 +315,7 @@ public:
|
|||||||
constexpr bool IsFwdIt = std::is_convertible_v<
|
constexpr bool IsFwdIt = std::is_convertible_v<
|
||||||
typename std::iterator_traits<InputIterator>::iterator_category,
|
typename std::iterator_traits<InputIterator>::iterator_category,
|
||||||
std::forward_iterator_tag>;
|
std::forward_iterator_tag>;
|
||||||
|
constexpr bool IsIdentity = std::is_same_v<Projection, q20::identity>;
|
||||||
|
|
||||||
if constexpr (IsFwdIt) {
|
if constexpr (IsFwdIt) {
|
||||||
const qsizetype n = std::distance(first, last);
|
const qsizetype n = std::distance(first, last);
|
||||||
@ -379,9 +380,14 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dst == dend) { // ran out of existing elements to overwrite
|
if (dst == dend) { // ran out of existing elements to overwrite
|
||||||
if constexpr (IsFwdIt) {
|
if constexpr (IsFwdIt && IsIdentity) {
|
||||||
dst = std::uninitialized_copy(first, last, dst);
|
dst = std::uninitialized_copy(first, last, dst);
|
||||||
break;
|
break;
|
||||||
|
} else if constexpr (IsFwdIt && !IsIdentity
|
||||||
|
&& std::is_nothrow_constructible_v<T, decltype(std::invoke(proj, *first))>) {
|
||||||
|
for (; first != last; ++dst, ++first) // uninitialized_copy with projection
|
||||||
|
q20::construct_at(dst, std::invoke(proj, *first));
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
(*this)->emplace(size, std::invoke(proj, *first));
|
(*this)->emplace(size, std::invoke(proj, *first));
|
||||||
|
Loading…
Reference in New Issue
Block a user