QVarLengthArray: simplify / optimize assign(It, It)
After many failed attempts at addressing my dissatisfaction with the if (n) checks, I finally realized that the problem is the while (first != last && end != end()) loop, which, when exited, gives no indication as to _why_ it was exited. Any attempt to re-construct the exit condition must needs re-check something that should be known already. To fix, then, use a while (true) loop and react on first == last and dst == end() separately. As a drive-by, cache end(). Task-number: QTBUG-106200 Change-Id: Ic873774451df4102163e6e65d93c35e5dcbbb037 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
5a3ac484db
commit
87e90a265f
@ -790,27 +790,28 @@ Q_OUTOFLINE_TEMPLATE void QVLABase<T>::assign_impl(qsizetype prealloc, void *arr
|
||||
}
|
||||
|
||||
auto dst = begin();
|
||||
while (first != last && dst != end()) {
|
||||
*dst = *first; // reuse initialized buffer
|
||||
const auto dend = end();
|
||||
while (true) {
|
||||
if (first == last) { // ran out of elements to assign
|
||||
std::destroy(dst, dend);
|
||||
break;
|
||||
}
|
||||
if (dst == dend) { // ran out of existing elements to overwrite
|
||||
if constexpr (IsFwdIt) {
|
||||
dst = std::uninitialized_copy(first, last, dst);
|
||||
break;
|
||||
} else {
|
||||
do {
|
||||
emplace_back_impl(prealloc, array, *first);
|
||||
} while (++first != last);
|
||||
return; // size() is already correct (and dst invalidated)!
|
||||
}
|
||||
}
|
||||
*dst = *first; // overwrite existing element
|
||||
++dst;
|
||||
++first;
|
||||
}
|
||||
|
||||
qsizetype n;
|
||||
if constexpr (IsFwdIt) {
|
||||
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());
|
||||
this->s = dst - begin();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
Loading…
Reference in New Issue
Block a user