Title
Precondition of inplace_vector::swap
Status
immediate
Section
[inplace.vector.modifiers]
Submitter
Arthur O'Dwyer

Created on 2024-09-07.00:00:00 last changed 4 days ago

Messages

Date: 2026-03-27.16:27:21

Proposed resolution:

This wording is relative to N5032.

  1. Modify [inplace.vector.modifiers] as indicated:

    [Drafting note: It is suggested to add the new wording to the end of the existing subclause]

    constexpr void swap(inplace_vector& x) noexcept(N == 0 ||
      (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>));
    

    -?- Preconditions: `T` meets the Cpp17MoveConstructible requirements. Let M be min(size(), x.size()). For each non-negative integer n < M, (*this)[n] is swappable with x[n] ([swappable.requirements]).

    -?- Effects: Exchanges the contents of *this and x.

Date: 2026-03-27.16:27:21

[ Croydon 2026-03-27; Status changed: New → Immediate. ]

Date: 2026-03-27.15:57:52

[ Croydon 2026-03-27; Jonathan provides new wording ]

Also require Cpp17MoveConstructible.

Date: 2024-09-15.00:00:00

[ 2024-09-18; Reflector poll ]

Set priority to 2 after reflector poll. The Preconditions: (but not the Effects:) would be changed again if P3160R2 is approved.

This wording is relative to N4988.

  1. Modify [inplace.vector.modifiers] as indicated:

    [Drafting note: It is suggested to add the new wording to the end of the existing subclause]

    constexpr void swap(inplace_vector& x) noexcept(N == 0 ||
      (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>));
    

    -?- Preconditions: Let M be min(size(), x.size()). For each non-negative integer n < M, (*this)[n] is swappable with ([swappable.requirements]) x[n].

    -?- Effects: Exchanges the contents of *this and x.

Date: 2024-09-07.00:00:00

Right now inplace_vector::swap has only a declaration in the class synopsis; it doesn't specify what the behavior of swap for inplace_vectors actually is. So I think the behavior ends up being governed by [container.reqmts], which are written from the point of view of a container that manages an external heap allocation so that swapping containers doesn't touch the elements at all, just changes their ownership.

inplace_vector::swap actually works more like array::swap, which has its own specification in [array.members], where it is defined in terms of std::swap_ranges. The std::swap_ranges algorithm ([alg.swap]) has a precondition! This precondition is missing from inplace_vector::swap.

That is, I think we currently have no wording that explains why

std::pmr::monotonic_buffer_resource mr1;
std::inplace_vector<std::pmr::vector<int>, 2> v1, v2;
v1.emplace_back(1, &mr1);
v2.emplace_back(1);
v1.swap(v2);

is undefined behavior. The current spec seems to say this Just Works, even though it physically cannot work because v1[0] and v2[0] don't dynamically meet the semantic requirements of being "swappable with" each other, and v1.swap(v2) is necessarily going to try to swap them.

History
Date User Action Args
2026-03-27 16:27:21adminsetmessages: + msg16138
2026-03-27 16:27:21adminsetstatus: new -> immediate
2026-03-27 15:57:52adminsetmessages: + msg16133
2024-09-18 22:37:26adminsetmessages: + msg14386
2024-09-08 10:47:26adminsetmessages: + msg14362
2024-09-07 00:00:00admincreate