How to call a delegate held in a Variant array?

Adam D. Ruppe destructionator at gmail.com
Tue Sep 10 14:31:29 PDT 2013


On Tuesday, 10 September 2013 at 21:16:56 UTC, H. S. Teoh wrote:
> My first guess would be: _methods["test"]();

Variant doesn't wrap the function and thus won't know how to call 
it; it doesn't implement opCall, and even if it did, it won't 
know types the arguments and return value are.

My guess would be to get the static type:

auto dg = v.get!(void delegate());
dg();

........ except this is throwing at runtime:
Variant: attempting to use incompatible types void()* and void()*


Ugh, that's annoying. Maybe using Variant isn't the right way. 
The technique I use to for storing random methods is to store a 
wrapper function instead. The wrapper function converts all the 
arguments into one common type (e.g. Variant) so then your 
methods array can be one type of delegate instead of a Variant[].

Variant delegate(Variant[] args)[] _methods;
	public void addMethod(T)(string name, T func)
	{
		this._methods ~= delegate Variant(Variant[] args) {
                      import std.traits;
                      import std.conv;

                      ParameterTypeTuple!func argTuple;

                      foreach(idx, arg; argTuple) {
                          argTuple = args[idx].get!(typeof(arg));
                      }

                      Variant returned;
                      static if(is(ReturnType!func == void))
                           func(argTuple);
                      else
                           returned = func(argTuple);
                      return returned;
                 };
	}


Then, when you call it, the static type of the methods wrapper is 
always the same and you can handle arguments and return value by 
wrapping/unwrapping the Variants.

You might have to cast away const when assigning to the argTuple 
or prepopulate it with default arguments, etc. The code here will 
work in simple cases though to get you started.


More information about the Digitalmars-d-learn mailing list