Jump to page: 1 2 3
Thread overview
[SAoC] Move semantics and STL containers
Sep 21
Suleyman
Sep 21
Suleyman
Sep 28
Suleyman
Sep 28
Exil
Sep 28
Manu
Oct 22
Suleyman
Oct 06
Exil
Oct 05
Suleyman
Oct 16
Suleyman
Oct 23
Suleyman
Oct 29
RazvanN
Oct 29
Suleyman
Oct 29
Suleyman
Oct 29
Suleyman
Oct 30
Suleyman
Nov 02
Suleyman
Nov 11
Suleyman
Nov 19
Suleyman
Nov 29
Suleyman
Nov 19
Suleyman
September 21
Hello,

I will be working in this SAoC season on the D bindings to simple STL containers project[1].

This thread will be updated weekly with progress status.

The theme of this SAoC project is to improve and consolidate D's interoperability through bindings to the C++ STL containers. This will involve fixing a number of DMD issues related to C++ interop, as well as implementing the move constructor in D.

Milestones:

* 1. Full implementation of rvalue ref.
 - `@rvalue ref` as attribute
 - __traits(isRvalueRef)
 - `__rvalue(T)` as type constructor
 - implement full semantics
 - expand `auto ref` to rvale ref
 - match the C++ mangling for rvalue ref

* 2. Full implementation of the move constructor
 - move constructor
 - move opAssign
 - implement full semantics:
   - default behaviour
   - `@disable`
   - relationship with the copy constructor
   - conflict with existing semantics

* 3. Fix blocking DMD issues and implement std::string and std::vector on all platforms
 - Fix issue https://issues.dlang.org/show_bug.cgi?id=20235
 - Investigate and fix the mangling issue which is blocking std::pair
 - implement move semantics for std::string
 - implement std::vector for GCC and Clang lib

* 4. Finalize the project
 - Ensure move semantics work properly
 - ensure backwards compatibility
 - implement existing STL containers on all platforms
 - resolve all D blockers

____

[1] https://github.com/dlang-cpp-interop/stl-containers/

September 21
Week 1 status:
    - `@rvalue ref` attribute fully implemented[1]
      - grammar definition[2]
      - parameter and return semantics
      - D and C++ name mangling
      - `cast(@rvalue ref)` to convert lvalues to rvalue ref
      - `__traits(isRvalueRef)` for parameters
      - fully functional with ctfe, inliner, optimizer, codgen
      - escape analysis is the same as `ref`

____
[1] https://github.com/dlang/dmd/pull/10426
[2] https://github.com/dlang/dlang.org/pull/2703

September 28
Week 2 status:

    - `@rvalue ref` attribute:
        - `auto @rvalue ref` for function parameters expands to either `ref` or `@rvalue ref`
        - `auto ref` for function parameters retains its current behaviour
        - `auto ref` on function returns infers refness properly between `ref`, `@rvalue ref`, and no ref.

    - `@rvalue` or `__rvalue` as a type constructor[1]:
        - grammar definition[2]
        - enable both syntaxes `@rvalue` and `__rvalue`
        - only usable with ref or with pointers
        - ability to cast to or from `@rvalue`
        - implicit conversion to or from `@rvalue` allowed except with pointers
        - special behaviour with function calls where rvalue arguments are implicitly `@rvalue` while lvalues need an explicit cast
        - `@rvalue` ref is overloadable with bare ref
        - recognized as a type specialization with `is(T == @rvalue)`
        - D and C++ name mangling
        - works with ctfe, inliner, optimizer, and escape analysis

____
[1] https://github.com/dlang/dmd/pull/10426
[2] https://github.com/dlang/dlang.org/pull/2704

September 28
On Saturday, 28 September 2019 at 11:06:02 UTC, Suleyman wrote:
> [1] https://github.com/dlang/dmd/pull/10426
> [2] https://github.com/dlang/dlang.org/pull/2704

So was @rvalue pre-approved or something? Last thing I heard about rvalue references is that they were rejected (along with the DIP) and a new DIP was being written. Was that forgone?


September 28
On Sat, Sep 28, 2019 at 12:55 PM Exil via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Saturday, 28 September 2019 at 11:06:02 UTC, Suleyman wrote:
> > [1] https://github.com/dlang/dmd/pull/10426
> > [2] https://github.com/dlang/dlang.org/pull/2704
>
> So was @rvalue pre-approved or something? Last thing I heard about rvalue references is that they were rejected (along with the DIP) and a new DIP was being written. Was that forgone?

Completely different and unrelated topic. Passing rvalue temporaries
by ref is different than rvalue references.
It's not preapproved, this work is optimistic.
September 29
Am Sat, 28 Sep 2019 14:29:35 -0700 schrieb Manu:

> On Sat, Sep 28, 2019 at 12:55 PM Exil via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> On Saturday, 28 September 2019 at 11:06:02 UTC, Suleyman wrote:
>> > [1] https://github.com/dlang/dmd/pull/10426 [2] https://github.com/dlang/dlang.org/pull/2704
>>
>> So was @rvalue pre-approved or something? Last thing I heard about rvalue references is that they were rejected (along with the DIP) and a new DIP was being written. Was that forgone?
> 
> Completely different and unrelated topic. Passing rvalue temporaries by
> ref is different than rvalue references.
> It's not preapproved, this work is optimistic.

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.



-- 
Johannes
October 05
Week 3 status:

  - `@rvalue` / `__rvalue` type constructor[1]:
    - implemented runtime type info[1][2]
    - `auto ref` infers `@rvalue`
      - `auto @rvalue ref` parameters expand to either `ref` or `@rvalue ref`
      - `auto ref` parameters retain their current behavior
      - `auto ref` returns infer all three options `ref`, `@rvalue ref`, and value.
    - implemented semantic for default arguments
    - implicit conversion is unidirectional, only from `@rvalue` to non `@rvalue` is allowed.
    - rvalue expressions are implicitly convertible to `@rvalue`
    - finding the common type of a binary expression is now aware of `@rvalue`
      - if both operands are `@rvalue` the result if `@rvalue`
      - else it's not `@rvalue`

____
[1] https://github.com/dlang/dmd/pull/10426
[2] https://github.com/dlang/druntime/pull/2814

October 06
On Saturday, 28 September 2019 at 21:29:35 UTC, Manu wrote:
> On Sat, Sep 28, 2019 at 12:55 PM Exil via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> On Saturday, 28 September 2019 at 11:06:02 UTC, Suleyman wrote:
>> > [1] https://github.com/dlang/dmd/pull/10426
>> > [2] https://github.com/dlang/dlang.org/pull/2704
>>
>> So was @rvalue pre-approved or something? Last thing I heard about rvalue references is that they were rejected (along with the DIP) and a new DIP was being written. Was that forgone?
>
> Completely different and unrelated topic. Passing rvalue temporaries
> by ref is different than rvalue references.
> It's not preapproved, this work is optimistic.

I wouldn't say they are completely different and unrelated. They both result in rvalues being attached to a reference. The only difference is one only allows rvalues specifically. It'd be a bad idea to allow both implementations, imo. It'd just complicate things further. Kind of a shame this was approved as a project, couldn't something else have been approved that didn't have a chance for the work to just be thrown away...
October 16
Week 4:
    - `@rvalue` type:
        - fixed minor bugs
        - more documentation and a DIP will come later at milestone 4.

October 22
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 `-preview=rvalueattribute`.

Usage example:

```d
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 returns.
  - `@rvalue ref` parameters only receive an rvalue or an "rvalue ref".
    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` parameters.
  - 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 `-preview=rvaluetype`.

Usage example:

```d
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 `@rvalue`.
  - 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.

« First   ‹ Prev
1 2 3