Title
Missing guarantees for `forward_list` modifiers
Status
voting
Section
[forward.list.modifiers]
Submitter
Jonathan Wakely

Created on 2024-10-05.00:00:00 last changed yesterday

Messages

Date: 2024-10-09.16:52:09

Proposed resolution:

This wording is relative to n4988.

  1. Change [forward.list.modifiers] as indicated:

    None of the overloads of `insert_after` shall affect the validity of iterators and references, and `erase_after` shall invalidate only iterators and references to the erased elements. The member functions in this subclause do not affect the validity of iterators and references when inserting elements, and when erasing elements invalidate iterators and references to the erased elements only. If an exception is thrown during `insert_after` by any of these member functions there shall be is no effect on the container.
Date: 2024-10-15.00:00:00

[ 2024-10-09; LWG telecon: Move to Ready ]

Date: 2024-10-15.00:00:00

[ 2024-10-09; LWG suggested improved wording ]

The proposed resolution potentially mandates a change to `resize` when increasing the size, requiring implementations to "roll back" earlier insertions if a later one throws, so that the size is left unchanged. It appears that libstdc++ and MSVC already do this, libc++ does not.

Date: 2024-10-15.00:00:00

[ 2024-10-09; Reflector poll ]

Set priority to 3 after reflector poll.

It was suggested to change "If an exception is thrown by any of these member functions that insert elements there is no effect on the forward_list" to simply "If an exception is thrown by any of these member functions there is no effect on the forward_list"

This wording is relative to n4988.

  1. Change [forward.list.modifiers] as indicated:

    None of the overloads of `insert_after` shall member functions in this subclause that insert elements affect the validity of iterators and references, and `erase_after` shall invalidate invalidates only iterators and references to the erased elements. If an exception is thrown during `insert_after` by any of these member functions there shall be is no effect on the `forward_list`.
Date: 2024-10-05.11:57:03

The new `std::list` members added by p1206r7, insert_range(const_iterator, R&&), prepend_range(R&&), and append_range(R&&), have the same exception safety guarantee as `std::list::insert(const_iterator, InputIterator, InputIterator)`, which is:

Remarks: Does not affect the validity of iterators and references. If an exception is thrown, there are no effects.

This guarantee was achieved for the new `list` functions simply by placing them in the same set of declarations as the existing `insert` overloads, at the start of [list.modifiers].

However, the new `std::forward_list` members, insert_range_after(const_iterator, R&&) and prepend_range(R&&), do not have the same guarantee as `forward_list::insert_after`. This looks like an omission caused by the fact that `insert_after`'s exception safety guarantee is given in a separate paragraph at the start of [forward.list.modifiers]:

None of the overloads of `insert_after` shall affect the validity of iterators and references, and `erase_after` shall invalidate only iterators and references to the erased elements. If an exception is thrown during `insert_after` there shall be no effect.

I think we should give similar guarantees for `insert_range_after` and `prepend_range`. The change might also be appropriate for `emplace_after` as well. A "no effects" guarantee is already given for `push_front` and `emplace_front` in [container.reqmts] p66, although that doesn't say anything about iterator invalidation so we might want to add that to [forward.list.modifiers] too. For the functions that insert a single element, it's trivial to not modify the list if allocating a new node of constructing the element throws. The strong exception safety guarantee for the multi-element insertion functions is easily achieved by inserting into a temporary `forward_list` first, then using `splice_after` which is non-throwing.

History
Date User Action Args
2024-11-19 16:09:07adminsetstatus: ready -> voting
2024-10-09 16:52:09adminsetmessages: + msg14432
2024-10-09 16:52:09adminsetstatus: new -> ready
2024-10-09 16:51:55adminsetmessages: + msg14431
2024-10-09 13:47:50adminsetmessages: + msg14429
2024-10-05 11:09:44adminsetmessages: + msg14426
2024-10-05 00:00:00admincreate