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