From f4878568f55a9c3b6eef8cc8fad9b1aa7e8ab4ce Mon Sep 17 00:00:00 2001 From: Neil Date: Fri, 16 Jul 2021 09:54:01 +1000 Subject: SplitVector::RoomFor does not resize when there is exactly enough room as this prevents extra reallocations. This change made 0-length gaps more likely and that caused attempts to std::move by 0 which is undefined and failed with the g++ standard library. Fixed by not moving for 0-length gap. --- src/SplitVector.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src/SplitVector.h') diff --git a/src/SplitVector.h b/src/SplitVector.h index 885055bd1..d233a50ed 100644 --- a/src/SplitVector.h +++ b/src/SplitVector.h @@ -27,19 +27,21 @@ protected: void GapTo(ptrdiff_t position) noexcept { if (position != part1Length) { try { - // This can never fail but std::move and std::move_backward are not noexcept. - if (position < part1Length) { - // Moving the gap towards start so moving elements towards end - std::move_backward( - body.data() + position, - body.data() + part1Length, - body.data() + gapLength + part1Length); - } else { // position > part1Length - // Moving the gap towards end so moving elements towards start - std::move( - body.data() + part1Length + gapLength, - body.data() + gapLength + position, - body.data() + part1Length); + if (gapLength > 0) { // If gap to move + // This can never fail but std::move and std::move_backward are not noexcept. + if (position < part1Length) { + // Moving the gap towards start so moving elements towards end + std::move_backward( + body.data() + position, + body.data() + part1Length, + body.data() + gapLength + part1Length); + } else { // position > part1Length + // Moving the gap towards end so moving elements towards start + std::move( + body.data() + part1Length + gapLength, + body.data() + gapLength + position, + body.data() + part1Length); + } } part1Length = position; } catch (...) { @@ -51,7 +53,7 @@ protected: /// Check that there is room in the buffer for an insertion, /// reallocating if more space needed. void RoomFor(ptrdiff_t insertionLength) { - if (gapLength <= insertionLength) { + if (gapLength < insertionLength) { while (growSize < static_cast(body.size() / 6)) growSize *= 2; ReAllocate(body.size() + insertionLength + growSize); -- cgit v1.2.3