Thread overview
stuck on opDiv / opBinary
Aug 30, 2015
Spacen Jasset
Aug 30, 2015
John Colvin
Aug 30, 2015
BBasile
Aug 30, 2015
Spacen Jasset
Aug 30, 2015
Timon Gehr
Aug 30, 2015
Spacen Jasset
August 30, 2015
I have just added an opDiv to this class, but it doesn't seem to pick it up.
math/vector.d(30): Error: 'this /= mag' is not a scalar, it is a Vector3

I can't see why that is, becuase my opMul works in the same place. Can anyone point out what I have done wrong?

Class Matrix {

    void normalise()
    {
        const float mag = magnitude();
        if (mag) {
            //this.scalarDivide(mag);
            this /= mag; // Not work
            this *= 1/mag; // Does work.

        }
    }

//    Vector3 opBinary(string op)(Vector3 rhs) if (op=='/')
    Vector3 opDiv(float scalar)
    {
        Vector3 v = this;
        v.scalarDivide(scalar);
        return v;
    }

}


August 30, 2015
On Sunday, 30 August 2015 at 17:02:58 UTC, Spacen Jasset wrote:
> I have just added an opDiv to this class, but it doesn't seem to pick it up.
> math/vector.d(30): Error: 'this /= mag' is not a scalar, it is a Vector3
>
> I can't see why that is, becuase my opMul works in the same place. Can anyone point out what I have done wrong?
>
> Class Matrix {
>
>     void normalise()
>     {
>         const float mag = magnitude();
>         if (mag) {
>             //this.scalarDivide(mag);
>             this /= mag; // Not work
>             this *= 1/mag; // Does work.
>
>         }
>     }
>
> //    Vector3 opBinary(string op)(Vector3 rhs) if (op=='/')
>     Vector3 opDiv(float scalar)
>     {
>         Vector3 v = this;
>         v.scalarDivide(scalar);
>         return v;
>     }
>
> }

Don't use opMul or opDiv etc, use opBinary

Could you provide a more complete example? It's hard to identify what the problem is from this snippet.
August 30, 2015
On Sunday, 30 August 2015 at 17:02:58 UTC, Spacen Jasset wrote:
> I have just added an opDiv to this class, but it doesn't seem to pick it up.
> math/vector.d(30): Error: 'this /= mag' is not a scalar, it is a Vector3
>
> I can't see why that is, becuase my opMul works in the same place. Can anyone point out what I have done wrong?
>
> Class Matrix {
>
>     void normalise()
>     {
>         const float mag = magnitude();
>         if (mag) {
>             //this.scalarDivide(mag);
>             this /= mag; // Not work
>             this *= 1/mag; // Does work.
>
>         }
>     }
>
> //    Vector3 opBinary(string op)(Vector3 rhs) if (op=='/')
>     Vector3 opDiv(float scalar)
>     {
>         Vector3 v = this;
>         v.scalarDivide(scalar);
>         return v;
>     }
>
> }

try

---
Vector3 opBinary(string op)(Vector3 rhs)
{
    static if (op =="/"){}
    else static assert(0, op ~ " not implemented");
}
---

you used the char litteral delims ('') instead of the strings ones ("").
August 30, 2015
On Sunday, 30 August 2015 at 18:12:40 UTC, BBasile wrote:
> On Sunday, 30 August 2015 at 17:02:58 UTC, Spacen Jasset wrote:
>> [...]
>
> try
>
> ---
> Vector3 opBinary(string op)(Vector3 rhs)
> {
>     static if (op =="/"){}
>     else static assert(0, op ~ " not implemented");
> }
> ---
>
> you used the char litteral delims ('') instead of the strings ones ("").

Ah yes, it's didnt' complain. But anyway that was the wrong funciton I implemented.

I found the problem. I failed to implement a opDivAssign
August 30, 2015
On 08/30/2015 07:02 PM, Spacen Jasset wrote:
> I have just added an opDiv to this class, but it doesn't seem to pick it
> up.
> math/vector.d(30): Error: 'this /= mag' is not a scalar, it is a Vector3
>
> I can't see why that is, becuase my opMul works in the same place. Can
> anyone point out what I have done wrong?
> ...

import std.math: sqrt;
import std.algorithm: map,sum,canFind;

struct Vector3{
    float[3] xyz;
    void normalise(){ this/=magnitude();  }
    float magnitude(){ return sqrt(xyz[].map!(a=>a*a).sum); }
    enum scalarOps=["*","/"];
    enum isScalarOp(string op)=scalarOps.canFind(op);
    void scalar(string op)(float scalar)if(isScalarOp!op){
        foreach(ref a;xyz) mixin(`a `~op~`=scalar;`);
    }
    Vector3 opBinary(string op)(float scalar)if(isScalarOp!op){
        Vector3 v=this;
        v.scalar!op(scalar);
        return v;
    }
    auto opOpAssign(string op)(float rhs)if(isScalarOp!op){
        return mixin(`this=this `~op~` rhs`);
    }
}

August 30, 2015
On Sunday, 30 August 2015 at 20:09:25 UTC, Timon Gehr wrote:
> On 08/30/2015 07:02 PM, Spacen Jasset wrote:
>> [...]
>
> import std.math: sqrt;
> import std.algorithm: map,sum,canFind;
>
> struct Vector3{
>     float[3] xyz;
>     void normalise(){ this/=magnitude();  }
>     float magnitude(){ return sqrt(xyz[].map!(a=>a*a).sum); }
>     enum scalarOps=["*","/"];
>     enum isScalarOp(string op)=scalarOps.canFind(op);
>     void scalar(string op)(float scalar)if(isScalarOp!op){
>         foreach(ref a;xyz) mixin(`a `~op~`=scalar;`);
>     }
>     Vector3 opBinary(string op)(float scalar)if(isScalarOp!op){
>         Vector3 v=this;
>         v.scalar!op(scalar);
>         return v;
>     }
>     auto opOpAssign(string op)(float rhs)if(isScalarOp!op){
>         return mixin(`this=this `~op~` rhs`);
>     }
> }

Thanks, that is interesting. I am curently porting, rather than trying to rewrite anything at the moment, but I will try this out later.
August 31, 2015
On 8/30/15 3:45 PM, Spacen Jasset wrote:
> On Sunday, 30 August 2015 at 18:12:40 UTC, BBasile wrote:
>> On Sunday, 30 August 2015 at 17:02:58 UTC, Spacen Jasset wrote:
>>> [...]
>>
>> try
>>
>> ---
>> Vector3 opBinary(string op)(Vector3 rhs)
>> {
>>     static if (op =="/"){}
>>     else static assert(0, op ~ " not implemented");
>> }
>> ---
>>
>> you used the char litteral delims ('') instead of the strings ones ("").
>
> Ah yes, it's didnt' complain.

Actually, that sounds like a bug to me. Trying to compare a string against a character should be an error, even in compile time constraint I would think.

> But anyway that was the wrong funciton I
> implemented.

Yes, but still you should use opBinary, even though the D1 versions will likely exist forever. It can tremendously cut down on your code size, and reduce your exposure to simple copy/paste bugs.

-Steve