Thread overview
Anybody have any idea on how to do shared operator overloads?
Jun 02, 2022
Ruby The Roobster
Jun 02, 2022
Ali Çehreli
Jun 02, 2022
Ruby The Roobster
Jun 02, 2022
Ruby The Roobster
Jun 02, 2022
Tejas
June 02, 2022

A stripped down version of some code I have:

public import std.complex;

public interface Mtype
{
    // ...
}

public class Number : Mtype
{
    public:
        this(Complex!real num = Complex!real(0,0))
        {
            this.num = num;
        }
        this(shared Complex!real num = cast(shared Complex!real)Complex!real(0,0))
        {
            this.num.re = num.re;
            this.im.re = im.re;
        }
        Number opBinary(string op)(Number rhs) //Standard opBinary
        {
            mixin("return new Number(this.num " ~ op ~ " rhs.num);");
        }
        shared(Number) opBinary(string op)(shared Number rhs) shared
        {
            return new shared Number(); //Placeholder untill I can get the code to work
        }
    package:
        Complex!real num;
}

bool isMtype(T)()
{
    bool ret = true;
    // ...
    shared T p = new shared T();
    shared T p2 = new shared T();
    ret &= __traits(compiles, T, p + p2);
    return ret;
}

static assert(isMtype!Number); //This fails.

Upon adding the line shared T c = p + p2 to isMtype, I get the following error:

source\dutils\math\core.d(138,22): Error: function call through null class reference null
source\dutils\math\core.d(142,15): called from here: isMtype()
source\dutils\math\core.d(142,1): while evaluating: static assert(cast(int)isMtype() == 1)

Anybody know how to get a working shared operator overload and fix this mess?

June 01, 2022
On 6/1/22 17:36, Ruby The Roobster wrote:
> A stripped down version of some code I have:

Not much experience here but I made two changes:

1) Added 'shared':

>          this(Complex!real num = Complex!real(0,0)) shared
>          {
>              this.num = num;
>          }
>          this(shared Complex!real num = cast(shared
> Complex!real)Complex!real(0,0))
>          {
>              this.num.re = num.re;
>              this.im.re = im.re;

2) Fixed apparent typos:

  this.num.im = num.im;

>          }

I can't guarantee that correct functions are called. It just compiles with 2.100.0. :)

Ali

June 02, 2022
On Thursday, 2 June 2022 at 01:00:57 UTC, Ali Çehreli wrote:
> On 6/1/22 17:36, Ruby The Roobster wrote:
> > A stripped down version of some code I have:
>
> Not much experience here but I made two changes:
>
> 1) Added 'shared':
>
> >          this(Complex!real num = Complex!real(0,0)) shared
> >          {
> >              this.num = num;
> >          }
> >          this(shared Complex!real num = cast(shared
> > Complex!real)Complex!real(0,0))
> >          {
> >              this.num.re = num.re;
> >              this.im.re = im.re;
>
> 2) Fixed apparent typos:
>
>   this.num.im = num.im;
>
> >          }
>
> I can't guarantee that correct functions are called. It just compiles with 2.100.0. :)
>
> Ali

Yes, those were typos.  However, when making this post, I forgot to mark ```this(shared Complex!real num = cast(shared Complex!real)Complex!real(0,0))``` as shared.  The other constructor is not marked as shared in my code, considering as shared classes have all of their members marked as shared.
June 02, 2022

On Thursday, 2 June 2022 at 01:29:39 UTC, Ruby The Roobster wrote:

>

On Thursday, 2 June 2022 at 01:00:57 UTC, Ali Çehreli wrote:

>

On 6/1/22 17:36, Ruby The Roobster wrote:

>

A stripped down version of some code I have:

Not much experience here but I made two changes:

  1. Added 'shared':
>
     this(Complex!real num = Complex!real(0,0)) shared
     {
         this.num = num;
     }
     this(shared Complex!real num = cast(shared

Complex!real)Complex!real(0,0))
{
this.num.re = num.re;
this.im.re = im.re;

  1. Fixed apparent typos:

this.num.im = num.im;

>
     }

I can't guarantee that correct functions are called. It just compiles with 2.100.0. :)

Ali

Yes, those were typos. However, when making this post, I forgot to mark this(shared Complex!real num = cast(shared Complex!real)Complex!real(0,0)) as shared. The other constructor is not marked as shared in my code, considering as shared classes have all of their members marked as shared.

I also have a bug: __traits(compiles) only checks if the expressions are SEMANTICALLY correct, not if they actually compile, which they don't.

Interestingly, this code compiles between 2.063 and 2.066.1, if you were to put it into run.dlang.io, given the above changes (including the p1 + p2!), and set to all compilers.

June 02, 2022

On Thursday, 2 June 2022 at 01:49:32 UTC, Ruby The Roobster wrote:

>

On Thursday, 2 June 2022 at 01:29:39 UTC, Ruby The Roobster wrote:

>

On Thursday, 2 June 2022 at 01:00:57 UTC, Ali Çehreli wrote:

>

On 6/1/22 17:36, Ruby The Roobster wrote:

>

A stripped down version of some code I have:

Not much experience here but I made two changes:

  1. Added 'shared':
>
     this(Complex!real num = Complex!real(0,0)) shared
     {
         this.num = num;
     }
     this(shared Complex!real num = cast(shared

Complex!real)Complex!real(0,0))
{
this.num.re = num.re;
this.im.re = im.re;

  1. Fixed apparent typos:

this.num.im = num.im;

>
     }

I can't guarantee that correct functions are called. It just compiles with 2.100.0. :)

Ali

Yes, those were typos. However, when making this post, I forgot to mark this(shared Complex!real num = cast(shared Complex!real)Complex!real(0,0)) as shared. The other constructor is not marked as shared in my code, considering as shared classes have all of their members marked as shared.

I also have a bug: __traits(compiles) only checks if the expressions are SEMANTICALLY correct, not if they actually compile, which they don't.

Interestingly, this code compiles between 2.063 and 2.066.1, if you were to put it into run.dlang.io, given the above changes (including the p1 + p2!), and set to all compilers.

I fixed the typos and added some extra constructors and also wrote a little more complex opBinary for the shared overload of Number. Now the thing works(AFAICT):

public import std.complex;
public import std.stdio;

public interface Mtype
{
    // ...
}

public class Number : Mtype
{
    public:
    	// new code begin
        this()
        {
            this.num = Complex!real(1,1);
        }
        this() shared
        {
            this.num = Complex!real(1,1);
        }
    	// new code ends
        this(Complex!real num = Complex!real(0,0))
        {
            this.num = num;
        }
        this(shared Complex!real num = cast(shared Complex!real)Complex!real(0,0)) shared
        {
            this.num.re = num.re;
            this.num.im = num.im;
        }
        Number opBinary(string op)(Number rhs) //Standard opBinary
        {
            mixin("return new Number(this.num " ~ op ~ " rhs.num);");
        }
        shared(Number) opBinary(string op)(shared Number rhs) shared
        //changed this code a little as well
        {
            mixin(q{return new shared Number(Complex!real(this.num.re} ~ op ~ q{rhs.num.re, this.num.im} ~ op ~ q{rhs.num.im));}); //Placeholder untill I can get the code to work
        }
    package:
        Complex!real num;
}

bool isMtype(T)()
{
    bool ret = true;
    // ...
    shared T p = new shared T();
    shared T p2 = new shared T();
    ret &= __traits(compiles, T, p + p2);
    return ret;
}

static assert(isMtype!Number); //This fails. Not anymore :D

void main()
{
    shared num1 = new shared Number();
    shared num2 = new shared Number();
    auto num3 = num1 + num2;
    writeln("real: ", num3.num.re, "\nimaginary: ",num3.num.im);
}