Thread overview
Call method with Variant array as parameters
Jul 14, 2018
Andre Pany
Jul 14, 2018
Timoses
Jul 14, 2018
Andre Pany
July 14, 2018
Hi,

I have a class with methods and I want to call a method by using a variant array.
The length of the array and the types exactly fits the method signature.

In the last line of main you see the coding which should be generated.
I need some coding which looks at the signature of bar and uses this information
to create "(args[0].get!string, args[1].get!long)".

I think it is possible with string mixins, but is there some better way?
Maybe a staticMap?

class Foo
{
    void bar(string s, long l) {}
}

void main()
{
    import std.variant: Variant;

    Foo foo = new Foo();

    Variant[] args = [Variant("Hello"), Variant(42)];
    __traits(getMember, foo, "bar")(args[0].get!string, args[1].get!long);
}

Kind regards
André
July 14, 2018
On Saturday, 14 July 2018 at 11:08:21 UTC, Andre Pany wrote:
> Hi,
>
> I have a class with methods and I want to call a method by using a variant array.
> The length of the array and the types exactly fits the method signature.
>
> In the last line of main you see the coding which should be generated.
> I need some coding which looks at the signature of bar and uses this information
> to create "(args[0].get!string, args[1].get!long)".
>
> I think it is possible with string mixins, but is there some better way?
> Maybe a staticMap?
>
> class Foo
> {
>     void bar(string s, long l) {}
> }
>
> void main()
> {
>     import std.variant: Variant;
>
>     Foo foo = new Foo();
>
>     Variant[] args = [Variant("Hello"), Variant(42)];
>     __traits(getMember, foo, "bar")(args[0].get!string, args[1].get!long);
> }
>
> Kind regards
> André

How about this?


import std.variant: Variant;
import std.traits : isCallable;

class Foo
{
    void bar(string s, long l)
    {
        import std.stdio : writeln;
        writeln(s); writeln(l);
    }
}

void call(T)(T fun, in Variant[] args)
         if (isCallable!fun)
{
    import std.traits : Parameters;
    alias Params = Parameters!fun;

    Params params;
    static foreach(i, param; params)
    {
        if (auto p = args[i].peek!(Params[i]))
        {
         	param = *p;
        }
        // perhaps create a warning if peeking was unsuccessful...
    }
    fun(params);
}

unittest
{
    Foo foo = new Foo();
    Variant[] args = [Variant("Hello"), Variant(42L)];
    call(&foo.bar, args);
}
July 14, 2018
On Saturday, 14 July 2018 at 11:37:20 UTC, Timoses wrote:
> On Saturday, 14 July 2018 at 11:08:21
>
> How about this?
>
>
> import std.variant: Variant;
> import std.traits : isCallable;
>
> class Foo
> {
>     void bar(string s, long l)
>     {
>         import std.stdio : writeln;
>         writeln(s); writeln(l);
>     }
> }
>
> void call(T)(T fun, in Variant[] args)
>          if (isCallable!fun)
> {
>     import std.traits : Parameters;
>     alias Params = Parameters!fun;
>
>     Params params;
>     static foreach(i, param; params)
>     {
>         if (auto p = args[i].peek!(Params[i]))
>         {
>          	param = *p;
>         }
>         // perhaps create a warning if peeking was unsuccessful...
>     }
>     fun(params);
> }
>
> unittest
> {
>     Foo foo = new Foo();
>     Variant[] args = [Variant("Hello"), Variant(42L)];
>     call(&foo.bar, args);
> }

Thank you so much!

Kind regards
Andre