Description:
Description of "base_list" field members
* `first` = the pointer to the first element of list, or to the sentinel `end_of_list` if empty
* `last` = the pointer to the `next` field of the last list element, or pointer to the `first` if empty
* `elements` = the number of elements of the list
In case when the `base_list` is empty, the function `void swap(base_list &rhs)` behaves wrong. Let's lay, `rhs` is empty, then the `swap` copies `rhs.last` field, which points to the field `rhs.first`, into the `this->last` field. Afterwards, `this->last` points to the `rhs.first`, which is obviously wrong. It doesn't matter which instance (`*this` or `rhs`) is empty.
Since the code is very old and the bug still presents here, I suppose that it's never triggered by the existing functionality. That's why I'd describe the issue as hypothetical which affects code quality.
How to repeat:
Swap two empty "base_list" instances.
Suggested fix:
Either fix the `base_list::swap` function or just remove this function totally: almost in each usage case the `base_list::swap` can be replaced with the `base_list::operator=`.