Thread overview
Is it possible to override and overload class Object?
Sep 19
JG
Sep 19
sighoya
Sep 19
sighoya
Sep 19
sighoya
September 18

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?

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

September 19

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?

September 19

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:

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

September 19

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.

Was that your problem to be solved?

September 19

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

September 19

Hmm, is not updateing the url anymore, here is what I mean by code:

  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;
    }
  }
September 19

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:

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