C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Relocation in C++

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Fri, 6 May 2022 12:04:48 +0100
On Fri, 6 May 2022 at 09:55, Sébastien Bini <sebastien.bini_at_[hidden]>
wrote:

> *> You'll need a relocate_wrapper type that can be (possibly implicitly)
> constructed from a callee-destroy prvalue, and that releases that value (by
> relocation to a prvalue) on request. So you call either
> push_back(relocate_wrapper(reloc x)), or relocate_back(reloc x).*
>
> This is similar to what is in the proposal: std::reloc_wrapper (page 24,
> https://github.com/SebastienBini/cpp-relocation-proposal/blob/main/relocation.pdf).
> You can relocate an object inside it, check if it has an object, and
> relocate it out. The problem is then that you need to perform two
> relocations (one inside the wrapper, one from the wrapper to the container).
>

Yes, that looks about right. The double-relocation can easily be elided,
especially if we give the compiler permission to do so as a
behavior-affecting optimization (i.e., above and beyond as-if).

Also, if no one sees a point of having non-default base-or-member
> initialisers in operator reloc member function, and that its source object
> is already destructed once the function body is reached, what would be
> wrong with this operator reloc?
>
> struct T : B
> {
> M data;
>
> /*
> * operator reloc returns a new instance.
> * actual relocation (base-class and data-member relocations) happen
> before the function body is called (as if by =default).
> * The function body only serves to make some adjustments, like fixing
> self-references.
> * 'this' pointer in reloc function body points to the newly
> constructed instance.
> * The source object is considered destructed and is no longer usable,
> that's why it does not appear as a parameter.
> * It is not possible to provide custom base-or-member-initializer.
> */
> operator reloc()
> {
> data.self = *this; // fix self-references here
> }
> };
>

The problem is: what if data is const? Then it will not be possible to
modify data.self in the function body. So I think you would need to be able
to write:

operator reloc(T&& rhs)
    : data([&] { M data = std::move(rhs.data); data.self = *this; return
data; }())
{}

By providing a base-or-member-initializer for data, you indicate that
rhs.data should be destroyed once that initializer completes. This scheme
can handle everything short of relocate-only const self-referential data
members (since it has to use move-and-destroy, not relocation proper), but
those are esoteric enough to not bother supporting (the user can just drop
const in that case).

Received on 2022-05-06 11:04:59