On 12/8/21 9:07 AM, Petar Kirov [ZombineDev] wrote:
On Wednesday, 8 December 2021 at 07:55:55 UTC, Timon Gehr wrote:
On 08.12.21 03:05, Andrey Zherikov wrote:
On Tuesday, 7 December 2021 at 18:50:04 UTC, Ali Çehreli wrote:
I don't know whether the workaround works with your program but that delegate is the equivalent of the following struct (the struct should be faster because there is no dynamic context allocation). Note the type of 'dg' is changed accordingly:

The problem with struct-based solution is that I will likely be stuck with only one implementation of delegate (i.e. opCall implementation). Or I'll have to implement dispatching inside opCall based on some "enum" by myself which seems weird to me. Do I miss anything?

This seems to work, maybe it is closer to what you are looking for.

...

Incidentally, yesterday I played with a very similar solution. Here's my version:

https://run.dlang.io/gist/PetarKirov/f347e59552dd87c4c02d0ce87d0e9cdc?compiler=dmd


```d
interface ICallable
{
     void opCall() const;
}

auto makeDelegate(alias fun, Args...)(auto ref Args args)
{
     return new class(args) ICallable
     {
         Args m_args;
         this(Args p_args) { m_args = p_args; }
         void opCall() const { fun(m_args); }
     };
}

alias Action = void delegate();

Action createDelegate(string s)
{
     import std.stdio;
     return &makeDelegate!((string str) => writeln(str))(s).opCall;
}

struct A
{
     Action[] dg;
}

A create()
{
     A a;
     a.dg ~= createDelegate("hello");
     a.dg ~= createDelegate("buy");
     return a;
}

void main()
{
     enum a = create();
     foreach(dg; a.dg)
         dg();
}
```

Nice, so the error message is lying. This is a bit more complete:

```d
import std.stdio, std.traits, core.lifetime;
auto partiallyApply(alias fun,C...)(C context){
    return &new class(move(context)){
        C context;
this(C context) { foreach(i,ref c;this.context) c=move(context[i]); }
        auto opCall(ParameterTypeTuple!fun[context.length..$] args) {
            return fun(context,forward!args);
        }
    }.opCall;
}

alias Action = void delegate();

Action createDelegate(string s){
    import std.stdio;
    return partiallyApply!((string str) => writeln(str))(s);
}

struct A{ Action[] dg; }

A create(){
    A a;
    a.dg ~= createDelegate("hello");
    a.dg ~= createDelegate("buy");
    return a;
}

void main(){
    enum a = create();
    foreach(dg; a.dg)
        dg();
}

```

Reply via email to