DMD 1.019 and 2.003 releases
Robert Fraser
fraserofthenight at gmail.com
Mon Jul 23 16:38:28 PDT 2007
Christian Kamm Wrote:
> The 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.
But there's still a niche for runtime reflection!
More information about the Digitalmars-d-announce
mailing list