Proposal to make "shared" (more) useful

Arafel er.krali at gmail.com
Fri Sep 14 08:18:25 UTC 2018


On 09/14/2018 09:32 AM, Kagamin wrote:
> struct Unshared(T)
> {
>      private T value;
>      this(T v) shared { opAssign(v); }
>      T get() shared { return *cast(T*)&value; }
>      alias get this;
>      void opAssign(T v) shared { *cast(T*)&value=v; }
> }
> 
> shared synchronized class A
> {
>      private Unshared!(int[]) a;
>      private Unshared!SysTime t;
>      this(){ t=Clock.currTime; }
>      int[] f()
>      {
>          return a;
>      }
> }

Almost there, you have to make "get" ref for it to work when calling 
methods that mutate the instance, though.


```
import std.datetime.systime;
import std.stdio;
import core.time;

shared struct Unshared(T)
{
     private T value;
     this(T v) shared { opAssign(v); }
     ref T get() shared { return *cast(T*)&value; }
     alias get this;
     void opAssign(T v) shared { *cast(T*)&value=v; }
}

shared synchronized class A
{
     private Unshared!(int[]) a;
     private Unshared!SysTime t;
     this(){ t=Clock.currTime; }
     int[] f()
     {
         return a;
     }
     void g() {
         writeln(t);
         t += 1.dur!"minutes"; // Doesn't work without "ref"
         writeln(t);
         t = t + 1.dur!"minutes";
         writeln(t);
     }
}

void main() {
     shared A a = new shared A;
     a.g;
}
```

Still, I don't know how to deal with structs with @disabled this() 
and/or specific constructors and other corner cases, it currently 
doesn't work 100% as it should:

```
import std.stdio;

struct S {
     @disable this();
     int i;
     this(int i_) {
         i = 2 * i_;
     }

     void opAssign(int i_) {
         i = 2 * i_;
     }

     void f() {
         i *= 2;
     }
}

shared struct Unshared(T)
{
     private T value;
     this(T v) shared { *cast(T*)&value=v; }
     ref T get() shared { return *cast(T*)&value; }
     alias get this;
     void opAssign(T v) shared { *cast(T*)&value=v; }
}

shared synchronized class A
{
     private Unshared!S s; // Should this even be possible? What about 
the @disable this??
	// I would expect at least one, if not both of the following, to work
     //private Unshared!S s2 = S(1);
     //private Unshared!S s3 = 1;

     this(){
         s = S(1);
         //s = 1;
         s.f;
     }
     void f() {
         writeln(s.i);
     }
}

void main() {
     // This is rightly not possible: @disable this()
     // S s1;
     S s = 2; // This doesn't work in Unshared
     s = 1; // Neither does this
     s.f;
     writeln(s.i); // 4 as it should

     shared A a = new shared A;
     a.f; // 4 as it should
}
```

That's why I think it should be in the language itself, or at a minimum 
in Phobos once all the bugs are found and ironed out, if possible.

A.


More information about the Digitalmars-d mailing list