www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [SAoC] Move semantics and STL containers

reply Suleyman <sahmi.soulaimane gmail.com> writes:
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/
Sep 21 2019
next sibling parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
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
Sep 21 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
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
Sep 28 2019
next sibling parent reply Exil <Exil gmall.com> writes:
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?
Sep 28 2019
parent reply Manu <turkeyman gmail.com> writes:
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.
Sep 28 2019
next sibling parent reply Johannes Pfau <nospam example.com> writes:
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
Sep 29 2019
parent Suleyman <sahmi.soulaimane gmail.com> writes:
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: 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. 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.
Oct 22 2019
prev sibling parent Exil <Exil gmall.com> writes:
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...
Oct 05 2019
prev sibling parent Suleyman <sahmi.soulaimane gmail.com> writes:
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
Oct 05 2019
prev sibling parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Week 4:
     - ` rvalue` type:
         - fixed minor bugs
         - more documentation and a DIP will come later at 
milestone 4.
Oct 15 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Week 5:

Start of milestone 2.

* Move constructor semantic implemented based on the work on 
rvalue ref.
* A default move constructor is generated if one or more members 
of a struct have  move constructor.
* The move opAssign implemented as well.
* A ` move` attribute with an accompanying `__move()` intrinsic 
was added as an alternative to rvalue ref.

Usage example:

1. with rvalue ref

compile with the compiler switch `-preview=rvalueattribute`.
```
struct S
{
     static char[] result;
     this( rvalue ref inout S) inout { result ~= "Mc"; }
     void opAssign( rvalue ref inout S) inout { result ~= "Ma"; }
}

unittest
{
     S a;
     S b = cast( rvalue ref)a;
     a = cast( rvalue ref)b;
     assert(S.result == "McMa");
}
```

2. with the ` move` attribute

compile with the compiler switch `-preview=moveattribute`.
```
struct S
{
     static char[] result;
     this(ref inout S)  move inout { result ~= "Mc"; }
     void opAssign(ref inout S)  move inout { result ~= "Ma"; }
}

unittest
{
     S a;
     S b = __move(a);
     a = __move(b);
     assert(S.result == "McMa");
}
```

Note: the implementation is not ready yet for things like 
internal pointers, some interaction with the codegen is needed to 
eliminate the remaining blits that still exist.
Oct 23 2019
next sibling parent reply RazvanN <razvan.nitu1305 gmail.com> writes:
On Wednesday, 23 October 2019 at 17:19:14 UTC, Suleyman wrote:
 Week 5:

 Start of milestone 2.

 [...]
The blits need to be eliminated only if the move constructor is defined, otherwise they should remain the same.
Oct 29 2019
parent Suleyman <sahmi.soulaimane gmail.com> writes:
On Tuesday, 29 October 2019 at 15:20:14 UTC, RazvanN wrote:
 On Wednesday, 23 October 2019 at 17:19:14 UTC, Suleyman wrote:
 Week 5:

 Start of milestone 2.

 [...]
The blits need to be eliminated only if the move constructor is defined, otherwise they should remain the same.
Yes for the blits that have a reason to remain, like saving side effect. For redundant blits they will be simply eliminated.
Oct 29 2019
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 10/23/19 1:19 PM, Suleyman wrote:
 Week 5:
 
 Start of milestone 2.
 
 * Move constructor semantic implemented based on the work on rvalue ref.
 * A default move constructor is generated if one or more members of a 
 struct have  move constructor.
 * The move opAssign implemented as well.
 * A ` move` attribute with an accompanying `__move()` intrinsic was 
 added as an alternative to rvalue ref.
 
 Usage example:
 
 1. with rvalue ref
 
 compile with the compiler switch `-preview=rvalueattribute`.
 ```
 struct S
 {
      static char[] result;
      this( rvalue ref inout S) inout { result ~= "Mc"; }
      void opAssign( rvalue ref inout S) inout { result ~= "Ma"; }
 }
 
 unittest
 {
      S a;
      S b = cast( rvalue ref)a;
      a = cast( rvalue ref)b;
      assert(S.result == "McMa");
 }
 ```
 
 2. with the ` move` attribute
 
 compile with the compiler switch `-preview=moveattribute`.
 ```
 struct S
 {
      static char[] result;
      this(ref inout S)  move inout { result ~= "Mc"; }
      void opAssign(ref inout S)  move inout { result ~= "Ma"; }
 }
 
 unittest
 {
      S a;
      S b = __move(a);
      a = __move(b);
      assert(S.result == "McMa");
 }
 ```
 
 Note: the implementation is not ready yet for things like internal 
 pointers, some interaction with the codegen is needed to eliminate the 
 remaining blits that still exist.
As far as I understand this is a major language change that proceeded without a known plan, and of which likelihood to be accepted is doubtful. This work must definitely be coordinated to the other related projects - binding rvalues to ref, move constructors, perfect forwarding, DIP 1014. We can't have different people work independently on their own vision of features that overlap 80%. Don't we risk adding this to our growing list of projects that people invest vast amounts of talent and work, just to abandon them?
Oct 29 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
On Tuesday, 29 October 2019 at 15:31:55 UTC, Andrei Alexandrescu 
wrote:
 On 10/23/19 1:19 PM, Suleyman
 [...]
As far as I understand this is a major language change that proceeded without a known plan, and of which likelihood to be accepted is doubtful. This work must definitely be coordinated to the other related projects - binding rvalues to ref, move constructors, perfect forwarding, DIP 1014. We can't have different people work independently on their own vision of features that overlap 80%. Don't we risk adding this to our growing list of projects that people invest vast amounts of talent and work, just to abandon them?
DIP 1014 is postblit based I was advised by Manu to work on a constructor based solution for the same reasons that lead to the copy constructor being adopted in D. Prefect forwarding is a combination of auto ref and rvalue ref. Razvan told me he was working on perfect forwarding DIP and we talked superficially about it. The implementation of rvalue ref which is required for a perfect forwarding solution which doesn't do a copy or move at each level is available. There is also `auto rvalue ref` which exactly does perfect forwarding. Binding rvalues to ref is a separate issue. Even in C++ there is rvalue ref and const ref. The core of move semantics and perfect forwarding has been implemented. Whichever syntax is accepted in the end it will be just parser work. For example the implementation of the ` move` attribute - which is an alternative to rvalue ref just in case rvalue ref is not accepted - does actually use the rvalue ref implementation underneath, it's only parsed and mangled differently. If I knew of something else related to move semantics that was likelier to be accepted I would have included it in this SAOC. We surely need to collaborate. This work itself is a collaboration, I only did the implementation, the ideas are not mine. I give credits to all the contributors who shared their ideas on the initial discussion thread https://forum.dlang.org/thread/oipegxuwqmrmmzefrqcx forum.dlang.org. We can open a thread somewhere or anybody who is interested can just contact me directly in Slack.
Oct 29 2019
next sibling parent Suleyman <sahmi.soulaimane gmail.com> writes:
On Tuesday, 29 October 2019 at 21:13:16 UTC, Suleyman wrote:
 [...] I give credits to all the contributors who shared their 
 ideas on the initial discussion thread [...]
I also give credits to my mentor Manu which explained and advised everything related related to this work.
Oct 29 2019
prev sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 30/10/2019 10:13 AM, Suleyman wrote:
 
 We surely need to collaborate. This work itself is a collaboration, I 
 only did the implementation, the ideas are not mine. I give credits to 
 all the contributors who shared their ideas on the initial discussion 
 thread 
 https://forum.dlang.org/thread/oipegxuwqmrmmzefrqcx forum.dlang.org. We 
 can open a thread somewhere or anybody who is interested can just 
 contact me directly in Slack.
For projects like this if you want a workgroup channel on the Discord server please let us know. Having as many interested parties in live chat is a great way to develop and explore ideas.
Oct 29 2019
parent Suleyman <sahmi.soulaimane gmail.com> writes:
On Wednesday, 30 October 2019 at 02:18:12 UTC, rikki cattermole 
wrote:
 On 30/10/2019 10:13 AM, Suleyman wrote:
 [...]
For projects like this if you want a workgroup channel on the Discord server please let us know. Having as many interested parties in live chat is a great way to develop and explore ideas.
This is a good idea.
Oct 30 2019
prev sibling next sibling parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Week 6:

A partial solution was implemented for issue 
https://issues.dlang.org/show_bug.cgi?id=20321.
A more complete solution is still work in progress.
Nov 01 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Week 7:

More progress on issue 20321. Made a second pull request[1].
Also audited all temporaries which are created in the glue layer 
of DMD and compiled a report about it[2]. This narrowed down the 
problem significantly. The report contains links to test cases 
and links to the pull request that has the fix if available.

[1] https://github.com/dlang/dmd/pull/10539
[2] 
https://gist.github.com/SSoulaimane/f87a9f86dc8808eab8ac787e237b47b2
Nov 11 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
week 8:
   - finished the semantics of the default move opAssign
     - the default move opAssign is generated if:
       1. struct the move constructor
       2. one of struct fields defines the move opAssign
Nov 18 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Week 9:
   - fixed issue 20235[1] which was blocking std::string.
   - fixed issue 20413[2] which was blocking std::pair.


[1] https://issues.dlang.org/show_bug.cgi?id=20235
[2] https://issues.dlang.org/show_bug.cgi?id=20413
Nov 28 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Week 11:

GCC and Clang versions of std::vector were ported. Like the 
windows port version there is not range API yet, only arrays are 
accepted, for this reason the bitmap packed vector<bool> is not 
yet implemented. The Range interface is on the TODO list for the 
future.
Dec 11 2019
next sibling parent Suleyman <sahmi.soulaimane gmail.com> writes:
On Wednesday, 11 December 2019 at 16:56:40 UTC, Suleyman wrote:
 Week 11:

 GCC and Clang versions of std::vector were ported. [...]
Pull request to `core.stdcpp.vector` https://github.com/dlang/druntime/pull/2866.
Dec 11 2019
prev sibling next sibling parent reply bachmeier <no spam.net> writes:
On Wednesday, 11 December 2019 at 16:56:40 UTC, Suleyman wrote:
 Week 11:

 GCC and Clang versions of std::vector were ported. Like the 
 windows port version there is not range API yet, only arrays 
 are accepted, for this reason the bitmap packed vector<bool> is 
 not yet implemented. The Range interface is on the TODO list 
 for the future.
Could you expand a bit on this? Does it mean I can call a C++ function taking std::vector<double> as an argument with a double[] allocated on the D side?
Dec 11 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
On Wednesday, 11 December 2019 at 17:02:47 UTC, bachmeier wrote:
 On Wednesday, 11 December 2019 at 16:56:40 UTC, Suleyman wrote:
 Week 11:

 GCC and Clang versions of std::vector were ported. Like the 
 windows port version there is not range API yet, only arrays 
 are accepted, for this reason the bitmap packed vector<bool> 
 is not yet implemented. The Range interface is on the TODO 
 list for the future.
Could you expand a bit on this? Does it mean I can call a C++ function taking std::vector<double> as an argument with a double[] allocated on the D side?
D doesn't have implicit constructors for function parameters otherwise you could do what you've described. But you can currently construct a vector and assign it from an array, it just won't do it automatically for function arguments for the reason mentioned. Example: ``` import core.stdcpp.vector; // construct vector!double v = [1.0, 2.1]; double[] a = []; // assign v = a; void f(vector!double); f(a); // error ```
Dec 11 2019
parent reply bachmeier <no spam.net> writes:
On Wednesday, 11 December 2019 at 17:15:26 UTC, Suleyman wrote:
 On Wednesday, 11 December 2019 at 17:02:47 UTC, bachmeier wrote:
 On Wednesday, 11 December 2019 at 16:56:40 UTC, Suleyman wrote:
 Week 11:

 GCC and Clang versions of std::vector were ported. Like the 
 windows port version there is not range API yet, only arrays 
 are accepted, for this reason the bitmap packed vector<bool> 
 is not yet implemented. The Range interface is on the TODO 
 list for the future.
Could you expand a bit on this? Does it mean I can call a C++ function taking std::vector<double> as an argument with a double[] allocated on the D side?
D doesn't have implicit constructors for function parameters otherwise you could do what you've described. But you can currently construct a vector and assign it from an array, it just won't do it automatically for function arguments for the reason mentioned. Example: ``` import core.stdcpp.vector; // construct vector!double v = [1.0, 2.1]; double[] a = []; // assign v = a; void f(vector!double); f(a); // error ```
Okay. That's reasonable. Does v = a copy or can we reuse a.ptr with your implementation? Keep in mind that I don't know much about std::vector or the work you're doing.
Dec 11 2019
parent Suleyman <sahmi.soulaimane gmail.com> writes:
On Wednesday, 11 December 2019 at 17:48:24 UTC, bachmeier wrote:
 [...]
Okay. That's reasonable. Does v = a copy or can we reuse a.ptr with your implementation? Keep in mind that I don't know much about std::vector or the work you're doing.
If you pass it a slice then it has to copy, and the reason being is that `vector!double` is short for `vector!(double, allocator!double)`, notice it has an allocator therefore it can't reuse the a pointer if the allocator is not the same. Even if hypothetically there was no allocator problem then a move operation - which is what you've described as reusing the slice pointer - can only be done if the constructor/opAssign of the vector knows that the slice is an rvalue (for example an array literal is an rvalue, or the result of an explicit move operation is also an rvalue) and I don't know of any way to declare a slice of rvalues right now. I will add a slice of rvalues as a type to my rvalue ref implementation (which will be documented and announced with a DIP in the next milestone). I was hesitant at first to allow slices of rvalues, but after porting std::vector I came across various move strategies among which was move iterators and since used slices instead, I found that I couldn't declare a move construtor/opAssign for slices, and I didn't, this is one of the lacking parts right now in the array API of vector, if you pass a slice it always has to copy no matter what.
Dec 11 2019
prev sibling parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Week 12:

The remaining parts of std::string were implemented. These are:

* atomic ref counting in the GCC version.
* growing with resize().
* reserve(), shrink_to_fit(), insert(), replace(), and swap().

link to `core.stdcpp.string` pull request 
https://github.com/dlang/druntime/pull/2878.
Dec 18 2019
parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
Recapitulation of milestone 3:

* Ported GCC and Clang std::vector.
* Implemented the rest of std::string for MSVC, GCC, and Clang.
* Fixed issue 20235[1] which was a blocker for both std::string 
and std::vector.
* Fixed a mangling issues which was blocking std::pair.

[1] : https://issues.dlang.org/show_bug.cgi?id=20235
Dec 18 2019
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 19 December 2019 at 03:46:56 UTC, Suleyman wrote:
 Recapitulation of milestone 3:

 * Ported GCC and Clang std::vector.
 * Implemented the rest of std::string for MSVC, GCC, and Clang.
 * Fixed issue 20235[1] which was a blocker for both std::string 
 and std::vector.
 * Fixed a mangling issues which was blocking std::pair.
std::pair is just a std::tuple, so does this mean std::tuple is usable? (great effort, std::vector is important :-)
Dec 19 2019
next sibling parent reply Gregor =?UTF-8?B?TcO8Y2ts?= <gregormueckl gmx.de> writes:
On Thursday, 19 December 2019 at 13:49:36 UTC, Ola Fosheim 
Grøstad wrote:
 std::pair is just a std::tuple, so does this mean std::tuple is 
 usable?
Careful: while std::pair is semantically a 2-tuple, it is actually a completely separate type and not a specialization. My guess is that this can't be corrected now because std::pair is older than std::tuple and was used in std::map and related associative containers.
Dec 19 2019
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 19 December 2019 at 20:09:36 UTC, Gregor Mückl wrote:
 On Thursday, 19 December 2019 at 13:49:36 UTC, Ola Fosheim 
 Grøstad wrote:
 std::pair is just a std::tuple, so does this mean std::tuple 
 is usable?
Careful: while std::pair is semantically a 2-tuple, it is actually a completely separate type and not a specialization. My guess is that this can't be corrected now because std::pair is older than std::tuple and was used in std::map and related associative containers.
Yes, it predates C++11 and the members are called first and second, but supports all the same operations except assignment? So the D implementation should be similar, I think? (I consider pair to be legacy so I don't use it anymore.)
Dec 19 2019
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 19 December 2019 at 22:58:06 UTC, Ola Fosheim 
Grøstad wrote:
 So the D implementation should be similar, I think?
What I mean by this is that if you implement std::tuple in D, you only need to swap out the mangling to get pair, everything else should be the same. (On the C++ side things like assignment does not work between pair and tuple, but the attribute names are not relevant for D, since D interface with the memory-object.)
Dec 19 2019
prev sibling parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
On Thursday, 19 December 2019 at 13:49:36 UTC, Ola Fosheim 
Grøstad wrote:
 On Thursday, 19 December 2019 at 03:46:56 UTC, Suleyman wrote:
 [...]
std::pair is just a std::tuple, so does this mean std::tuple is usable?
It was on the TODO list but since you asked for it here it is https://github.com/dlang/druntime/pull/2879. unique_ptr in the GCC implementation also uses std::tuple internally.
Dec 21 2019
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 21 December 2019 at 11:55:24 UTC, Suleyman wrote:
 It was on the TODO list but since you asked for it here it is 
 https://github.com/dlang/druntime/pull/2879. unique_ptr in the 
 GCC implementation also uses std::tuple internally.
I see you implemented tuple concatenation as well. That is pretty cool!
Dec 21 2019
parent Suleyman <sahmi.soulaimane gmail.com> writes:
On Saturday, 21 December 2019 at 12:40:08 UTC, Ola Fosheim 
Grøstad wrote:
 On Saturday, 21 December 2019 at 11:55:24 UTC, Suleyman wrote:
 [...]
I see you implemented tuple concatenation as well. That is pretty cool!
It's a lot easier to implement in D than in C++ thanks to AliasSeq. AliasSeq isn't perfect but is very powerful.
Dec 21 2019
prev sibling parent Suleyman <sahmi.soulaimane gmail.com> writes:
This marks the end of milestone 2 for which the objective was to 
implement user controlled move semantics in D.

Accomplished tasks:
- Implementation of the move constructor and move opAssign using 
rvalue ref or alternatively using the  move attribute.
- Fixing most cases of issue 20321 where the compiler copies 
objects without calling the copy or move constructor.

The following tasks will be continued after the SAOC period 
because they didn't fit the schedule of this milestone.
- Implement move semantics in druntime functions that perform 
array operations.
- Solve the two remaining cases of issue 20321.
Nov 18 2019