Post by Christian KammThe extended compile time reflection opens the door for all kinds of cool
things! Here's an RTTI-Visitor, for instance.
It uses compile-time foreach to build a sequence of if-statements that check
the classinfo and call the matching method.
Regards,
Christian
// released into the public domain
import std.stdio;
class A
{}
class B : A
{}
class C : A
{}
class Dispatcher
{
void foo(A a)
{
writefln("A");
}
void foo(B b)
{
writefln("B");
}
mixin Dispatch!("foo");
}
class ExDispatcher : Dispatcher
{
alias Dispatcher.foo foo;
override void foo(B b)
{
writefln("B override");
}
void foo(C c)
{
writefln("C");
}
mixin Dispatch!("foo");
}
void main()
{
auto disp = new Dispatcher;
disp.dispatch(new A); // calls disp.foo(A)
disp.dispatch(new B); // calls disp.foo(B)
Dispatcher exdisp = new ExDispatcher;
exdisp.dispatch(new A); // calls disp.foo(A)
exdisp.dispatch(new B); // calls exdisp.foo(B)
exdisp.dispatch(new C); // calls exdisp.foo(C)
}
class MethodNotFoundException : Exception
{
this(string msg) { super(msg); }
}
template Dispatch(string fname)
{
mixin("alias typeof(" ~ fname ~ ") fsym;");
static if(is(fsym arg_types == function) && is(fsym return_type == return))
{
return_type dispatch(Object o, arg_types[1..$] params)
{
alias typeof(__traits(getVirtualFunctions, typeof(this), fname)) funcs;
foreach(i, func; funcs)
{
static if(is(func it_arg_types == function) && is(func it_return_type == return))
{
static assert(is(arg_types[1..$] == it_arg_types[1..$]) && is(return_type == it_return_type),
"Except for the first argument, the signature of all functions must be identical.");
static assert(is(it_arg_types[0] == class), "First argument must be a class type.");
if(it_arg_types[0].classinfo is o.classinfo)
return __traits(getVirtualFunctions, this, fname)[i](cast(it_arg_types[0]) o, params);
}
else
static assert(false, fname ~ " is not a function");
}
throw new MethodNotFoundException("No matching method '" ~ fname ~ "' found in " ~ this.classinfo.name ~ " for class " ~ o.classinfo.name);
}
}
else
static assert(false, fname ~ " is not a function");
}
Awesome! My first thought was generating hash functions for arbitrary structures, which would make using classes in AAs much easier.