www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - No need opUnary

reply Salih Dincer <salihdb hotmail.com> writes:
Don't you think it's interesting that it doesn't need unary 
operator overloading?

```d
import std.stdio;

struct S
{
   int value;

   alias opCall this;
   this(int i) {
     value = i;
   }

   alias opAssign = opCall;
    property opCall(int x) {
     return value = x;
   }

    property opCall() inout {
     return value;
   }

    property opOpAssign(string op)(int x) {
     write(":"); // came here before
     mixin("return value"~op~"=x;");
   }
   // no need: opUnary(string op)();
}

void main()
{

   S a = S(10),
     b = S(-1);

   writeln(a + b); // 9
   writeln(++a + b); // :10

   a += 10; // :

   assert(a == 21);
   writeln("\n--");

   writeln(-b); // 1
}
```
SDB 79
Dec 18 2022
next sibling parent reply j <my.email gmail.com> writes:
On Sunday, 18 December 2022 at 16:21:05 UTC, Salih Dincer wrote:
 Don't you think it's interesting that it doesn't need unary 
 operator overloading?

 ```d
 import std.stdio;

 struct S
 {
   int value;

   alias opCall this;
   this(int i) {
     value = i;
   }

   alias opAssign = opCall;
    property opCall(int x) {
     return value = x;
   }

    property opCall() inout {
     return value;
   }

    property opOpAssign(string op)(int x) {
     write(":"); // came here before
     mixin("return value"~op~"=x;");
   }
   // no need: opUnary(string op)();
 }

 void main()
 {

   S a = S(10),
     b = S(-1);

   writeln(a + b); // 9
   writeln(++a + b); // :10

   a += 10; // :

   assert(a == 21);
   writeln("\n--");

   writeln(-b); // 1
 }
 ```
 SDB 79
Why are you using property everywhere?
Dec 18 2022
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Sunday, 18 December 2022 at 21:17:02 UTC, j wrote:
 Why are you using ` property` everywhere?
You are right but if I don't use it for `opCall()` the output will be like `S(9)`. Likewise, if I don't use `inout`, the program is terminated. I think it's a bug with `std.format` that I said last time. Because in old versions it works whether you use `inout` or not. SDB 79
Dec 18 2022
parent reply j <my.email gmail.com> writes:
On Monday, 19 December 2022 at 04:26:39 UTC, Salih Dincer wrote:
 On Sunday, 18 December 2022 at 21:17:02 UTC, j wrote:
 Why are you using ` property` everywhere?
You are right but if I don't use it for `opCall()` the output will be like `S(9)`. Likewise, if I don't use `inout`, the program is terminated. I think it's a bug with `std.format` that I said last time. Because in old versions it works whether you use `inout` or not. SDB 79
Was my email deleted? Which compiler are you using?
Dec 18 2022
parent Salih Dincer <salihdb hotmail.com> writes:
On Monday, 19 December 2022 at 07:32:02 UTC, j wrote:
 Was my email deleted? Which compiler are you using?
Are you an AI engine? SDB 79
Dec 19 2022
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/18/22 08:21, Salih Dincer wrote:
 Don't you think it's interesting that it doesn't need unary operator
 overloading?
Yes, it is interesting. I put comments to explain it to myself: import std.stdio; struct S { int value; /* The folowing declaration allows objects of this type to be implicitly convertible to 'int' (the return type of 'opCall'). In other words, since opCall returns 'int', now we know S objects can implicitly be used in place of an int. The value will be determined by calling opCall. For those of us who may not know opCall, it allows an object to be used as a function. For example, when you have an 'obj', you can do 'obj()'. (And as seen below, it returns 'int' for this struct.) (Note: It confused me for a bit because there are two opCall definitions below and they both return 'int'. However, there is no ambiguity because the compiler picks the one that takes no parameter for the following alias this.) */ alias opCall this; this(int i) { value = i; } /* I didn't know one could do the following. You are giving a new name (opAssign) to opCall. I wonder whether the compiler considers opCall for the assignment operation or whether it looks for a proper opAssign definition. (Too lazy to check...) */ alias opAssign = opCall; /* This is the function call operator that takes an 'int', supporting usages like obj(42). */ property opCall(int x) { return value = x; } /* This is the function call opCall that takes nothing, supporting usages like obj(). */ property opCall() inout { return value; } /* This is the operator overload for usages like 'obj += 42'. */ property opOpAssign(string op)(int x) { write(":"); // came here before mixin("return value"~op~"=x;"); } // no need: opUnary(string op)(); } void main() { /* Ok, this is regular object construction. */ S a = S(10), /* Using a comma above is something I would never do but 'b' is another object being constructed regularly. */ b = S(-1); /* Since S does not define the '+' operation, I think the compiler looks and finds an implicit conversion, which happens to be to 'int'. I think the following expression is addition of two ints: 10 + (-1)' */ writeln(a + b); // 9 /* Although S does not support the ++ operator, the D compiler finds the += operation and replaces ++ with a+=1. And then a is implicitly converted to 'int', gets the value 11. Again, the expression is an int addition of 11 + (-1). */ writeln(++a + b); // :10 /* This uses opOpAssign. */ a += 10; // : /* This result makes sense. */ assert(a == 21); writeln("\n--"); writeln(-b); // 1 } Ali
Dec 19 2022