The old code had several bugs:
- it immediately clobbered *this with new state, before having copied
over the elements from the old to the new buffer
- when buffer relocation threw, it would keep the new (partially-filled)
buffer and throw away the old
- it unconditionally used std::move() for non-relocatable types, making
it impossible to restore the original buffer when a move throws
Instead of clobbering *this with new state, do all the work on the
side and change *this only once the reallocation has happened
successfully.
Also use q_uninitialized_relocate_n() and unique_ptr in the
implementation to simplify the code. The former got the necessary
update to use std::move_if_noexcept() instead of an unconditional
std::move() for the non-relocatable case.
[ChangeLog][QtCore][QVarLengthArray] The append()-like functions are
now strongly exception safe. This means reallocation will now use
copies instead of moves, unless the value_type has a noexcept move
constructor.
Fixes: QTBUG-99039
Change-Id: I031251b8d14ac045592d01caed59d4638c3d9892
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>