[SAoC] Move semantics and STL containers

Suleyman sahmi.soulaimane at gmail.com
Tue Oct 22 11:38:23 UTC 2019

On Sunday, 29 September 2019 at 09:53:09 UTC, Johannes Pfau wrote:
> But is there some kind of explanation for these changes? 
> There's the spec PR of course, but that does not really explain 
> why / how to use this feature.

A short description of each implementation:

## Rvalue attribute

The rvalue attribute is under the compiler switch 

Usage example:

struct S {}

void func(@rvalue ref S p);
@rvalue ref S func();

S a;
auto b = cast(@rvalue ref)a;

void gun(@rvalue ref S p)
     enum r = __traits(isRvalueRef, p);

void func()(auto @rvalue ref S p);
auto @rvalue ref S func();

Semantics are similar to C++ rvalue ref. The C++ ABI and name 
mangling is matched as well with `extern(C++)` functions.

In short summary:

* The `@rvalue ref` attribute:
   - can only be applied to function parameters or function 
   - `@rvalue ref` parameters only receive an rvalue or an "rvalue 
     where an "rvalue ref" is one of:
       1. `cast(@rvalue ref)` expression.
       2. return value of an `@rvalue ref` function.
   - `@rvalue ref` functions only returns an "rvalue ref".
   - `@rvalue ref` can be overloaded with `ref`, but not with 
value parameters.
   - `cast(@rvalue ref)` only applies to lvalues.
   - `__traits(isRvalueRef)` return `true` for `@rvalue ref` 
   - The result of `__traits(getAttributes)` when called with a 
function parameter includes `"@rvalue ref"` when applicable.
   - The result of `__traits(getFunctionAttributes)` includes 
`"@rvalue ref"` when the function returns it.
   - `auto ref` parameters retain their present semantics, with an 
additional flavor `auto @rvalue ref` which expands to either:
     1. `ref` if the argument received is an lvalue.
     2. `@rvalue ref` if the argument received is an rvalue.
   - `auto ref` on function returns infers either:
     1. `ref` if the return expression is an lvalue.
     2. `@rvalue ref` if return expression is "rvalue ref".
     3. value if the return expression is an rvalue.

     `auto ref` and `auto @rvalue ref` are synonymous when applied 
to function returns since they do not clash with one another 
unlike the case with parameters.

## Rvalue type constructor

The rvalue type constructor is under the compiler switch 

Usage example:

struct S {}

void func(@rvalue ref S p);
ref @rvalue(S) func();

S a;
auto b = cast(@rvalue)a;

void gun(ref @rvalue(S) p)
     enum r = is(typeof(p) == @rvalue);

const(@rvalue(S))* var;

void func()(auto ref @rvalue(S) p);
auto ref @rvalue(S) func();

assert(typeid(@rvalue(int)).toString() == "@rvalue(int)");

static assert(is(@rvalue(S) : S));
static assert(!is(@rvalue(S)* : S*));

Semantics summary:

* The `@rvalue` type constructor:
   - Two syntaxes are made available `@rvalue` and `__rvalue`, 
which one of them will be retained is TBR.
   - Tariables cannot be declared with `@rvalue` types except if 
declared with `ref` which only applies to functions parameters. 
But pointers to `@rvalue` types (ex: `@rvalue(T)*`) are allowed 
for variable declarations.
   - The element type of arrays and associative arrays cannot be 
   - The address of an `@rvalue ref` parameter is an rvalue 
pointer (`@rvalue(T)*`).
   - `is(T == @rvalue)` is `true` for `@rvalue` types.
   - `cast(@rvalue)` puts `@rvalue` on.
   - `typeid()` distinguishes `@rvalue` types.
   - implicit conversion for `@rvalue` is only allowed in one 
direction i.e from `@rvalue` to less.
   - The semantics of parameter overloading, function return 
values, `auto ref` and `auto @rvalue ref` mentioned in the rvalue 
attribute section also apply here unchanged.

More information about the Digitalmars-d mailing list