2593. Moved-from state of Allocators

Section: 20.5.3.5 [allocator.requirements] Status: WP Submitter: David Krauss Opened: 2016-02-19 Last modified: 2017-07-30

Priority: 4

View other active issues in [allocator.requirements].

View all other issues in [allocator.requirements].

View all issues with WP status.

Discussion:

20.5.3.5 [allocator.requirements] suggests that the moved-from state of an allocator may be unequal to its previous state. Such a move constructor would break most container implementations, which move-construct the embedded allocator along with a compressed pair. Even if a moved-from container is empty, it should still subsequently allocate from the same resource pool as it did before.

std::vector<int, pool> a(500, my_pool);
auto b = std::move(a); // b uses my_pool too.
a.resize(500); // should still use my_pool.

[2016-02, Jacksonville]

Marshall will see if this can be resolved editorially.

After discussion, the editors and I decided that this could not be handled editorially. The bit about a moved-from state of an allocator being the same as the original state is a normative change. I submitted a pull request to handle the mismatched variables in the table.

Previous resolution [SUPERSEDED]:

This wording is relative to N4567.

  1. Change 20.5.3.5 [allocator.requirements], Table 28 — "Allocator requirements" as indicated:

    Note there's an editorial error in Table 28 in that line and the surrounding ones. The left column was apparently updated to use u and the right column is still using a/a1/b.

    Table 28 — Allocator requirements
    Expression Return type Assertion/note
    pre-/post-condition
    Default
    X u(move(a));
    X u = move(a);
    Shall not exit via an exception. post: u is equal to a and equal to the prior value of aa1 equals the prior value of a.

[2016-06-20, Oulu, Daniel comments]

According to the current working draft, the situation has changed due to changes performed by the project editor, the revised resolution has been adjusted to N4594.

[2016-08 - Chicago]

Thurs AM: Moved to LEWG, as this decision (should allocators only be copyable, not movable) is design.

[2017-02 in Kona, LEWG responds]

Alisdair Meredith says that if you have a do-not-propagate-on-move-assignment, then the move of the allocator must compare equal to the original.

Have a data structure where all allocators are equal. Construct an element somewhere else moving from inside the container (which doesn't have a POCMA trait); you don't want the allocator of the moved-from element to now be different. So in that case, the allocator's move constructor must behave the same as copy.

We don't need to go as far as this issue, but going that far is ok for Bloomberg.

[2017-06-02 Issues Telecon]

We discussed containers that have sentinel nodes, etc, and so might have to allocate/deallocate using a moved-from allocator - and decided that we didn't want any part of that

Adjusted the wording slightly, and moved to Tentatively Ready

Previous resolution [SUPERSEDED]:

This wording is relative to N4594.

  1. Change 20.5.3.5 [allocator.requirements], Table 28 — "Allocator requirements" as indicated:

    Table 28 — Allocator requirements
    Expression Return type Assertion/note
    pre-/post-condition
    Default
    X u(std::move(a));
    X u = std::move(a);
    Shall not exit via an exception. post: u is equal to a and equal to the prior value of au is equal to the prior value of a..

Proposed resolution:

This wording is relative to N4594.

  1. Change 20.5.3.5 [allocator.requirements], Table 28 — "Allocator requirements" as indicated:

    Table 28 — Allocator requirements
    Expression Return type Assertion/note
    pre-/post-condition
    Default
    X u(std::move(a));
    X u = std::move(a);
    Shall not exit via an exception. post: The value of a is unchanged and is equal to uu is equal to the prior value of a.