Repository navigation
fix erase_if method - #17101
fix erase_if method#17101
Conversation
| // Move item to the end of the list and shrink by 1 | ||
| std::memcpy(ptr, last, sizeof(Ty)); | ||
| last = _data + (--_size); | ||
| last = _data + (--_size - 1); // set new last |
There was a problem hiding this comment.
This is still wrong due to the swapped value not being evaluated. I need to fix this properly.
There was a problem hiding this comment.
yes I also thought that the logic was overall not correct. The swapped ptr <> last is not tested (ptr will be increased in the for cycle and not tested).
Ok waiting for your fix and I will close this PR
There was a problem hiding this comment.
if scanning/swapping order is not important then the following code (iterating from last to fist) should be ok:
for (auto last = _data + (_size - 1), ptr = last; ptr >= _data; ptr--)
{
if (predicate(*ptr))
{
ret = true;
if (ptr != last) // If not last
{
// Move last item into current one
std::memcpy(ptr, last, sizeof(Ty));
}
// Pop last entry from list and set new last item
_size--;
last--;
}
}
There was a problem hiding this comment.
This is still wrong, the deleted item is not removed. Swapping is important for single-pass filter alogrithms to avoid backtracking but I botched it this time and we don't have unit tests to catch these things.
There was a problem hiding this comment.
#17102 fixes this properly. I also wrote the test for it in case you want to toy around with it: https://godbolt.org/z/4745MGT6z
There was a problem hiding this comment.
yes I saw https://godbolt.org/z/4745MGT6z. Items are properly removed also with my code but of course the scanning from last to first produces same values but with different order. If order was not important then my code seems faster (a maximum of _size iterations with less code).
Also for a typical list with many items my if (ptr != last) ) statement is basically always satisfied while your if (ptr == last) is at maximum only one time satisfied incurring in some performance drop.
There was a problem hiding this comment.
not sure I understood the missing removal, it seems there, but ok I see you provided the PR, so closing this
My fault for not testing this thoroughly, I missed the reversed direction of the scan.
There was a problem hiding this comment.
pushed my changes as a reminder in case they will be ok.
I also thought if the items removed from the list are object types needing to be destroyed (e.g. release allocated pointers etc.)
There was a problem hiding this comment.
Simple array is stricly for POD types. This is enforced by the template.
Now for the impl, yours is fine so I'll merge to give credit, but I absolutely despise reversed loops unless I have no other choice (debugging requires inverting logic in the head which is not easy) so I will also merge my PR after to replace it.
There was a problem hiding this comment.
no problem at all. Not interested to credits etc.. Any solution fixing bugs is ok for me. I simply pushed my last changes just as reminder for myself before (sooner or later) I will permanently delete this PR from my repo.
Fixes made by #17040 highlighted a further bug in
erase_ifmethod that should be fixed now. Probably more than the listed bug reports below were affected by the bug.fixes #17098
should fix #17043