Repository navigation
Conversation
The svector move constructor and move assignment are noexcept, but the constructor swapped with an empty vector and the assignment copied the elements. When the source held more than N elements, both allocated a new heap buffer, so a std::bad_alloc called std::terminate. Every move of an xarray with more than four dimensions went through that path. The noexcept free swap also called the member swap, which can resize. Moving now takes over the heap buffer of the source, together with its allocator. When the source uses its inline buffer, the elements are moved into the current storage, which always has room for N elements. The moved-from vector is left empty. Swapping two svectors of the same type goes through three moves and does not allocate either. The noexcept conditions now use is_nothrow_move_assignable, which matches how the elements are transferred.
Contributor
Merging this PR will degrade performance by 18.92%1 warning
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist
Description
The
svectormove constructor, move assignment andswaparenoexcept, but they allocate when the vector holds more thanNelements. Both copy into a new heap buffer, so astd::bad_alloccallsstd::terminate. Moving anxarraywith more than four dimensions goes through this path.Moves now take over the heap buffer of the source, together with its allocator. When the source uses its inline buffer, its elements are moved into the current storage, which always holds at least
Nelements. If*thisowned a heap buffer that gets replaced, it is freed with its own allocator first. Self-move assignment is a no-op. Swapping two svectors of the same type goes through moves and does not allocate.Behavior change: a moved-from
svectoris now always empty. Move assignment used to leave the source untouched.svector.movechecks that the heap buffer is transferred and the source is left empty; on master it fails on the buffer address. I also ran heap and inline moves, self-move and swaps with a stateful tracking allocator under AddressSanitizer and LeakSanitizer: each buffer was freed by the allocator that allocated it, and nothing leaked.