Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Implementing run-time dispatch in D
import std.conv : to;
import std.meta : ApplyLeft, Filter;
import std.stdio : writef, writefln, writeln;
import std.variant : Variant;
void main()
{
auto c = new MyClass();
c.call("v0", [ ]);
c.call("v1", [ Variant(42), Variant("test") ]);
c.call("v2", [ Variant(42), Variant("test"), Variant(["test1", "test2"]) ]);
c.call("s0", [ ]).writeln;
c.call("s1", [ Variant(21) ]).writeln;
c.call("s2", [ Variant("hello "), Variant("world!") ]).writeln;
c.call("d3", [ Variant(0), Variant(3), Variant(4) ]).writeln;
}
class MyClass
{
void v0() { writeln("f0()"); }
void v1(int x, string y) { writefln("f1(%s, %s)", x, y); }
void v2(int x, string y, string[] z) { writefln("f2(%s, %s, %s)", x, y, z); }
string s0() { writef("s0() returns: "); return "some string"; }
string s1(int x) { writef("s1(%s) returns: ", x); return (x * 2).to!string; }
string s2(string x, string y) { writef("s2(%s, %s) returns: ", x, y); return x ~ y; }
double d3(double x, double y, double z) { writef("d3(%s, %s, %s) returns: ", x, y, z); return (x*x + y*y + z*z) ^^ 0.5; }
}
Variant call(T)(T self, string methodName, Variant[] args)
{
import std.traits : ReturnType, Parameters;
switch (methodName)
{
default:
throw new Exception("Unknown method: " ~ methodName);
static foreach (name; AllMemberFunctions!MyClass)
{
case name:
{
Parameters!(mixin("self." ~ name)) tuple;
static foreach (i; 0 .. tuple.length)
tuple[i] = args[i].get!(typeof(tuple[i]));
static if (is(ReturnType!(mixin("self." ~ name)) == void))
{
mixin("self." ~ name ~ "(tuple);");
return Variant();
}
else
return Variant(mixin("self." ~ name ~ "(tuple)"));
}
}
}
}
enum isMethod(T, string name) =
__traits(isVirtualFunction, mixin("T.init." ~ name));
alias AllMemberFunctions(T) = Filter!(
ApplyLeft!(isMethod, T), // filtering condition: each string must be the name of member function of T
__traits(allMembers, T) // sequence to filter: the names of all members of T
);
@PetarKirov

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.