Skip to content

flat_set's transparent insertion requirements are deficient #4105

@achabense

Description

@achabense

The precondition of flat_set's transparent insertion is specified as follows:

https://eel.is/c++draft/flat.set#modifiers-2
Preconditions: The conversion from x into value_type constructs an object u, for which find(x) == find(u) is true.

... which is highly problematic. #4084 tried to add the following test. As fs.find(2) == fs.end(), and fs.find(2-10) == fs.end(), this is currently allowed by the standard.

void test_insert_transparent_partially_inconsistent() {
    struct broken_key {
        int key;
        explicit operator int() const {
            return key - 10;
        }
    };

    flat_set<int, key_comparer/*comparator able to extract ".key" if present*/> fs{ 0, 3, 5 };

    // fs.find(2) == fs.end(), and fs.find(2-10) == fs.end(), so this is currently allowed by the standard:
    fs.insert(broken_key{ 2 });
    // ... (assert fs has "{-8, 0, 3, 5}")
    // ...
}

The problem is that the precondition cannot ensure the lower_bound(transparent-key) be the same as lower_bound(convert-result). If we must adhere to the current specification, after deciding that the transparent-key is not contained (by finding its lower_bound and doing the comparision), we still need to verify that the bound is also the real lower_bound for the convert-result; and if not, we need to fall back to another (non-transparent) insert function.

The condition above is unlikely useful but is generally undetectable, and the solution will have considerable performance impact. As commented in #4084, the real solution might be making the precondition more restrictive in the standard.

The current implementation will work fine if the precondition is specified as:

The conversion from x into value_type constructs an object u, for which "contains(x) == contains(u) && lower_bound(x) == lower_bound(u)" is true.

Metadata

Metadata

Assignees

No one assigned

    Labels

    LWG issue neededA wording defect that should be submitted to LWG as a new issueflat_meowC++23 container adaptorsresolvedSuccessfully resolved without a commit

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions