www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Call method with Variant array as parameters

reply Andre Pany <andre s-e-a-p.de> writes:
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é
Jul 14 2018
parent reply Timoses <timosesu gmail.com> writes:
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); }
Jul 14 2018
parent Andre Pany <andre s-e-a-p.de> writes:
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
Jul 14 2018