www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is it possible to override and overload class Object?

reply Salih Dincer <salihdb hotmail.com> writes:
Hi All,

My problem is actually about the `new` operator.  As far as I 
know, we cannot overload it.  Therefore, all the operators that I 
use to create arrays with basic types work fine, but I need an 
extra struct Array to use it in my own type (struct Payload in 
the example).

Is there a simpler way to use the `+=` and `~=` operators on an 
array of my own type?

```d
struct Array(T)
{
   T* ptr;
   size_t length;
   
   ref auto opIndex(size_t i)
     => ptr[i];

   ref auto opIndex()
     => this;
   
   auto opSlice(size_t beg, size_t end)
     => Array(&ptr[beg], end - beg);

   void opOpAssign(string op)(int rhs)
   if(op == "+")
   {
     foreach(i; 0..length)
     {
       ptr[i] += rhs;
     }
   }

   void opOpAssign(string op)(string rhs)
   if(op == "~")
   {
     foreach(i; 0..length)
     {
       ptr[i] ~= rhs;
     }
   }

   auto toString(ToSink sink) const
   {
     sink("[");
     const limit = length - 1;
     foreach(i; 0..limit)
     {
       sink.fmt("%s, ", ptr[i]);
     }
     sink.fmt("%s]", ptr[limit]);
   }
}

struct Payload(T)
{
   string id;
   T value;

   alias opCall this;

   this(T x) { value = x; }

   auto opCall(T x)
     => value = x;

   auto opCall() inout
     => value;

   auto opOpAssign(string op : "+")(T x)
     => value += x;

   auto opOpAssign(string op : "~")(string x)
     => id ~= x;
   
   auto toString(ToSink sink) const
     => sink.fmt("%s: %s", id, value);
}

alias ToSink = void delegate(const(char)[]);

import std.stdio, std.format: fmt = formattedWrite;
alias Type =
     //Payload!
     int;
enum len = 4;

void main()
{
   auto arr = new Type[len];
   arr[] += Type(1);

   if(!is(Type == int))
     arr[] += cast(Type)1;
   arr.writeln;

   auto payloads = Array!Type(arr.ptr, arr.length);

   foreach(i; 0..len)
     payloads[i] = i + 1;

   payloads[] += 4;
   payloads.writeln;
   
   static if(!is(Type == int))
   {
     foreach(i, str; ["beş", "altı", "yedi", "sekiz"])
       payloads[i].id = str;
     payloads[] ~= " sayısı";
     payloads.writeln;
   }
}
```
**Playground:** https://run.dlang.io/is/qKKSok

Also please try and remove comment on line 74...

SDB 79
Sep 18 2023
next sibling parent reply JG <jg jg.com> writes:
On Monday, 18 September 2023 at 21:21:45 UTC, Salih Dincer wrote:
 Hi All,

 My problem is actually about the `new` operator.  As far as I 
 know, we cannot overload it.  Therefore, all the operators that 
 I use to create arrays with basic types work fine, but I need 
 an extra struct Array to use it in my own type (struct Payload 
 in the example).

 [...]
It is a bit unclear, what you want to achieve. Forgetting about the implementation what would you like to write but can't?
Sep 18 2023
parent Salih Dincer <salihdb hotmail.com> writes:
On Tuesday, 19 September 2023 at 06:28:07 UTC, JG wrote:
 It is a bit unclear, what you want to achieve. Forgetting about 
 the implementation what would you like to write but can't?
Actually, what I want to do is quite simple: The data kept as AA will be stored in a payload array and according to its value. But it's not enough! Because whenever I want, I have to add string to key(id) or change the value mathematically. I managed to do this, but it was a very winding road :( For example: ```d string[size_t] data; void main() { data = [0: "zero", 1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six"]; auto len = data.length; auto arr = new Type[len]; foreach(i, ref e; arr) { e = Type(data[i], cast(int)i); } auto pay = Array!Type(arr.ptr, len); pay[] ~= " quantity"; pay[] += 10; pay.writeln; /* Prints: [zero quantity: 10, one quantity: 11, two quantity: 12, three quantity: 13, four quantity: 14, five quantity: 15, six quantity: 16] //*/ } ``` SDB 79
Sep 19 2023
prev sibling next sibling parent sighoya <sighoya gmail.com> writes:
On Monday, 18 September 2023 at 21:21:45 UTC, Salih Dincer wrote:
 Also please try and remove comment on line 74...

 SDB 79
Adding a semicolon should [do it](https://run.dlang.io/?compiler=dmd&source=struct%20Array(T)%0A%7B%0A%20%20T*%20ptr;%0A%20%C2%A0size_t%20length;%0A%20%C2%A0%0A%20%C2%A0ref%20auto%20opIndex(size_t%20i)%0A%20%20%20%20%3D%3E%20ptr%5Bi%5D;%0A%20%20%0A%20%C2%A0ref%20auto%20opIndex()%0A%20%20%20%20%3D%3E%20this;%0A%20%C2%A0%0A%20%20auto%20opSlice(size_t%20beg,%20size_t%20end)%0A%20%C2%A0%20%C2%A0%3D%3E%20Array(%26ptr%5Bbeg%5D,%20end%20-%20beg);%0A%0A%20%C2%A0void%20opOpAssign(string%20op)(int%20rhs)%20%0A%20%C2%A0if(op%20%3D%3D%20%22%2B%22)%0A%20%20%7B%0A%20%20%20%20foreach(i;%200..length)%0A%20%20%20%20%7B%0A%20%C2%A0%20%C2%A0%20%C2%A0ptr%5Bi%5D%20%2B%3D%20rhs;%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%20%20%0A%20%C2%A0void%20opOpAssign(string%20op)(string%20rhs)%20%0A%20%C2%A0if(op%20%3D%3D%20%22~%22)%0A%20%20%7B%0A%20%20%20%20foreach(i;%200..length)%0A%20%20%20%20%7B%0A%20%C2%A0%20%C2%A0%20%C2%A0ptr%5Bi%5D%20~%3D%20rhs;%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%0A%20%C2%A0auto%20toString(ToSink%20sink)%20const%0A%20%20%7B%0A%20%20%20%20sink(%22%5B%22);%0A%20%20%20%20const%20limit%20%3D%20length%20-%201;%0A%20%20%20%20foreach(i;%200..limit)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20sink.fmt(%22%25s,%20%22,%20ptr%5Bi%5D);%0A%20%20%20%20%7D%0A%20%20%20%20sink.fmt(%22%25s%5D%22,%20ptr%5Blimit%5D);%0A%20%20%7D%0A%7D%0A%0Astruct%20Payload(T)%0A%7B%0A%20%20string%20id;%0A%20%C2%A0T%20value;%0A%20%20%20%20%0A%20%20alias%20opCall%20this;%0A%20%0A%20%C2%A0this(T%20x)%20%7B%20value%20%3D%20x;%20%7D%0A%20%20%0A%20%C2%A0auto%20opCall(T%20x)%0A%20%20%20%20%3D%3E%20value%20%3D%20x;%0A%20%20%0A%20%C2%A0auto%20opCall()%20inout%0A%20%20%20%20%3D%3E%20value;%0A%20%20%0A%20%C2%A0auto%20opOpAssign(string%20op%20:%20%22%2B%22)(T%20x)%0A%20%C2%A0%20%C2%A0%3D%3E%20value%20%2B%3D%20x;%0A%20%20%0A%20%C2%A0auto%20opOpAssign(string%20op%20:%20%22~%22)(string%20x)%0A%20%C2%A0%20%C2%A0%3D%3E%20id%20~%3D%20x;%0A%20%C2%A0%0A%20%20auto%20toString(ToSink%20sink)%20const%0A%20%C2%A0%20%C2%A0%3D%3E%20sink.fmt(%22%25s:%20%25s%22,%20id,%20value);%0A%7D%0A%0Aalias%20ToSink%20%3D%20void%20delegate(const(char)%5B%5D);%0A%0Aimport%20std.stdio,%20std.format:%20fmt%20%3D%20formattedWrite;%0Aalias%20Type%20%3D%0A%20%C2%A0%20%C2%A0%2F%2FPayload!%0A%20%C2%A0%20%C2%A0int;%0Aenum%20len%20%3D%204;%0A%0Avoid%20main()%20%0A%7B%0A%20%C2%A0auto%20arr%20%3D%20new%20Type%5Blen%5D;%0A%20%C2%A0arr%5B%5D%20%2B%3D%20Type(1);%0A%20%20%0A%20%C2%A0if(!is(Type%20%3D%3D%20int))%0A%20%C2%A0%20%C2%A0arr%5B%5D%20%2B%3D%20cast(Type)1;%0A%20%C2%A0arr.writeln;%0A%20%20%20%20%0A%20%C2%A0auto%20payloads%20%3D%20Array!Type(arr.ptr,%20arr.length);%0A%20%20%0A%20%C2%A0foreach(i;%200..len)%0A%20%C2%A0%20%C2%A0payloads%5Bi%5D%20%3D%20i%20%2B%201;%0A%20%0A%20%C2%A0payloads%5B%5D%20%2B%3D%204;%0A%20%20payloads.writeln;%0A%20%C2%A0%0A%20%C2%A0static%20if(!is(Type%20%3D%3D%20int))%0A%20%20%7B%0A%20%20%20%C2%A0foreach(i,%20str;%20%5B%22be%C5%9F%22,%20%22alt%C4%B1%22,%20%22yedi%22,%20%22sekiz%22%5D)%0A%20%C2%A0%20%20%C2%A0%20payloads%5Bi%5D.id%20%3D%20str;%0A%20%C2%A0%20%20payloads%5B%5D%20~%3D%20%22%20say%C4%B1s%C4%B1%22;%0A%20%20%20%C2%A0payloads.writeln;%0A%20%C2%A0%7D%0A%7D). Was that your problem to be solved?
Sep 19 2023
prev sibling parent reply sighoya <sighoya gmail.com> writes:
On Monday, 18 September 2023 at 21:21:45 UTC, Salih Dincer wrote:
[...]
Maybe your goal was to use the same operator and to switch by type, should be possible, [see here](https://run.dlang.io/?compiler=dmd&source=struct%20Array(T)%0A%7B%0A%20%20T*%20ptr;%0A%20%C2%A0size_t%20length;%0A%20%C2%A0%0A%20%C2%A0ref%20auto%20opIndex(size_t%20i)%0A%20%20%20%20%3D%3E%20ptr%5Bi%5D;%0A%20%20%0A%20%C2%A0ref%20auto%20opIndex()%0A%20%20%20%20%3D%3E%20this;%0A%20%C2%A0%0A%20%20auto%20opSlice(size_t%20beg,%20size_t%20end)%0A%20%C2%A0%20%C2%A0%3D%3E%20Array(%26ptr%5Bbeg%5D,%20end%20-%20beg);%0A%0A%20%C2%A0void%20opOpAssign(string%20op)(int%20rhs)%20%0A%20%C2%A0if(op%20%3D%3D%20%22%2B%22)%0A%20%20%7B%0A%20%20%20%20foreach(i;%200..length)%0A%20%20%20%20%7B%0A%20%C2%A0%20%C2%A0%20%C2%A0ptr%5Bi%5D%20%2B%3D%20rhs;%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%20%20%0A%20%C2%A0void%20opOpAssign(string%20op)(string%20rhs)%20%0A%20%C2%A0if(op%20%3D%3D%20%22~%22)%0A%20%20%7B%0A%20%20%20%20foreach(i;%200..length)%0A%20%20%20%20%7B%0A%20%C2%A0%20%C2%A0%20%C2%A0ptr%5Bi%5D%20~%3D%20rhs;%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%0A%20%C2%A0auto%20toString(ToSink%20sink)%20const%0A%20%20%7B%0A%20%20%20%20sink(%22%5B%22);%0A%20%20%20%20const%20limit%20%3D%20length%20-%201;%0A%20%20%20%20foreach(i;%200..limit)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20sink.fmt(%22%25s,%20%22,%20ptr%5Bi%5D);%0A%20%20%20%20%7D%0A%20%20%20%20sink.fmt(%22%25s%5D%22,%20ptr%5Blimit%5D);%0A%20%20%7D%0A%7D%0A%0Astruct%20Payload(T)%0A%7B%0A%20%20string%20id;%0A%20%C2%A0T%20value;%0A%20%20%20%20%0A%20%20alias%20opCall%20this;%0A%20%0A%20%C2%A0this(T%20x)%20%7B%20value%20%3D%20x;%20%7D%0A%20%20%0A%20%C2%A0auto%20opCall(T%20x)%0A%20%20%20%20%3D%3E%20value%20%3D%20x;%0A%20%20%0A%20%C2%A0auto%20opCall()%20inout%0A%20%20%20%20%3D%3E%20value;%0A%20%20%0A%20%C2%A0auto%20opOpAssign(string%20op%20:%20%22%2B%22)(T%20x)%0A%20%C2%A0%20%C2%A0%3D%3E%20value%20%2B%3D%20x;%0A%20%20%0A%20%C2%A0auto%20opOpAssign(string%20op%20:%20%22~%22)(string%20x)%0A%20%C2%A0%20%C2%A0%3D%3E%20id%20~%3D%20x;%0A%20%C2%A0%0A%20%20auto%20toString(ToSink%20sink)%20const%0A%20%C2%A0%20%C2%A0%3D%3E%20sink.fmt(%22%25s:%20%25s%22,%20id,%20value);%0A%7D%0A%0Aalias%20ToSink%20%3D%20void%20delegate(const(char)%5B%5D);%0A%0Aimport%20std.stdio,%20std.format:%20fmt%20%3D%20formattedWrite;%0Aalias%20Type%20%3D%0A%20%C2%A0%20%C2%A0%2F%2FPayload!%0A%20%C2%A0%20%C2%A0int;%0Aenum%20len%20%3D%204;%0A%0Avoid%20main()%20%0A%7B%0A%20%C2%A0auto%20arr%20%3D%20new%20Type%5Blen%5D;%0A%20%C2%A0arr%5B%5D%20%2B%3D%20Type(1);%0A%20%20%0A%20%C2%A0if(!is(Type%20%3D%3D%20int))%0A%20%C2%A0%20%C2%A0arr%5B%5D%20%2B%3D%20cast(Type)1;%0A%20%C2%A0arr.writeln;%0A%20%20%20%20%0A%20%C2%A0auto%20payloads%20%3D%20Array!Type(arr.ptr,%20arr.length);%0A%20%20%0A%20%C2%A0foreach(i;%200..len)%0A%20%C2%A0%20%C2%A0payloads%5Bi%5D%20%3D%20i%20%2B%201;%0A%20%0A%20%C2%A0payloads%5B%5D%20%2B%3D%204;%0A%20%20payloads.writeln;%0A%20%C2%A0%0A%20%C2%A0static%20if(!is(Type%20%3D%3D%20int))%0A%20%20%7B%0A%20%20%20%C2%A0foreach(i,%20str;%20%5B%22be%C5%9F%22,%20%22alt%C4%B1%22,%20%22yedi%22,%20%22sekiz%22%5D)%0A%20%C2%A0%20%20%C2%A0%20payloads%5Bi%5D.id%20%3D%20str;%0A%20%C2%A0%20%20payloads%5B%5D%20~%3D%20%22%20say%C4%B1s%C4%B1%22;%0A%20%20%20%C2%A0payloads.writeln;%0A%20%C2%A0%7D%0A%7D)
Sep 19 2023
parent reply sighoya <sighoya gmail.com> writes:
Hmm, is not updateing the url anymore, here is what I mean by 
code:
```d
   void opOpAssign(string op,T:int)(T rhs)
   if(op == "+")
   {
     foreach(i; 0..length)
     {
       ptr[i] += rhs;
     }
   }

   void opOpAssign(string op,T:string)(T rhs)
   if(op == "+")
   {
     foreach(i; 0..length)
     {
       ptr[i] ~= rhs;
     }
   }
```
Sep 19 2023
parent Salih Dincer <salihdb hotmail.com> writes:
On Tuesday, 19 September 2023 at 16:47:14 UTC, sighoya wrote:
 Hmm, is not updateing the url anymore, here is what I mean by 
 code
Your suggestion brought this solution to my mind. It looks really delicious, thank you: ```d void opOpAssign(string op: "+", R)(R rhs) { import std.traits; static if(isNumeric!R) foreach(i; 0..length) ptr[i] += rhs; else foreach(i; 0..length) ptr[i] ~= rhs; } ``` Both structures are not even 60 lines total. I like this last edit: https://run.dlang.io/is/Ciusqs SDB 79
Sep 19 2023